Add linux emulator platform

This commit is contained in:
Thomas Langewouters 2021-03-01 21:38:45 +01:00
parent 0ca341a7ae
commit 67a63105ce
20 changed files with 377 additions and 65 deletions

View File

@ -107,6 +107,7 @@
#ifdef WINDOWS
#include "winsock2.h"
#include "Windows.h"
#elif defined(POSIX)
#else
#include "Arduino.h"
#endif
@ -183,7 +184,7 @@ static WiFiSpiClass WiFi;
#if HASP_USE_MQTT > 0
#include "mqtt/hasp_mqtt.h"
#ifdef WINDOWS
#if defined(WINDOWS) || defined(POSIX)
#define USE_PAHO
#else
#define USE_PUBSUBCLIENT
@ -230,7 +231,7 @@ static WiFiSpiClass WiFi;
#define PGM_P const char*
#endif
#if defined(WINDOWS)
#if defined(WINDOWS) || defined(POSIX)
#ifndef __FlashStringHelper
#define __FlashStringHelper char
#endif
@ -248,11 +249,17 @@ static WiFiSpiClass WiFi;
#endif
#endif
#ifdef WINDOWS
#if defined(WINDOWS)
#include <Windows.h>
#define delay Sleep
#endif
#if defined(POSIX)
#define delay SDL_Delay
#endif
#if defined(WINDOWS) || defined(POSIX)
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <Windows.h>
#include <SDL2/SDL.h>
#define snprintf_P snprintf
@ -261,7 +268,6 @@ static WiFiSpiClass WiFi;
#define strcmp_P strcmp
#define strstr_P strstr
#define halRestartMcu()
#define delay Sleep
#define millis SDL_GetTicks
#define DEC 10
@ -275,4 +281,4 @@ static WiFiSpiClass WiFi;
//#define guiCalibrate()
#endif
#endif // HASP_CONF_H
#endif // HASP_CONF_H

View File

@ -1,7 +1,7 @@
#ifndef HASP_MACRO_H
#define HASP_MACRO_H
#ifdef WINDOWS
#if defined(WINDOWS) || defined(POSIX)
#define LOG_OUTPUT(x, ...) printf(__VA_ARGS__)
#else
#define LOG_OUTPUT(...) Log.output(...)
@ -69,4 +69,4 @@
#endif
#endif
#endif

View File

@ -2,7 +2,7 @@
* INCLUDES
*********************/
#ifndef WINDOWS
#if !(defined(WINDOWS)||defined(POSIX))
#include <Arduino.h>
#include <stdio.h>

View File

@ -8,8 +8,13 @@
#include "Arduino.h"
#endif
#ifdef WINDOWS
#if defined(WINDOWS) || defined(POSIX)
#include <cstdint>
#endif
#if defined(POSIX)
#include <stddef.h>
#endif
#ifdef WINDOWS
#include "Windows.h"
#endif
@ -97,10 +102,14 @@ class BaseDevice {
#elif defined(WINDOWS)
#warning Building for Win32 Devices
#include "win32/hasp_win32.h"
#elif defined(POSIX)
#warning Building for Posix Devices
#include "posix/hasp_posix.h"
#else
#warning Building for Generic Devices
using dev::BaseDevice;
extern dev::BaseDevice haspDevice;
#endif
#endif
#endif

View File

@ -0,0 +1,108 @@
#if defined(POSIX)
#include <cstdint>
#include "hasp_posix.h"
#include "hasp_conf.h"
#include "hasp/hasp_utilities.h"
#include "hasp_debug.h"
#include "display/monitor.h"
namespace dev {
void PosixDevice::reboot()
{}
void PosixDevice::show_info()
{
LOG_VERBOSE(0, F("Processor : %s"), "unknown");
LOG_VERBOSE(0, F("CPU freq. : %i MHz"), 0);
}
const char* PosixDevice::get_hostname()
{
return _hostname.c_str();
}
void PosixDevice::set_hostname(const char* hostname)
{
_hostname = hostname;
}
const char* PosixDevice::get_core_version()
{
return "posix";
}
const char* PosixDevice::get_display_driver()
{
return "SDL2";
}
void PosixDevice::set_backlight_pin(uint8_t pin)
{
// PosixDevice::backlight_pin = pin;
}
void PosixDevice::set_backlight_level(uint8_t level)
{
uint8_t new_level = level >= 0 ? level : 0;
new_level = new_level <= 100 ? new_level : 100;
if(_backlight_level != new_level)
{
_backlight_level = new_level;
update_backlight();
}
}
uint8_t PosixDevice::get_backlight_level()
{
return _backlight_level;
}
void PosixDevice::set_backlight_power(bool power)
{
_backlight_power = power;
update_backlight();
}
bool PosixDevice::get_backlight_power()
{
return _backlight_power != 0;
}
void PosixDevice::update_backlight()
{
monitor_backlight(_backlight_power ? map(_backlight_level, 0, 100, 0, 255) : 0);
}
size_t PosixDevice::get_free_max_block()
{
return 0;
}
size_t PosixDevice::get_free_heap(void)
{
return 0;
}
uint8_t PosixDevice::get_heap_fragmentation()
{
return 0;
}
uint16_t PosixDevice::get_cpu_frequency()
{
return 0;
}
bool PosixDevice::is_system_pin(uint8_t pin)
{
return false;
}
} // namespace dev
dev::PosixDevice haspDevice;
#endif // POSIX

View File

@ -0,0 +1,76 @@
/* MIT License - Copyright (c) 2020 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef HASP_DEVICE_POSIX_H
#define HASP_DEVICE_POSIX_H
#include <cstdint>
#include <cstddef>
extern "C"
{
#include <inttypes.h>
#include <stdlib.h>
#include <stddef.h>
}
#include "hasp_conf.h"
#include "../device.h"
#if defined(POSIX)
static inline void itoa(int i, char *out, int unused_)
{
(void) unused_;
sprintf(out, "%d", i);
}
namespace dev {
class PosixDevice : public BaseDevice {
public:
PosixDevice()
{
_hostname = "localhost";
_backlight_power = 1;
_backlight_level = 100;
}
void reboot() override;
void show_info() override;
const char* get_hostname();
void set_hostname(const char*);
const char* get_core_version();
const char* get_display_driver();
void set_backlight_pin(uint8_t pin);
void set_backlight_level(uint8_t val);
uint8_t get_backlight_level();
void set_backlight_power(bool power);
bool get_backlight_power();
size_t get_free_max_block();
size_t get_free_heap();
uint8_t get_heap_fragmentation();
uint16_t get_cpu_frequency();
bool is_system_pin(uint8_t pin) override;
private:
std::string _hostname;
uint8_t _backlight_pin;
uint8_t _backlight_level;
uint8_t _backlight_power;
void update_backlight();
};
} // namespace dev
using dev::PosixDevice;
extern dev::PosixDevice haspDevice;
#endif // POSIX
#endif // HASP_DEVICE_POSIX_H

View File

@ -40,7 +40,7 @@ class BaseTft {
#elif defined(STM32F4)
#warning Building for STM32F4xx Devices
#include "tft_driver_tftespi.h"
#elif defined(WINDOWS)
#elif defined(WINDOWS) || defined(POSIX)
#warning Building for Win32 Devices
#include "tft_driver_sdl2.h"
#else
@ -49,4 +49,4 @@ using dev::BaseTft;
extern dev::BaseTft haspTft;
#endif
#endif
#endif

View File

@ -14,7 +14,7 @@
#include "../hasp_debug.h"
#include "hasp_gui.h" // for screenshot
#if WINDOWS
#if defined(WINDOWS) || defined(POSIX)
#include <iostream>
#include <fstream>
#include <sstream>
@ -878,7 +878,7 @@ void dispatch_reboot(bool saveConfig)
LOG_VERBOSE(TAG_MSGR, F("-------------------------------------"));
LOG_TRACE(TAG_MSGR, F(D_DISPATCH_REBOOT));
#if WINDOWS
#if defined(WINDOWS) || defined(POSIX)
fflush(stdout);
#else
Serial.flush();
@ -1039,4 +1039,4 @@ void everySecond()
}
}
}
#endif
#endif

View File

@ -597,7 +597,7 @@ void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char* attr, con
int hasp_parse_json_attributes(lv_obj_t* obj, const JsonObject& doc)
{
int i = 0;
#ifdef WINDOWS
#if defined(WINDOWS) || defined(POSIX)
// String v((char *)0);
// v.reserve(64);
std::string v;
@ -1043,4 +1043,4 @@ void hasp_object_delete(lv_obj_t* obj)
// TODO: delete value_str data for ALL parts
my_obj_set_value_str_txt(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, NULL);
}
}

View File

@ -10,7 +10,7 @@
#include "lang/lang.h"
#ifndef WINDOWS
#if (!defined(WINDOWS)) && (!defined(POSIX))
#include "ArduinoLog.h"
/* ===== Default Event Processors ===== */

View File

@ -26,7 +26,7 @@
#include "hasp/hasp_dispatch.h"
#include "hasp/hasp.h"
#ifdef WINDOWS
#if defined(WINDOWS) || defined(POSIX)
#include "display/monitor.h"
#include "indev/mouse.h"
#endif
@ -152,7 +152,7 @@ void guiSetup(void)
const size_t guiVDBsize = 2 * 512u; // 4 KBytes * 2
guiVdbBuffer1 = (lv_color_t*)malloc(sizeof(lv_color_t) * guiVDBsize);
#elif defined(WINDOWS)
#elif defined(WINDOWS) || defined(POSIX)
const size_t guiVDBsize = LV_HOR_RES_MAX * 10;
static lv_color_t guiVdbBuffer1[guiVDBsize]; /*Declare a buffer for 10 lines*/
@ -224,7 +224,7 @@ void guiSetup(void)
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
#if defined(WINDOWS)
#if defined(WINDOWS) || defined(POSIX)
indev_drv.read_cb = mouse_read;
#else
indev_drv.read_cb = drv_touch_read;
@ -256,7 +256,7 @@ void guiSetup(void)
lv_indev_set_cursor(mouse_indev, cursor); /*Connect the image object to the driver*/
}
#if !defined(WINDOWS)
#if !(defined(WINDOWS) || defined(POSIX))
drv_touch_init(gui_settings.rotation); // Touch driver
#endif
@ -285,7 +285,7 @@ void guiLoop(void)
// tick.update();
#endif
#if !defined(WINDOWS)
#if !(defined(WINDOWS) || defined(POSIX))
drv_touch_loop(); // update touch
#endif
}
@ -623,4 +623,4 @@ void guiTakeScreenshot()
LOG_ERROR(TAG_GUI, F("Data sent does not match header size"));
}
}
#endif
#endif

View File

@ -1,7 +1,7 @@
/* MIT License - Copyright (c) 2019-2021 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifndef WINDOWS
#if !(defined(WINDOWS) || defined(POSIX))
#include <Arduino.h>
#include "lvgl.h"
@ -164,4 +164,4 @@ void loop()
#endif
}
#endif
#endif

View File

@ -1,9 +1,14 @@
/* MIT License - Copyright (c) 2019-2021 Francis Van Roie
For full license information read the LICENSE file in the project folder */
#ifdef WINDOWS
#if defined(WINDOWS)
#include <windows.h>
#endif
#if defined(POSIX)
#include <netdb.h>
#include <unistd.h>
#endif
#include <cstdlib>
#include <iostream>
@ -27,6 +32,7 @@ bool isRunning = 1;
uint8_t mainLoopCounter = 0;
unsigned long mainLastLoopTime = 0;
#if defined(WINDOWS)
// https://gist.github.com/kingseva/a918ec66079a9475f19642ec31276a21
void BindStdHandlesToConsole()
{
@ -86,6 +92,7 @@ void InitializeConsoleOutput()
// Redirect all standard output streams to the console
BindStdHandlesToConsole();
}
#endif
void debugLvglLogEvent(lv_log_level_t level, const char* file, uint32_t line, const char* funcname, const char* descr)
{
@ -121,11 +128,14 @@ void setup()
mainLastLoopTime = millis() - 1000; // reset loop counter
delay(250);
printf("%s %d\n", __FILE__, __LINE__);
}
void loop()
{
printf("1 \n");
haspLoop();
printf("2 \n");
mqttLoop();
// debugLoop(); // Console
@ -156,11 +166,11 @@ void loop()
}
mainLastLoopTime += 1000;
}
printf("loop\n");
// delay(6);
}
#ifdef WINDOWS
#if defined(WINDOWS) || defined(POSIX)
void usage(char* progName)
{
@ -181,18 +191,20 @@ void usage(char* progName)
// << " -v | --verbose Verbosity level" << std::endl
<< std::endl;
fflush(stdout);
#if defined(WINDOWS)
static const char s[] = "\n";
DWORD slen = lstrlen(s);
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE), s, slen, &slen, NULL);
#endif
}
int main(int argc, char* argv[])
{
bool showhelp = false;
int count;
#ifdef WINDOWS
InitializeConsoleOutput();
#endif
haspDevice.show_info();
@ -221,6 +233,7 @@ int main(int argc, char* argv[])
for(count = 0; count < argc; count++)
std::cout << " argv[" << count << "] " << argv[count] << "\n" << std::endl << std::flush;
#if defined(WINDOWS)
SetConsoleCP(65001); // 65001 = UTF-8
static const char s[] = "tränenüberströmt™\n";
DWORD slen = lstrlen(s);
@ -233,7 +246,7 @@ int main(int argc, char* argv[])
if(!WriteConsole(std_out, "Hello World!", 12, NULL, NULL)) {
// return 67;
}
#endif
for(count = 0; count < argc; count++) {
if(argv[count][0] == '-') {
@ -257,24 +270,29 @@ int main(int argc, char* argv[])
if(showhelp) {
usage("hasp-lvgl");
#if defined(WINDOWS)
WriteConsole(std_out, "bye", 3, NULL, NULL);
FreeConsole();
#endif
return 0;
}
// printf("%s %d\n", __FILE__, __LINE__);
// fflush(stdout);
printf("pre setup\n");
setup();
printf("to loop\n");
while(isRunning) {
loop();
// std::cout << "HSetup OK\n";
}
printf("endrunning\n");
return 0;
}
#endif
#endif
#endif

View File

@ -9,7 +9,7 @@
#include "hasp_conf.h"
#ifdef WINDOWS
#if defined(WINDOWS) || defined(POSIX)
#define __FlashStringHelper char
#endif
@ -35,4 +35,4 @@ bool mqttSetConfig(const JsonObject& settings);
// String mqttGetNodename(void);
// #endif
#endif
#endif

View File

@ -29,7 +29,7 @@ const char FP_MQTT_HA_NAME[] PROGMEM = "name";
const char FP_MQTT_HA_MODEL[] PROGMEM = "mdl";
const char FP_MQTT_HA_MANUFACTURER[] PROGMEM = "mf";
#ifndef WINDOWS
#if !(defined(WINDOWS) || defined(POSIX))
#include "hal/hasp_hal.h"

View File

@ -433,4 +433,4 @@ void mqttLoop(){};
void mqttEvery5Seconds(bool wifiIsConnected){};
#endif // USE_PAHO
#endif // USE_MQTT
#endif // USE_MQTT

View File

@ -6,28 +6,4 @@ for e in [ env, projenv ]:
if "-m32" in e['CCFLAGS']:
e.Append(LINKFLAGS = ["-m32"])
env.Append(
LINKFLAGS=[
"-static",
"-static-libgcc",
"-static-libstdc++"
]
)
# Override unused "upload" to execute compiled binary
from SCons.Script import AlwaysBuild
AlwaysBuild(env.Alias("build", "$BUILD_DIR/${PROGNAME}", "$BUILD_DIR/${PROGNAME}"))
# Add custom target to explorer
env.AddTarget(
name = "execute",
dependencies = "$BUILD_DIR\${PROGNAME}.exe",
actions = "$BUILD_DIR\${PROGNAME}.exe",
# actions = 'cmd.exe /C "start cmd.exe /C $BUILD_DIR\${PROGNAME}.exe"',
title = "Execute",
description = "Build and execute",
group="General"
)
#print('=====================================')
#print(env.Dump())

View File

@ -0,0 +1,25 @@
env.Append(
LINKFLAGS=[
"-static",
"-static-libgcc",
"-static-libstdc++"
]
)
# Override unused "upload" to execute compiled binary
from SCons.Script import AlwaysBuild
AlwaysBuild(env.Alias("build", "$BUILD_DIR/${PROGNAME}", "$BUILD_DIR/${PROGNAME}"))
# Add custom target to explorer
env.AddTarget(
name = "execute",
dependencies = "$BUILD_DIR\${PROGNAME}.exe",
actions = "$BUILD_DIR\${PROGNAME}.exe",
# actions = 'cmd.exe /C "start cmd.exe /C $BUILD_DIR\${PROGNAME}.exe"',
title = "Execute",
description = "Build and execute",
group="General"
)
#print('=====================================')
#print(env.Dump())

View File

@ -0,0 +1,92 @@
[env:emulator_64bits]
platform = native@^1.1.3
extra_scripts = tools/sdl2_build_extra.py
build_flags =
${env.build_flags}
; ----- Monitor
-D TFT_WIDTH=240
-D TFT_HEIGHT=320
; SDL drivers options
;-D LV_LVGL_H_INCLUDE_SIMPLE
;-D LV_DRV_NO_CONF
-D LV_MEM_SIZE=262144U ; 256kB lvgl memory
-D USE_MONITOR
-D MONITOR_ZOOM=1 ; can be fractional like 1.5 or 2
-D USE_MOUSE
-D USE_MOUSEWHEEL
-D USE_KEYBOARD
; ----- ArduinoJson
-D ARDUINOJSON_DECODE_UNICODE=1
-D HASP_NUM_PAGES=12
-D HASP_USE_SPIFFS=0
-D HASP_USE_LITTLEFS=0
-D HASP_USE_EEPROM=0
-D HASP_USE_GPIO=0
-D HASP_USE_CONFIG=0 ; Standalone application, as library
-D HASP_USE_DEBUG=1
-D HASP_USE_MQTT=1
-D MQTT_MAX_PACKET_SIZE=2048
;-D LV_LOG_LEVEL=LV_LOG_LEVEL_INFO
;-D LV_LOG_PRINTF=1
; Add recursive dirs for hal headers search
-D POSIX
-D PAHO_MQTT_STATIC
-DPAHO_WITH_SSL=TRUE
-DPAHO_BUILD_DOCUMENTATION=FALSE
-DPAHO_BUILD_SAMPLES=FALSE
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_VERBOSE_MAKEFILE=TRUE
;-D NO_PERSISTENCE
-I.pio/libdeps/emulator_64bits/paho/src
-I.pio/libdeps/emulator_64bits/ArduinoJson/src
-I lib/ArduinoJson/src
-I lib/lv_fs_if
!python -c "import os; print(' '.join(['-I {}'.format(i[0].replace('\x5C','/')) for i in os.walk('hal/sdl2')]))"
; ----- Statically linked libraries --------------------
-lSDL2
-lm
-lpthread
lib_deps =
${env.lib_deps}
;lv_drivers@~7.9.0
;lv_drivers=https://github.com/littlevgl/lv_drivers/archive/7d71907c1d6b02797d066f50984b866e080ebeed.zip
https://github.com/eclipse/paho.mqtt.c.git
bblanchon/ArduinoJson@^6.17.2 ; Json(l) parser
lib_ignore =
paho
AXP192
ArduinoLog
lv_fs_if
src_filter =
+<*>
-<*.h>
+<../hal/sdl2>
+<../.pio/libdeps/emulator_64bits/paho/src/*.c>
+<../.pio/libdeps/emulator_64bits/paho/src/MQTTClient.c>
-<../.pio/libdeps/emulator_64bits/paho/src/MQTTAsync.c>
-<../.pio/libdeps/emulator_64bits/paho/src/MQTTAsyncUtils.c>
-<../.pio/libdeps/emulator_64bits/paho/src/MQTTVersion.c>
-<../.pio/libdeps/emulator_64bits/paho/src/SSLSocket.c>
+<MQTTClient.c>
-<MQTTAsync.c>
-<MQTTAsyncUtils.c>
-<MQTTVersion.c>
-<SSLSocket.c>
-<sys/>
-<hal/>
-<drv/>
-<drv/touch>
-<drv/tft>
+<dev/>
-<hal/>
-<svc/>
-<hasp_filesystem.cpp>
+<font/>
+<hasp/>
+<lang/>
-<log/>
+<mqtt/>
+<../.pio/libdeps/emulator_64bits/ArduinoJson/src/ArduinoJson.h>

View File

@ -1,6 +1,8 @@
[env:emulator_64bits]
platform = native@^1.1.3
extra_scripts = tools/sdl2_build_extra.py
extra_scripts =
tools/sdl2_build_extra.py
tools/windows_build_extra.py
build_flags =
${env.build_flags}
; ----- Monitor