From e6abd496f9e02d7f24ff0c01efcf12ec62b835d1 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Tue, 27 Jan 2026 08:04:21 +0100 Subject: [PATCH] Various improvements (#461) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * **New Features** * Time and delay utilities added (ticks, ms, µs); SD card now uses an expansion-header CS pin; HTTP downloads warn when run on the GUI task and yield to avoid blocking. * **Bug Fixes / Reliability** * Many hard-crash paths converted to guarded checks to reduce abrupt termination and improve stability. * **Tests** * Unit tests added to validate time and delay accuracy. * **Chores** * License header and build/macro updates. --- CODING_STYLE.md | 8 --- .../Source/devices/TdeckKeyboard.cpp | 2 +- .../Source/devices/SdCard.cpp | 3 +- Devices/m5stack-tab5/device.properties | 3 + Devices/simulator/Source/LvglTask.cpp | 4 +- Devices/simulator/Source/Main.cpp | 2 +- Devices/simulator/Source/Simulator.cpp | 2 +- Devices/simulator/Source/hal/SdlDisplay.h | 5 +- Devices/simulator/Source/hal/SdlKeyboard.h | 3 +- Devices/simulator/Source/hal/SdlTouch.h | 5 +- Drivers/DRV2605/Source/Drv2605.cpp | 5 +- Drivers/EspLcdCompat/Source/EspLcdDisplay.cpp | 9 +-- Drivers/EspLcdCompat/Source/EspLcdDisplay.h | 5 +- .../EspLcdCompat/Source/EspLcdDisplayV2.cpp | 9 +-- Drivers/EspLcdCompat/Source/EspLcdDisplayV2.h | 2 +- Drivers/RgbDisplay/Source/RgbDisplay.cpp | 7 +- Platforms/PlatformEsp32/Source/ErrorEsp32.cpp | 1 + .../Include/Tactility/service/loader/Loader.h | 4 +- Tactility/Private/Tactility/app/AppInstance.h | 4 +- .../Tactility/service/gui/GuiService.h | 13 +++- .../Source/app/alertdialog/AlertDialog.cpp | 2 +- .../Source/app/appdetails/AppDetails.cpp | 8 +-- Tactility/Source/app/apphub/AppHubApp.cpp | 2 +- .../app/apphubdetails/AppHubDetailsApp.cpp | 2 +- Tactility/Source/app/applist/AppList.cpp | 2 +- .../Source/app/appsettings/AppSettings.cpp | 2 +- Tactility/Source/app/boot/Boot.cpp | 2 +- .../app/crashdiagnostics/CrashDiagnostics.cpp | 2 +- Tactility/Source/app/display/Display.cpp | 2 +- Tactility/Source/app/files/FilesApp.cpp | 2 +- Tactility/Source/app/files/View.cpp | 7 +- Tactility/Source/app/fileselection/View.cpp | 5 +- .../Source/app/gpssettings/GpsSettings.cpp | 2 +- .../Source/app/i2cscanner/I2cScanner.cpp | 2 +- .../Source/app/imageviewer/ImageViewer.cpp | 2 +- .../Source/app/inputdialog/InputDialog.cpp | 2 +- .../Source/app/keyboard/KeyboardSettings.cpp | 2 +- Tactility/Source/app/launcher/Launcher.cpp | 6 +- .../app/localesettings/LocaleSettings.cpp | 2 +- Tactility/Source/app/power/Power.cpp | 2 +- .../Source/app/screenshot/Screenshot.cpp | 4 +- .../app/selectiondialog/SelectionDialog.cpp | 2 +- Tactility/Source/app/settings/Settings.cpp | 2 +- .../Source/app/systeminfo/SystemInfo.cpp | 2 +- .../app/timedatesettings/TimeDateSettings.cpp | 2 +- Tactility/Source/app/timezone/TimeZone.cpp | 4 +- .../app/trackball/TrackballSettings.cpp | 2 +- .../Source/app/usbsettings/UsbSettings.cpp | 4 +- .../webserversettings/WebServerSettings.cpp | 4 +- .../app/wifiapsettings/WifiApSettings.cpp | 11 +-- Tactility/Source/app/wificonnect/View.cpp | 2 +- .../Source/app/wificonnect/WifiConnect.cpp | 4 +- .../Source/app/wifimanage/WifiManage.cpp | 2 +- Tactility/Source/hal/Hal.cpp | 10 +-- Tactility/Source/hal/gps/GpsInit.cpp | 2 +- Tactility/Source/hal/i2c/I2c.cpp | 2 +- Tactility/Source/kernel/SystemEvents.cpp | 5 +- Tactility/Source/lvgl/Spinner.cpp | 2 +- Tactility/Source/lvgl/Statusbar.cpp | 18 ++--- Tactility/Source/lvgl/Toolbar.cpp | 5 +- Tactility/Source/network/Http.cpp | 6 +- .../service/displayidle/DisplayIdle.cpp | 4 +- Tactility/Source/service/gui/GuiService.cpp | 21 ++++-- Tactility/Source/service/gui/Keyboard.cpp | 4 +- .../service/keyboardidle/KeyboardIdle.cpp | 4 +- Tactility/Source/service/loader/Loader.cpp | 2 +- .../service/screenshot/ScreenshotTask.cpp | 2 +- .../Source/service/statusbar/Statusbar.cpp | 5 +- .../service/webserver/WebServerService.cpp | 3 +- Tactility/Source/service/wifi/Wifi.cpp | 3 +- Tactility/Source/service/wifi/WifiEsp.cpp | 5 +- Tactility/Source/service/wifi/WifiMock.cpp | 10 +-- TactilityC/Source/tt_app.cpp | 2 +- TactilityC/Source/tt_hal_device.cpp | 2 +- TactilityC/Source/tt_hal_display.cpp | 2 +- TactilityCore/CMakeLists.txt | 9 +-- TactilityCore/Include/Tactility/Check.h | 69 ------------------- TactilityCore/Include/Tactility/CoreDefines.h | 2 - .../Include/Tactility/TactilityCore.h | 1 - TactilityCore/Source/Check.cpp | 40 ----------- TactilityCore/Source/crypt/Crypt.cpp | 12 ++-- TactilityKernel/Include/Tactility/Check.h | 32 +++++++++ TactilityKernel/Include/Tactility/Delay.h | 54 +++++++++++++++ .../Include/Tactility/FreeRTOS/port.h | 2 +- TactilityKernel/Include/Tactility/Time.h | 65 +++++++++++++++++ .../Include/Tactility/concurrent/EventGroup.h | 8 +-- .../Include/Tactility/concurrent/Mutex.h | 10 +-- .../Tactility/concurrent/RecursiveMutex.h | 14 ++-- TactilityKernel/Source/Crash.cpp | 39 +++++++++++ TactilityKernel/Source/Driver.cpp | 3 +- TactilityKernel/Source/Log.cpp | 4 ++ .../Source/concurrent/EventGroup.cpp | 2 +- Tests/Tactility/CMakeLists.txt | 2 +- Tests/TactilityCore/CMakeLists.txt | 1 + Tests/TactilityKernel/TimeAndDelay.cpp | 30 ++++++++ 95 files changed, 433 insertions(+), 284 deletions(-) delete mode 100644 TactilityCore/Include/Tactility/Check.h delete mode 100644 TactilityCore/Source/Check.cpp create mode 100644 TactilityKernel/Include/Tactility/Check.h create mode 100644 TactilityKernel/Include/Tactility/Delay.h create mode 100644 TactilityKernel/Include/Tactility/Time.h create mode 100644 TactilityKernel/Source/Crash.cpp create mode 100644 Tests/TactilityKernel/TimeAndDelay.cpp diff --git a/CODING_STYLE.md b/CODING_STYLE.md index 18c9d459..0001c02d 100644 --- a/CODING_STYLE.md +++ b/CODING_STYLE.md @@ -46,14 +46,6 @@ void getLimit() { } ``` -### Preprocessor - -Preprocessor functions are written in snake-case and prefixed with `tt_`, for example: - -```c++ -#define tt_check(x) if (!(x)) { /* .. */ } -``` - ### Type names Consts are lower camel case with capital letters. diff --git a/Devices/lilygo-tdeck/Source/devices/TdeckKeyboard.cpp b/Devices/lilygo-tdeck/Source/devices/TdeckKeyboard.cpp index 5d730e0b..f0dc6e0f 100644 --- a/Devices/lilygo-tdeck/Source/devices/TdeckKeyboard.cpp +++ b/Devices/lilygo-tdeck/Source/devices/TdeckKeyboard.cpp @@ -29,7 +29,7 @@ static bool keyboard_i2c_read(uint8_t* output) { * @param indev_drv * @param data */ -static void keyboard_read_callback(TT_UNUSED lv_indev_t* indev, lv_indev_data_t* data) { +static void keyboard_read_callback(lv_indev_t* indev, lv_indev_data_t* data) { static uint8_t last_buffer = 0x00; uint8_t read_buffer = 0x00; diff --git a/Devices/m5stack-cardputer-adv/Source/devices/SdCard.cpp b/Devices/m5stack-cardputer-adv/Source/devices/SdCard.cpp index b7a130a9..8715d72c 100644 --- a/Devices/m5stack-cardputer-adv/Source/devices/SdCard.cpp +++ b/Devices/m5stack-cardputer-adv/Source/devices/SdCard.cpp @@ -3,6 +3,7 @@ #include constexpr auto SDCARD_PIN_CS = GPIO_NUM_12; +constexpr auto EXPANSION_HEADER_PIN_CS = GPIO_NUM_5; using tt::hal::sdcard::SpiSdCardDevice; @@ -14,7 +15,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, tt::hal::spi::getLock(SPI3_HOST), - std::vector(), + std::vector { EXPANSION_HEADER_PIN_CS }, SPI3_HOST ); diff --git a/Devices/m5stack-tab5/device.properties b/Devices/m5stack-tab5/device.properties index 45461460..c9a3945d 100644 --- a/Devices/m5stack-tab5/device.properties +++ b/Devices/m5stack-tab5/device.properties @@ -18,6 +18,9 @@ dpi=294 [lvgl] colorDepth=16 +[cdn] +warningMessage=Only the original hardware variant with the ILI9881C display is supported for now + [sdkconfig] CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 diff --git a/Devices/simulator/Source/LvglTask.cpp b/Devices/simulator/Source/LvglTask.cpp index b0631dc6..530a9904 100644 --- a/Devices/simulator/Source/LvglTask.cpp +++ b/Devices/simulator/Source/LvglTask.cpp @@ -52,7 +52,7 @@ static void lvgl_unlock() { } void lvgl_task_interrupt() { - tt_check(task_lock(portMAX_DELAY)); + check(task_lock(portMAX_DELAY)); task_set_running(false); // interrupt task with boolean as flag task_unlock(); } @@ -75,7 +75,7 @@ void lvgl_task_start() { assert(task_result == pdTRUE); } -static void lvgl_task(TT_UNUSED void* arg) { +static void lvgl_task(void* arg) { LOGGER.info("LVGL task started"); /** Ideally. the display handle would be created during Simulator.start(), diff --git a/Devices/simulator/Source/Main.cpp b/Devices/simulator/Source/Main.cpp index 2aa69536..55f4565c 100644 --- a/Devices/simulator/Source/Main.cpp +++ b/Devices/simulator/Source/Main.cpp @@ -15,7 +15,7 @@ void setMain(MainFunction newMainFunction) { mainFunction = newMainFunction; } -static void freertosMainTask(TT_UNUSED void* parameter) { +static void freertosMainTask(void* parameter) { LOGGER.info("starting app_main()"); assert(simulator::mainFunction); mainFunction(); diff --git a/Devices/simulator/Source/Simulator.cpp b/Devices/simulator/Source/Simulator.cpp index a00cca71..e712b27f 100644 --- a/Devices/simulator/Source/Simulator.cpp +++ b/Devices/simulator/Source/Simulator.cpp @@ -17,7 +17,7 @@ static bool initBoot() { return true; } -TT_UNUSED static void deinitPower() { +static void deinitPower() { lvgl_task_interrupt(); while (lvgl_task_is_running()) { tt::kernel::delayMillis(10); diff --git a/Devices/simulator/Source/hal/SdlDisplay.h b/Devices/simulator/Source/hal/SdlDisplay.h index 3ccc7f59..eb02f4da 100644 --- a/Devices/simulator/Source/hal/SdlDisplay.h +++ b/Devices/simulator/Source/hal/SdlDisplay.h @@ -1,6 +1,7 @@ #pragma once #include "SdlTouch.h" +#include #include /** Hack: variable comes from LvglTask.cpp */ @@ -14,11 +15,11 @@ public: std::string getDescription() const override { return ""; } bool start() override { return true; } - bool stop() override { tt_crash("Not supported"); } + bool stop() override { check(false, "Not supported"); } bool supportsLvgl() const override { return true; } bool startLvgl() override { return displayHandle != nullptr; } - bool stopLvgl() override { tt_crash("Not supported"); } + bool stopLvgl() override { check(false, "Not supported"); } lv_display_t* _Nullable getLvglDisplay() const override { return displayHandle; } std::shared_ptr _Nullable getTouchDevice() override { return std::make_shared(); } diff --git a/Devices/simulator/Source/hal/SdlKeyboard.h b/Devices/simulator/Source/hal/SdlKeyboard.h index 10e6978e..e8476405 100644 --- a/Devices/simulator/Source/hal/SdlKeyboard.h +++ b/Devices/simulator/Source/hal/SdlKeyboard.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include class SdlKeyboard final : public tt::hal::keyboard::KeyboardDevice { @@ -17,7 +18,7 @@ public: return handle != nullptr; } - bool stopLvgl() override { tt_crash("Not supported"); } + bool stopLvgl() override { check(false, "Not supported"); } bool isAttached() const override { return true; } diff --git a/Devices/simulator/Source/hal/SdlTouch.h b/Devices/simulator/Source/hal/SdlTouch.h index 9ae1790e..be32c97a 100644 --- a/Devices/simulator/Source/hal/SdlTouch.h +++ b/Devices/simulator/Source/hal/SdlTouch.h @@ -1,6 +1,7 @@ #pragma once #include "Tactility/hal/touch/TouchDevice.h" +#include #include class SdlTouch final : public tt::hal::touch::TouchDevice { @@ -15,7 +16,7 @@ public: bool start() override { return true; } - bool stop() override { tt_crash("Not supported"); } + bool stop() override { check(false, "Not supported"); } bool supportsLvgl() const override { return true; } @@ -24,7 +25,7 @@ public: return handle != nullptr; } - bool stopLvgl() override { tt_crash("Not supported"); } + bool stopLvgl() override { check(false, "Not supported"); } lv_indev_t* _Nullable getLvglIndev() override { return handle; } diff --git a/Drivers/DRV2605/Source/Drv2605.cpp b/Drivers/DRV2605/Source/Drv2605.cpp index b5bb4358..eba47020 100644 --- a/Drivers/DRV2605/Source/Drv2605.cpp +++ b/Drivers/DRV2605/Source/Drv2605.cpp @@ -6,10 +6,7 @@ static const auto LOGGER = tt::Logger("DRV2605"); Drv2605::Drv2605(i2c_port_t port, bool autoPlayStartupBuzz) : I2cDevice(port, ADDRESS), autoPlayStartupBuzz(autoPlayStartupBuzz) { - if (!init()) { - LOGGER.error("Failed to initialize DRV2605"); - tt_crash(); - } + check(init(), "Initialize DRV2605"); if (autoPlayStartupBuzz) { setWaveFormForBuzz(); diff --git a/Drivers/EspLcdCompat/Source/EspLcdDisplay.cpp b/Drivers/EspLcdCompat/Source/EspLcdDisplay.cpp index 7aacd821..794deadf 100644 --- a/Drivers/EspLcdCompat/Source/EspLcdDisplay.cpp +++ b/Drivers/EspLcdCompat/Source/EspLcdDisplay.cpp @@ -10,9 +10,10 @@ static const auto LOGGER = tt::Logger("EspLcdDisplay"); EspLcdDisplay::~EspLcdDisplay() { - if (displayDriver != nullptr && displayDriver.use_count() > 1) { - tt_crash("DisplayDriver is still in use. This will cause memory access violations."); - } + check( + displayDriver == nullptr || displayDriver.use_count() < 2, // 1 reference is held by this class + "DisplayDriver is still in use. This will cause memory access violations." + ); } bool EspLcdDisplay::start() { @@ -115,7 +116,7 @@ std::shared_ptr EspLcdDisplay::getDisplayDriver } else if (lvgl_port_config.color_format == LV_COLOR_FORMAT_RGB888) { color_format = tt::hal::display::ColorFormat::RGB888; } else { - tt_crash("unsupported driver"); + check(false, "unsupported driver"); } displayDriver = std::make_shared( diff --git a/Drivers/EspLcdCompat/Source/EspLcdDisplay.h b/Drivers/EspLcdCompat/Source/EspLcdDisplay.h index 11ca8a18..3ca4e3e6 100644 --- a/Drivers/EspLcdCompat/Source/EspLcdDisplay.h +++ b/Drivers/EspLcdCompat/Source/EspLcdDisplay.h @@ -7,7 +7,8 @@ #include #include -class TT_DEPRECATED EspLcdDisplay : public tt::hal::display::DisplayDevice { +/** @deprecated use EspLcdDisplayV2 */ +class EspLcdDisplay : public tt::hal::display::DisplayDevice { esp_lcd_panel_io_handle_t _Nullable ioHandle = nullptr; esp_lcd_panel_handle_t _Nullable panelHandle = nullptr; @@ -29,7 +30,7 @@ protected: virtual bool isRgbPanel() const { return false; } - virtual lvgl_port_display_rgb_cfg_t getLvglPortDisplayRgbConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { tt_crash("Not supported"); } + virtual lvgl_port_display_rgb_cfg_t getLvglPortDisplayRgbConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { check(false, "Not supported"); } public: diff --git a/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.cpp b/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.cpp index 3eba9994..fe277bdb 100644 --- a/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.cpp +++ b/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.cpp @@ -18,9 +18,10 @@ inline unsigned int getBufferSize(const std::shared_ptr& co } EspLcdDisplayV2::~EspLcdDisplayV2() { - if (displayDriver != nullptr && displayDriver.use_count() > 1) { - tt_crash("DisplayDriver is still in use. This will cause memory access violations."); - } + check( + displayDriver == nullptr || displayDriver.use_count() < 2, // 1 reference is held by this class + "DisplayDriver is still in use. This will cause memory access violations." + ); } bool EspLcdDisplayV2::applyConfiguration() const { @@ -215,7 +216,7 @@ std::shared_ptr EspLcdDisplayV2::getDisplayDriv } else if (lvgl_port_config.color_format == LV_COLOR_FORMAT_RGB888) { color_format = tt::hal::display::ColorFormat::RGB888; } else { - tt_crash("unsupported driver"); + check(false, "unsupported driver"); } displayDriver = std::make_shared( diff --git a/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.h b/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.h index 94c66ec4..ab431dcc 100644 --- a/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.h +++ b/Drivers/EspLcdCompat/Source/EspLcdDisplayV2.h @@ -53,7 +53,7 @@ protected: virtual bool isRgbPanel() const { return false; } - virtual lvgl_port_display_rgb_cfg_t getLvglPortDisplayRgbConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { tt_crash("Not supported"); } + virtual lvgl_port_display_rgb_cfg_t getLvglPortDisplayRgbConfig(esp_lcd_panel_io_handle_t ioHandle, esp_lcd_panel_handle_t panelHandle) { check(false, "Not supported"); } // Hook for MIPI-DSI DPI panels to let LVGL port use DSI-specific path virtual bool useDsiPanel() const { return false; } diff --git a/Drivers/RgbDisplay/Source/RgbDisplay.cpp b/Drivers/RgbDisplay/Source/RgbDisplay.cpp index fdd4499e..b0d23178 100644 --- a/Drivers/RgbDisplay/Source/RgbDisplay.cpp +++ b/Drivers/RgbDisplay/Source/RgbDisplay.cpp @@ -12,9 +12,10 @@ static const auto LOGGER = tt::Logger("RgbDisplay"); RgbDisplay::~RgbDisplay() { - if (displayDriver != nullptr && displayDriver.use_count() > 1) { - tt_crash("DisplayDriver is still in use. This will cause memory access violations."); - } + check( + displayDriver == nullptr || displayDriver.use_count() == 0, + "DisplayDriver is still in use. This will cause memory access violations." + ); } bool RgbDisplay::start() { diff --git a/Platforms/PlatformEsp32/Source/ErrorEsp32.cpp b/Platforms/PlatformEsp32/Source/ErrorEsp32.cpp index 5264fd59..9b0d7135 100644 --- a/Platforms/PlatformEsp32/Source/ErrorEsp32.cpp +++ b/Platforms/PlatformEsp32/Source/ErrorEsp32.cpp @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 #include error_t esp_err_to_error(esp_err_t error) { diff --git a/Tactility/Include/Tactility/service/loader/Loader.h b/Tactility/Include/Tactility/service/loader/Loader.h index fd95aebb..aeee3725 100644 --- a/Tactility/Include/Tactility/service/loader/Loader.h +++ b/Tactility/Include/Tactility/service/loader/Loader.h @@ -46,12 +46,12 @@ private: int findAppInStack(const std::string& id) const; - bool onStart(TT_UNUSED ServiceContext& service) override { + bool onStart(ServiceContext& service) override { dispatcherThread->start(); return true; } - void onStop(TT_UNUSED ServiceContext& service) override { + void onStop(ServiceContext& service) override { // Send stop signal to thread and wait for thread to finish mutex.withLock([this] { dispatcherThread->stop(); diff --git a/Tactility/Private/Tactility/app/AppInstance.h b/Tactility/Private/Tactility/app/AppInstance.h index 2df6a712..dfd10d27 100644 --- a/Tactility/Private/Tactility/app/AppInstance.h +++ b/Tactility/Private/Tactility/app/AppInstance.h @@ -53,10 +53,10 @@ class AppInstance : public AppContext { #ifdef ESP_PLATFORM return createElfApp(manifest); #else - tt_crash("not supported"); + check(false, "not supported"); #endif } else { - tt_crash("not implemented"); + check(false, "not implemented"); } } diff --git a/Tactility/Private/Tactility/service/gui/GuiService.h b/Tactility/Private/Tactility/service/gui/GuiService.h index 908091dd..a3830774 100644 --- a/Tactility/Private/Tactility/service/gui/GuiService.h +++ b/Tactility/Private/Tactility/service/gui/GuiService.h @@ -17,6 +17,13 @@ constexpr auto GUI_THREAD_FLAG_INPUT = (1 << 1); constexpr auto GUI_THREAD_FLAG_EXIT = (1 << 2); constexpr auto GUI_THREAD_FLAG_ALL = (GUI_THREAD_FLAG_DRAW | GUI_THREAD_FLAG_INPUT | GUI_THREAD_FLAG_EXIT); +/** + * Output a log warning if the current task is the GUI task. + * This is meant for code that should either create their own task or use a different task to execute on. + * @param[in] context a descriptive name or label that refers to the caller of this function + */ +void warnIfRunningOnGuiTask(const char* context); + class GuiService final : public Service { // Thread and lock @@ -46,7 +53,7 @@ class GuiService final : public Service { void redraw(); void lock() const { - tt_check(mutex.lock(pdMS_TO_TICKS(1000))); + check(mutex.lock(pdMS_TO_TICKS(1000))); } void unlock() const { @@ -59,9 +66,9 @@ class GuiService final : public Service { public: - bool onStart(TT_UNUSED ServiceContext& service) override; + bool onStart(ServiceContext& service) override; - void onStop(TT_UNUSED ServiceContext& service) override; + void onStop(ServiceContext& service) override; void requestDraw(); diff --git a/Tactility/Source/app/alertdialog/AlertDialog.cpp b/Tactility/Source/app/alertdialog/AlertDialog.cpp index bbd09359..d865aae9 100644 --- a/Tactility/Source/app/alertdialog/AlertDialog.cpp +++ b/Tactility/Source/app/alertdialog/AlertDialog.cpp @@ -95,7 +95,7 @@ public: void onShow(AppContext& app, lv_obj_t* parent) override { auto parameters = app.getParameters(); - tt_check(parameters != nullptr, "Parameters missing"); + check(parameters != nullptr, "Parameters missing"); std::string title = getTitleParameter(app.getParameters()); lv_obj_t* toolbar = lvgl::toolbar_create(parent, title); diff --git a/Tactility/Source/app/appdetails/AppDetails.cpp b/Tactility/Source/app/appdetails/AppDetails.cpp index 95fd55f8..3614d8e7 100644 --- a/Tactility/Source/app/appdetails/AppDetails.cpp +++ b/Tactility/Source/app/appdetails/AppDetails.cpp @@ -4,9 +4,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -27,7 +27,7 @@ class AppDetailsApp : public App { std::shared_ptr manifest; - static void onPressUninstall(TT_UNUSED lv_event_t* event) { + static void onPressUninstall(lv_event_t* event) { auto* self = static_cast(lv_event_get_user_data(event)); std::vector choices = { "Yes", @@ -40,7 +40,7 @@ public: void onCreate(AppContext& app) override { const auto parameters = app.getParameters(); - tt_check(parameters != nullptr, "Parameters missing"); + check(parameters != nullptr, "Parameters missing"); auto app_id = parameters->getString("appId"); manifest = findAppManifestById(app_id); assert(manifest != nullptr); @@ -86,7 +86,7 @@ public: } } - void onResult(TT_UNUSED AppContext& appContext, TT_UNUSED LaunchId launchId, TT_UNUSED Result result, std::unique_ptr bundle) override { + void onResult(AppContext& appContext, LaunchId launchId, Result result, std::unique_ptr bundle) override { if (result != Result::Ok || bundle == nullptr) { return; } diff --git a/Tactility/Source/app/apphub/AppHubApp.cpp b/Tactility/Source/app/apphub/AppHubApp.cpp index f14ccf39..a6596024 100644 --- a/Tactility/Source/app/apphub/AppHubApp.cpp +++ b/Tactility/Source/app/apphub/AppHubApp.cpp @@ -157,7 +157,7 @@ class AppHubApp final : public App { public: - void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { + void onShow(AppContext& app, lv_obj_t* parent) override { lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT); diff --git a/Tactility/Source/app/apphubdetails/AppHubDetailsApp.cpp b/Tactility/Source/app/apphubdetails/AppHubDetailsApp.cpp index 980bb8e2..8be2305f 100644 --- a/Tactility/Source/app/apphubdetails/AppHubDetailsApp.cpp +++ b/Tactility/Source/app/apphubdetails/AppHubDetailsApp.cpp @@ -186,7 +186,7 @@ public: } } - void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { + void onShow(AppContext& app, lv_obj_t* parent) override { lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT); diff --git a/Tactility/Source/app/applist/AppList.cpp b/Tactility/Source/app/applist/AppList.cpp index 89dd6d77..bc7ea771 100644 --- a/Tactility/Source/app/applist/AppList.cpp +++ b/Tactility/Source/app/applist/AppList.cpp @@ -24,7 +24,7 @@ class AppListApp final : public App { public: - void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { + void onShow(AppContext& app, lv_obj_t* parent) override { auto* toolbar = lvgl::toolbar_create(parent, app); lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0); diff --git a/Tactility/Source/app/appsettings/AppSettings.cpp b/Tactility/Source/app/appsettings/AppSettings.cpp index 2d2a12d2..c55621e0 100644 --- a/Tactility/Source/app/appsettings/AppSettings.cpp +++ b/Tactility/Source/app/appsettings/AppSettings.cpp @@ -25,7 +25,7 @@ class AppSettingsApp final : public App { public: - void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { + void onShow(AppContext& app, lv_obj_t* parent) override { auto* toolbar = lvgl::toolbar_create(parent, "Installed Apps"); lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0); diff --git a/Tactility/Source/app/boot/Boot.cpp b/Tactility/Source/app/boot/Boot.cpp index e4460249..d01cf0e5 100644 --- a/Tactility/Source/app/boot/Boot.cpp +++ b/Tactility/Source/app/boot/Boot.cpp @@ -170,7 +170,7 @@ public: thread.join(); } - void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { + void onShow(AppContext& app, lv_obj_t* parent) override { lvgl::obj_set_style_bg_blacken(parent); lv_obj_set_style_border_width(parent, 0, LV_STATE_DEFAULT); lv_obj_set_style_radius(parent, 0, LV_STATE_DEFAULT); diff --git a/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp b/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp index 16981ec4..64a53ed3 100644 --- a/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp +++ b/Tactility/Source/app/crashdiagnostics/CrashDiagnostics.cpp @@ -17,7 +17,7 @@ static const auto LOGGER = Logger("CrashDiagnostics"); extern const AppManifest manifest; -void onContinuePressed(TT_UNUSED lv_event_t* event) { +void onContinuePressed(lv_event_t* event) { stop(manifest.appId); launcher::start(); } diff --git a/Tactility/Source/app/display/Display.cpp b/Tactility/Source/app/display/Display.cpp index 4361329e..b169b24a 100644 --- a/Tactility/Source/app/display/Display.cpp +++ b/Tactility/Source/app/display/Display.cpp @@ -236,7 +236,7 @@ public: } } - void onHide(TT_UNUSED AppContext& app) override { + void onHide(AppContext& app) override { if (displaySettingsUpdated) { // Dispatch it, so file IO doesn't block the UI const settings::display::DisplaySettings settings_to_save = displaySettings; diff --git a/Tactility/Source/app/files/FilesApp.cpp b/Tactility/Source/app/files/FilesApp.cpp index d34825b6..9b30b3d0 100644 --- a/Tactility/Source/app/files/FilesApp.cpp +++ b/Tactility/Source/app/files/FilesApp.cpp @@ -27,7 +27,7 @@ public: view->init(appContext, parent); } - void onResult(AppContext& appContext, TT_UNUSED LaunchId launchId, Result result, std::unique_ptr bundle) override { + void onResult(AppContext& appContext, LaunchId launchId, Result result, std::unique_ptr bundle) override { view->onResult(launchId, result, std::move(bundle)); } }; diff --git a/Tactility/Source/app/files/View.cpp b/Tactility/Source/app/files/View.cpp index 96d17a2f..07408976 100644 --- a/Tactility/Source/app/files/View.cpp +++ b/Tactility/Source/app/files/View.cpp @@ -1,12 +1,13 @@ #include #include -#include #include #include #include #include #include +#include +#include #include #include #include @@ -58,7 +59,7 @@ static void onDeletePressedCallback(lv_event_t* event) { view->onDeletePressed(); } -static void onNavigateUpPressedCallback(TT_UNUSED lv_event_t* event) { +static void onNavigateUpPressedCallback(lv_event_t* event) { auto* view = static_cast(lv_event_get_user_data(event)); view->onNavigateUpPressed(); } @@ -179,7 +180,7 @@ void View::onDirEntryLongPressed(int32_t index) { } void View::createDirEntryWidget(lv_obj_t* list, dirent& dir_entry) { - tt_check(list); + check(list); const char* symbol; if (dir_entry.d_type == file::TT_DT_DIR || dir_entry.d_type == file::TT_DT_CHR) { symbol = LV_SYMBOL_DIRECTORY; diff --git a/Tactility/Source/app/fileselection/View.cpp b/Tactility/Source/app/fileselection/View.cpp index 95cd43e8..3acd453d 100644 --- a/Tactility/Source/app/fileselection/View.cpp +++ b/Tactility/Source/app/fileselection/View.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include #include @@ -30,7 +31,7 @@ static void onDirEntryPressedCallback(lv_event_t* event) { view->onDirEntryPressed(index); } -static void onNavigateUpPressedCallback(TT_UNUSED lv_event_t* event) { +static void onNavigateUpPressedCallback(lv_event_t* event) { auto* view = static_cast(lv_event_get_user_data(event)); view->onNavigateUpPressed(); } @@ -126,7 +127,7 @@ void View::onPathTextChanged(lv_event_t* event) { } void View::createDirEntryWidget(lv_obj_t* list, dirent& dir_entry) { - tt_check(list); + check(list); const char* symbol; if (dir_entry.d_type == file::TT_DT_DIR || dir_entry.d_type == file::TT_DT_CHR) { symbol = LV_SYMBOL_DIRECTORY; diff --git a/Tactility/Source/app/gpssettings/GpsSettings.cpp b/Tactility/Source/app/gpssettings/GpsSettings.cpp index cbcceb1b..710c75ef 100644 --- a/Tactility/Source/app/gpssettings/GpsSettings.cpp +++ b/Tactility/Source/app/gpssettings/GpsSettings.cpp @@ -318,7 +318,7 @@ class GpsSettingsApp final : public App { } } - void onGpsToggled(TT_UNUSED lv_event_t* event) { + void onGpsToggled(lv_event_t* event) { bool wants_on = lv_obj_has_state(switchWidget, LV_STATE_CHECKED); auto state = service->getState(); bool is_on = (state == service::gps::State::On) || (state == service::gps::State::OnPending); diff --git a/Tactility/Source/app/i2cscanner/I2cScanner.cpp b/Tactility/Source/app/i2cscanner/I2cScanner.cpp index e0698b2d..101bca32 100644 --- a/Tactility/Source/app/i2cscanner/I2cScanner.cpp +++ b/Tactility/Source/app/i2cscanner/I2cScanner.cpp @@ -325,7 +325,7 @@ void I2cScannerApp::selectBus(int32_t selected) { updateViews(); } -void I2cScannerApp::onPressScan(TT_UNUSED lv_event_t* event) { +void I2cScannerApp::onPressScan(lv_event_t* event) { if (scanState == ScanStateScanning) { stopScanning(); } else { diff --git a/Tactility/Source/app/imageviewer/ImageViewer.cpp b/Tactility/Source/app/imageviewer/ImageViewer.cpp index 401d30ad..9640035b 100644 --- a/Tactility/Source/app/imageviewer/ImageViewer.cpp +++ b/Tactility/Source/app/imageviewer/ImageViewer.cpp @@ -45,7 +45,7 @@ class ImageViewerApp final : public App { lv_obj_align_to(file_label, wrapper, LV_ALIGN_BOTTOM_LEFT, 0, 0); std::shared_ptr bundle = app.getParameters(); - tt_check(bundle != nullptr, "Parameters not set"); + check(bundle != nullptr, "Parameters not set"); std::string file_argument; if (bundle->optString(IMAGE_VIEWER_FILE_ARGUMENT, file_argument)) { std::string prefixed_path = lvgl::PATH_PREFIX + file_argument; diff --git a/Tactility/Source/app/inputdialog/InputDialog.cpp b/Tactility/Source/app/inputdialog/InputDialog.cpp index a330bb52..8eb258a3 100644 --- a/Tactility/Source/app/inputdialog/InputDialog.cpp +++ b/Tactility/Source/app/inputdialog/InputDialog.cpp @@ -79,7 +79,7 @@ public: void onShow(AppContext& app, lv_obj_t* parent) override { auto parameters = app.getParameters(); - tt_check(parameters != nullptr, "Parameters missing"); + check(parameters != nullptr, "Parameters missing"); std::string title = getTitleParameter(app.getParameters()); auto* toolbar = lvgl::toolbar_create(parent, title); diff --git a/Tactility/Source/app/keyboard/KeyboardSettings.cpp b/Tactility/Source/app/keyboard/KeyboardSettings.cpp index 89bc1f9a..5706f4c5 100644 --- a/Tactility/Source/app/keyboard/KeyboardSettings.cpp +++ b/Tactility/Source/app/keyboard/KeyboardSettings.cpp @@ -170,7 +170,7 @@ public: } } - void onHide(TT_UNUSED AppContext& app) override { + void onHide(AppContext& app) override { if (updated) { const auto copy = kbSettings; getMainDispatcher().dispatch([copy]{ settings::keyboard::save(copy); }); diff --git a/Tactility/Source/app/launcher/Launcher.cpp b/Tactility/Source/app/launcher/Launcher.cpp index 6bb705aa..12d4e2d7 100644 --- a/Tactility/Source/app/launcher/Launcher.cpp +++ b/Tactility/Source/app/launcher/Launcher.cpp @@ -76,7 +76,7 @@ class LauncherApp final : public App { return show_power_button; } - static void onAppPressed(TT_UNUSED lv_event_t* e) { + static void onAppPressed(lv_event_t* e) { auto* appId = static_cast(lv_event_get_user_data(e)); start(appId); } @@ -90,7 +90,7 @@ class LauncherApp final : public App { public: - void onCreate(TT_UNUSED AppContext& app) override { + void onCreate(AppContext& app) override { settings::BootSettings boot_properties; if (settings::loadBootSettings(boot_properties) && !boot_properties.autoStartAppId.empty()) { LOGGER.info("Starting {}", boot_properties.autoStartAppId); @@ -98,7 +98,7 @@ public: } } - void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { + void onShow(AppContext& app, lv_obj_t* parent) override { auto* buttons_wrapper = lv_obj_create(parent); auto ui_scale = hal::getConfiguration()->uiScale; diff --git a/Tactility/Source/app/localesettings/LocaleSettings.cpp b/Tactility/Source/app/localesettings/LocaleSettings.cpp index e3159237..93b2858b 100644 --- a/Tactility/Source/app/localesettings/LocaleSettings.cpp +++ b/Tactility/Source/app/localesettings/LocaleSettings.cpp @@ -149,7 +149,7 @@ public: lv_obj_add_event_cb(languageDropdown, onLanguageSet, LV_EVENT_VALUE_CHANGED, this); } - void onHide(TT_UNUSED AppContext& app) override { + void onHide(AppContext& app) override { if (settingsUpdated && regionTextArea) { settings::SystemSettings sysSettings; if (settings::loadSystemSettings(sysSettings)) { diff --git a/Tactility/Source/app/power/Power.cpp b/Tactility/Source/app/power/Power.cpp index 11e18640..95f39a61 100644 --- a/Tactility/Source/app/power/Power.cpp +++ b/Tactility/Source/app/power/Power.cpp @@ -183,7 +183,7 @@ public: update_timer.start(); } - void onHide(TT_UNUSED AppContext& app) override { + void onHide(AppContext& app) override { update_timer.stop(); } }; diff --git a/Tactility/Source/app/screenshot/Screenshot.cpp b/Tactility/Source/app/screenshot/Screenshot.cpp index 82d172e9..bf25fb0d 100644 --- a/Tactility/Source/app/screenshot/Screenshot.cpp +++ b/Tactility/Source/app/screenshot/Screenshot.cpp @@ -58,14 +58,14 @@ std::shared_ptr _Nullable optApp() { } } -static void onStartPressedCallback(TT_UNUSED lv_event_t* event) { +static void onStartPressedCallback(lv_event_t* event) { auto app = optApp(); if (app != nullptr) { app->onStartPressed(); } } -static void onModeSetCallback(TT_UNUSED lv_event_t* event) { +static void onModeSetCallback(lv_event_t* event) { auto app = optApp(); if (app != nullptr) { app->onModeSet(); diff --git a/Tactility/Source/app/selectiondialog/SelectionDialog.cpp b/Tactility/Source/app/selectiondialog/SelectionDialog.cpp index 0cd15a70..e4933482 100644 --- a/Tactility/Source/app/selectiondialog/SelectionDialog.cpp +++ b/Tactility/Source/app/selectiondialog/SelectionDialog.cpp @@ -80,7 +80,7 @@ public: lv_obj_set_flex_grow(list, 1); auto parameters = app.getParameters(); - tt_check(parameters != nullptr, "Parameters missing"); + check(parameters != nullptr, "Parameters missing"); std::string items_concatenated; if (parameters->optString(PARAMETER_BUNDLE_KEY_ITEMS, items_concatenated)) { std::vector items = string::split(items_concatenated, PARAMETER_ITEM_CONCATENATION_TOKEN); diff --git a/Tactility/Source/app/settings/Settings.cpp b/Tactility/Source/app/settings/Settings.cpp index 190bde12..38a202d2 100644 --- a/Tactility/Source/app/settings/Settings.cpp +++ b/Tactility/Source/app/settings/Settings.cpp @@ -16,7 +16,7 @@ static void onAppPressed(lv_event_t* e) { } static void createWidget(const std::shared_ptr& manifest, void* parent) { - tt_check(parent); + check(parent); auto* list = (lv_obj_t*)parent; const void* icon = !manifest->appIcon.empty() ? manifest->appIcon.c_str() : TT_ASSETS_APP_ICON_FALLBACK; auto* btn = lv_list_add_button(list, icon, manifest->appName.c_str()); diff --git a/Tactility/Source/app/systeminfo/SystemInfo.cpp b/Tactility/Source/app/systeminfo/SystemInfo.cpp index 50fa8736..bc90d3fd 100644 --- a/Tactility/Source/app/systeminfo/SystemInfo.cpp +++ b/Tactility/Source/app/systeminfo/SystemInfo.cpp @@ -692,7 +692,7 @@ class SystemInfoApp final : public App { tasksTimer.start(); // Tasks/CPU: every 15s } - void onHide(TT_UNUSED AppContext& app) override { + void onHide(AppContext& app) override { memoryTimer.stop(); tasksTimer.stop(); } diff --git a/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp b/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp index df98d8bc..b52bccf7 100644 --- a/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp +++ b/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp @@ -134,7 +134,7 @@ public: lv_label_set_text(timeZoneLabel, timeZoneName.c_str()); } - void onResult(AppContext& app, TT_UNUSED LaunchId launchId, Result result, std::unique_ptr bundle) override { + void onResult(AppContext& app, LaunchId launchId, Result result, std::unique_ptr bundle) override { if (result == Result::Ok && bundle != nullptr) { const auto name = timezone::getResultName(*bundle); const auto code = timezone::getResultCode(*bundle); diff --git a/Tactility/Source/app/timezone/TimeZone.cpp b/Tactility/Source/app/timezone/TimeZone.cpp index 5059cb9a..2d8a9ebd 100644 --- a/Tactility/Source/app/timezone/TimeZone.cpp +++ b/Tactility/Source/app/timezone/TimeZone.cpp @@ -73,12 +73,12 @@ class TimeZoneApp final : public App { lv_obj_t* listWidget = nullptr; lv_obj_t* filterTextareaWidget = nullptr; - static void onTextareaValueChangedCallback(TT_UNUSED lv_event_t* e) { + static void onTextareaValueChangedCallback(lv_event_t* e) { auto* app = (TimeZoneApp*)lv_event_get_user_data(e); app->onTextareaValueChanged(e); } - void onTextareaValueChanged(TT_UNUSED lv_event_t* e) { + void onTextareaValueChanged(lv_event_t* e) { if (mutex.lock(100 / portTICK_PERIOD_MS)) { if (updateTimer->isRunning()) { updateTimer->stop(); diff --git a/Tactility/Source/app/trackball/TrackballSettings.cpp b/Tactility/Source/app/trackball/TrackballSettings.cpp index 332060e7..2cc3e394 100644 --- a/Tactility/Source/app/trackball/TrackballSettings.cpp +++ b/Tactility/Source/app/trackball/TrackballSettings.cpp @@ -197,7 +197,7 @@ public: } } - void onHide(TT_UNUSED AppContext& app) override { + void onHide(AppContext& app) override { if (updated) { const auto copy = tbSettings; getMainDispatcher().dispatch([copy]{ settings::trackball::save(copy); }); diff --git a/Tactility/Source/app/usbsettings/UsbSettings.cpp b/Tactility/Source/app/usbsettings/UsbSettings.cpp index 049afa2a..9d8f0521 100644 --- a/Tactility/Source/app/usbsettings/UsbSettings.cpp +++ b/Tactility/Source/app/usbsettings/UsbSettings.cpp @@ -11,12 +11,12 @@ namespace tt::app::usbsettings { -static void onRebootMassStorageSdmmc(TT_UNUSED lv_event_t* event) { +static void onRebootMassStorageSdmmc(lv_event_t* event) { hal::usb::rebootIntoMassStorageSdmmc(); } // Flash reboot handler -static void onRebootMassStorageFlash(TT_UNUSED lv_event_t* event) { +static void onRebootMassStorageFlash(lv_event_t* event) { hal::usb::rebootIntoMassStorageFlash(); } diff --git a/Tactility/Source/app/webserversettings/WebServerSettings.cpp b/Tactility/Source/app/webserversettings/WebServerSettings.cpp index 68f8ca07..e4ac9309 100644 --- a/Tactility/Source/app/webserversettings/WebServerSettings.cpp +++ b/Tactility/Source/app/webserversettings/WebServerSettings.cpp @@ -183,7 +183,7 @@ class WebServerSettingsApp final : public App { } public: - void onCreate(TT_UNUSED AppContext& app) override { + void onCreate(AppContext& app) override { wsSettings = settings::webserver::loadOrGetDefault(); originalSettings = wsSettings; } @@ -353,7 +353,7 @@ public: "AP mode uses the password configured above."); } - void onHide(TT_UNUSED AppContext& app) override { + void onHide(AppContext& app) override { if (updated) { // Read values from text areas if (textAreaApPassword) { diff --git a/Tactility/Source/app/wifiapsettings/WifiApSettings.cpp b/Tactility/Source/app/wifiapsettings/WifiApSettings.cpp index eba75f7c..973566f0 100644 --- a/Tactility/Source/app/wifiapsettings/WifiApSettings.cpp +++ b/Tactility/Source/app/wifiapsettings/WifiApSettings.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,7 @@ class WifiApSettings : public App { std::string ssid; PubSub::SubscriptionHandle wifiSubscription = nullptr; - static void onPressForget(TT_UNUSED lv_event_t* event) { + static void onPressForget(lv_event_t* event) { std::vector choices = { "Yes", "No" @@ -61,7 +62,7 @@ class WifiApSettings : public App { static void onPressConnect(lv_event_t* event) { auto app = getCurrentAppContext(); auto parameters = app->getParameters(); - tt_check(parameters != nullptr, "Parameters missing"); + check(parameters != nullptr, "Parameters missing"); std::string ssid = parameters->getString("ssid"); service::wifi::settings::WifiApSettings settings; @@ -124,7 +125,7 @@ public: void onCreate(AppContext& app) override { const auto parameters = app.getParameters(); - tt_check(parameters != nullptr, "Parameters missing"); + check(parameters != nullptr, "Parameters missing"); ssid = parameters->getString("ssid"); } @@ -209,7 +210,7 @@ public: viewEnabled = false; } - void onResult(TT_UNUSED AppContext& appContext, TT_UNUSED LaunchId launchId, TT_UNUSED Result result, std::unique_ptr bundle) override { + void onResult(AppContext& appContext, LaunchId launchId, Result result, std::unique_ptr bundle) override { if (result != Result::Ok || bundle == nullptr) { return; } @@ -220,7 +221,7 @@ public: } auto parameters = appContext.getParameters(); - tt_check(parameters != nullptr, "Parameters missing"); + check(parameters != nullptr, "Parameters missing"); std::string ssid = parameters->getString("ssid"); if (!service::wifi::settings::remove(ssid.c_str())) { diff --git a/Tactility/Source/app/wificonnect/View.cpp b/Tactility/Source/app/wificonnect/View.cpp index 9f79dcb0..57819240 100644 --- a/Tactility/Source/app/wificonnect/View.cpp +++ b/Tactility/Source/app/wificonnect/View.cpp @@ -21,7 +21,7 @@ void View::resetErrors() { lv_obj_add_flag(connection_error, LV_OBJ_FLAG_HIDDEN); } -static void onConnect(TT_UNUSED lv_event_t* event) { +static void onConnect(lv_event_t* event) { auto wifi = std::static_pointer_cast(getCurrentApp()); auto& view = wifi->getView(); diff --git a/Tactility/Source/app/wificonnect/WifiConnect.cpp b/Tactility/Source/app/wificonnect/WifiConnect.cpp index 3bd24f7a..629c6668 100644 --- a/Tactility/Source/app/wificonnect/WifiConnect.cpp +++ b/Tactility/Source/app/wificonnect/WifiConnect.cpp @@ -15,7 +15,7 @@ constexpr auto* WIFI_CONNECT_PARAM_PASSWORD = "password"; // String extern const AppManifest manifest; -static void onConnect(const service::wifi::settings::WifiApSettings& ap_settings, bool remember, TT_UNUSED void* parameter) { +static void onConnect(const service::wifi::settings::WifiApSettings& ap_settings, bool remember, void* parameter) { auto* wifi = static_cast(parameter); wifi->getState().setApSettings(ap_settings); wifi->getState().setConnecting(true); @@ -88,7 +88,7 @@ void WifiConnect::onShow(AppContext& app, lv_obj_t* parent) { unlock(); } -void WifiConnect::onHide(TT_UNUSED AppContext& app) { +void WifiConnect::onHide(AppContext& app) { // No need to lock view, as this is called from within Gui's LVGL context lock(); viewEnabled = false; diff --git a/Tactility/Source/app/wifimanage/WifiManage.cpp b/Tactility/Source/app/wifimanage/WifiManage.cpp index ab8a4241..9b035afc 100644 --- a/Tactility/Source/app/wifimanage/WifiManage.cpp +++ b/Tactility/Source/app/wifimanage/WifiManage.cpp @@ -131,7 +131,7 @@ void WifiManage::onShow(AppContext& app, lv_obj_t* parent) { } } -void WifiManage::onHide(TT_UNUSED AppContext& app) { +void WifiManage::onHide(AppContext& app) { lock(); service::wifi::getPubsub()->unsubscribe(wifiSubscription); wifiSubscription = nullptr; diff --git a/Tactility/Source/hal/Hal.cpp b/Tactility/Source/hal/Hal.cpp index 88d8e8b1..9c58cae1 100644 --- a/Tactility/Source/hal/Hal.cpp +++ b/Tactility/Source/hal/Hal.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -68,20 +69,19 @@ void init(const Configuration& configuration) { kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalBegin); kernel::publishSystemEvent(kernel::SystemEvent::BootInitI2cBegin); - tt_check(i2c::init(configuration.i2c), "I2C init failed"); + check(i2c::init(configuration.i2c), "I2C init failed"); kernel::publishSystemEvent(kernel::SystemEvent::BootInitI2cEnd); kernel::publishSystemEvent(kernel::SystemEvent::BootInitSpiBegin); - tt_check(spi::init(configuration.spi), "SPI init failed"); + check(spi::init(configuration.spi), "SPI init failed"); kernel::publishSystemEvent(kernel::SystemEvent::BootInitSpiEnd); kernel::publishSystemEvent(kernel::SystemEvent::BootInitUartBegin); - tt_check(uart::init(configuration.uart), "UART init failed"); + check(uart::init(configuration.uart), "UART init failed"); kernel::publishSystemEvent(kernel::SystemEvent::BootInitUartEnd); if (configuration.initBoot != nullptr) { - LOGGER.info("Init boot"); - tt_check(configuration.initBoot(), "Init boot failed"); + check(configuration.initBoot(), "Init boot failed"); } registerDevices(configuration); diff --git a/Tactility/Source/hal/gps/GpsInit.cpp b/Tactility/Source/hal/gps/GpsInit.cpp index 1a7c7a4a..c20eb6bb 100644 --- a/Tactility/Source/hal/gps/GpsInit.cpp +++ b/Tactility/Source/hal/gps/GpsInit.cpp @@ -139,7 +139,7 @@ GpsResponse getACKCas(uart::Uart& uart, uint8_t class_id, uint8_t msg_id, uint32 bool init(uart::Uart& uart, GpsModel type) { switch (type) { case GpsModel::Unknown: - tt_crash(); + check(false); case GpsModel::AG3335: case GpsModel::AG3352: return initAg33xx(uart); diff --git a/Tactility/Source/hal/i2c/I2c.cpp b/Tactility/Source/hal/i2c/I2c.cpp index defa39ac..d01457dd 100644 --- a/Tactility/Source/hal/i2c/I2c.cpp +++ b/Tactility/Source/hal/i2c/I2c.cpp @@ -202,7 +202,7 @@ bool masterWrite(i2c_port_t port, uint8_t address, const uint8_t* data, uint16_t } bool masterWriteRegister(i2c_port_t port, uint8_t address, uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout) { - tt_check(reg != 0); + check(reg != 0); auto lock = getLock(port).asScopedLock(); if (!lock.lock(timeout)) { diff --git a/Tactility/Source/kernel/SystemEvents.cpp b/Tactility/Source/kernel/SystemEvents.cpp index 58839bdd..89df4816 100644 --- a/Tactility/Source/kernel/SystemEvents.cpp +++ b/Tactility/Source/kernel/SystemEvents.cpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace tt::kernel { @@ -53,7 +54,7 @@ static const char* getEventName(SystemEvent event) { return TT_STRINGIFY(Time); } - tt_crash(); // Missing case above + check(false); // Missing case above } void publishSystemEvent(SystemEvent event) { @@ -83,7 +84,7 @@ SystemEventSubscription subscribeSystemEvent(SystemEvent event, OnSystemEvent ha mutex.unlock(); return id; } else { - tt_crash(); + check(false); } } diff --git a/Tactility/Source/lvgl/Spinner.cpp b/Tactility/Source/lvgl/Spinner.cpp index 205eb162..164de705 100644 --- a/Tactility/Source/lvgl/Spinner.cpp +++ b/Tactility/Source/lvgl/Spinner.cpp @@ -42,7 +42,7 @@ static void anim_rotation_callback(void* var, int32_t v) { lv_obj_set_style_transform_rotation(object, v, 0); } -static void spinner_constructor(TT_UNUSED const lv_obj_class_t* object_class, lv_obj_t* object) { +static void spinner_constructor(const lv_obj_class_t* object_class, lv_obj_t* object) { lv_obj_remove_flag(object, LV_OBJ_FLAG_CLICKABLE); lv_anim_t a; diff --git a/Tactility/Source/lvgl/Statusbar.cpp b/Tactility/Source/lvgl/Statusbar.cpp index 649fefab..90cc80bf 100644 --- a/Tactility/Source/lvgl/Statusbar.cpp +++ b/Tactility/Source/lvgl/Statusbar.cpp @@ -1,5 +1,6 @@ #define LV_USE_PRIVATE_API 1 // For actual lv_obj_t declaration +#include #include #include #include @@ -10,7 +11,6 @@ #include #include #include -#include #include #include @@ -116,7 +116,7 @@ static void statusbar_pubsub_event(Statusbar* statusbar) { } } -static void onTimeChanged(TT_UNUSED kernel::SystemEvent event) { +static void onTimeChanged(kernel::SystemEvent event) { if (statusbar_data.mutex.lock()) { statusbar_data.time_update_timer->reset(5); statusbar_data.mutex.unlock(); @@ -142,7 +142,7 @@ static void statusbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) } } -static void statusbar_destructor(TT_UNUSED const lv_obj_class_t* class_p, lv_obj_t* obj) { +static void statusbar_destructor(const lv_obj_class_t* class_p, lv_obj_t* obj) { auto* statusbar = (Statusbar*)obj; statusbar_data.pubsub->unsubscribe(statusbar->pubsub_subscription); } @@ -215,7 +215,7 @@ static void update_main(Statusbar* statusbar) { } } -static void statusbar_event(TT_UNUSED const lv_obj_class_t* class_p, lv_event_t* event) { +static void statusbar_event(const lv_obj_class_t* class_p, lv_event_t* event) { // Call the ancestor's event handler lv_result_t result = lv_obj_event_base(&statusbar_class, event); if (result != LV_RES_OK) { @@ -258,7 +258,7 @@ void statusbar_icon_remove(int8_t id) { if (LOGGER.isLoggingDebug()) { LOGGER.debug("id {}: remove", id); } - tt_check(id >= 0 && id < STATUSBAR_ICON_LIMIT); + check(id >= 0 && id < STATUSBAR_ICON_LIMIT); statusbar_data.mutex.lock(); StatusbarIcon* icon = &statusbar_data.icons[id]; icon->claimed = false; @@ -276,10 +276,10 @@ void statusbar_icon_set_image(int8_t id, const std::string& image) { LOGGER.debug("id {}: set image {}", id, image); } } - tt_check(id >= 0 && id < STATUSBAR_ICON_LIMIT); + check(id >= 0 && id < STATUSBAR_ICON_LIMIT); statusbar_data.mutex.lock(); StatusbarIcon* icon = &statusbar_data.icons[id]; - tt_check(icon->claimed); + check(icon->claimed); icon->image = image; statusbar_data.mutex.unlock(); statusbar_data.pubsub->publish(nullptr); @@ -289,10 +289,10 @@ void statusbar_icon_set_visibility(int8_t id, bool visible) { if (LOGGER.isLoggingDebug()) { LOGGER.debug("id {}: set visibility {}", id, visible); } - tt_check(id >= 0 && id < STATUSBAR_ICON_LIMIT); + check(id >= 0 && id < STATUSBAR_ICON_LIMIT); statusbar_data.mutex.lock(); StatusbarIcon* icon = &statusbar_data.icons[id]; - tt_check(icon->claimed); + check(icon->claimed); icon->visible = visible; statusbar_data.mutex.unlock(); statusbar_data.pubsub->publish(nullptr); diff --git a/Tactility/Source/lvgl/Toolbar.cpp b/Tactility/Source/lvgl/Toolbar.cpp index fdc9c321..4c1a2f97 100644 --- a/Tactility/Source/lvgl/Toolbar.cpp +++ b/Tactility/Source/lvgl/Toolbar.cpp @@ -2,6 +2,7 @@ #include +#include #include #include @@ -63,7 +64,7 @@ static const lv_obj_class_t toolbar_class = { .theme_inheritable = false }; -static void stop_app(TT_UNUSED lv_event_t* event) { +static void stop_app(lv_event_t* event) { app::stop(); } @@ -166,7 +167,7 @@ void toolbar_set_nav_action(lv_obj_t* obj, const char* icon, lv_event_cb_t callb lv_obj_t* toolbar_add_button_action(lv_obj_t* obj, const char* imageOrButton, bool isImage, lv_event_cb_t callback, void* user_data) { auto* toolbar = reinterpret_cast(obj); - tt_check(toolbar->action_count < TOOLBAR_ACTION_LIMIT, "max actions reached"); + check(toolbar->action_count < TOOLBAR_ACTION_LIMIT, "max actions reached"); toolbar->action_count++; auto ui_scale = hal::getConfiguration()->uiScale; diff --git a/Tactility/Source/network/Http.cpp b/Tactility/Source/network/Http.cpp index 59dba22e..84b65dae 100644 --- a/Tactility/Source/network/Http.cpp +++ b/Tactility/Source/network/Http.cpp @@ -3,6 +3,8 @@ #include #include +#include "Tactility/service/gui/GuiService.h" + #ifdef ESP_PLATFORM #include #include @@ -19,7 +21,8 @@ void download( const std::function& onSuccess, const std::function& onError ) { - LOGGER.info("Downloading {} to {}", url, downloadFilePath); + service::gui::warnIfRunningOnGuiTask("HTTP"); + LOGGER.info("Downloading from {} to {}", url, downloadFilePath); #ifdef ESP_PLATFORM getMainDispatcher().dispatch([url, certFilePath, downloadFilePath, onSuccess, onError] { LOGGER.info("Loading certificate"); @@ -90,6 +93,7 @@ void download( onError("Failed to write all bytes"); return; } + taskYIELD(); } fclose(file); LOGGER.info("Downloaded {} to {}", url, downloadFilePath); diff --git a/Tactility/Source/service/displayidle/DisplayIdle.cpp b/Tactility/Source/service/displayidle/DisplayIdle.cpp index 06424c6e..e577b257 100644 --- a/Tactility/Source/service/displayidle/DisplayIdle.cpp +++ b/Tactility/Source/service/displayidle/DisplayIdle.cpp @@ -59,7 +59,7 @@ class DisplayIdleService final : public Service { } public: - bool onStart(TT_UNUSED ServiceContext& service) override { + bool onStart(ServiceContext& service) override { // Load settings once at startup and cache them // This eliminates file I/O from timer callback (prevents watchdog timeout) cachedDisplaySettings = settings::display::loadOrGetDefault(); @@ -73,7 +73,7 @@ public: return true; } - void onStop(TT_UNUSED ServiceContext& service) override { + void onStop(ServiceContext& service) override { if (timer) { timer->stop(); timer = nullptr; diff --git a/Tactility/Source/service/gui/GuiService.cpp b/Tactility/Source/service/gui/GuiService.cpp index 525c007e..c24adc29 100644 --- a/Tactility/Source/service/gui/GuiService.cpp +++ b/Tactility/Source/service/gui/GuiService.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include #include @@ -15,6 +17,15 @@ extern const ServiceManifest manifest; static const auto LOGGER = Logger("GuiService"); using namespace loader; +constexpr auto* GUI_TASK_NAME = "gui"; + +void warnIfRunningOnGuiTask(const char* context) { + const char* task_name = pcTaskGetName(nullptr); + if (strcmp(GUI_TASK_NAME, task_name) == 0) { + LOGGER.warn("{} shouldn't run on the GUI task", context); + } +} + // region AppManifest void GuiService::onLoaderEvent(LoaderService::Event event) { @@ -114,7 +125,7 @@ void GuiService::redraw() { unlock(); } -bool GuiService::onStart(TT_UNUSED ServiceContext& service) { +bool GuiService::onStart(ServiceContext& service) { auto* screen_root = lv_screen_active(); if (screen_root == nullptr) { LOGGER.error("No display found"); @@ -122,11 +133,13 @@ bool GuiService::onStart(TT_UNUSED ServiceContext& service) { } thread = new Thread( - "gui", + GUI_TASK_NAME, 4096, // Last known minimum was 2800 for launching desktop []() { return guiMain(); } ); + thread->setPriority(THREAD_PRIORITY_SERVICE); + const auto loader = findLoaderService(); assert(loader != nullptr); loader_pubsub_subscription = loader->getPubsub()->subscribe([this](auto event) { @@ -169,7 +182,7 @@ bool GuiService::onStart(TT_UNUSED ServiceContext& service) { return true; } -void GuiService::onStop(TT_UNUSED ServiceContext& service) { +void GuiService::onStop(ServiceContext& service) { lock(); const auto loader = findLoaderService(); @@ -186,7 +199,7 @@ void GuiService::onStop(TT_UNUSED ServiceContext& service) { unlock(); - tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS)); + check(lvgl::lock(1000 / portTICK_PERIOD_MS)); lv_group_delete(keyboardGroup); lvgl::unlock(); } diff --git a/Tactility/Source/service/gui/Keyboard.cpp b/Tactility/Source/service/gui/Keyboard.cpp index 727049d3..99d775b8 100644 --- a/Tactility/Source/service/gui/Keyboard.cpp +++ b/Tactility/Source/service/gui/Keyboard.cpp @@ -17,7 +17,7 @@ static void show_keyboard(lv_event_t* event) { } } -static void hide_keyboard(TT_UNUSED lv_event_t* event) { +static void hide_keyboard(lv_event_t* event) { auto service = findService(); if (service != nullptr) { service->softwareKeyboardHide(); @@ -53,7 +53,7 @@ void GuiService::keyboardAddTextArea(lv_obj_t* textarea) { lock(); if (isStarted) { - tt_check(lvgl::lock(0), "lvgl should already be locked before calling this method"); + check(lvgl::lock(0), "lvgl should already be locked before calling this method"); if (softwareKeyboardIsEnabled()) { lv_obj_add_event_cb(textarea, show_keyboard, LV_EVENT_FOCUSED, nullptr); diff --git a/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp b/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp index feab24f8..62c5ea1d 100644 --- a/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp +++ b/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp @@ -58,7 +58,7 @@ class KeyboardIdleService final : public Service { } public: - bool onStart(TT_UNUSED ServiceContext& service) override { + bool onStart(ServiceContext& service) override { // Load settings once at startup and cache them // This eliminates file I/O from timer callback (prevents watchdog timeout) cachedKeyboardSettings = settings::keyboard::loadOrGetDefault(); @@ -72,7 +72,7 @@ public: return true; } - void onStop(TT_UNUSED ServiceContext& service) override { + void onStop(ServiceContext& service) override { if (timer) { timer->stop(); timer = nullptr; diff --git a/Tactility/Source/service/loader/Loader.cpp b/Tactility/Source/service/loader/Loader.cpp index dc4cccc4..da2c43a2 100644 --- a/Tactility/Source/service/loader/Loader.cpp +++ b/Tactility/Source/service/loader/Loader.cpp @@ -245,7 +245,7 @@ void LoaderService::transitionAppToState(const std::shared_ptr switch (state) { using enum app::State; case Initial: - tt_crash(LOG_MESSAGE_ILLEGAL_STATE); + check(false, LOG_MESSAGE_ILLEGAL_STATE); case Created: assert(app->getState() == app::State::Initial); app->getApp()->onCreate(*app); diff --git a/Tactility/Source/service/screenshot/ScreenshotTask.cpp b/Tactility/Source/service/screenshot/ScreenshotTask.cpp index 00511628..0f9cbdbc 100644 --- a/Tactility/Source/service/screenshot/ScreenshotTask.cpp +++ b/Tactility/Source/service/screenshot/ScreenshotTask.cpp @@ -107,7 +107,7 @@ void ScreenshotTask::taskStart() { return; } - tt_check(thread == nullptr); + check(thread == nullptr); thread = new Thread( "screenshot", 8192, diff --git a/Tactility/Source/service/statusbar/Statusbar.cpp b/Tactility/Source/service/statusbar/Statusbar.cpp index 636d33a9..6f2c2aa7 100644 --- a/Tactility/Source/service/statusbar/Statusbar.cpp +++ b/Tactility/Source/service/statusbar/Statusbar.cpp @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -71,7 +72,7 @@ static const char* getWifiStatusIcon(wifi::RadioState state, bool secure) { rssi = wifi::getRssi(); return getWifiStatusIconForRssi(rssi); default: - tt_crash("not implemented"); + check(false, "not implemented"); } } @@ -85,7 +86,7 @@ static const char* getSdCardStatusIcon(hal::sdcard::SdCardDevice::State state) { case Timeout: return STATUSBAR_ICON_SDCARD_ALERT; default: - tt_crash("Unhandled SdCard state"); + check(false, "Unhandled SdCard state"); } } diff --git a/Tactility/Source/service/webserver/WebServerService.cpp b/Tactility/Source/service/webserver/WebServerService.cpp index a8689059..e95ea03d 100644 --- a/Tactility/Source/service/webserver/WebServerService.cpp +++ b/Tactility/Source/service/webserver/WebServerService.cpp @@ -1,5 +1,6 @@ #ifdef ESP_PLATFORM +#include #include #include #include @@ -93,7 +94,7 @@ static void publish_event(WebServerService* webserver, WebServerEvent event) { std::shared_ptr> getPubsub() { WebServerService* webserver = g_webServerInstance.load(); if (webserver == nullptr) { - tt_crash("Service not running"); + check(false, "Service not running"); } return webserver->getPubsub(); diff --git a/Tactility/Source/service/wifi/Wifi.cpp b/Tactility/Source/service/wifi/Wifi.cpp index 2650cf35..01fdde02 100644 --- a/Tactility/Source/service/wifi/Wifi.cpp +++ b/Tactility/Source/service/wifi/Wifi.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -22,7 +23,7 @@ const char* radioStateToString(RadioState state) { case Off: return TT_STRINGIFY(Off); } - tt_crash("not implemented"); + check(false, "not implemented"); } extern const ServiceManifest manifest; diff --git a/Tactility/Source/service/wifi/WifiEsp.cpp b/Tactility/Source/service/wifi/WifiEsp.cpp index 211bdb72..4c58f7cf 100644 --- a/Tactility/Source/service/wifi/WifiEsp.cpp +++ b/Tactility/Source/service/wifi/WifiEsp.cpp @@ -6,6 +6,7 @@ #include +#include #include #include #include @@ -140,7 +141,7 @@ static std::shared_ptr wifi_singleton; std::shared_ptr> getPubsub() { auto wifi = wifi_singleton; if (wifi == nullptr) { - tt_crash("Service not running"); + check(false, "Service not running"); } return wifi->pubsub; @@ -472,7 +473,7 @@ static void dispatchAutoConnect(std::shared_ptr wifi) { } } -static void eventHandler(TT_UNUSED void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { +static void eventHandler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { auto wifi = wifi_singleton; if (wifi == nullptr) { LOGGER.error("eventHandler: no wifi instance"); diff --git a/Tactility/Source/service/wifi/WifiMock.cpp b/Tactility/Source/service/wifi/WifiMock.cpp index ae8573b8..d316c514 100644 --- a/Tactility/Source/service/wifi/WifiMock.cpp +++ b/Tactility/Source/service/wifi/WifiMock.cpp @@ -76,7 +76,7 @@ void setScanRecords(uint16_t records) { } std::vector getScanResults() { - tt_check(wifi); + check(wifi); std::vector records; records.push_back((ApRecord) { @@ -145,14 +145,14 @@ class WifiService final : public Service { public: - bool onStart(TT_UNUSED ServiceContext& service) override { - tt_check(wifi == nullptr); + bool onStart(ServiceContext& service) override { + check(wifi == nullptr); wifi = new Wifi(); return true; } - void onStop(TT_UNUSED ServiceContext& service) override { - tt_check(wifi != nullptr); + void onStop(ServiceContext& service) override { + check(wifi != nullptr); delete wifi; wifi = nullptr; } diff --git a/TactilityC/Source/tt_app.cpp b/TactilityC/Source/tt_app.cpp index 4e9df28f..e87ec87b 100644 --- a/TactilityC/Source/tt_app.cpp +++ b/TactilityC/Source/tt_app.cpp @@ -28,7 +28,7 @@ void tt_app_register( reinterpret_cast(appRegistration.onResult) ); #else - tt_crash("TactilityC is not intended for PC/Simulator"); + check(false, "TactilityC is not intended for PC/Simulator"); #endif } diff --git a/TactilityC/Source/tt_hal_device.cpp b/TactilityC/Source/tt_hal_device.cpp index dbd91730..0393b13a 100644 --- a/TactilityC/Source/tt_hal_device.cpp +++ b/TactilityC/Source/tt_hal_device.cpp @@ -21,7 +21,7 @@ static tt::hal::Device::Type toTactilityDeviceType(DeviceType type) { case DEVICE_TYPE_GPS: return tt::hal::Device::Type::Gps; default: - tt_crash("Device::Type not supported"); + check(false, "Device::Type not supported"); } } diff --git a/TactilityC/Source/tt_hal_display.cpp b/TactilityC/Source/tt_hal_display.cpp index 5d5a7778..eb35e237 100644 --- a/TactilityC/Source/tt_hal_display.cpp +++ b/TactilityC/Source/tt_hal_display.cpp @@ -20,7 +20,7 @@ static ColorFormat toColorFormat(tt::hal::display::ColorFormat format) { case tt::hal::display::ColorFormat::RGB888: return COLOR_FORMAT_RGB888; default: - tt_crash("ColorFormat not supported"); + check(false, "ColorFormat not supported"); } } diff --git a/TactilityCore/CMakeLists.txt b/TactilityCore/CMakeLists.txt index b1c8891f..1824f94d 100644 --- a/TactilityCore/CMakeLists.txt +++ b/TactilityCore/CMakeLists.txt @@ -6,7 +6,7 @@ if (DEFINED ENV{ESP_IDF_VERSION}) idf_component_register( SRCS ${SOURCE_FILES} INCLUDE_DIRS "Include/" - REQUIRES TactilityFreeRtos mbedtls nvs_flash esp_rom + REQUIRES TactilityFreeRtos TactilityKernel mbedtls nvs_flash esp_rom ) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") @@ -26,8 +26,9 @@ else() add_definitions(-D_Nullable=) add_definitions(-D_Nonnull=) - target_link_libraries(TactilityCore - PUBLIC TactilityFreeRtos - PUBLIC mbedtls + target_link_libraries(TactilityCore PUBLIC + TactilityFreeRtos + TactilityKernel + mbedtls ) endif() \ No newline at end of file diff --git a/TactilityCore/Include/Tactility/Check.h b/TactilityCore/Include/Tactility/Check.h deleted file mode 100644 index c0f93c94..00000000 --- a/TactilityCore/Include/Tactility/Check.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file check.h - * - * Tactility crash and check functions. - * - * The main problem with crashing is that you can't do anything without disturbing registers, - * and if you disturb registers, you won't be able to see the correct register values in the debugger. - * - * Current solution works around it by passing the message through r12 and doing some magic with registers in crash function. - * r0-r10 are stored in the ram2 on crash routine start and restored at the end. - * The only register that is going to be lost is r11. - * - */ -#pragma once - -#include "CoreDefines.h" -#include "Logger.h" - -#include - -#define TT_NORETURN [[noreturn]] - -/** Crash system */ -namespace tt { - /** - * Don't call this directly. Use tt_crash() as it will trace info. - */ - TT_NORETURN void _crash(); -} - -// TODO: Move crash logic to kernel namespace and consider refactoring to C++ -/** Crash system with message. */ -#define tt_crash(...) TT_ARG_CAT(_tt_crash,TT_ARGCOUNT(__VA_ARGS__))(__VA_ARGS__) - -#define _tt_crash0() do { \ - tt::Logger("Kernel").error("Crash at {}:{}", __FILE__, __LINE__); \ - tt::_crash(); \ - } while (0) - -#define _tt_crash1(message) do { \ - tt::Logger("Kernel").error("Crash: {}\n\tat {}:{}", message, __FILE__, __LINE__); \ - tt::_crash(); \ - } while (0) - -/** Halt the system - * @param[in] optional message (const char*) - */ -#define tt_halt(...) M_APPLY(__tt_halt, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__))) - -/** Check condition and crash if check failed */ -#define tt_check_internal(__e, __m) \ - do { \ - if (!(__e)) { \ - tt::Logger("Kernel").error("Check failed: {}", #__e); \ - if (__m) { \ - tt_crash(__m); \ - } else { \ - tt_crash(""); \ - } \ - } \ - } while (0) - -/** Check condition and crash if failed - * - * @param[in] condition to check - * @param[in] optional message (const char*) - */ - -#define tt_check(x, ...) if (!(x)) { tt::Logger("Kernel").error("Check failed: {}", #x); tt::_crash(); } diff --git a/TactilityCore/Include/Tactility/CoreDefines.h b/TactilityCore/Include/Tactility/CoreDefines.h index eb742716..db12a602 100644 --- a/TactilityCore/Include/Tactility/CoreDefines.h +++ b/TactilityCore/Include/Tactility/CoreDefines.h @@ -1,7 +1,5 @@ #pragma once -#define TT_UNUSED __attribute__((unused)) - #define TT_STRINGIFY(x) #x // region Variable arguments support diff --git a/TactilityCore/Include/Tactility/TactilityCore.h b/TactilityCore/Include/Tactility/TactilityCore.h index 88ccddf9..25c46467 100644 --- a/TactilityCore/Include/Tactility/TactilityCore.h +++ b/TactilityCore/Include/Tactility/TactilityCore.h @@ -2,6 +2,5 @@ #include -#include "Check.h" #include "CoreDefines.h" #include "Logger.h" diff --git a/TactilityCore/Source/Check.cpp b/TactilityCore/Source/Check.cpp deleted file mode 100644 index 07a57e7a..00000000 --- a/TactilityCore/Source/Check.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include - -#include -#include - -static const auto LOGGER = tt::Logger("kernel"); - -static void logMemoryInfo() { -#ifdef ESP_PLATFORM - LOGGER.error("default caps:"); - LOGGER.error(" total: {}", heap_caps_get_total_size(MALLOC_CAP_DEFAULT)); - LOGGER.error(" free: {}", heap_caps_get_free_size(MALLOC_CAP_DEFAULT)); - LOGGER.error(" min free: {}", heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT)); - LOGGER.error("internal caps:"); - LOGGER.error(" total: {}", heap_caps_get_total_size(MALLOC_CAP_INTERNAL)); - LOGGER.error(" free: {}", heap_caps_get_free_size(MALLOC_CAP_INTERNAL)); - LOGGER.error(" min free: {}", heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL)); -#endif -} - -static void logTaskInfo() { - const char* name = pcTaskGetName(nullptr); - const char* safe_name = name ? name : "main"; - LOGGER.error("Task: {}", safe_name); - LOGGER.error("Stack watermark: {}", uxTaskGetStackHighWaterMark(NULL) * 4); -} - -namespace tt { - -TT_NORETURN void _crash() { - logTaskInfo(); - logMemoryInfo(); - // TODO: Add breakpoint when debugger is attached. -#ifdef ESP_PLATFORM - esp_system_abort("System halted. Connect debugger for more info."); -#endif - __builtin_unreachable(); -} - -} diff --git a/TactilityCore/Source/crypt/Crypt.cpp b/TactilityCore/Source/crypt/Crypt.cpp index 2b306764..9d5a1b54 100644 --- a/TactilityCore/Source/crypt/Crypt.cpp +++ b/TactilityCore/Source/crypt/Crypt.cpp @@ -29,7 +29,7 @@ static void get_hardware_key(uint8_t key[32]) { // MAC can be 6 or 8 bytes size_t mac_length = esp_mac_addr_len_get(ESP_MAC_EFUSE_FACTORY); LOGGER.info("Using MAC with length {}", mac_length); - tt_check(mac_length <= 8); + check(mac_length <= 8); ESP_ERROR_CHECK(esp_read_mac(mac, ESP_MAC_EFUSE_FACTORY)); // Fill buffer with repeating MAC @@ -68,13 +68,13 @@ static void get_nvs_key(uint8_t key[32]) { if (result != ESP_OK) { LOGGER.error("Failed to get key from NVS ({})", esp_err_to_name(result)); - tt_crash("NVS error"); + check(false, "NVS error"); } size_t length = 32; if (nvs_get_blob(handle, "key", key, &length) == ESP_OK) { LOGGER.info("Fetched key from NVS ({} bytes)", length); - tt_check(length == 32); + check(length == 32); } else { // TODO: Improved randomness esp_cpu_cycle_count_t cycle_count = esp_cpu_get_cycle_count(); @@ -144,7 +144,7 @@ static int aes256CryptCbc( const unsigned char* input, unsigned char* output ) { - tt_check(key && iv && input && output); + check(key && iv && input && output); if ((length % 16) || (length == 0)) { return -1; // TODO: Proper error code from mbed lib? @@ -163,7 +163,7 @@ static int aes256CryptCbc( } int encrypt(const uint8_t iv[16], const uint8_t* inData, uint8_t* outData, size_t dataLength) { - tt_check(dataLength % 16 == 0, "Length is not a multiple of 16 bytes (for AES 256"); + check(dataLength % 16 == 0, "Length is not a multiple of 16 bytes (for AES 256)"); uint8_t key[32]; getKey(key); @@ -175,7 +175,7 @@ int encrypt(const uint8_t iv[16], const uint8_t* inData, uint8_t* outData, size_ } int decrypt(const uint8_t iv[16], const uint8_t* inData, uint8_t* outData, size_t dataLength) { - tt_check(dataLength % 16 == 0, "Length is not a multiple of 16 bytes (for AES 256"); + check(dataLength % 16 == 0, "Length is not a multiple of 16 bytes (for AES 256)"); uint8_t key[32]; getKey(key); diff --git a/TactilityKernel/Include/Tactility/Check.h b/TactilityKernel/Include/Tactility/Check.h new file mode 100644 index 00000000..a3f7c9da --- /dev/null +++ b/TactilityKernel/Include/Tactility/Check.h @@ -0,0 +1,32 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +__attribute__((noreturn)) extern void __crash(void); + +#define CHECK_GET_MACRO(_1, _2, NAME, ...) NAME +#define check(...) CHECK_GET_MACRO(__VA_ARGS__, CHECK_MSG, CHECK_NO_MSG)(__VA_ARGS__) + +#define CHECK_NO_MSG(condition) \ + do { \ + if (!(condition)) { \ + LOG_E("Error", "Check failed: %s at %s:%d", #condition, __FILE__, __LINE__); \ + __crash(); \ + } \ + } while (0) + +#define CHECK_MSG(condition, message) \ + do { \ + if (!(condition)) { \ + LOG_E("Error", "Check failed: %s at %s:%d", message, __FILE__, __LINE__); \ + __crash(); \ + } \ + } while (0) + +#ifdef __cplusplus +} +#endif diff --git a/TactilityKernel/Include/Tactility/Delay.h b/TactilityKernel/Include/Tactility/Delay.h new file mode 100644 index 00000000..516f0d4e --- /dev/null +++ b/TactilityKernel/Include/Tactility/Delay.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Time.h" +#include + +#ifdef ESP_PLATFORM +#include +#else +#include +#endif + +#include +#include "Tactility/FreeRTOS/FreeRTOS.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Delay the current task for the specified amount of ticks + * @warning Does not work in ISR context + */ +static inline void delay_ticks(TickType_t ticks) { + check(xPortInIsrContext() == pdFALSE); + if (ticks == 0U) { + taskYIELD(); + } else { + vTaskDelay(ticks); + } +} + +/** + * Delay the current task for the specified amount of milliseconds + * @warning Does not work in ISR context + */ +static inline void delay_millis(uint32_t milliSeconds) { + delay_ticks(millis_to_ticks(milliSeconds)); +} + +/** + * Stall the currently active CPU core for the specified amount of microseconds. + * This does not allow other tasks to run on the stalled CPU core. + */ +static inline void delay_micros(uint32_t microseconds) { +#ifdef ESP_PLATFORM + ets_delay_us(microseconds); +#else + usleep(microseconds); +#endif +} + +#ifdef __cplusplus +} +#endif diff --git a/TactilityKernel/Include/Tactility/FreeRTOS/port.h b/TactilityKernel/Include/Tactility/FreeRTOS/port.h index f78a0793..8ef15699 100644 --- a/TactilityKernel/Include/Tactility/FreeRTOS/port.h +++ b/TactilityKernel/Include/Tactility/FreeRTOS/port.h @@ -5,6 +5,6 @@ #include "FreeRTOS.h" #ifndef ESP_PLATFORM -#define xPortInIsrContext(x) (false) +#define xPortInIsrContext() (pdFALSE) #define vPortAssertIfInISR() #endif diff --git a/TactilityKernel/Include/Tactility/Time.h b/TactilityKernel/Include/Tactility/Time.h new file mode 100644 index 00000000..17dcbbcf --- /dev/null +++ b/TactilityKernel/Include/Tactility/Time.h @@ -0,0 +1,65 @@ +#pragma once + +#include + +#include "Tactility/FreeRTOS/task.h" + +#ifdef ESP_PLATFORM +#include +#else +#include +#include +#endif + +// Projects that include this header must align with Tactility's frequency (e.g. apps) +static_assert(configTICK_RATE_HZ == 1000); + +static inline uint32_t get_tick_frequency() { + return configTICK_RATE_HZ; +} + +/** @return the amount of ticks that have passed since FreeRTOS' main task started */ +static inline TickType_t get_ticks() { + if (xPortInIsrContext() == pdTRUE) { + return xTaskGetTickCountFromISR(); + } else { + return xTaskGetTickCount(); + } +} + +/** @return the milliseconds that have passed since FreeRTOS' main task started */ +static inline size_t get_millis() { + return get_ticks() * portTICK_PERIOD_MS; +} + +/** @return the frequency at which the kernel task schedulers operate */ +uint32_t kernel_get_tick_frequency(); + +/** @return the microseconds that have passed since boot */ +static inline int64_t get_micros_since_boot() { +#ifdef ESP_PLATFORM + return esp_timer_get_time(); +#else + timespec ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { + return (static_cast(ts.tv_sec) * 1000000LL) + (ts.tv_nsec / 1000); + } + timeval tv; + gettimeofday(&tv, nullptr); + return (static_cast(tv.tv_sec) * 1000000LL) + tv.tv_usec; +#endif +} + +/** Convert seconds to ticks */ +static inline TickType_t seconds_to_ticks(uint32_t seconds) { + return static_cast(seconds) * 1000U / portTICK_PERIOD_MS; +} + +/** Convert milliseconds to ticks */ +static inline TickType_t millis_to_ticks(uint32_t milliSeconds) { +#if configTICK_RATE_HZ == 1000 + return static_cast(milliSeconds); +#else + return static_cast(((float)configTICK_RATE_HZ) / 1000.0f * (float)milliSeconds); +#endif +} diff --git a/TactilityKernel/Include/Tactility/concurrent/EventGroup.h b/TactilityKernel/Include/Tactility/concurrent/EventGroup.h index c5cd124f..bb99b355 100644 --- a/TactilityKernel/Include/Tactility/concurrent/EventGroup.h +++ b/TactilityKernel/Include/Tactility/concurrent/EventGroup.h @@ -5,21 +5,21 @@ extern "C" { #endif -#include #include #include +#include #include #include static inline void event_group_construct(EventGroupHandle_t* eventGroup) { - assert(xPortInIsrContext() == pdFALSE); + check(xPortInIsrContext() == pdFALSE); *eventGroup = xEventGroupCreate(); } static inline void event_group_destruct(EventGroupHandle_t* eventGroup) { - assert(xPortInIsrContext() == pdFALSE); - assert(*eventGroup != NULL); + check(xPortInIsrContext() == pdFALSE); + check(*eventGroup != NULL); vEventGroupDelete(*eventGroup); *eventGroup = NULL; } diff --git a/TactilityKernel/Include/Tactility/concurrent/Mutex.h b/TactilityKernel/Include/Tactility/concurrent/Mutex.h index eddc4e69..600b9558 100644 --- a/TactilityKernel/Include/Tactility/concurrent/Mutex.h +++ b/TactilityKernel/Include/Tactility/concurrent/Mutex.h @@ -4,6 +4,8 @@ #include #include + +#include #include #ifdef __cplusplus @@ -28,17 +30,17 @@ inline static void mutex_destruct(struct Mutex* mutex) { } inline static void mutex_lock(struct Mutex* mutex) { - assert(xPortInIsrContext() != pdTRUE); + check(xPortInIsrContext() != pdTRUE); xSemaphoreTake(mutex->handle, portMAX_DELAY); } inline static bool mutex_try_lock(struct Mutex* mutex) { - assert(xPortInIsrContext() != pdTRUE); + check(xPortInIsrContext() != pdTRUE); return xSemaphoreTake(mutex->handle, 0) == pdTRUE; } inline static bool mutex_try_lock_timed(struct Mutex* mutex, TickType_t timeout) { - assert(xPortInIsrContext() != pdTRUE); + check(xPortInIsrContext() != pdTRUE); return xSemaphoreTake(mutex->handle, timeout) == pdTRUE; } @@ -51,7 +53,7 @@ inline static bool mutex_is_locked(struct Mutex* mutex) { } inline static void mutex_unlock(struct Mutex* mutex) { - assert(xPortInIsrContext() != pdTRUE); + check(xPortInIsrContext() != pdTRUE); xSemaphoreGive(mutex->handle); } diff --git a/TactilityKernel/Include/Tactility/concurrent/RecursiveMutex.h b/TactilityKernel/Include/Tactility/concurrent/RecursiveMutex.h index b2e451c4..35725550 100644 --- a/TactilityKernel/Include/Tactility/concurrent/RecursiveMutex.h +++ b/TactilityKernel/Include/Tactility/concurrent/RecursiveMutex.h @@ -3,7 +3,7 @@ #pragma once #include -#include +#include #include #ifdef __cplusplus @@ -19,14 +19,14 @@ inline static void recursive_mutex_construct(struct RecursiveMutex* mutex) { } inline static void recursive_mutex_destruct(struct RecursiveMutex* mutex) { - assert(mutex->handle != NULL); - vPortAssertIfInISR(); + check(mutex->handle != NULL); + check(xPortInIsrContext() != pdTRUE); vSemaphoreDelete(mutex->handle); mutex->handle = NULL; } inline static void recursive_mutex_lock(struct RecursiveMutex* mutex) { - assert(xPortInIsrContext() != pdTRUE); + check(xPortInIsrContext() != pdTRUE); xSemaphoreTakeRecursive(mutex->handle, portMAX_DELAY); } @@ -39,17 +39,17 @@ inline static bool recursive_mutex_is_locked(struct RecursiveMutex* mutex) { } inline static bool recursive_mutex_try_lock(struct RecursiveMutex* mutex) { - assert(xPortInIsrContext() != pdTRUE); + check(xPortInIsrContext() != pdTRUE); return xSemaphoreTakeRecursive(mutex->handle, 0) == pdTRUE; } inline static bool recursive_mutex_try_lock_timed(struct RecursiveMutex* mutex, TickType_t timeout) { - assert(xPortInIsrContext() != pdTRUE); + check(xPortInIsrContext() != pdTRUE); return xSemaphoreTakeRecursive(mutex->handle, timeout) == pdTRUE; } inline static void recursive_mutex_unlock(struct RecursiveMutex* mutex) { - assert(xPortInIsrContext() != pdTRUE); + check(xPortInIsrContext() != pdTRUE); xSemaphoreGiveRecursive(mutex->handle); } diff --git a/TactilityKernel/Source/Crash.cpp b/TactilityKernel/Source/Crash.cpp new file mode 100644 index 00000000..4edb9813 --- /dev/null +++ b/TactilityKernel/Source/Crash.cpp @@ -0,0 +1,39 @@ +#include +#include + +static const auto* TAG = LOG_TAG("Kernel"); + +static void log_memory_info() { +#ifdef ESP_PLATFORM + LOG_E(TAG, "Default memory caps:"); + LOG_E(TAG, " Total: %" PRIu64, static_cast(heap_caps_get_total_size(MALLOC_CAP_DEFAULT))); + LOG_E(TAG, " Free: %" PRIu64, static_cast(heap_caps_get_free_size(MALLOC_CAP_DEFAULT))); + LOG_E(TAG, " Min free: %" PRIu64, static_cast(heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT))); + LOG_E(TAG, "Internal memory caps:"); + LOG_E(TAG, " Total: %" PRIu64, static_cast(heap_caps_get_total_size(MALLOC_CAP_INTERNAL))); + LOG_E(TAG, " Free: %" PRIu64, static_cast(heap_caps_get_free_size(MALLOC_CAP_INTERNAL))); + LOG_E(TAG, " Min free: %" PRIu64, static_cast(heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL))); +#endif +} + +static void log_task_info() { + const char* name = pcTaskGetName(nullptr); + const char* safe_name = name ? name : "main"; + LOG_E(TAG, "Task: %s", safe_name); +} + +extern "C" { + +__attribute__((noreturn)) void __crash(void) { + log_task_info(); + log_memory_info(); + // TODO: Add breakpoint when debugger is attached. +#ifdef ESP_PLATFORM + esp_system_abort("System halted. Connect debugger for more info."); +#else + while (true) { /* Indefinite lock-up */ } +#endif + __builtin_unreachable(); +} + +} diff --git a/TactilityKernel/Source/Driver.cpp b/TactilityKernel/Source/Driver.cpp index 217eac3f..97a25b0d 100644 --- a/TactilityKernel/Source/Driver.cpp +++ b/TactilityKernel/Source/Driver.cpp @@ -70,7 +70,6 @@ static error_t driver_remove(Driver* driver) { ledger.lock(); const auto iterator = std::ranges::find(ledger.drivers, driver); - // check that there actually is a 3 in our vector if (iterator == ledger.drivers.end()) { ledger.unlock(); return ERROR_NOT_FOUND; @@ -184,7 +183,7 @@ error_t driver_unbind(Driver* driver, Device* device) { driver_internal_data(driver)->use_count--; driver_unlock(driver); - LOG_I(TAG, "unbound %s to %s", driver->name, device->name); + LOG_I(TAG, "unbound %s from %s", driver->name, device->name); return ERROR_NONE; diff --git a/TactilityKernel/Source/Log.cpp b/TactilityKernel/Source/Log.cpp index f02f9c22..5c378ffe 100644 --- a/TactilityKernel/Source/Log.cpp +++ b/TactilityKernel/Source/Log.cpp @@ -7,6 +7,8 @@ #include #include +extern "C" { + void log_generic(const char* tag, const char* format, ...) { va_list args; va_start(args, format); @@ -16,4 +18,6 @@ void log_generic(const char* tag, const char* format, ...) { va_end(args); } +} + #endif \ No newline at end of file diff --git a/TactilityKernel/Source/concurrent/EventGroup.cpp b/TactilityKernel/Source/concurrent/EventGroup.cpp index cab2f1fd..26ea21a0 100644 --- a/TactilityKernel/Source/concurrent/EventGroup.cpp +++ b/TactilityKernel/Source/concurrent/EventGroup.cpp @@ -48,7 +48,7 @@ error_t event_group_wait( uint32_t* outFlags, TickType_t timeout ) { - if (xPortInIsrContext()) { + if (xPortInIsrContext() == pdTRUE) { return ERROR_ISR_STATUS; } diff --git a/Tests/Tactility/CMakeLists.txt b/Tests/Tactility/CMakeLists.txt index 2e0fcddd..87c29eea 100644 --- a/Tests/Tactility/CMakeLists.txt +++ b/Tests/Tactility/CMakeLists.txt @@ -21,7 +21,7 @@ add_test(NAME TactilityTests target_link_libraries(TactilityTests PRIVATE Tactility TactilityCore - Tactility + TactilityKernel Simulator SDL2::SDL2-static SDL2-static ) diff --git a/Tests/TactilityCore/CMakeLists.txt b/Tests/TactilityCore/CMakeLists.txt index b11ae240..550cedfe 100644 --- a/Tests/TactilityCore/CMakeLists.txt +++ b/Tests/TactilityCore/CMakeLists.txt @@ -20,6 +20,7 @@ add_test(NAME TactilityCoreTests target_link_libraries(TactilityCoreTests PUBLIC TactilityCore + TactilityKernel TactilityFreeRtos freertos_kernel ) diff --git a/Tests/TactilityKernel/TimeAndDelay.cpp b/Tests/TactilityKernel/TimeAndDelay.cpp new file mode 100644 index 00000000..753368f1 --- /dev/null +++ b/Tests/TactilityKernel/TimeAndDelay.cpp @@ -0,0 +1,30 @@ +#include "doctest.h" +#include +#include + +TEST_CASE("delay ticks should be accurate within 1 tick") { + auto start_time = get_ticks(); + delay_ticks(100); + auto end_time = get_ticks(); + auto difference = end_time - start_time; + CHECK_EQ(difference >= 100, true); + CHECK_EQ(difference <= 101, true); +} + +TEST_CASE("delay millis should be accurate within 1 tick") { + auto start_time = get_millis(); + delay_millis(100); + auto end_time = get_millis(); + auto difference = end_time - start_time; + CHECK_EQ(difference >= 100, true); + CHECK_EQ(difference <= 101, true); +} + +TEST_CASE("microsecond time should be accurate within 1 tick") { + auto start_time = get_micros_since_boot(); + delay_millis(100); + auto end_time = get_micros_since_boot(); + auto difference = (end_time - start_time) / 1000; + CHECK_EQ(difference >= 99, true); + CHECK_EQ(difference <= 101, true); +}