From c629b943336dcfb897c1b9919d7abeecbc982bec Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 4 Sep 2020 15:03:22 -0700 Subject: [PATCH 01/10] 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 From 6a475d82884d58b1fbe138cfafcd4acae9fd2840 Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 4 Sep 2020 17:23:17 -0700 Subject: [PATCH 02/10] WIP --- .vscode/settings.json | 3 +- platformio.ini | 6 +-- src/concurrency/BaseNotifiedWorkerThread.h | 37 ++++++++++++++ ...d.cpp => FreeRtosNotifiedWorkerThread.cpp} | 8 +++- .../FreeRtosNotifiedWorkerThread.h | 40 ++++++++++++++++ src/concurrency/NotifiedWorkerThread.h | 48 ++++--------------- src/concurrency/PosixNotifiedWorkerThread.h | 26 ++++++++++ src/configuration.h | 24 +++++----- src/freertosinc.h | 8 ++++ src/main.cpp | 2 +- src/mesh/NodeDB.cpp | 9 +++- 11 files changed, 152 insertions(+), 59 deletions(-) create mode 100644 src/concurrency/BaseNotifiedWorkerThread.h rename src/concurrency/{NotifiedWorkerThread.cpp => FreeRtosNotifiedWorkerThread.cpp} (70%) create mode 100644 src/concurrency/FreeRtosNotifiedWorkerThread.h create mode 100644 src/concurrency/PosixNotifiedWorkerThread.h diff --git a/.vscode/settings.json b/.vscode/settings.json index e6f1d49e1..9b72a2a2f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -48,7 +48,8 @@ "optional": "cpp", "string_view": "cpp", "cassert": "cpp", - "iterator": "cpp" + "iterator": "cpp", + "shared_mutex": "cpp" }, "cSpell.words": [ "Blox", diff --git a/platformio.ini b/platformio.ini index 80115757c..60808a56d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -62,6 +62,7 @@ lib_deps = 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 + SPI ; Common settings for Ardino targets [arduino_base] @@ -70,7 +71,6 @@ framework = arduino lib_deps = ${env.lib_deps} - SPI ; Common settings for ESP targes, mixin with extends = esp32_base [esp32_base] @@ -248,7 +248,7 @@ lib_deps = [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 +src_filter = ${env.src_filter} - - +build_flags = ${env.build_flags} -DRADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED framework = arduino board = linux_x86_64 diff --git a/src/concurrency/BaseNotifiedWorkerThread.h b/src/concurrency/BaseNotifiedWorkerThread.h new file mode 100644 index 000000000..6d5db0ba5 --- /dev/null +++ b/src/concurrency/BaseNotifiedWorkerThread.h @@ -0,0 +1,37 @@ +#pragma once + +#include "WorkerThread.h" + +namespace concurrency { + +/** + * @brief A worker thread that waits on a freertos notification + */ +class BaseNotifiedWorkerThread : public WorkerThread +{ + public: + /** + * Notify this thread so it can run + */ + virtual void notify(uint32_t v = 0, eNotifyAction action = eNoAction) = 0; + + protected: + /** + * The notification that was most recently used to wake the thread. Read from loop() + */ + uint32_t notification = 0; + + /** + * What notification bits should be cleared just after we read and return them in notification? + * + * Defaults to clear all of them. + */ + uint32_t clearOnRead = UINT32_MAX; + + /** + * A method that should block execution - either waiting ona queue/mutex or a "task notification" + */ + virtual void block() = 0; +}; + +} // namespace concurrency diff --git a/src/concurrency/NotifiedWorkerThread.cpp b/src/concurrency/FreeRtosNotifiedWorkerThread.cpp similarity index 70% rename from src/concurrency/NotifiedWorkerThread.cpp rename to src/concurrency/FreeRtosNotifiedWorkerThread.cpp index 7785ecf8c..8fec432dc 100644 --- a/src/concurrency/NotifiedWorkerThread.cpp +++ b/src/concurrency/FreeRtosNotifiedWorkerThread.cpp @@ -1,19 +1,23 @@ #include "NotifiedWorkerThread.h" +#ifdef HAS_FREE_RTOS + namespace concurrency { /** * Notify this thread so it can run */ -void NotifiedWorkerThread::notify(uint32_t v, eNotifyAction action) +void FreeRtosNotifiedWorkerThread::notify(uint32_t v, eNotifyAction action) { xTaskNotify(taskHandle, v, action); } -void NotifiedWorkerThread::block() +void FreeRtosNotifiedWorkerThread::block() { xTaskNotifyWait(0, // don't clear notification on entry clearOnRead, ¬ification, portMAX_DELAY); // Wait forever } } // namespace concurrency + +#endif \ No newline at end of file diff --git a/src/concurrency/FreeRtosNotifiedWorkerThread.h b/src/concurrency/FreeRtosNotifiedWorkerThread.h new file mode 100644 index 000000000..c18009e43 --- /dev/null +++ b/src/concurrency/FreeRtosNotifiedWorkerThread.h @@ -0,0 +1,40 @@ +#pragma once + +#include "BaseNotifiedWorkerThread.h" + +#ifdef HAS_FREE_RTOS + +namespace concurrency { + +/** + * @brief A worker thread that waits on a freertos notification + */ +class FreeRtosNotifiedWorkerThread : public BaseNotifiedWorkerThread +{ + public: + /** + * Notify this thread so it can run + */ + void notify(uint32_t v = 0, eNotifyAction action = eNoAction); + + /** + * Notify from an ISR + * + * This must be inline or IRAM_ATTR on ESP32 + */ + inline void notifyFromISR(BaseType_t *highPriWoken, uint32_t v = 0, eNotifyAction action = eNoAction) + { + xTaskNotifyFromISR(taskHandle, v, action, highPriWoken); + } + + protected: + + /** + * A method that should block execution - either waiting ona queue/mutex or a "task notification" + */ + virtual void block(); +}; + +} // namespace concurrency + +#endif \ No newline at end of file diff --git a/src/concurrency/NotifiedWorkerThread.h b/src/concurrency/NotifiedWorkerThread.h index 5ab5a58e7..dee92eb8a 100644 --- a/src/concurrency/NotifiedWorkerThread.h +++ b/src/concurrency/NotifiedWorkerThread.h @@ -1,47 +1,17 @@ #pragma once -#include "WorkerThread.h" +#include "FreeRtosNotifiedWorkerThread.h" +#include "PosixNotifiedWorkerThread.h" -namespace concurrency { - -/** - * @brief A worker thread that waits on a freertos notification - */ -class NotifiedWorkerThread : public WorkerThread +namespace concurrency { - public: - /** - * Notify this thread so it can run - */ - void notify(uint32_t v = 0, eNotifyAction action = eNoAction); - /** - * Notify from an ISR - * - * This must be inline or IRAM_ATTR on ESP32 - */ - inline void notifyFromISR(BaseType_t *highPriWoken, uint32_t v = 0, eNotifyAction action = eNoAction) - { - xTaskNotifyFromISR(taskHandle, v, action, highPriWoken); - } +#ifdef HAS_FREE_RTOS +typedef FreeRtosNotifiedWorkerThread NotifiedWorkerThread; +#endif - protected: - /** - * The notification that was most recently used to wake the thread. Read from loop() - */ - uint32_t notification = 0; - - /** - * What notification bits should be cleared just after we read and return them in notification? - * - * Defaults to clear all of them. - */ - uint32_t clearOnRead = UINT32_MAX; - - /** - * A method that should block execution - either waiting ona queue/mutex or a "task notification" - */ - virtual void block(); -}; +#ifdef __unix__ +typedef PosixNotifiedWorkerThread NotifiedWorkerThread; +#endif } // namespace concurrency diff --git a/src/concurrency/PosixNotifiedWorkerThread.h b/src/concurrency/PosixNotifiedWorkerThread.h new file mode 100644 index 000000000..d75b74dd8 --- /dev/null +++ b/src/concurrency/PosixNotifiedWorkerThread.h @@ -0,0 +1,26 @@ +#pragma once + +#include "BaseNotifiedWorkerThread.h" + +namespace concurrency { + +/** + * @brief A worker thread that waits on a freertos notification + */ +class PosixNotifiedWorkerThread : public BaseNotifiedWorkerThread +{ + public: + /** + * Notify this thread so it can run + */ + void notify(uint32_t v = 0, eNotifyAction action = eNoAction); + + protected: + + /** + * A method that should block execution - either waiting ona queue/mutex or a "task notification" + */ + virtual void block(); +}; + +} // namespace concurrency diff --git a/src/configuration.h b/src/configuration.h index d127c4781..713aa9509 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -59,7 +59,7 @@ along with this program. If not, see . #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 +#elif defined(NRF52_SERIES) // All of the NRF52 targets are configured using variant.h, so this section shouldn't need to be // board specific // @@ -103,17 +103,6 @@ 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 // ----------------------------------------------------------------------------- @@ -128,6 +117,17 @@ along with this program. If not, see . #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 + // ----------------------------------------------------------------------------- // OLED // ----------------------------------------------------------------------------- diff --git a/src/freertosinc.h b/src/freertosinc.h index 8d4465077..798cf6410 100644 --- a/src/freertosinc.h +++ b/src/freertosinc.h @@ -37,5 +37,13 @@ typedef uint32_t BaseType_t; #define portMAX_DELAY UINT32_MAX #define tskIDLE_PRIORITY 0 +#define configMAX_PRIORITIES 10 // Highest priority level + +// Don't do anything on non free rtos platforms when done with the ISR +#define portYIELD_FROM_ISR(x) + +enum eNotifyAction { + eNoAction +}; #endif diff --git a/src/main.cpp b/src/main.cpp index 53780f6fb..49ade89f4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -223,7 +223,7 @@ void setup() // Init our SPI controller (must be before screen and lora) initSPI(); -#ifdef NRF52_SERIES +#ifdef NO_ESP32 SPI.begin(); #else // ESP32 diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 93d0787d3..e162c55ec 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -32,7 +32,14 @@ DeviceState versions used to be defined in the .proto file but really only this #define DEVICESTATE_CUR_VER 11 #define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER -#ifndef NO_ESP32 +#ifdef PORTDUINO +// Portduino version +#include "PortduinoFS.h" +#define FS PortduinoFS +#define FSBegin() FS.begin(true) +#define FILE_O_WRITE "w" +#define FILE_O_READ "r" +#elif !defined(NO_ESP32) // ESP32 version #include "SPIFFS.h" #define FS SPIFFS From fefd3d78f3a307deb853fc2bbaf80fcab14b6802 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 5 Sep 2020 12:34:48 -0700 Subject: [PATCH 03/10] Portduino WIP now compiles but does not link --- platformio.ini | 4 ++-- src/PowerFSM.cpp | 5 ++--- src/concurrency/BaseNotifiedWorkerThread.h | 7 +++++++ src/concurrency/BaseThread.cpp | 1 - src/concurrency/FreeRtosThread.cpp | 1 - src/concurrency/PeriodicScheduler.cpp | 3 +-- src/concurrency/PeriodicTask.h | 4 ++-- src/concurrency/WorkerThread.cpp | 5 ++--- src/configuration.h | 4 ++++ src/esp32/BluetoothSoftwareUpdate.cpp | 5 ++--- src/freertosinc.h | 4 +--- src/gps/GPS.cpp | 5 ++--- src/gps/NEMAGPS.cpp | 3 +-- src/main.cpp | 7 +++---- src/mesh/MeshService.cpp | 3 +-- src/mesh/NodeDB.cpp | 2 +- src/mesh/PacketHistory.cpp | 3 +-- src/mesh/PhoneAPI.cpp | 5 ++--- src/mesh/RadioInterface.cpp | 3 +-- src/mesh/ReliableRouter.cpp | 3 +-- src/mesh/ReliableRouter.h | 3 +-- src/mesh/TypedQueue.h | 2 +- src/mesh/mesh-pb-constants.cpp | 2 +- src/sleep.cpp | 5 ++--- src/timing.cpp | 10 ---------- src/timing.h | 9 --------- 26 files changed, 41 insertions(+), 67 deletions(-) delete mode 100644 src/timing.cpp delete mode 100644 src/timing.h diff --git a/platformio.ini b/platformio.ini index 60808a56d..a8940879e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -248,7 +248,7 @@ lib_deps = [env:linux] platform = https://github.com/geeksville/platform-portduino.git -src_filter = ${env.src_filter} - - -build_flags = ${env.build_flags} -DRADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED +src_filter = ${env.src_filter} - - - +build_flags = ${env.build_flags} framework = arduino board = linux_x86_64 diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 80580fd03..128947bcd 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -8,7 +8,6 @@ #include "graphics/Screen.h" #include "sleep.h" #include "target_specific.h" -#include "timing.h" static void sdsEnter() { @@ -16,7 +15,7 @@ static void sdsEnter() // Don't deepsleep if we have USB power or if the user as pressed a button recently // !isUSBPowered <- doesn't work yet because the axp192 isn't letting the battery fully charge when we are awake - FIXME - if (timing::millis() - lastPressMs > radioConfig.preferences.mesh_sds_timeout_secs) + if (millis() - lastPressMs > radioConfig.preferences.mesh_sds_timeout_secs) { doDeepSleep(radioConfig.preferences.sds_secs); } @@ -131,7 +130,7 @@ static void onEnter() static uint32_t lastPingMs; - uint32_t now = timing::millis(); + uint32_t now = millis(); if (now - lastPingMs > 30 * 1000) { // if more than a minute since our last press, ask other nodes to update their state if (displayedNodeNum) diff --git a/src/concurrency/BaseNotifiedWorkerThread.h b/src/concurrency/BaseNotifiedWorkerThread.h index 6d5db0ba5..03b82c4b0 100644 --- a/src/concurrency/BaseNotifiedWorkerThread.h +++ b/src/concurrency/BaseNotifiedWorkerThread.h @@ -15,6 +15,13 @@ class BaseNotifiedWorkerThread : public WorkerThread */ virtual void notify(uint32_t v = 0, eNotifyAction action = eNoAction) = 0; + /** + * Notify from an ISR + * + * This must be inline or IRAM_ATTR on ESP32 + */ + virtual void notifyFromISR(BaseType_t *highPriWoken, uint32_t v = 0, eNotifyAction action = eNoAction) { notify(v, action); } + protected: /** * The notification that was most recently used to wake the thread. Read from loop() diff --git a/src/concurrency/BaseThread.cpp b/src/concurrency/BaseThread.cpp index b7fea6a68..ab39a8c9f 100644 --- a/src/concurrency/BaseThread.cpp +++ b/src/concurrency/BaseThread.cpp @@ -1,5 +1,4 @@ #include "Thread.h" -#include "timing.h" #include namespace concurrency diff --git a/src/concurrency/FreeRtosThread.cpp b/src/concurrency/FreeRtosThread.cpp index 8d67eee13..1fe7108e3 100644 --- a/src/concurrency/FreeRtosThread.cpp +++ b/src/concurrency/FreeRtosThread.cpp @@ -2,7 +2,6 @@ #ifdef HAS_FREE_RTOS -#include "timing.h" #include #ifdef ARDUINO_ARCH_ESP32 diff --git a/src/concurrency/PeriodicScheduler.cpp b/src/concurrency/PeriodicScheduler.cpp index d2fa77f9c..5902ddd7a 100644 --- a/src/concurrency/PeriodicScheduler.cpp +++ b/src/concurrency/PeriodicScheduler.cpp @@ -1,7 +1,6 @@ #include "PeriodicScheduler.h" #include "PeriodicTask.h" #include "LockGuard.h" -#include "../timing.h" namespace concurrency { @@ -10,7 +9,7 @@ void PeriodicScheduler::loop() { LockGuard lg(&lock); - uint32_t now = timing::millis(); + uint32_t now = millis(); for (auto t : tasks) { if (t->period && (now - t->lastMsec) >= t->period) { diff --git a/src/concurrency/PeriodicTask.h b/src/concurrency/PeriodicTask.h index 910c0dfde..74d4c8a34 100644 --- a/src/concurrency/PeriodicTask.h +++ b/src/concurrency/PeriodicTask.h @@ -1,7 +1,7 @@ #pragma once +#include #include "PeriodicScheduler.h" -#include "timing.h" namespace concurrency { @@ -38,7 +38,7 @@ class PeriodicTask */ void setPeriod(uint32_t p) { - lastMsec = timing::millis(); // reset starting from now + lastMsec = millis(); // reset starting from now period = p; } diff --git a/src/concurrency/WorkerThread.cpp b/src/concurrency/WorkerThread.cpp index 8ea1e6a85..b2ec18d81 100644 --- a/src/concurrency/WorkerThread.cpp +++ b/src/concurrency/WorkerThread.cpp @@ -1,5 +1,4 @@ #include "WorkerThread.h" -#include "timing.h" namespace concurrency { @@ -17,8 +16,8 @@ void WorkerThread::doRun() #ifdef DEBUG_STACK static uint32_t lastPrint = 0; - if (timing::millis() - lastPrint > 10 * 1000L) { - lastPrint = timing::millis(); + if (millis() - lastPrint > 10 * 1000L) { + lastPrint = millis(); meshtastic::printThreadInfo("net"); } #endif diff --git a/src/configuration.h b/src/configuration.h index 713aa9509..ff85fa06a 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -341,6 +341,10 @@ along with this program. If not, see . #define HW_VENDOR "nrf52unknown" // FIXME - unknown nrf52 board +#elif PORTDUINO + +#define HW_VENDOR "portduino" + #endif #ifdef USE_RF95 diff --git a/src/esp32/BluetoothSoftwareUpdate.cpp b/src/esp32/BluetoothSoftwareUpdate.cpp index 9bc7445a8..4fa518ccb 100644 --- a/src/esp32/BluetoothSoftwareUpdate.cpp +++ b/src/esp32/BluetoothSoftwareUpdate.cpp @@ -1,7 +1,6 @@ #include #include "../concurrency/LockGuard.h" -#include "../timing.h" #include "BluetoothSoftwareUpdate.h" #include "PowerFSM.h" #include "RadioLibInterface.h" @@ -102,7 +101,7 @@ int update_crc32_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble } else { if (Update.end()) { DEBUG_MSG("OTA done, rebooting in 5 seconds!\n"); - rebootAtMsec = timing::millis() + 5000; + rebootAtMsec = millis() + 5000; } else { DEBUG_MSG("Error Occurred. Error #: %d\n", Update.getError()); } @@ -128,7 +127,7 @@ int update_result_callback(uint16_t conn_handle, uint16_t attr_handle, struct bl void bluetoothRebootCheck() { - if (rebootAtMsec && timing::millis() > rebootAtMsec) { + if (rebootAtMsec && millis() > rebootAtMsec) { DEBUG_MSG("Rebooting for update\n"); ESP.restart(); } diff --git a/src/freertosinc.h b/src/freertosinc.h index 798cf6410..c5dfddc8e 100644 --- a/src/freertosinc.h +++ b/src/freertosinc.h @@ -42,8 +42,6 @@ typedef uint32_t BaseType_t; // Don't do anything on non free rtos platforms when done with the ISR #define portYIELD_FROM_ISR(x) -enum eNotifyAction { - eNoAction -}; +enum eNotifyAction { eNoAction, eSetValueWithoutOverwrite, eSetValueWithOverwrite }; #endif diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 3902b655e..b3ab28d29 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -1,7 +1,6 @@ #include "GPS.h" #include "configuration.h" -#include "timing.h" #include #include @@ -36,7 +35,7 @@ void readFromRTC() struct timeval tv; /* btw settimeofday() is helpfull here too*/ if (!gettimeofday(&tv, NULL)) { - uint32_t now = timing::millis(); + uint32_t now = millis(); DEBUG_MSG("Read RTC time as %ld (cur millis %u) valid=%d\n", tv.tv_sec, now, timeSetFromGPS); timeStartMsec = now; @@ -79,7 +78,7 @@ void perhapsSetRTC(struct tm &t) uint32_t getTime() { - return ((timing::millis() - timeStartMsec) / 1000) + zeroOffsetSecs; + return ((millis() - timeStartMsec) / 1000) + zeroOffsetSecs; } uint32_t getValidTime() diff --git a/src/gps/NEMAGPS.cpp b/src/gps/NEMAGPS.cpp index a1d848ad8..abd0ba003 100644 --- a/src/gps/NEMAGPS.cpp +++ b/src/gps/NEMAGPS.cpp @@ -1,6 +1,5 @@ #include "NEMAGPS.h" #include "configuration.h" -#include "timing.h" static int32_t toDegInt(RawDegrees d) { @@ -19,7 +18,7 @@ void NEMAGPS::loop() reader.encode(c); } - uint32_t now = timing::millis(); + uint32_t now = millis(); if ((now - lastUpdateMsec) > 20 * 1000) { // Ugly hack for now - limit update checks to once every 20 secs (but still consume // serial chars at whatever rate) lastUpdateMsec = now; diff --git a/src/main.cpp b/src/main.cpp index 49ade89f4..9a057c0b0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,7 +38,6 @@ #include "graphics/Screen.h" #include "main.h" #include "sleep.h" -#include "timing.h" #include #include // #include @@ -392,15 +391,15 @@ void loop() // Show boot screen for first 3 seconds, then switch to normal operation. static bool showingBootScreen = true; - if (showingBootScreen && (timing::millis() > 3000)) { + if (showingBootScreen && (millis() > 3000)) { screen.stopBootScreen(); showingBootScreen = false; } #ifdef DEBUG_STACK static uint32_t lastPrint = 0; - if (timing::millis() - lastPrint > 10 * 1000L) { - lastPrint = timing::millis(); + if (millis() - lastPrint > 10 * 1000L) { + lastPrint = millis(); meshtastic::printThreadInfo("main"); } #endif diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index f5d0ac173..70070b12b 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -13,7 +13,6 @@ #include "main.h" #include "mesh-pb-constants.h" #include "power.h" -#include "timing.h" /* receivedPacketQueue - this is a queue of messages we've received from the mesh, which we are keeping to deliver to the phone. @@ -309,7 +308,7 @@ int MeshService::onGPSChanged(const meshtastic::GPSStatus *unused) // We limit our GPS broadcasts to a max rate static uint32_t lastGpsSend; - uint32_t now = timing::millis(); + uint32_t now = millis(); if (lastGpsSend == 0 || now - lastGpsSend > radioConfig.preferences.position_broadcast_secs * 1000) { lastGpsSend = now; DEBUG_MSG("Sending position to mesh\n"); diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index e162c55ec..634bd9515 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -36,7 +36,7 @@ DeviceState versions used to be defined in the .proto file but really only this // Portduino version #include "PortduinoFS.h" #define FS PortduinoFS -#define FSBegin() FS.begin(true) +#define FSBegin() true #define FILE_O_WRITE "w" #define FILE_O_READ "r" #elif !defined(NO_ESP32) diff --git a/src/mesh/PacketHistory.cpp b/src/mesh/PacketHistory.cpp index b83fab3c6..3d1884ace 100644 --- a/src/mesh/PacketHistory.cpp +++ b/src/mesh/PacketHistory.cpp @@ -1,7 +1,6 @@ #include "PacketHistory.h" #include "configuration.h" #include "mesh-pb-constants.h" -#include "../timing.h" PacketHistory::PacketHistory() { @@ -19,7 +18,7 @@ bool PacketHistory::wasSeenRecently(const MeshPacket *p, bool withUpdate) return false; // Not a floodable message ID, so we don't care } - uint32_t now = timing::millis(); + uint32_t now = millis(); for (size_t i = 0; i < recentPackets.size();) { PacketRecord &r = recentPackets[i]; diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp index 2e8800c13..caadf8563 100644 --- a/src/mesh/PhoneAPI.cpp +++ b/src/mesh/PhoneAPI.cpp @@ -4,7 +4,6 @@ #include "NodeDB.h" #include "PowerFSM.h" #include "RadioInterface.h" -#include "timing.h" #include PhoneAPI::PhoneAPI() @@ -21,7 +20,7 @@ void PhoneAPI::init() void PhoneAPI::checkConnectionTimeout() { if (isConnected) { - bool newConnected = (timing::millis() - lastContactMsec < radioConfig.preferences.phone_timeout_secs * 1000L); + bool newConnected = (millis() - lastContactMsec < radioConfig.preferences.phone_timeout_secs * 1000L); if (!newConnected) { isConnected = false; onConnectionChanged(isConnected); @@ -35,7 +34,7 @@ void PhoneAPI::checkConnectionTimeout() void PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength) { powerFSM.trigger(EVENT_CONTACT_FROM_PHONE); // As long as the phone keeps talking to us, don't let the radio go to sleep - lastContactMsec = timing::millis(); + lastContactMsec = millis(); if (!isConnected) { isConnected = true; onConnectionChanged(isConnected); diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 45a9fed75..7629fdbe5 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -6,7 +6,6 @@ #include "assert.h" #include "configuration.h" #include "sleep.h" -#include "timing.h" #include #include #include @@ -163,7 +162,7 @@ size_t RadioInterface::beginSending(MeshPacket *p) // DEBUG_MSG("sending queued packet on mesh (txGood=%d,rxGood=%d,rxBad=%d)\n", rf95.txGood(), rf95.rxGood(), rf95.rxBad()); assert(p->which_payload == MeshPacket_encrypted_tag); // It should have already been encoded by now - lastTxStart = timing::millis(); + lastTxStart = millis(); PacketHeader *h = (PacketHeader *)radiobuf; diff --git a/src/mesh/ReliableRouter.cpp b/src/mesh/ReliableRouter.cpp index 174c184a0..acec6b7f9 100644 --- a/src/mesh/ReliableRouter.cpp +++ b/src/mesh/ReliableRouter.cpp @@ -2,7 +2,6 @@ #include "MeshTypes.h" #include "configuration.h" #include "mesh-pb-constants.h" -#include "timing.h" // ReliableRouter::ReliableRouter() {} @@ -163,7 +162,7 @@ PendingPacket *ReliableRouter::startRetransmission(MeshPacket *p) */ void ReliableRouter::doRetransmissions() { - uint32_t now = timing::millis(); + uint32_t now = millis(); // FIXME, we should use a better datastructure rather than walking through this map. // for(auto el: pending) { diff --git a/src/mesh/ReliableRouter.h b/src/mesh/ReliableRouter.h index 04974febb..f2e8774d8 100644 --- a/src/mesh/ReliableRouter.h +++ b/src/mesh/ReliableRouter.h @@ -2,7 +2,6 @@ #include "FloodingRouter.h" #include "../concurrency/PeriodicTask.h" -#include "../timing.h" #include /** @@ -49,7 +48,7 @@ struct PendingPacket { PendingPacket() {} PendingPacket(MeshPacket *p); - void setNextTx() { nextTxMsec = timing::millis() + random(20 * 1000L, 22 * 1000L); } + void setNextTx() { nextTxMsec = millis() + random(20 * 1000L, 22 * 1000L); } }; class GlobalPacketIdHashFunction diff --git a/src/mesh/TypedQueue.h b/src/mesh/TypedQueue.h index 90ed07f10..a2b82626f 100644 --- a/src/mesh/TypedQueue.h +++ b/src/mesh/TypedQueue.h @@ -53,7 +53,7 @@ template class TypedQueue public: TypedQueue(int maxElements) {} - // int numFree() { return uxQueueSpacesAvailable(h); } + int numFree() { return 1; } // Always claim 1 free, because we can grow to any size bool isEmpty() { return q.empty(); } diff --git a/src/mesh/mesh-pb-constants.cpp b/src/mesh/mesh-pb-constants.cpp index dc0d188ab..cc6beb73a 100644 --- a/src/mesh/mesh-pb-constants.cpp +++ b/src/mesh/mesh-pb-constants.cpp @@ -6,7 +6,7 @@ #include #include -#ifdef NO_ESP32 +#if 0 // FIXME NRF52 only #include "Adafruit_LittleFS.h" using namespace Adafruit_LittleFS_Namespace; // To get File type #endif diff --git a/src/sleep.cpp b/src/sleep.cpp index 3bce72669..a08707762 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -7,7 +7,6 @@ #include "error.h" #include "main.h" #include "target_specific.h" -#include "timing.h" #ifndef NO_ESP32 #include "esp32/pm.h" @@ -123,11 +122,11 @@ bool doPreflightSleep() /// Tell devices we are going to sleep and wait for them to handle things static void waitEnterSleep() { - uint32_t now = timing::millis(); + uint32_t now = millis(); while (!doPreflightSleep()) { delay(100); // Kinda yucky - wait until radio says say we can shutdown (finished in process sends/receives) - if (timing::millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep + if (millis() - now > 30 * 1000) { // If we wait too long just report an error and go to sleep recordCriticalError(ErrSleepEnterWait); assert(0); // FIXME - for now we just restart, need to fix bug #167 break; diff --git a/src/timing.cpp b/src/timing.cpp deleted file mode 100644 index f7cffaa65..000000000 --- a/src/timing.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "timing.h" -#include "freertosinc.h" - -namespace timing { - - uint32_t millis() { - return xTaskGetTickCount(); - } - -} // namespace timing diff --git a/src/timing.h b/src/timing.h deleted file mode 100644 index 7f741d45f..000000000 --- a/src/timing.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -namespace timing { - - uint32_t millis(); - -} // namespace timing \ No newline at end of file From b8d39845cf803be26e47f5849e690bc0d1474912 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 6 Sep 2020 09:24:08 -0700 Subject: [PATCH 04/10] portduino now links! --- src/concurrency/PosixNotifiedWorkerThread.cpp | 14 +++++++++++++ src/graphics/Screen.cpp | 1 + src/main.cpp | 1 + src/main.h | 2 +- src/portduino/PortduinoGlue.cpp | 20 +++++++++++++++++++ src/target_specific.h | 6 +++++- 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/concurrency/PosixNotifiedWorkerThread.cpp create mode 100644 src/portduino/PortduinoGlue.cpp diff --git a/src/concurrency/PosixNotifiedWorkerThread.cpp b/src/concurrency/PosixNotifiedWorkerThread.cpp new file mode 100644 index 000000000..ac24cf86a --- /dev/null +++ b/src/concurrency/PosixNotifiedWorkerThread.cpp @@ -0,0 +1,14 @@ +#include "PosixNotifiedWorkerThread.h" +#include + +using namespace concurrency; + +/** + * Notify this thread so it can run + */ +void PosixNotifiedWorkerThread::notify(uint32_t v, eNotifyAction action) NOT_IMPLEMENTED("notify"); + +/** + * A method that should block execution - either waiting ona queue/mutex or a "task notification" + */ +void PosixNotifiedWorkerThread::block() NOT_IMPLEMENTED("block"); \ No newline at end of file diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 3cf3e93f7..f9ad490de 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -31,6 +31,7 @@ along with this program. If not, see . #include "graphics/images.h" #include "main.h" #include "mesh-pb-constants.h" +#include "target_specific.h" #include "utils.h" using namespace meshtastic; /** @todo remove */ diff --git a/src/main.cpp b/src/main.cpp index 9a057c0b0..aaea60a6d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,6 +38,7 @@ #include "graphics/Screen.h" #include "main.h" #include "sleep.h" +#include "target_specific.h" #include #include // #include diff --git a/src/main.h b/src/main.h index fb64d9ff0..74ad0b441 100644 --- a/src/main.h +++ b/src/main.h @@ -21,6 +21,6 @@ extern graphics::Screen screen; // Return a human readable string of the form "Meshtastic_ab13" const char *getDeviceName(); -void getMacAddr(uint8_t *dmac); + void nrf52Setup(), esp32Setup(), nrf52Loop(), esp32Loop(); \ No newline at end of file diff --git a/src/portduino/PortduinoGlue.cpp b/src/portduino/PortduinoGlue.cpp new file mode 100644 index 000000000..8ef3263fb --- /dev/null +++ b/src/portduino/PortduinoGlue.cpp @@ -0,0 +1,20 @@ +#include "CryptoEngine.h" +#include "target_specific.h" +#include + +// FIXME - move getMacAddr/setBluetoothEnable into a HALPlatform class + +void getMacAddr(uint8_t *dmac) +{ + notImplemented("getMacAddr"); +} + +void setBluetoothEnable(bool on) +{ + notImplemented("setBluetoothEnable"); +} + +// FIXME - implement real crypto for linux +CryptoEngine *crypto = new CryptoEngine(); + +void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel"); \ No newline at end of file diff --git a/src/target_specific.h b/src/target_specific.h index 6acca364a..1e79df510 100644 --- a/src/target_specific.h +++ b/src/target_specific.h @@ -1,6 +1,10 @@ #pragma once +#include + // Functions that are unique to particular target types (esp32, bare, nrf52 etc...) // Enable/disable bluetooth. -void setBluetoothEnable(bool on); \ No newline at end of file +void setBluetoothEnable(bool on); + +void getMacAddr(uint8_t *dmac); \ No newline at end of file From 97ab07e05c421c1a801783ce39c21e85d441cb67 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 6 Sep 2020 10:09:40 -0700 Subject: [PATCH 05/10] WIP --- platformio.ini | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/platformio.ini b/platformio.ini index a8940879e..4ee70850f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -25,7 +25,7 @@ default_envs = linux # nrf52840dk-geeksville # linux # or if you'd like to chang ; 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 +build_flags = -Wno-missing-field-initializers -Isrc -Isrc/mesh -Isrc/gps -Ilib/nanopb/include -Wl,-Map,.pio/build/output.map -DHW_VERSION_${sysenv.COUNTRY} -DAPP_VERSION=${sysenv.APP_VERSION} -DHW_VERSION=${sysenv.HW_VERSION} @@ -64,7 +64,7 @@ lib_deps = Wire ; explicitly needed here because the AXP202 library forgets to add it SPI -; Common settings for Ardino targets +; Common settings for conventional (non Portduino) Ardino targets [arduino_base] framework = arduino @@ -72,6 +72,8 @@ framework = arduino lib_deps = ${env.lib_deps} +build_flags = ${env.build_flags} -Os + ; Common settings for ESP targes, mixin with extends = esp32_base [esp32_base] extends = arduino_base @@ -81,7 +83,7 @@ src_filter = upload_speed = 921600 debug_init_break = tbreak setup build_flags = - ${env.build_flags} -Wall -Wextra -Isrc/esp32 -Isrc/esp32-mfix-esp32-psram-cache-issue -lnimble -std=c++11 + ${arduino_base.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 @@ -149,7 +151,7 @@ build_flags = platform = https://github.com/HelTecAutomation/platform-asrmicro650x.git ; we use top-of-tree because stable version has too many bugs - asrmicro650x board = cubecell_board_plus ; FIXME, bug in cubecell arduino - they are supposed to set ARDUINO -build_flags = ${env.build_flags} -DARDUINO=100 -Isrc/cubecell +build_flags = ${arduino_base.build_flags} -DARDUINO=100 -Isrc/cubecell src_filter = ${env.src_filter} - - @@ -163,7 +165,7 @@ debug_tool = jlink build_type = debug ; I'm debugging with ICE a lot now ; note: liboberon provides the AES256 implementation for NRF52 (though not using the hardware acceleration of the NRF52840 - FIXME) build_flags = - ${env.build_flags} -Wno-unused-variable + ${arduino_base.build_flags} -Wno-unused-variable -Isrc/nrf52 -Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.3 ;-DCFG_DEBUG=3 @@ -249,6 +251,6 @@ lib_deps = [env:linux] platform = https://github.com/geeksville/platform-portduino.git src_filter = ${env.src_filter} - - - -build_flags = ${env.build_flags} +build_flags = ${arduino_base.build_flags} framework = arduino board = linux_x86_64 From 2a067e7f6bf73aae62350a66c22d48a6ac2f86c8 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 6 Sep 2020 14:45:43 -0700 Subject: [PATCH 06/10] make gps optional. Portduino almost works in sim! --- platformio.ini | 2 +- src/main.cpp | 8 ++++++-- src/mesh/MeshService.cpp | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index 4ee70850f..95db806e9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -251,6 +251,6 @@ lib_deps = [env:linux] platform = https://github.com/geeksville/platform-portduino.git src_filter = ${env.src_filter} - - - -build_flags = ${arduino_base.build_flags} +build_flags = ${arduino_base.build_flags} -O0 framework = arduino board = linux_x86_64 diff --git a/src/main.cpp b/src/main.cpp index aaea60a6d..655d8a8bd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -268,7 +268,10 @@ void setup() gps = new NEMAGPS(); gps->setup(); #endif - gpsStatus->observe(&gps->newStatus); + if (gps) + gpsStatus->observe(&gps->newStatus); + else + DEBUG_MSG("Warning: No GPS found - running without GPS\n"); nodeStatus->observe(&nodeDB.newStatus); service.init(); @@ -362,7 +365,8 @@ void loop() { uint32_t msecstosleep = 1000 * 30; // How long can we sleep before we again need to service the main loop? - gps->loop(); // FIXME, remove from main, instead block on read + if (gps) + gps->loop(); // FIXME, remove from main, instead block on read router.loop(); powerFSM.run_machine(); service.loop(); diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 70070b12b..6dc248933 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -67,8 +67,8 @@ void MeshService::init() sendOwnerPeriod.setup(); nodeDB.init(); - assert(gps); - gpsObserver.observe(&gps->newStatus); + if (gps) + gpsObserver.observe(&gps->newStatus); packetReceivedObserver.observe(&router.notifyPacketReceived); } From 94e4b301259840e1d43966367e0fefc3bb468021 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 6 Sep 2020 16:07:32 -0700 Subject: [PATCH 07/10] add crude sim getmacaddr --- src/portduino/PortduinoGlue.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/portduino/PortduinoGlue.cpp b/src/portduino/PortduinoGlue.cpp index 8ef3263fb..690af6071 100644 --- a/src/portduino/PortduinoGlue.cpp +++ b/src/portduino/PortduinoGlue.cpp @@ -4,9 +4,21 @@ // FIXME - move getMacAddr/setBluetoothEnable into a HALPlatform class +uint32_t hwId; // fixme move into portduino + void getMacAddr(uint8_t *dmac) { - notImplemented("getMacAddr"); + if (!hwId) { + notImplemented("getMacAddr"); + hwId = random(); + } + + dmac[0] = 0x80; + dmac[1] = 0; + dmac[2] = 0; + dmac[3] = hwId >> 16; + dmac[4] = hwId >> 8; + dmac[5] = hwId & 0xff; } void setBluetoothEnable(bool on) From e0d5b9dce1a4f43a3c236cc46a857c2afc787f4b Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 6 Sep 2020 16:09:07 -0700 Subject: [PATCH 08/10] use simradio on portduino --- src/configuration.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index ff85fa06a..54bc3f94e 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -60,7 +60,7 @@ along with this program. If not, see . #define NO_ESP32 // Don't use ESP32 libs (mainly bluetooth) #elif defined(NRF52_SERIES) // All of the NRF52 targets are configured using variant.h, so this section shouldn't need to be - // board specific +// board specific // // Standard definitions for NRF52 targets @@ -343,7 +343,9 @@ along with this program. If not, see . #elif PORTDUINO -#define HW_VENDOR "portduino" +#define HW_VENDOR "portduino" + +#define USE_SIM_RADIO #endif From f8bb6bbcb4e46481504e2571335888cc6df0a032 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 6 Sep 2020 16:32:13 -0700 Subject: [PATCH 09/10] try to bang on SPI from simulator --- src/configuration.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/configuration.h b/src/configuration.h index 54bc3f94e..b8f35c0e4 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -200,8 +200,6 @@ along with this program. If not, see . #define BUTTON_PIN 39 #define BATTERY_PIN 35 // A battery voltage measurement pin, voltage divider connected here to measure battery voltage -#define USE_RF95 - #define USE_RF95 #define LORA_DIO0 26 // a No connect on the SX1262 module #define LORA_RESET 23 @@ -347,6 +345,18 @@ along with this program. If not, see . #define USE_SIM_RADIO +#define USE_RF95 +#define LORA_DIO0 26 // a No connect on the SX1262 module +#define LORA_RESET 23 +#define LORA_DIO1 33 // Not really used +#define LORA_DIO2 32 // Not really used + +// Fake SPI device selections +#define RF95_SCK 5 +#define RF95_MISO 19 +#define RF95_MOSI 27 +#define RF95_NSS 18 + #endif #ifdef USE_RF95 From f3d38d84c97dcff05469a5bfd169315284ea9dbd Mon Sep 17 00:00:00 2001 From: geeksville Date: Mon, 7 Sep 2020 13:03:37 -0700 Subject: [PATCH 10/10] fix nrf52 build --- platformio.ini | 11 +++++++---- src/concurrency/PosixNotifiedWorkerThread.cpp | 7 ++++++- src/mesh/mesh-pb-constants.cpp | 6 +++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/platformio.ini b/platformio.ini index 95db806e9..9e8abddd1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = linux # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here +default_envs = tbeam # lora-relay-v1 # 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 @@ -74,12 +74,14 @@ lib_deps = build_flags = ${env.build_flags} -Os +src_filter = ${env.src_filter} - + ; Common settings for ESP targes, mixin with extends = esp32_base [esp32_base] extends = arduino_base platform = espressif32 src_filter = - ${env.src_filter} - + ${arduino_base.src_filter} - upload_speed = 921600 debug_init_break = tbreak setup build_flags = @@ -153,7 +155,7 @@ board = cubecell_board_plus ; FIXME, bug in cubecell arduino - they are supposed to set ARDUINO build_flags = ${arduino_base.build_flags} -DARDUINO=100 -Isrc/cubecell src_filter = - ${env.src_filter} - - + ${arduino_base.src_filter} - - ; Common settings for NRF52 based targets [nrf52_base] @@ -170,7 +172,7 @@ build_flags = -Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.3 ;-DCFG_DEBUG=3 src_filter = - ${env.src_filter} - - + ${arduino_base.src_filter} - - lib_ignore = BluetoothOTA monitor_port = /dev/ttyACM1 @@ -248,6 +250,7 @@ lib_deps = TFT_eSPI # Adafruit ST7735 and ST7789 Library +; The Portduino based sim environment on top of linux [env:linux] platform = https://github.com/geeksville/platform-portduino.git src_filter = ${env.src_filter} - - - diff --git a/src/concurrency/PosixNotifiedWorkerThread.cpp b/src/concurrency/PosixNotifiedWorkerThread.cpp index ac24cf86a..e759a871e 100644 --- a/src/concurrency/PosixNotifiedWorkerThread.cpp +++ b/src/concurrency/PosixNotifiedWorkerThread.cpp @@ -1,4 +1,7 @@ #include "PosixNotifiedWorkerThread.h" + +#ifdef __unix__ + #include using namespace concurrency; @@ -11,4 +14,6 @@ void PosixNotifiedWorkerThread::notify(uint32_t v, eNotifyAction action) NOT_IMP /** * A method that should block execution - either waiting ona queue/mutex or a "task notification" */ -void PosixNotifiedWorkerThread::block() NOT_IMPLEMENTED("block"); \ No newline at end of file +void PosixNotifiedWorkerThread::block() NOT_IMPLEMENTED("block"); + +#endif \ No newline at end of file diff --git a/src/mesh/mesh-pb-constants.cpp b/src/mesh/mesh-pb-constants.cpp index cc6beb73a..337e585de 100644 --- a/src/mesh/mesh-pb-constants.cpp +++ b/src/mesh/mesh-pb-constants.cpp @@ -6,10 +6,10 @@ #include #include -#if 0 // FIXME NRF52 only +#ifdef ARDUINO_ARCH_NRF52 #include "Adafruit_LittleFS.h" using namespace Adafruit_LittleFS_Namespace; // To get File type -#endif +#endif /// helper function for encoding a record as a protobuf, any failures to encode are fatal and we will panic /// returns the encoded packet size @@ -49,7 +49,7 @@ bool readcb(pb_istream_t *stream, uint8_t *buf, size_t count) return count == 0; } - status = (file->read(buf, count) == (int) count); + status = (file->read(buf, count) == (int)count); if (file->available() == 0) stream->bytes_left = 0;