From 1c63a7067362d1ff40152c2366bb0dc99d6b1bde Mon Sep 17 00:00:00 2001 From: geeksville Date: Fri, 5 Jun 2020 17:30:09 -0700 Subject: [PATCH 01/10] cubecell WIP --- docs/hardware/cubecell-TODO.md | 6 ++++++ platformio.ini | 12 +++++++++++- src/WorkerThread.cpp | 4 ++++ src/WorkerThread.h | 7 ++++++- src/configuration.h | 20 +++++++++++++++++++- src/freertosinc.h | 3 +++ src/lock.cpp | 15 +++++++++++++++ src/lock.h | 2 ++ 8 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 docs/hardware/cubecell-TODO.md diff --git a/docs/hardware/cubecell-TODO.md b/docs/hardware/cubecell-TODO.md new file mode 100644 index 00000000..b96acbb3 --- /dev/null +++ b/docs/hardware/cubecell-TODO.md @@ -0,0 +1,6 @@ + +https://heltec-automation-docs.readthedocs.io/en/latest/cubecell/index.html + +https://github.com/HelTecAutomation/ASR650x-Arduino?utm_source=platformio.org&utm_medium=docs + +* Either portfreertos or make not theaded versions of Lock, WorkerThread, Queue (probably the latter). diff --git a/platformio.ini b/platformio.ini index c51e0954..5d5bb51e 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = tbeam ; Note: the github actions CI test build can't yet build NRF52 targets +default_envs = cubecellplus ; Note: the github actions CI test build can't yet build NRF52 targets [common] ; common is not currently used @@ -123,6 +123,16 @@ board = ttgo-lora32-v1 build_flags = ${esp32_base.build_flags} -D TTGO_LORA_V2 +; The Heltec Cubecell plus +[env:cubecellplus] +platform = https://github.com/HelTecAutomation/platform-asrmicro650x.git ; we use top-of-tree because stable version has too many bugs - asrmicro650x +framework = arduino +board = cubecell_board_plus +; FIXME, bug in cubecell arduino - they are supposed to set ARDUINO +build_flags = ${env.build_flags} -DARDUINO=100 +src_filter = + ${env.src_filter} - + ; Common settings for NRF52 based targets [nrf52_base] platform = nordicnrf52 diff --git a/src/WorkerThread.cpp b/src/WorkerThread.cpp index f84d83be..36be2769 100644 --- a/src/WorkerThread.cpp +++ b/src/WorkerThread.cpp @@ -1,6 +1,8 @@ #include "WorkerThread.h" #include +#ifdef configUSE_PREEMPTION + void Thread::start(const char *name, size_t stackSize, uint32_t priority) { auto r = xTaskCreate(callRun, name, stackSize, this, priority, &taskHandle); @@ -35,3 +37,5 @@ void NotifiedWorkerThread::block() xTaskNotifyWait(0, // don't clear notification on entry clearOnRead, ¬ification, portMAX_DELAY); // Wait forever } + +#endif \ No newline at end of file diff --git a/src/WorkerThread.h b/src/WorkerThread.h index 86ec08e1..e5294941 100644 --- a/src/WorkerThread.h +++ b/src/WorkerThread.h @@ -1,5 +1,8 @@ #include +// FIXME - ugly check to see if we have freertos +#ifdef configUSE_PREEMPTION + class Thread { protected: @@ -86,4 +89,6 @@ class NotifiedWorkerThread : public WorkerThread * A method that should block execution - either waiting ona queue/mutex or a "task notification" */ virtual void block(); -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/src/configuration.h b/src/configuration.h index bc64d318..9b43cb22 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -73,6 +73,22 @@ along with this program. If not, see . #define BUTTON_PIN PIN_BUTTON1 // FIXME, use variant.h defs for all of this!!! (even on the ESP32 targets) +#elif defined(CubeCell_BoardPlus) + +// +// Standard definitions for CubeCell targets +// + +#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 +#define BUTTON_PIN PIN_BUTTON1 + #else // @@ -256,9 +272,11 @@ along with this program. If not, see . #define DEBUG_PORT console // Serial debug port -#ifdef NO_ESP32 +// What platforms should use SEGGER? +#ifdef NRF52_SERIES #define USE_SEGGER #endif + #ifdef USE_SEGGER #include "SEGGER_RTT.h" #define DEBUG_MSG(...) SEGGER_RTT_printf(0, __VA_ARGS__) diff --git a/src/freertosinc.h b/src/freertosinc.h index 0d86ee2c..6536b91c 100644 --- a/src/freertosinc.h +++ b/src/freertosinc.h @@ -9,8 +9,11 @@ #include #include #else +// not yet supported on cubecell +#ifndef CubeCell_BoardPlus #include #include #include #include +#endif #endif \ No newline at end of file diff --git a/src/lock.cpp b/src/lock.cpp index 8041799e..4a8d28cf 100644 --- a/src/lock.cpp +++ b/src/lock.cpp @@ -5,6 +5,7 @@ namespace meshtastic { +#ifdef configUSE_PREEMPTION Lock::Lock() { handle = xSemaphoreCreateBinary(); @@ -21,6 +22,20 @@ void Lock::unlock() { assert(xSemaphoreGive(handle)); } +#else +Lock::Lock() +{ +} + +void Lock::lock() +{ +} + +void Lock::unlock() +{ +} +#endif + LockGuard::LockGuard(Lock *lock) : lock(lock) { diff --git a/src/lock.h b/src/lock.h index a6afa2f6..6a90c61b 100644 --- a/src/lock.h +++ b/src/lock.h @@ -25,7 +25,9 @@ class Lock void unlock(); private: +#ifdef configUSE_PREEMPTION SemaphoreHandle_t handle; +#endif }; // RAII lock guard. From 514d45c21943690f699851d1e2e3f037d3703580 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 16 Jun 2020 06:38:08 -0700 Subject: [PATCH 02/10] oops supposed to be TXEN --- src/mesh/SX1262Interface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp index 3fe4afa3..3eba7444 100644 --- a/src/mesh/SX1262Interface.cpp +++ b/src/mesh/SX1262Interface.cpp @@ -35,7 +35,7 @@ bool SX1262Interface::init() int res = lora.begin(freq, bw, sf, cr, syncWord, power, currentLimit, preambleLength, tcxoVoltage, useRegulatorLDO); DEBUG_MSG("LORA init result %d\n", res); -#ifdef SX1262_RXEN +#ifdef SX1262_TXEN // lora.begin sets Dio2 as RF switch control, which is not true if we are manually controlling RX and TX if (res == ERR_NONE) res = lora.setDio2AsRfSwitch(false); From d9ab6986ade1613f2b1d9cbc3fa2299d6074429b Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 16 Jun 2020 12:02:13 -0700 Subject: [PATCH 03/10] per @dafeman 1.8V works on E22 --- src/mesh/SX1262Interface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesh/SX1262Interface.cpp b/src/mesh/SX1262Interface.cpp index 3eba7444..e9ec8e7f 100644 --- a/src/mesh/SX1262Interface.cpp +++ b/src/mesh/SX1262Interface.cpp @@ -25,7 +25,7 @@ bool SX1262Interface::init() float tcxoVoltage = 0; // None - we use an XTAL #else float tcxoVoltage = - 2.4; // E22 uses DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575 + 1.8; // E22 uses DIO3 to power tcxo per https://github.com/jgromes/RadioLib/issues/12#issuecomment-520695575 #endif bool useRegulatorLDO = false; // Seems to depend on the connection to pin 9/DCC_SW - if an inductor DCDC? @@ -101,7 +101,7 @@ void SX1262Interface::setStandby() #ifdef SX1262_RXEN // we have RXEN/TXEN control - turn off RX and TX power digitalWrite(SX1262_RXEN, LOW); -#endif +#endif #ifdef SX1262_TXEN digitalWrite(SX1262_TXEN, LOW); #endif From 656faf4ce991ef317d1720822092267843cb17e3 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 16 Jun 2020 15:01:39 -0700 Subject: [PATCH 04/10] ram investigation notes --- bin/dump-ram-users.sh | 3 + docs/software/TODO.md | 3 +- docs/software/nrf52-TODO.md | 5 + docs/software/ramusage-nrf52.txt | 188 +++++++++++++++++++++++++++++++ linker/nrf52840_s140_sim832.ld | 46 ++++++++ 5 files changed, 244 insertions(+), 1 deletion(-) create mode 100755 bin/dump-ram-users.sh create mode 100644 docs/software/ramusage-nrf52.txt create mode 100644 linker/nrf52840_s140_sim832.ld diff --git a/bin/dump-ram-users.sh b/bin/dump-ram-users.sh new file mode 100755 index 00000000..f0438834 --- /dev/null +++ b/bin/dump-ram-users.sh @@ -0,0 +1,3 @@ +arm-none-eabi-readelf -s -e .pio/build/nrf52dk/firmware.elf | head -80 + +nm -CSr --size-sort .pio/build/nrf52dk/firmware.elf | grep '^200' diff --git a/docs/software/TODO.md b/docs/software/TODO.md index 7bf42881..a47d73e6 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -1,8 +1,8 @@ # High priority - nrf52 free memory https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/hathach-memory-map -- modem sleep should work if we lower serial rate to 115kb? - encryption review findings writeup +- NRF52 BLE - cubecell - DSR @@ -43,6 +43,7 @@ During the beta timeframe the following improvements 'would be nice' Items after the first final candidate release. +- dynamic frequency scaling could save a lot of power on ESP32, but it seems to corrupt uart (even with ref_tick set correctly) - Change back to using a fixed sized MemoryPool rather than MemoryDynamic (see bug #149) - scan to find channels with low background noise? (Use CAD mode of the RF95 to automatically find low noise channels) - If the phone doesn't read fromradio mailbox within X seconds, assume the phone is gone and we can stop queing location msgs diff --git a/docs/software/nrf52-TODO.md b/docs/software/nrf52-TODO.md index 1836f64b..d6d91868 100644 --- a/docs/software/nrf52-TODO.md +++ b/docs/software/nrf52-TODO.md @@ -2,6 +2,11 @@ ## Misc work items +RAM investigation. +nRF52832-QFAA 64KB ram, 512KB flash vs +nrf52832-QFAB 32KB ram, 512kb flash +nrf52840 256KB RAM, 1MB flash + platform.json "framework-arduinoadafruitnrf52": { diff --git a/docs/software/ramusage-nrf52.txt b/docs/software/ramusage-nrf52.txt new file mode 100644 index 00000000..4884cca6 --- /dev/null +++ b/docs/software/ramusage-nrf52.txt @@ -0,0 +1,188 @@ +23K + messages ++ heap of 30ish packets, 300ish bytes per packet: 8KB ++ 14KB soft device RAM + +therefore: +a) we should store all ToPhone message queued messages compressed as protobufs (since they will become that anyways) +b) a smarter MeshPacket in memory representation would save about 4KB of RAM? + +2000790c 00003558 B devicestate // 16KB +2000b53c 00001000 b _cache_buffer // 4KB flash filesystem support +20003b1c 000006b0 B console +2000d5f4 00000400 b vApplicationGetTimerTaskMemory::uxTimerTaskStack +2000da04 00000400 b _acUpBuffer +2000c558 0000036c B Bluefruit +2000c8d8 00000358 b _cdcd_itf +2000e54c 00000258 B _midid_itf +2000d0dc 00000200 b ucStaticTimerQueueStorage.9390 +2000e044 00000200 b _mscd_buf +2000e284 000001cc b _vendord_itf +2000d410 00000190 b vApplicationGetIdleTaskMemory::uxIdleTaskStack +2000374c 0000016c D __global_locale +2000de48 0000012c B USBDevice +2000afa4 00000100 b Router::send(_MeshPacket*)::bytes +2000aea4 00000100 b Router::perhapsDecode(_MeshPacket*)::bytes +200039b0 000000f4 B powerFSM +20004258 000000f0 B screen +2000cd7c 000000c4 b _dcd +2000cc68 000000c0 b _usbd_qdef_buf +2000b3c4 000000bc B Wire +2000cef4 000000a8 B Serial2 +2000ce4c 000000a8 B Serial1 +2000e498 000000a8 B _SEGGER_RTT +2000b498 000000a4 B InternalFS +2000dfb8 0000008c b _hidd_itf +2000b260 00000088 b meshtastic::normalFrames +2000cfdc 00000064 b pxReadyTasksLists +2000b340 00000060 b meshtastic::drawTextMessageFrame(OLEDDisplay*, OLEDDisplayUiState*, short, short)::tempBuf +200036ec 00000060 d impure_data +2000b104 00000060 B bledfu +2000b0a4 00000060 B blebas +20003684 00000058 D _usbd_qdef +200038c0 00000058 d tzinfo +2000d5a0 00000054 b vApplicationGetTimerTaskMemory::xTimerTaskTCB +2000d3bc 00000054 b vApplicationGetIdleTaskMemory::xIdleTaskTCB +2000d308 00000050 b xStaticTimerQueue.9389 +2000b1f4 00000050 B hrmc +2000b1a4 00000050 B bslc +20004360 0000004c B service +2000d374 00000048 b m_cb +2000df74 00000042 b _desc_str +2000cd3c 00000040 b _usbd_ctrl_buf +20004214 00000040 B realRouter +2000e244 00000040 b _mscd_itf +2000b164 00000040 B bledis +20003634 00000038 d _InternalFSConfig +2000cc30 00000031 b _usbd_dev +2000398c 00000020 B periodicScheduler +2000cfa4 00000020 b callbacksInt +2000de10 0000001f b fw_str.13525 +20003974 00000018 b object.9934 +2000ae68 00000018 B nodeDB +2000366c 00000018 d _cache +2000b314 00000014 b meshtastic::drawNodeInfo(OLEDDisplay*, OLEDDisplayUiState*, short, short)::signalStr +2000b300 00000014 b meshtastic::drawNodeInfo(OLEDDisplay*, OLEDDisplayUiState*, short, short)::lastStr +2000b2ec 00000014 b meshtastic::drawNodeInfo(OLEDDisplay*, OLEDDisplayUiState*, short, short)::distStr +200041e0 00000014 b getDeviceName()::name +2000d0b8 00000014 b xTasksWaitingTermination +2000d0a4 00000014 b xSuspendedTaskList +2000d08c 00000014 b xPendingReadyList +2000d06c 00000014 b xDelayedTaskList2 +2000d058 00000014 b xDelayedTaskList1 +2000d2f0 00000014 b xActiveTimerList2 +2000d2dc 00000014 b xActiveTimerList1 +2000b480 00000014 B SPI +2000c8c4 00000014 B Serial +2000cd28 00000014 b _ctrl_xfer +2000de30 00000011 b serial_str.13534 +2000c544 00000010 b BLEAdvertising::_start(unsigned short, unsigned short)::gap_adv +20003614 00000010 d meshtastic::btPIN +2000434c 00000010 b sendOwnerPeriod +2000ae8c 00000010 b staticPool +2000e484 00000010 B xQueueRegistry +20003b04 00000010 B stateSERIAL +20003af4 00000010 B stateSDS +20003ae4 00000010 B stateON +20003ad4 00000010 B stateNB +20003ac4 00000010 B stateLS +20003ab4 00000010 B stateDARK +20003aa4 00000010 B stateBOOT +200041f8 00000010 B ledPeriodic +2000b244 00000010 B hrms +2000d9f4 00000010 b _acDownBuffer +2000b3b8 0000000c B preflightSleep +20004208 0000000c B powerStatus +2000e540 0000000c B nrf_nvic_state +2000b3ac 0000000c B notifySleep +2000b3a0 0000000c B notifyDeepSleep +2000e463 0000000b b __tzname_std +2000e458 0000000b b __tzname_dst +2000b338 00000008 b meshtastic::estimatedHeading(double, double)::oldLon +2000b330 00000008 b meshtastic::estimatedHeading(double, double)::oldLat +200041d0 00000008 b zeroOffsetSecs +2000ae80 00000008 b spiSettings +200038b8 00000008 D _tzname +20003b14 00000008 B noopPrint +2000cfc4 00000008 b channelMap +2000cf9c 00000008 b callbackDeferred +200043ac 00000006 b ourMacAddr +2000435c 00000004 b MeshService::onGPSChanged(void*)::lastGpsSend +2000b32c 00000004 b meshtastic::estimatedHeading(double, double)::b +2000b328 00000004 b meshtastic::drawNodeInfo(OLEDDisplay*, OLEDDisplayUiState*, short, short)::simRadian +2000362c 00000004 d meshtastic::Screen::setup()::bootFrames +20003628 00000004 d meshtastic::Screen::handleStartBluetoothPinScreen(unsigned long)::btFrames +200039ac 00000004 b onEnter()::lastPingMs +2000ae9c 00000004 b generatePacketId()::i +2000ae88 00000004 B RadioLibInterface::instance +2000b2e8 00000004 b meshtastic::nodeIndex +20003610 00000004 d meshtastic::targetFramerate +2000c554 00000004 B BLEService::lastService +200041cc 00000004 b timeStartMsec +200036dc 00000004 d sbrk_heap_top +2000d364 00000004 b _loopHandle +2000c540 00000004 b guard variable for BLEAdvertising::_start(unsigned short, unsigned short)::gap_adv +2000d0d0 00000004 b xYieldPending +2000d35c 00000004 b xTimerTaskHandle +2000d358 00000004 b xTimerQueue +2000d0cc 00000004 b xTickCount +2000d0a0 00000004 b xSchedulerRunning +2000d088 00000004 b xNumOfOverflows +2000d084 00000004 b xNextTaskUnblockTime +2000d304 00000004 b xLastTime.9343 +2000d080 00000004 b xIdleTaskHandle +2000d054 00000004 b uxTopReadyPriority +2000d050 00000004 b uxTaskNumber +2000d04c 00000004 b uxSchedulerSuspended +2000d048 00000004 b uxPendedTicks +2000d044 00000004 b uxDeletedTasksWaitingCleanUp +2000d040 00000004 b uxCurrentNumberOfTasks +2000d360 00000004 b uxCriticalNesting +2000cc64 00000004 b _usbd_q +2000e478 00000004 B _timezone +200036e0 00000004 D SystemCoreClock +2000c53c 00000004 b _sem +2000d0d8 00000004 b pxOverflowTimerList +2000cfd8 00000004 b pxOverflowDelayedTaskList +2000cfd4 00000004 b pxDelayedTaskList +2000d0d4 00000004 b pxCurrentTimerList +2000cfd0 00000004 B pxCurrentTCB +2000e470 00000004 b prev_tzenv +2000360c 00000004 D preftmp +20003608 00000004 D preffile +2000b25c 00000004 B nrf52Bluetooth +2000d370 00000004 b m_usbevt_handler +2000d36c 00000004 b m_sleepevt_handler +2000d368 00000004 b m_pofwarn_handler +2000e454 00000004 B __malloc_sbrk_start +2000e450 00000004 B __malloc_free_list +2000e480 00000004 B MAIN_MonCnt +2000e47c 00000004 b initial_env +200036e8 00000004 D _impure_ptr +200041d8 00000004 B gps +2000e7a4 00000004 B errno +20003918 00000004 D environ +2000cfcc 00000004 b enabled +2000ae64 00000004 B displayedNodeNum +2000e474 00000004 B _daylight +2000b254 00000004 B crypto +2000ce44 00000004 B count_duration +2000de0c 00000004 b _cb_task +2000de08 00000004 b _cb_queue +2000de04 00000004 b _cb_qdepth +2000de44 00000004 B bootloaderVersion +200041f5 00000001 b ledBlinker()::ledOn +20003604 00000001 d loop::showingBootScreen +200041f4 00000001 b loop::wasPressed +2000b494 00000001 b DefaultFontTableLookup(unsigned char)::LASTCHAR +2000aea0 00000001 b generatePacketId()::didInit +20003624 00000001 d meshtastic::prevFrame +2000b258 00000001 b bleOn +200041dc 00000001 B timeSetFromGPS +20004348 00000001 B ssd1306_found +2000ce49 00000001 B pin_sound +2000e494 00000001 B nrfx_power_irq_enabled +2000ce48 00000001 B no_stop +20003630 00000001 D neo6M +2000ce40 00000001 b _initialized +200036e4 00000001 D __fdlib_version +20003970 00000001 b completed.9929 diff --git a/linker/nrf52840_s140_sim832.ld b/linker/nrf52840_s140_sim832.ld new file mode 100644 index 00000000..27374668 --- /dev/null +++ b/linker/nrf52840_s140_sim832.ld @@ -0,0 +1,46 @@ +/* Linker script to configure memory regions. + +geeksville: modified this to simulate a nrf52832 but with a sd140 soft device. So I can +see how the memory footprint works on this lower end CPU. Note: to work with sd140 in my bootloader +I need to start ram at 0x6000 (instead of the correct 0x3600 for sd132) - so I have less +RAM available than on a real 832. +*/ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x6D000 - 0x26000 + /* FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xED000 - 0x26000 */ + + /* SRAM required by S132 depend on + * - Attribute Table Size + * - Vendor UUID count + * - Max ATT MTU + * - Concurrent connection peripheral + central + secure links + * - Event Len, HVN queue, Write CMD queue + */ + /* RAM (rwx) : ORIGIN = 0x20003600, LENGTH = 0x20010000 - 0x20003600 */ + RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20010000 - 0x20006000 +} + +SECTIONS +{ + . = ALIGN(4); + .svc_data : + { + PROVIDE(__start_svc_data = .); + KEEP(*(.svc_data)) + PROVIDE(__stop_svc_data = .); + } > RAM + + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM +} INSERT AFTER .data; + +INCLUDE "nrf52_common.ld" From 99dac51b9dc2cb61d089f4b41754bfcc48e9268f Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 16 Jun 2020 15:02:11 -0700 Subject: [PATCH 05/10] Don't use a (huge - 16KB) scratch buffer for device state loading --- src/mesh/NodeDB.cpp | 27 ++++++++++++++++++--------- src/mesh/NodeDB.h | 3 +++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 4e87ac77..8a296875 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -110,8 +110,7 @@ void NodeDB::resetRadioConfig() */ } -void NodeDB::init() -{ +void NodeDB::installDefaultDeviceState() { // init our devicestate with valid flags so protobuf writing/reading will work devicestate.has_my_node = true; devicestate.has_radio = true; @@ -140,11 +139,16 @@ void NodeDB::init() // owner.short_name now sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]); sprintf(owner.short_name, "?%02X", myNodeInfo.my_node_num & 0xff); +} + +void NodeDB::init() +{ + installDefaultDeviceState(); if (!FSBegin()) // FIXME - do this in main? { DEBUG_MSG("ERROR filesystem mount Failed\n"); - // FIXME - report failure to phone + assert(0); // FIXME - report failure to phone } // saveToDisk(); @@ -210,7 +214,7 @@ const char *preftmp = "/db.proto.tmp"; void NodeDB::loadFromDisk() { #ifdef FS - static DeviceState scratch; + // static DeviceState scratch; We no longer read into a tempbuf because this structure is 15KB of valuable RAM auto f = FS.open(preffile); if (f) { @@ -219,16 +223,18 @@ void NodeDB::loadFromDisk() // DEBUG_MSG("Preload channel name=%s\n", channelSettings.name); - memset(&scratch, 0, sizeof(scratch)); - if (!pb_decode(&stream, DeviceState_fields, &scratch)) { + memset(&devicestate, 0, sizeof(devicestate)); + if (!pb_decode(&stream, DeviceState_fields, &devicestate)) { DEBUG_MSG("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream)); + installDefaultDeviceState(); // Our in RAM copy might now be corrupt // FIXME - report failure to phone } else { - if (scratch.version < DEVICESTATE_MIN_VER) + if (devicestate.version < DEVICESTATE_MIN_VER) { DEBUG_MSG("Warn: devicestate is old, discarding\n"); + installDefaultDeviceState(); + } else { - DEBUG_MSG("Loaded saved preferences version %d\n", scratch.version); - devicestate = scratch; + DEBUG_MSG("Loaded saved preferences version %d\n", devicestate.version); } // DEBUG_MSG("Postload channel name=%s\n", channelSettings.name); @@ -238,6 +244,9 @@ void NodeDB::loadFromDisk() } else { DEBUG_MSG("No saved preferences found\n"); } + + + #else DEBUG_MSG("ERROR: Filesystem not implemented\n"); #endif diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 0171228a..611024e2 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -93,6 +93,9 @@ class NodeDB /// read our db from flash void loadFromDisk(); + + /// Reinit device state from scratch (not loading from disk) + void installDefaultDeviceState(); }; /** From f35b15b09c2c29b37dfcdf43df8f21b89034894f Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 16 Jun 2020 15:26:30 -0700 Subject: [PATCH 06/10] Shrink devicestate for small mcus --- docs/software/ramusage-nrf52.txt | 4 +++- proto | 2 +- src/mesh/NodeDB.cpp | 18 +++++++++--------- src/mesh/mesh-pb-constants.h | 4 +++- src/mesh/mesh.pb.c | 2 +- src/mesh/mesh.pb.h | 8 ++++---- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/docs/software/ramusage-nrf52.txt b/docs/software/ramusage-nrf52.txt index 4884cca6..7258539f 100644 --- a/docs/software/ramusage-nrf52.txt +++ b/docs/software/ramusage-nrf52.txt @@ -4,7 +4,9 @@ therefore: a) we should store all ToPhone message queued messages compressed as protobufs (since they will become that anyways) -b) a smarter MeshPacket in memory representation would save about 4KB of RAM? +b) shrink packet pool size because none of that storage will be used for ToPhone packets +c) don't allocate any storage in RAM for the tophone messages we save inside device state, instead just use nanopb callbacks to save/load those +d) a smarter MeshPacket in memory representation would save about 4KB of RAM? 2000790c 00003558 B devicestate // 16KB 2000b53c 00001000 b _cache_buffer // 4KB flash filesystem support diff --git a/proto b/proto index e7f181ef..72cbde93 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit e7f181ef6fd4e38c40e0d0be552149f8bbe75a66 +Subproject commit 72cbde93ffbc2ee917f9d7328558475e02a91cba diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 8a296875..2c2204c6 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -110,7 +110,10 @@ void NodeDB::resetRadioConfig() */ } -void NodeDB::installDefaultDeviceState() { +void NodeDB::installDefaultDeviceState() +{ + memset(&devicestate, 0, sizeof(devicestate)); + // init our devicestate with valid flags so protobuf writing/reading will work devicestate.has_my_node = true; devicestate.has_radio = true; @@ -118,7 +121,7 @@ void NodeDB::installDefaultDeviceState() { devicestate.radio.has_channel_settings = true; devicestate.radio.has_preferences = true; devicestate.node_db_count = 0; - devicestate.receive_queue_count = 0; + devicestate.receive_queue_count = 0; // Not yet implemented FIXME resetRadioConfig(); @@ -138,7 +141,7 @@ void NodeDB::installDefaultDeviceState() { pickNewNodeNum(); // Note: we will repick later, just in case the settings are corrupted, but we need a valid // owner.short_name now sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]); - sprintf(owner.short_name, "?%02X", myNodeInfo.my_node_num & 0xff); + sprintf(owner.short_name, "?%02X", (unsigned)(myNodeInfo.my_node_num & 0xff)); } void NodeDB::init() @@ -226,14 +229,13 @@ void NodeDB::loadFromDisk() memset(&devicestate, 0, sizeof(devicestate)); if (!pb_decode(&stream, DeviceState_fields, &devicestate)) { DEBUG_MSG("Error: can't decode protobuf %s\n", PB_GET_ERROR(&stream)); - installDefaultDeviceState(); // Our in RAM copy might now be corrupt + installDefaultDeviceState(); // Our in RAM copy might now be corrupt // FIXME - report failure to phone } else { if (devicestate.version < DEVICESTATE_MIN_VER) { DEBUG_MSG("Warn: devicestate is old, discarding\n"); - installDefaultDeviceState(); - } - else { + installDefaultDeviceState(); + } else { DEBUG_MSG("Loaded saved preferences version %d\n", devicestate.version); } @@ -245,8 +247,6 @@ void NodeDB::loadFromDisk() DEBUG_MSG("No saved preferences found\n"); } - - #else DEBUG_MSG("ERROR: Filesystem not implemented\n"); #endif diff --git a/src/mesh/mesh-pb-constants.h b/src/mesh/mesh-pb-constants.h index baa9f5b5..789eb14a 100644 --- a/src/mesh/mesh-pb-constants.h +++ b/src/mesh/mesh-pb-constants.h @@ -8,7 +8,9 @@ #define member_size(type, member) sizeof(((type *)0)->member) /// max number of packets which can be waiting for delivery to android - note, this value comes from mesh.options protobuf -#define MAX_RX_TOPHONE (member_size(DeviceState, receive_queue) / member_size(DeviceState, receive_queue[0])) +// FIXME - max_count is actually 32 but we save/load this as one long string of preencoded MeshPacket bytes - not a big array in RAM +// #define MAX_RX_TOPHONE (member_size(DeviceState, receive_queue) / member_size(DeviceState, receive_queue[0])) +#define MAX_RX_TOPHONE 32 /// max number of nodes allowed in the mesh #define MAX_NUM_NODES (member_size(DeviceState, node_db) / member_size(DeviceState, node_db[0])) diff --git a/src/mesh/mesh.pb.c b/src/mesh/mesh.pb.c index 88db1a21..ddc720cf 100644 --- a/src/mesh/mesh.pb.c +++ b/src/mesh/mesh.pb.c @@ -39,7 +39,7 @@ PB_BIND(NodeInfo, NodeInfo, AUTO) PB_BIND(MyNodeInfo, MyNodeInfo, AUTO) -PB_BIND(DeviceState, DeviceState, 4) +PB_BIND(DeviceState, DeviceState, 2) PB_BIND(DebugString, DebugString, 2) diff --git a/src/mesh/mesh.pb.h b/src/mesh/mesh.pb.h index 8e4ba34b..2651d6cb 100644 --- a/src/mesh/mesh.pb.h +++ b/src/mesh/mesh.pb.h @@ -183,7 +183,7 @@ typedef struct _DeviceState { pb_size_t node_db_count; NodeInfo node_db[32]; pb_size_t receive_queue_count; - MeshPacket receive_queue[32]; + MeshPacket receive_queue[1]; bool has_rx_text_message; MeshPacket rx_text_message; uint32_t version; @@ -244,7 +244,7 @@ typedef struct _ToRadio { #define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0} #define MyNodeInfo_init_default {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} -#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default, MeshPacket_init_default}, false, MeshPacket_init_default, 0} +#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0} #define DebugString_init_default {""} #define FromRadio_init_default {0, 0, {MeshPacket_init_default}} #define ToRadio_init_default {0, {MeshPacket_init_default}} @@ -260,7 +260,7 @@ typedef struct _ToRadio { #define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}} #define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0} #define MyNodeInfo_init_zero {0, 0, 0, "", "", "", 0, 0, 0, 0, 0, 0, 0, 0} -#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero, MeshPacket_init_zero}, false, MeshPacket_init_zero, 0} +#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0} #define DebugString_init_zero {""} #define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}} #define ToRadio_init_zero {0, {MeshPacket_init_zero}} @@ -596,7 +596,7 @@ extern const pb_msgdesc_t ManufacturingData_msg; #define RadioConfig_UserPreferences_size 93 #define NodeInfo_size 132 #define MyNodeInfo_size 110 -#define DeviceState_size 15100 +#define DeviceState_size 5305 #define DebugString_size 258 #define FromRadio_size 322 #define ToRadio_size 316 From e66b2234f6bcbca0780f3bfa995c3fc0155f6e9c Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 16 Jun 2020 15:27:08 -0700 Subject: [PATCH 07/10] Experiment with small ram NRF52s --- platformio.ini | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index f0f63bc3..249b1ab7 100644 --- a/platformio.ini +++ b/platformio.ini @@ -133,7 +133,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 -Isrc/nrf52 -Isdk-nrfxlib/crypto/nrf_oberon/include -Lsdk-nrfxlib/crypto/nrf_oberon/lib/cortex-m4/hard-float/ -lliboberon_3.0.3 + ${env.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 src_filter = ${env.src_filter} - @@ -157,6 +157,9 @@ debug_init_break = extends = nrf52_base board = nrf52840_dk_modified +# For experimenting with RAM sizes +# board_build.ldscript = linker/nrf52840_s140_sim832.ld + ; The PPR board [env:ppr] extends = nrf52_base From a47524b762c05f2a9b9defd7e7a59ed53b77b85c Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 16 Jun 2020 17:01:50 -0700 Subject: [PATCH 08/10] cubecell wip --- platformio.ini | 6 +-- src/WorkerThread.h | 4 +- src/configuration.h | 8 ++- src/cubecell/FS.h | 1 + src/freertosinc.h | 23 +++++--- src/main.cpp | 12 +++-- src/mesh/MemoryPool.h | 2 + src/mesh/NodeDB.cpp | 4 +- src/mesh/PacketHistory.h | 5 +- src/mesh/PointerQueue.h | 2 + src/mesh/RadioLibInterface.h | 4 ++ src/mesh/ReliableRouter.h | 2 +- src/mesh/TypedQueue.h | 44 +++++++++++++++ src/nrf52/PmuBQ25703A.cpp | 100 ----------------------------------- src/nrf52/PmuBQ25703A.h | 22 -------- src/nrf52/SPIFFS.h | 3 -- 16 files changed, 91 insertions(+), 151 deletions(-) create mode 100644 src/cubecell/FS.h delete mode 100644 src/nrf52/PmuBQ25703A.cpp delete mode 100644 src/nrf52/PmuBQ25703A.h delete mode 100644 src/nrf52/SPIFFS.h diff --git a/platformio.ini b/platformio.ini index c235f94c..a74eb601 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = cubecellplus ; Note: the github actions CI test build can't yet build NRF52 targets +default_envs = nrf52dk ; Note: the github actions CI test build can't yet build NRF52 targets [common] ; common is not currently used @@ -131,9 +131,9 @@ platform = https://github.com/HelTecAutomation/platform-asrmicro650x.git ; we us framework = arduino board = cubecell_board_plus ; FIXME, bug in cubecell arduino - they are supposed to set ARDUINO -build_flags = ${env.build_flags} -DARDUINO=100 +build_flags = ${env.build_flags} -DARDUINO=100 -Isrc/cubecell src_filter = - ${env.src_filter} - + ${env.src_filter} - - ; Common settings for NRF52 based targets [nrf52_base] diff --git a/src/WorkerThread.h b/src/WorkerThread.h index afe5c2b6..ab186486 100644 --- a/src/WorkerThread.h +++ b/src/WorkerThread.h @@ -1,7 +1,7 @@ #include +#include "freertosinc.h" -// FIXME - ugly check to see if we have freertos -#ifdef configUSE_PREEMPTION +#ifdef HAS_FREE_RTOS class Thread { diff --git a/src/configuration.h b/src/configuration.h index 807dd8fc..09132fd4 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -81,13 +81,11 @@ along with this program. If not, see . #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 -#define BUTTON_PIN PIN_BUTTON1 +#define LED_PIN -1 // FIXME totally bogus +#define BUTTON_PIN -1 #else @@ -189,7 +187,7 @@ along with this program. If not, see . #define HW_VENDOR "heltec" // the default ESP32 Pin of 15 is the Oled SCL, set to 36 and 37 and works fine. -//Tested on Neo6m module. +// Tested on Neo6m module. #undef GPS_RX_PIN #undef GPS_TX_PIN #define GPS_RX_PIN 36 diff --git a/src/cubecell/FS.h b/src/cubecell/FS.h new file mode 100644 index 00000000..3f72219a --- /dev/null +++ b/src/cubecell/FS.h @@ -0,0 +1 @@ +// Placeholder FIXME \ No newline at end of file diff --git a/src/freertosinc.h b/src/freertosinc.h index 6536b91c..818eae6b 100644 --- a/src/freertosinc.h +++ b/src/freertosinc.h @@ -1,19 +1,30 @@ #pragma once -// 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 +// 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 +#define HAS_FREE_RTOS #include -#include -#include #include +#include +#include #else // not yet supported on cubecell #ifndef CubeCell_BoardPlus +#define HAS_FREE_RTOS #include -#include -#include #include +#include +#include +#else + +#include + +typedef uint32_t TickType_t; +typedef uint32_t BaseType_t; + +#define portMAX_DELAY UINT32_MAX + #endif #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index e6820e84..16aa2099 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,6 +44,13 @@ #include "BluetoothUtil.h" #endif +#include "RF95Interface.h" +#include "SX1262Interface.h" + +#ifdef NRF52_SERIES +#include "variant.h" +#endif + // We always create a screen object, but we only init it if we find the hardware meshtastic::Screen screen(SSD1306_ADDRESS); @@ -117,12 +124,7 @@ static uint32_t ledBlinker() Periodic ledPeriodic(ledBlinker); -#include "RF95Interface.h" -#include "SX1262Interface.h" -#ifdef NO_ESP32 -#include "variant.h" -#endif void setup() { diff --git a/src/mesh/MemoryPool.h b/src/mesh/MemoryPool.h index 4fefb4c4..dc6305d1 100644 --- a/src/mesh/MemoryPool.h +++ b/src/mesh/MemoryPool.h @@ -107,6 +107,7 @@ template class MemoryPool : public Allocator maxElements); // sanity check to make sure a programmer didn't free something that didn't come from this pool } +#ifdef HAS_FREE_RTOS /// Return a buffer from an ISR, if higherPriWoken is set to true you have some work to do ;-) void releaseFromISR(T *p, BaseType_t *higherPriWoken) { @@ -115,6 +116,7 @@ template class MemoryPool : public Allocator (size_t)(p - buf) < maxElements); // sanity check to make sure a programmer didn't free something that didn't come from this pool } +#endif protected: /// Return a queable object which has been prefilled with zeros - allow timeout to wait for available buffers (you diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 2c2204c6..9bebda11 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -3,7 +3,6 @@ #include #include "FS.h" -#include "SPIFFS.h" #include "CryptoEngine.h" #include "GPS.h" @@ -34,11 +33,14 @@ DeviceState versions used to be defined in the .proto file but really only this #define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER #ifndef NO_ESP32 +// ESP32 version +#include "SPIFFS.h" #define FS SPIFFS #define FSBegin() FS.begin(true) #define FILE_O_WRITE "w" #define FILE_O_READ "r" #else +// NRF52 version #include "InternalFileSystem.h" #define FS InternalFS #define FSBegin() FS.begin() diff --git a/src/mesh/PacketHistory.h b/src/mesh/PacketHistory.h index 3cc81084..d390915a 100644 --- a/src/mesh/PacketHistory.h +++ b/src/mesh/PacketHistory.h @@ -35,9 +35,8 @@ class PacketRecordOrderFunction // If the timer ticks have rolled over the difference between times will be _enormous_. Handle that case specially uint32_t t1 = p1.rxTimeMsec, t2 = p2.rxTimeMsec; - if (abs(t1 - t2) > - UINT32_MAX / - 2) { // time must have rolled over, swap them because the new little number is 'bigger' than the old big number + if (t1 - t2 > UINT32_MAX / 2) { + // time must have rolled over, swap them because the new little number is 'bigger' than the old big number t1 = t2; t2 = p1.rxTimeMsec; } diff --git a/src/mesh/PointerQueue.h b/src/mesh/PointerQueue.h index ef97eac4..b587ac64 100644 --- a/src/mesh/PointerQueue.h +++ b/src/mesh/PointerQueue.h @@ -18,6 +18,7 @@ template class PointerQueue : public TypedQueue return this->dequeue(&p, maxWait) ? p : nullptr; } +#ifdef HAS_FREE_RTOS // returns a ptr or null if the queue was empty T *dequeuePtrFromISR(BaseType_t *higherPriWoken) { @@ -25,4 +26,5 @@ template class PointerQueue : public TypedQueue return this->dequeueFromISR(&p, higherPriWoken) ? p : nullptr; } +#endif }; diff --git a/src/mesh/RadioLibInterface.h b/src/mesh/RadioLibInterface.h index 706fcdf0..cb6991d4 100644 --- a/src/mesh/RadioLibInterface.h +++ b/src/mesh/RadioLibInterface.h @@ -3,6 +3,10 @@ #include "PeriodicTask.h" #include "RadioInterface.h" +#ifdef CubeCell_BoardPlus +#define RADIOLIB_SOFTWARE_SERIAL_UNSUPPORTED +#endif + #include // ESP32 has special rules about ISR code diff --git a/src/mesh/ReliableRouter.h b/src/mesh/ReliableRouter.h index 51cb587a..beb58a8e 100644 --- a/src/mesh/ReliableRouter.h +++ b/src/mesh/ReliableRouter.h @@ -48,7 +48,7 @@ struct PendingPacket { PendingPacket() {} PendingPacket(MeshPacket *p); - void setNextTx() { nextTxMsec = millis() + random(20 * 1000, 22 * 1000); } + void setNextTx() { nextTxMsec = millis() + random(20 * 1000L, 22 * 1000L); } }; class GlobalPacketIdHashFunction diff --git a/src/mesh/TypedQueue.h b/src/mesh/TypedQueue.h index a16e624f..90ed07f1 100644 --- a/src/mesh/TypedQueue.h +++ b/src/mesh/TypedQueue.h @@ -5,6 +5,8 @@ #include "freertosinc.h" +#ifdef HAS_FREE_RTOS + /** * A wrapper for freertos queues. Note: each element object should be small * and POD (Plain Old Data type) as elements are memcpied by value. @@ -35,3 +37,45 @@ template class TypedQueue bool dequeueFromISR(T *p, BaseType_t *higherPriWoken) { return xQueueReceiveFromISR(h, p, higherPriWoken); } }; + +#else + +#include + +/** + * A wrapper for freertos queues. Note: each element object should be small + * and POD (Plain Old Data type) as elements are memcpied by value. + */ +template class TypedQueue +{ + std::queue q; + + public: + TypedQueue(int maxElements) {} + + // int numFree() { return uxQueueSpacesAvailable(h); } + + bool isEmpty() { return q.empty(); } + + bool enqueue(T x, TickType_t maxWait = portMAX_DELAY) + { + q.push(x); + return true; + } + + // bool enqueueFromISR(T x, BaseType_t *higherPriWoken) { return xQueueSendToBackFromISR(h, &x, higherPriWoken) == pdTRUE; } + + bool dequeue(T *p, TickType_t maxWait = portMAX_DELAY) + { + if (isEmpty()) + return false; + else { + *p = q.front(); + q.pop(); + return true; + } + } + + // bool dequeueFromISR(T *p, BaseType_t *higherPriWoken) { return xQueueReceiveFromISR(h, p, higherPriWoken); } +}; +#endif diff --git a/src/nrf52/PmuBQ25703A.cpp b/src/nrf52/PmuBQ25703A.cpp deleted file mode 100644 index c369ca2b..00000000 --- a/src/nrf52/PmuBQ25703A.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifdef ARDUINO_NRF52840_PPR -#include "PmuBQ25703A.h" -#include - -// Default address for device. Note, it is without read/write bit. When read with analyser, -// this will appear 1 bit shifted to the left -#define BQ25703ADevaddr 0xD6 - -const byte Lorro_BQ25703A::BQ25703Aaddr = BQ25703ADevaddr; - -void PmuBQ25703A::init() -{ - // Set the watchdog timer to not have a timeout - regs.chargeOption0.set_WDTMR_ADJ(0); - assert(writeRegEx(regs.chargeOption0)); // FIXME, instead log a critical hw failure and reboot - delay(15); // FIXME, why are these delays required? - check datasheet - - // Set the ADC on IBAT and PSYS to record values - // When changing bitfield values, call the writeRegEx function - // This is so you can change all the bits you want before sending out the byte. - regs.chargeOption1.set_EN_IBAT(1); - regs.chargeOption1.set_EN_PSYS(1); - assert(writeRegEx(regs.chargeOption1)); - delay(15); - - // Set ADC to make continuous readings. (uses more power) - regs.aDCOption.set_ADC_CONV(1); - // Set individual ADC registers to read. All have default off. - regs.aDCOption.set_EN_ADC_VBUS(1); - regs.aDCOption.set_EN_ADC_PSYS(1); - regs.aDCOption.set_EN_ADC_IDCHG(1); - regs.aDCOption.set_EN_ADC_ICHG(1); - regs.aDCOption.set_EN_ADC_VSYS(1); - regs.aDCOption.set_EN_ADC_VBAT(1); - // Once bits have been twiddled, send bytes to device - assert(writeRegEx(regs.aDCOption)); - delay(15); -} - -#endif - -/* - - -//Initialise the device and library -Lorro_BQ25703A BQ25703A; - -//Instantiate with reference to global set -extern Lorro_BQ25703A::Regt BQ25703Areg; - -uint32_t previousMillis; -uint16_t loopInterval = 1000; - -void setup() { - - Serial.begin(115200); - - -} - -void loop() { - - uint32_t currentMillis = millis(); - - if( currentMillis - previousMillis > loopInterval ){ - previousMillis = currentMillis; - - Serial.print( "Voltage of VBUS: " ); - Serial.print( BQ25703Areg.aDCVBUSPSYS.get_VBUS() ); - Serial.println( "mV" ); - delay( 15 ); - - Serial.print( "System power usage: " ); - Serial.print( BQ25703Areg.aDCVBUSPSYS.get_sysPower() ); - Serial.println( "W" ); - delay( 15 ); - - Serial.print( "Voltage of VBAT: " ); - Serial.print( BQ25703Areg.aDCVSYSVBAT.get_VBAT() ); - Serial.println( "mV" ); - delay( 15 ); - - Serial.print( "Voltage of VSYS: " ); - Serial.print( BQ25703Areg.aDCVSYSVBAT.get_VSYS() ); - Serial.println( "mV" ); - delay( 15 ); - - Serial.print( "Charging current: " ); - Serial.print( BQ25703Areg.aDCIBAT.get_ICHG() ); - Serial.println( "mA" ); - delay( 15 ); - - Serial.print( "Voltage of VSYS: " ); - Serial.print( BQ25703Areg.aDCIBAT.get_IDCHG() ); - Serial.println( "mA" ); - delay( 15 ); - - } - -}*/ \ No newline at end of file diff --git a/src/nrf52/PmuBQ25703A.h b/src/nrf52/PmuBQ25703A.h deleted file mode 100644 index 804b85bf..00000000 --- a/src/nrf52/PmuBQ25703A.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -class PmuBQ25703A : private Lorro_BQ25703A -{ - Lorro_BQ25703A::Regt regs; - - public: - /** - * Configure the PMU for our board - */ - void init(); - - // Methods to have a common API with AXP192 - bool isBatteryConnect() { return true; } // FIXME - bool isVBUSPlug() { return true; } - bool isChargeing() { return true; } // FIXME, intentional misspelling - - /// battery voltage in mV - int getBattVoltage() { return 3200; } -}; diff --git a/src/nrf52/SPIFFS.h b/src/nrf52/SPIFFS.h deleted file mode 100644 index 81969366..00000000 --- a/src/nrf52/SPIFFS.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -// FIXME - make a FS abstraction for NRF52 \ No newline at end of file From 03f019dea26f3cbcfb9af608ecf35b0926234ba6 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 16 Jun 2020 19:55:14 -0700 Subject: [PATCH 09/10] memory size debugging --- docs/software/ramusage-nrf52.txt | 14 ++++++++++++-- lib/nanopb/include/pb.h | 2 +- src/mesh/Router.cpp | 7 ++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/docs/software/ramusage-nrf52.txt b/docs/software/ramusage-nrf52.txt index 7258539f..9969806e 100644 --- a/docs/software/ramusage-nrf52.txt +++ b/docs/software/ramusage-nrf52.txt @@ -1,12 +1,22 @@ 23K + messages -+ heap of 30ish packets, 300ish bytes per packet: 8KB ++ heap of 70ish packets, 300ish bytes per packet: 20KB + 14KB soft device RAM +With max length Data inside the packet +Size of NodeInfo 104 +Size of SubPacket 272 +Size of MeshPacket 304 + +If Data was smaller: for 70 data packets we would save 7KB. We would need to make SubPacket.data and MeshPacket.encrypted into "type:FT_POINTER" - variably sized mallocs +Size of NodeInfo 104 +Size of SubPacket 96 +Size of MeshPacket 292 (could have been much smaller but I forgot to shrink MeshPacket.encrypted) + therefore: a) we should store all ToPhone message queued messages compressed as protobufs (since they will become that anyways) b) shrink packet pool size because none of that storage will be used for ToPhone packets c) don't allocate any storage in RAM for the tophone messages we save inside device state, instead just use nanopb callbacks to save/load those -d) a smarter MeshPacket in memory representation would save about 4KB of RAM? +d) a smarter MeshPacket in memory representation would save about 7KB of RAM. call pb_release before freeing each freshly malloced MeshPacket 2000790c 00003558 B devicestate // 16KB 2000b53c 00001000 b _cache_buffer // 4KB flash filesystem support diff --git a/lib/nanopb/include/pb.h b/lib/nanopb/include/pb.h index 8e87b626..45504e99 100644 --- a/lib/nanopb/include/pb.h +++ b/lib/nanopb/include/pb.h @@ -11,7 +11,7 @@ *****************************************************************/ /* Enable support for dynamically allocated fields */ -/* #define PB_ENABLE_MALLOC 1 */ +#define PB_ENABLE_MALLOC 1 /* Define this if your CPU / compiler combination does not support * unaligned memory access to packed structures. */ diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 444ccc7a..fa425ddb 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -34,7 +34,12 @@ Allocator &packetPool = staticPool; * * Currently we only allow one interface, that may change in the future */ -Router::Router() : fromRadioQueue(MAX_RX_FROMRADIO) {} +Router::Router() : fromRadioQueue(MAX_RX_FROMRADIO) +{ + DEBUG_MSG("Size of NodeInfo %d\n", sizeof(NodeInfo)); + DEBUG_MSG("Size of SubPacket %d\n", sizeof(SubPacket)); + DEBUG_MSG("Size of MeshPacket %d\n", sizeof(MeshPacket)); +} /** * do idle processing From 154114e900b7dc22a035f778b436d90c64a04a16 Mon Sep 17 00:00:00 2001 From: geeksville Date: Wed, 17 Jun 2020 11:35:21 -0700 Subject: [PATCH 10/10] merge cubecell experiments back into master (might delete later) --- platformio.ini | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platformio.ini b/platformio.ini index a74eb601..4ac4fa25 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = nrf52dk ; Note: the github actions CI test build can't yet build NRF52 targets +default_envs = tbeam ; Note: the github actions CI test build can't yet build NRF52 targets [common] ; common is not currently used @@ -125,7 +125,9 @@ board = ttgo-lora32-v1 build_flags = ${esp32_base.build_flags} -D TTGO_LORA_V2 -; The Heltec Cubecell plus +; The Heltec Cubecell plus +; IMPORTANT NOTE: This target doesn't yet work and probably won't ever work. I'm keeping it around for now. +; For more details see my post in the forum. [env:cubecellplus] platform = https://github.com/HelTecAutomation/platform-asrmicro650x.git ; we use top-of-tree because stable version has too many bugs - asrmicro650x framework = arduino