From c629b943336dcfb897c1b9919d7abeecbc982bec Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 4 Sep 2020 15:03:22 -0700 Subject: [PATCH] portduino WIP --- platformio.ini | 43 ++++++++++------- src/concurrency/BaseThread.cpp | 13 +++++ src/concurrency/BaseThread.h | 47 ++++++++++++++++++ .../{Thread.cpp => FreeRtosThread.cpp} | 20 ++++---- src/concurrency/FreeRtosThread.h | 44 +++++++++++++++++ src/concurrency/Lock.cpp | 11 ++++- src/concurrency/Lock.h | 6 ++- src/concurrency/PosixThread.h | 33 +++++++++++++ src/concurrency/Thread.h | 48 ++++--------------- src/configuration.h | 29 ++++++----- src/freertosinc.h | 21 ++++++-- 11 files changed, 230 insertions(+), 85 deletions(-) create mode 100644 src/concurrency/BaseThread.cpp create mode 100644 src/concurrency/BaseThread.h rename src/concurrency/{Thread.cpp => FreeRtosThread.cpp} (68%) create mode 100644 src/concurrency/FreeRtosThread.h create mode 100644 src/concurrency/PosixThread.h diff --git a/platformio.ini b/platformio.ini index 2ba2ba5fa..80115757c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = tbeam # or if you'd like to change the default to something like lora-relay-v1 put that here +default_envs = linux # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here [common] ; common is not currently used @@ -23,12 +23,6 @@ default_envs = tbeam # or if you'd like to change the default to something like [env] -framework = arduino - -; customize the partition table -; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables -board_build.partitions = partition-table.csv - ; note: we add src to our include search path so that lmic_project_config can override ; FIXME: fix lib/BluetoothOTA dependency back on src/ so we can remove -Isrc build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/nanopb/include -Os -Wl,-Map,.pio/build/output.map @@ -60,25 +54,34 @@ debug_tool = jlink lib_deps = https://github.com/meshtastic/esp8266-oled-ssd1306.git ; ESP8266_SSD1306 - SPI 1260 ; OneButton library for non-blocking button debounce 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib - Wire ; explicitly needed here because the AXP202 library forgets to add it https://github.com/meshtastic/arduino-fsm.git https://github.com/meshtastic/SparkFun_Ublox_Arduino_Library.git https://github.com/meshtastic/RadioLib.git#7989a269be590a5d4914ac04069b58f4930c45c1 https://github.com/meshtastic/TinyGPSPlus.git https://github.com/meshtastic/AXP202X_Library.git#8404abb6d4b486748636bc6ad72d2a47baaf5460 + Wire ; explicitly needed here because the AXP202 library forgets to add it + +; Common settings for Ardino targets +[arduino_base] + +framework = arduino + +lib_deps = + ${env.lib_deps} + SPI ; Common settings for ESP targes, mixin with extends = esp32_base [esp32_base] +extends = arduino_base platform = espressif32 src_filter = ${env.src_filter} - upload_speed = 921600 debug_init_break = tbreak setup build_flags = - ${env.build_flags} -Wall -Wextra -Isrc/esp32 -mfix-esp32-psram-cache-issue -lnimble -std=c++11 + ${env.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11 -DLOG_LOCAL_LEVEL=ESP_LOG_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DAXP_DEBUG_PORT=Serial # Hmm - this doesn't work yet @@ -87,6 +90,10 @@ lib_ignore = segger_rtt platform_packages = framework-arduinoespressif32 @ https://github.com/meshtastic/arduino-esp32.git#1adba3f11ca8406ac0a704d151697b572058b53d +; customize the partition table +; http://docs.platformio.org/en/latest/platforms/espressif32.html#partition-tables +board_build.partitions = partition-table.csv + ; not needed included in ttgo-t-beam board file ; also to use PSRAM https://docs.platformio.org/en/latest/platforms/espressif32.html#external-ram-psram ; -DBOARD_HAS_PSRAM @@ -99,7 +106,7 @@ platform_packages = extends = esp32_base board = ttgo-t-beam lib_deps = - ${env.lib_deps} + ${arduino_base.lib_deps} build_flags = ${esp32_base.build_flags} -D TBEAM_V10 @@ -150,6 +157,7 @@ src_filter = [nrf52_base] ; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files ; platform = nordicnrf52 +extends = arduino_base platform = https://github.com/meshtastic/platform-nordicnrf52.git#62d185fe61b6c84c554046106529b4fd8f155e2c debug_tool = jlink build_type = debug ; I'm debugging with ICE a lot now @@ -212,7 +220,7 @@ monitor_speed = 115200 extends = nrf52_base board = ppr lib_deps = - ${env.lib_deps} + ${arduino_base.lib_deps} UC1701 ; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus @@ -233,11 +241,14 @@ build_flags = ${nrf52_base.build_flags} -Ivariants/lora_relay_v1 -DSPI_FREQUENCY=27000000 src_filter = ${nrf52_base.src_filter} +<../variants/lora_relay_v1> lib_deps = - ${env.lib_deps} + ${arduino_base.lib_deps} SparkFun BQ27441 LiPo Fuel Gauge Arduino Library TFT_eSPI # Adafruit ST7735 and ST7789 Library - - - +[env:linux] +platform = https://github.com/geeksville/platform-portduino.git +src_filter = ${env.src_filter} +<../../Portduino/src> - - +build_flags = ${env.build_flags} -I../Portduino/src -I../Portduino/cores/arduino/api +framework = arduino +board = linux_x86_64 diff --git a/src/concurrency/BaseThread.cpp b/src/concurrency/BaseThread.cpp new file mode 100644 index 000000000..b7fea6a68 --- /dev/null +++ b/src/concurrency/BaseThread.cpp @@ -0,0 +1,13 @@ +#include "Thread.h" +#include "timing.h" +#include + +namespace concurrency +{ + +void BaseThread::callRun(void *_this) +{ + ((BaseThread *)_this)->doRun(); +} + +} // namespace concurrency diff --git a/src/concurrency/BaseThread.h b/src/concurrency/BaseThread.h new file mode 100644 index 000000000..b1947cf45 --- /dev/null +++ b/src/concurrency/BaseThread.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include + +#include "freertosinc.h" + +namespace concurrency +{ + +/** + * @brief Base threading + */ +class BaseThread +{ + protected: + /** + * set this to true to ask thread to cleanly exit asap + */ + volatile bool wantExit = false; + + public: + virtual void start(const char *name, size_t stackSize = 1024, uint32_t priority = tskIDLE_PRIORITY) = 0; + + virtual ~BaseThread() {} + + // uint32_t getStackHighwaterMark() { return uxTaskGetStackHighWaterMark(taskHandle); } + + protected: + /** + * The method that will be called when start is called. + */ + virtual void doRun() = 0; + + /** + * All thread run methods must periodically call serviceWatchdog, or the system will declare them hung and panic. + * + * this only applies after startWatchdog() has been called. If you need to sleep for a long time call stopWatchdog() + */ + virtual void serviceWatchdog() {} + virtual void startWatchdog() {} + virtual void stopWatchdog() {} + + static void callRun(void *_this); +}; + +} // namespace concurrency diff --git a/src/concurrency/Thread.cpp b/src/concurrency/FreeRtosThread.cpp similarity index 68% rename from src/concurrency/Thread.cpp rename to src/concurrency/FreeRtosThread.cpp index 1e1c7bb63..8d67eee13 100644 --- a/src/concurrency/Thread.cpp +++ b/src/concurrency/FreeRtosThread.cpp @@ -1,4 +1,7 @@ -#include "Thread.h" +#include "FreeRtosThread.h" + +#ifdef HAS_FREE_RTOS + #include "timing.h" #include @@ -9,25 +12,20 @@ namespace concurrency { -void Thread::start(const char *name, size_t stackSize, uint32_t priority) +void FreeRtosThread::start(const char *name, size_t stackSize, uint32_t priority) { auto r = xTaskCreate(callRun, name, stackSize, this, priority, &taskHandle); assert(r == pdPASS); } -void Thread::callRun(void *_this) -{ - ((Thread *)_this)->doRun(); -} - -void Thread::serviceWatchdog() +void FreeRtosThread::serviceWatchdog() { #ifdef ARDUINO_ARCH_ESP32 esp_task_wdt_reset(); #endif } -void Thread::startWatchdog() +void FreeRtosThread::startWatchdog() { #ifdef ARDUINO_ARCH_ESP32 auto r = esp_task_wdt_add(taskHandle); @@ -35,7 +33,7 @@ void Thread::startWatchdog() #endif } -void Thread::stopWatchdog() +void FreeRtosThread::stopWatchdog() { #ifdef ARDUINO_ARCH_ESP32 auto r = esp_task_wdt_delete(taskHandle); @@ -44,3 +42,5 @@ void Thread::stopWatchdog() } } // namespace concurrency + +#endif \ No newline at end of file diff --git a/src/concurrency/FreeRtosThread.h b/src/concurrency/FreeRtosThread.h new file mode 100644 index 000000000..6f52119db --- /dev/null +++ b/src/concurrency/FreeRtosThread.h @@ -0,0 +1,44 @@ +#pragma once + +#include "BaseThread.h" +#include "freertosinc.h" + +#ifdef HAS_FREE_RTOS + +namespace concurrency +{ + +/** + * @brief Base threading + */ +class FreeRtosThread : public BaseThread +{ + protected: + TaskHandle_t taskHandle = NULL; + + public: + void start(const char *name, size_t stackSize = 1024, uint32_t priority = tskIDLE_PRIORITY); + + virtual ~FreeRtosThread() { vTaskDelete(taskHandle); } + + // uint32_t getStackHighwaterMark() { return uxTaskGetStackHighWaterMark(taskHandle); } + + protected: + /** + * The method that will be called when start is called. + */ + virtual void doRun() = 0; + + /** + * All thread run methods must periodically call serviceWatchdog, or the system will declare them hung and panic. + * + * this only applies after startWatchdog() has been called. If you need to sleep for a long time call stopWatchdog() + */ + void serviceWatchdog(); + void startWatchdog(); + void stopWatchdog(); +}; + +} // namespace concurrency + +#endif \ No newline at end of file diff --git a/src/concurrency/Lock.cpp b/src/concurrency/Lock.cpp index 07f5a2ef5..ffe997f8d 100644 --- a/src/concurrency/Lock.cpp +++ b/src/concurrency/Lock.cpp @@ -1,8 +1,10 @@ #include "Lock.h" #include -namespace concurrency { +namespace concurrency +{ +#ifdef HAS_FREE_RTOS Lock::Lock() { handle = xSemaphoreCreateBinary(); @@ -19,5 +21,12 @@ void Lock::unlock() { assert(xSemaphoreGive(handle)); } +#else +Lock::Lock() {} + +void Lock::lock() {} + +void Lock::unlock() {} +#endif } // namespace concurrency diff --git a/src/concurrency/Lock.h b/src/concurrency/Lock.h index 09877cc25..1b9ea20d5 100644 --- a/src/concurrency/Lock.h +++ b/src/concurrency/Lock.h @@ -2,7 +2,8 @@ #include "../freertosinc.h" -namespace concurrency { +namespace concurrency +{ /** * @brief Simple wrapper around FreeRTOS API for implementing a mutex lock @@ -26,8 +27,9 @@ class Lock void unlock(); private: +#ifdef HAS_FREE_RTOS SemaphoreHandle_t handle; - +#endif }; } // namespace concurrency diff --git a/src/concurrency/PosixThread.h b/src/concurrency/PosixThread.h new file mode 100644 index 000000000..3f46ebc08 --- /dev/null +++ b/src/concurrency/PosixThread.h @@ -0,0 +1,33 @@ +#pragma once + +#include "BaseThread.h" + +#ifdef __unix__ + +namespace concurrency +{ + +/** + * @brief Base threading + */ +class PosixThread : public BaseThread +{ + protected: + public: + void start(const char *name, size_t stackSize = 1024, uint32_t priority = tskIDLE_PRIORITY) {} + + virtual ~PosixThread() {} + + // uint32_t getStackHighwaterMark() { return uxTaskGetStackHighWaterMark(taskHandle); } + + protected: + /** + * The method that will be called when start is called. + */ + virtual void doRun() = 0; + +}; + +} // namespace concurrency + +#endif \ No newline at end of file diff --git a/src/concurrency/Thread.h b/src/concurrency/Thread.h index ce72111e9..f9fa60fde 100644 --- a/src/concurrency/Thread.h +++ b/src/concurrency/Thread.h @@ -1,47 +1,17 @@ #pragma once -#include "freertosinc.h" +#include "FreeRtosThread.h" +#include "PosixThread.h" -namespace concurrency { - -/** - * @brief Base threading - */ -class Thread +namespace concurrency { - protected: - TaskHandle_t taskHandle = NULL; - /** - * set this to true to ask thread to cleanly exit asap - */ - volatile bool wantExit = false; - - public: - void start(const char *name, size_t stackSize = 1024, uint32_t priority = tskIDLE_PRIORITY); - - virtual ~Thread() { vTaskDelete(taskHandle); } - - uint32_t getStackHighwaterMark() { return uxTaskGetStackHighWaterMark(taskHandle); } - - protected: - /** - * The method that will be called when start is called. - */ - virtual void doRun() = 0; - - /** - * All thread run methods must periodically call serviceWatchdog, or the system will declare them hung and panic. - * - * this only applies after startWatchdog() has been called. If you need to sleep for a long time call stopWatchdog() - */ - void serviceWatchdog(); - void startWatchdog(); - void stopWatchdog(); - - private: - static void callRun(void *_this); -}; +#ifdef HAS_FREE_RTOS +typedef FreeRtosThread Thread; +#endif +#ifdef __unix__ +typedef PosixThread Thread; +#endif } // namespace concurrency diff --git a/src/configuration.h b/src/configuration.h index 50e16e6ac..d127c4781 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -55,24 +55,21 @@ along with this program. If not, see . /// Convert a preprocessor name into a quoted string and if that string is empty use "unset" #define optstr(s) (xstr(s)[0] ? xstr(s) : "unset") -#ifdef NRF52_SERIES // All of the NRF52 targets are configured using variant.h, so this section shouldn't need to be - // board specific +#ifdef PORTDUINO + +#define NO_ESP32 // Don't use ESP32 libs (mainly bluetooth) + +#elif NRF52_SERIES // All of the NRF52 targets are configured using variant.h, so this section shouldn't need to be + // board specific // // Standard definitions for NRF52 targets // -// Nop definition for these attributes - not used on NRF52 -#define EXT_RAM_ATTR -#define IRAM_ATTR - #define NO_ESP32 // Don't use ESP32 libs (mainly bluetooth) // We bind to the GPS using variant.h instead for this platform (Serial1) -// FIXME, not yet ready for NRF52 -#define RTC_DATA_ATTR - #define LED_PIN PIN_LED1 // LED1 on nrf52840-DK // If the variant filed defines as standard button @@ -89,9 +86,6 @@ along with this program. If not, see . #define NO_ESP32 // Don't use ESP32 libs (mainly bluetooth) -// FIXME, not yet ready for NRF52 -#define RTC_DATA_ATTR - #define LED_PIN -1 // FIXME totally bogus #define BUTTON_PIN -1 @@ -109,6 +103,17 @@ along with this program. If not, see . #define GPS_TX_PIN 12 #endif +// +// Standard definitions for !ESP32 targets +// + +#ifdef NO_ESP32 +// Nop definition for these attributes - not used on NRF52 +#define EXT_RAM_ATTR +#define IRAM_ATTR +#define RTC_DATA_ATTR +#endif + // ----------------------------------------------------------------------------- // LoRa SPI // ----------------------------------------------------------------------------- diff --git a/src/freertosinc.h b/src/freertosinc.h index 818eae6b3..8d4465077 100644 --- a/src/freertosinc.h +++ b/src/freertosinc.h @@ -3,22 +3,32 @@ // The FreeRTOS includes are in a different directory on ESP32 and I can't figure out how to make that work with platformio gcc // options so this is my quick hack to make things work -#ifdef ARDUINO_ARCH_ESP32 +#if defined(ARDUINO_ARCH_ESP32) #define HAS_FREE_RTOS + #include #include #include #include -#else -// not yet supported on cubecell -#ifndef CubeCell_BoardPlus +#endif + +#if defined(ARDUINO_NRF52_ADAFRUIT) #define HAS_FREE_RTOS + #include #include #include #include +#endif + +#ifdef HAS_FREE_RTOS + +// Include real FreeRTOS defs above + #else +// Include placeholder fake FreeRTOS defs + #include typedef uint32_t TickType_t; @@ -26,5 +36,6 @@ typedef uint32_t BaseType_t; #define portMAX_DELAY UINT32_MAX +#define tskIDLE_PRIORITY 0 + #endif -#endif \ No newline at end of file