C++ conversions (#111)
* Remove version from artifact name * Target C++ 20 and higher * Use cpp string * Better crash implementation * String utils in cpp style * Replace parameter methods with start() method * MutexType to Mutex::Type * Kernel c to cpp style * Cleanup event flag * More cpp conversions * Test fixes * Updated ideas docs
This commit is contained in:
parent
d52fe52d96
commit
42e843b463
5
.github/actions/build-firmware/action.yml
vendored
5
.github/actions/build-firmware/action.yml
vendored
@ -4,9 +4,6 @@ inputs:
|
||||
board-name:
|
||||
description: The name of the board
|
||||
required: true
|
||||
version:
|
||||
description: The name of the board
|
||||
required: true
|
||||
sdkconfig:
|
||||
description: The sdkconfig file to build
|
||||
required: true
|
||||
@ -32,6 +29,6 @@ runs:
|
||||
- name: 'Upload Artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tactility-${{ inputs.board-name }}-${{ inputs.version }}
|
||||
name: tactility-${{ inputs.board-name }}
|
||||
path: build/Tactility.bin
|
||||
retention-days: 5
|
||||
|
||||
4
.github/workflows/build-firmware.yml
vendored
4
.github/workflows/build-firmware.yml
vendored
@ -12,7 +12,6 @@ jobs:
|
||||
uses: ./.github/actions/build-firmware
|
||||
with:
|
||||
board-name: yellowboard
|
||||
version: snapshot
|
||||
sdkconfig: sdkconfig.board.yellow_board
|
||||
arch: esp32
|
||||
lilygo-tdeck:
|
||||
@ -23,7 +22,6 @@ jobs:
|
||||
uses: ./.github/actions/build-firmware
|
||||
with:
|
||||
board-name: lilygotdeck
|
||||
version: snapshot
|
||||
sdkconfig: sdkconfig.board.lilygo_tdeck
|
||||
arch: esp32s3
|
||||
m5stack-core2:
|
||||
@ -34,7 +32,6 @@ jobs:
|
||||
uses: ./.github/actions/build-firmware
|
||||
with:
|
||||
board-name: m5stackcore2
|
||||
version: snapshot
|
||||
sdkconfig: sdkconfig.board.m5stack_core2
|
||||
arch: esp32
|
||||
m5stack-cores3:
|
||||
@ -45,6 +42,5 @@ jobs:
|
||||
uses: ./.github/actions/build-firmware
|
||||
with:
|
||||
board-name: m5stackcores3
|
||||
version: snapshot
|
||||
sdkconfig: sdkconfig.board.m5stack_cores3
|
||||
arch: esp32s3
|
||||
|
||||
@ -22,7 +22,7 @@ void app_main() {
|
||||
&hello_world_app,
|
||||
},
|
||||
.services = {},
|
||||
.auto_start_app_id = nullptr
|
||||
.autoStartAppId = nullptr
|
||||
};
|
||||
|
||||
tt::run(config);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_lcd_touch_gt911.h"
|
||||
#include "Log.h"
|
||||
#include "Kernel.h"
|
||||
#include "kernel/Kernel.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
#define TAG "tdeck_touch"
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
#define TAG "lvgl_task"
|
||||
|
||||
// Mutex for LVGL drawing
|
||||
static tt::Mutex lvgl_mutex(tt::MutexTypeRecursive);
|
||||
static tt::Mutex task_mutex(tt::MutexTypeRecursive);
|
||||
static tt::Mutex lvgl_mutex(tt::Mutex::TypeRecursive);
|
||||
static tt::Mutex task_mutex(tt::Mutex::TypeRecursive);
|
||||
|
||||
static uint32_t task_max_sleep_ms = 10;
|
||||
// Mutex for LVGL task state (to modify task_running state)
|
||||
|
||||
@ -17,7 +17,7 @@ static bool initBoot() {
|
||||
TT_UNUSED static void deinitPower() {
|
||||
lvgl_task_interrupt();
|
||||
while (lvgl_task_is_running()) {
|
||||
tt::delay_ms(10);
|
||||
tt::kernel::delayMillis(10);
|
||||
}
|
||||
|
||||
#if LV_ENABLE_GC || !LV_MEM_CUSTOM
|
||||
|
||||
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
add_definitions(-DTT_DEBUG)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_ASM_COMPILE_OBJECT "${CMAKE_CXX_COMPILER_TARGET}")
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
# TODOs
|
||||
- Gpio: Use Timer instead of Thread
|
||||
- I2cScannerThread: Use Timer instead of Thread
|
||||
- Bug: I2C Scanner is on M5Stack devices is broken
|
||||
- WiFi AP Connect app: add "Forget" option.
|
||||
- T-Deck Plus: Implement battery status
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
|
||||
@ -37,7 +37,7 @@ class AppInstance : public AppContext {
|
||||
|
||||
private:
|
||||
|
||||
Mutex mutex = Mutex(MutexTypeNormal);
|
||||
Mutex mutex = Mutex(Mutex::TypeNormal);
|
||||
const AppManifest& manifest;
|
||||
State state = StateInitial;
|
||||
Flags flags = { .showStatusbar = true };
|
||||
|
||||
@ -143,7 +143,7 @@ struct Loader {
|
||||
std::shared_ptr<PubSub> pubsub_internal = std::make_shared<PubSub>();
|
||||
std::shared_ptr<PubSub> pubsub_external = std::make_shared<PubSub>();
|
||||
MessageQueue queue = MessageQueue(2, sizeof(LoaderMessage)); // 2 entries, so you can stop the current app while starting a new one without blocking
|
||||
Mutex mutex = Mutex(MutexTypeRecursive);
|
||||
Mutex mutex = Mutex(Mutex::TypeRecursive);
|
||||
std::stack<app::AppInstance*> app_stack;
|
||||
};
|
||||
|
||||
|
||||
@ -155,9 +155,9 @@ void run(const Configuration& config) {
|
||||
TT_LOG_I(TAG, "init starting desktop app");
|
||||
service::loader::startApp(app::boot::manifest.id, true);
|
||||
|
||||
if (config.auto_start_app_id) {
|
||||
TT_LOG_I(TAG, "init auto-starting %s", config.auto_start_app_id);
|
||||
service::loader::startApp(config.auto_start_app_id, true);
|
||||
if (config.autoStartAppId) {
|
||||
TT_LOG_I(TAG, "init auto-starting %s", config.autoStartAppId);
|
||||
service::loader::startApp(config.autoStartAppId, true);
|
||||
}
|
||||
|
||||
TT_LOG_I(TAG, "init complete");
|
||||
|
||||
@ -12,7 +12,7 @@ typedef struct {
|
||||
// List of user applications
|
||||
const app::AppManifest* const apps[TT_CONFIG_APPS_LIMIT];
|
||||
const service::ServiceManifest* const services[TT_CONFIG_SERVICES_LIMIT];
|
||||
const char* auto_start_app_id;
|
||||
const char* autoStartAppId;
|
||||
} Configuration;
|
||||
|
||||
/**
|
||||
|
||||
@ -10,7 +10,7 @@ namespace tt::app {
|
||||
typedef std::unordered_map<std::string, const AppManifest*> AppManifestMap;
|
||||
|
||||
static AppManifestMap app_manifest_map;
|
||||
static Mutex hash_mutex(MutexTypeNormal);
|
||||
static Mutex hash_mutex(Mutex::TypeNormal);
|
||||
|
||||
void addApp(const AppManifest* manifest) {
|
||||
TT_LOG_I(TAG, "Registering manifest %s", manifest->id.c_str());
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
#include <Check.h>
|
||||
#include <Thread.h>
|
||||
#include <Kernel.h>
|
||||
#include "Assets.h"
|
||||
#include "TactilityCore.h"
|
||||
|
||||
#include "app/AppContext.h"
|
||||
#include "lvgl.h"
|
||||
#include "app/display/DisplaySettings.h"
|
||||
#include "hal/Display.h"
|
||||
#include "service/loader/Loader.h"
|
||||
#include "lvgl/Style.h"
|
||||
#include "app/display/DisplaySettings.h"
|
||||
|
||||
#include "lvgl.h"
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "sdkconfig.h"
|
||||
@ -26,7 +26,7 @@ struct Data {
|
||||
};
|
||||
|
||||
static int32_t threadCallback(TT_UNUSED void* context) {
|
||||
TickType_t start_time = tt::get_ticks();
|
||||
TickType_t start_time = tt::kernel::getTicks();
|
||||
|
||||
auto* lvgl_display = lv_display_get_default();
|
||||
tt_assert(lvgl_display != nullptr);
|
||||
@ -37,11 +37,11 @@ static int32_t threadCallback(TT_UNUSED void* context) {
|
||||
hal_display->setBacklightDuty(backlight_duty);
|
||||
}
|
||||
|
||||
TickType_t end_time = tt::get_ticks();
|
||||
TickType_t end_time = tt::kernel::getTicks();
|
||||
TickType_t ticks_passed = end_time - start_time;
|
||||
TickType_t minimum_ticks = (CONFIG_TT_SPLASH_DURATION / portTICK_PERIOD_MS);
|
||||
if (minimum_ticks > ticks_passed) {
|
||||
tt::delay_ticks(minimum_ticks - ticks_passed);
|
||||
tt::kernel::delayTicks(minimum_ticks - ticks_passed);
|
||||
}
|
||||
tt::service::loader::stopApp();
|
||||
tt::service::loader::startApp("Desktop");
|
||||
|
||||
@ -81,7 +81,7 @@ static void onNavigateUpPressed(TT_UNUSED lv_event_t* event) {
|
||||
if (strcmp(files_data->current_path, "/") != 0) {
|
||||
TT_LOG_I(TAG, "Navigating upwards");
|
||||
char new_absolute_path[MAX_PATH_LENGTH];
|
||||
if (string_get_path_parent(files_data->current_path, new_absolute_path)) {
|
||||
if (string::getPathParent(files_data->current_path, new_absolute_path)) {
|
||||
data_set_entries_for_path(files_data, new_absolute_path);
|
||||
}
|
||||
}
|
||||
@ -102,7 +102,7 @@ static void viewFile(const char* path, const char* filename) {
|
||||
// For PC we need to make the path relative to the current work directory,
|
||||
// because that's how LVGL maps its 'drive letter' to the file system.
|
||||
char* processed_filepath;
|
||||
if (get_platform() == PlatformSimulator) {
|
||||
if (kernel::getPlatform() == kernel::PlatformSimulator) {
|
||||
char cwd[PATH_MAX];
|
||||
if (getcwd(cwd, sizeof(cwd)) == nullptr) {
|
||||
TT_LOG_E(TAG, "Failed to get current working directory");
|
||||
@ -126,7 +126,7 @@ static void viewFile(const char* path, const char* filename) {
|
||||
service::loader::startApp("ImageViewer", false, bundle);
|
||||
} else if (isSupportedTextFile(filename)) {
|
||||
auto bundle = std::make_shared<Bundle>();
|
||||
if (get_platform() == PlatformEsp) {
|
||||
if (kernel::getPlatform() == kernel::PlatformEsp) {
|
||||
bundle->putString(TEXT_VIEWER_FILE_ARGUMENT, processed_filepath);
|
||||
} else {
|
||||
// Remove forward slash, because we need a relative path
|
||||
@ -220,7 +220,7 @@ static void onShow(AppContext& app, lv_obj_t* parent) {
|
||||
static void onStart(AppContext& app) {
|
||||
auto data = std::make_shared<Data>();
|
||||
// PC platform is bound to current work directory because of the LVGL file system mapping
|
||||
if (get_platform() == PlatformSimulator) {
|
||||
if (kernel::getPlatform() == kernel::PlatformSimulator) {
|
||||
char cwd[PATH_MAX];
|
||||
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
|
||||
data_set_entries_for_path(data, cwd);
|
||||
|
||||
@ -42,7 +42,7 @@ bool data_set_entries_for_path(std::shared_ptr<Data> data, const char* path) {
|
||||
* ESP32 does not have a root directory, so we have to create it manually.
|
||||
* We'll add the NVS Flash partitions and the binding for the sdcard.
|
||||
*/
|
||||
if (get_platform() == PlatformEsp && strcmp(path, "/") == 0) {
|
||||
if (kernel::getPlatform() == kernel::PlatformEsp && strcmp(path, "/") == 0) {
|
||||
int dir_entries_count = 3;
|
||||
auto** dir_entries = static_cast<dirent**>(malloc(sizeof(struct dirent*) * 3));
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ static int32_t taskMain(void* context) {
|
||||
bool interrupted = false;
|
||||
|
||||
while (!interrupted) {
|
||||
delay_ms(100);
|
||||
kernel::delayMillis(100);
|
||||
|
||||
gpio->updatePinStates();
|
||||
gpio->updatePinWidgets();
|
||||
|
||||
@ -27,7 +27,7 @@ std::string getPortNamesForDropdown() {
|
||||
}
|
||||
port_index++;
|
||||
}
|
||||
return string_join(config_names, "\n");
|
||||
return string::join(config_names, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ enum ScanState {
|
||||
|
||||
struct Data {
|
||||
// Core
|
||||
Mutex mutex = Mutex(MutexTypeRecursive);
|
||||
Mutex mutex = Mutex(Mutex::TypeRecursive);
|
||||
Thread* _Nullable scanThread = nullptr;
|
||||
// State
|
||||
ScanState scanState;
|
||||
|
||||
@ -41,7 +41,7 @@ static void updateUi(std::shared_ptr<Data> data) {
|
||||
uint16_t charge_level_scaled = (int16_t)charge_level * 100 / 255;
|
||||
int32_t current = data->power->getCurrent();
|
||||
|
||||
lvgl::lock(ms_to_ticks(1000));
|
||||
lvgl::lock(kernel::millisToTicks(1000));
|
||||
lv_obj_set_state(data->enable_switch, LV_STATE_CHECKED, charging_enabled);
|
||||
lv_label_set_text_fmt(data->charge_state, "Charging: %s", charge_state);
|
||||
lv_label_set_text_fmt(data->charge_level, "Charge level: %d%%", charge_level_scaled);
|
||||
@ -110,7 +110,7 @@ static void onShow(AppContext& app, lv_obj_t* parent) {
|
||||
data->current = lv_label_create(wrapper);
|
||||
|
||||
updateUi(data);
|
||||
data->update_timer->start(ms_to_ticks(1000));
|
||||
data->update_timer->start(kernel::millisToTicks(1000));
|
||||
}
|
||||
|
||||
static void onHide(TT_UNUSED AppContext& app) {
|
||||
|
||||
@ -124,7 +124,7 @@ static void create_path_ui(std::shared_ptr<ScreenshotUi> ui, lv_obj_t* parent) {
|
||||
lv_textarea_set_one_line(path_textarea, true);
|
||||
lv_obj_set_flex_grow(path_textarea, 1);
|
||||
ui->path_textarea = path_textarea;
|
||||
if (get_platform() == PlatformEsp) {
|
||||
if (kernel::getPlatform() == kernel::PlatformEsp) {
|
||||
if (hal::sdcard::getState() == hal::sdcard::StateMounted) {
|
||||
lv_textarea_set_text(path_textarea, "A:/sdcard");
|
||||
} else {
|
||||
|
||||
@ -16,9 +16,14 @@ namespace tt::app::selectiondialog {
|
||||
|
||||
#define TAG "selection_dialog"
|
||||
|
||||
void setItemsParameter(Bundle& bundle, const std::vector<std::string>& items) {
|
||||
std::string result = string_join(items, PARAMETER_ITEM_CONCATENATION_TOKEN);
|
||||
bundle.putString(PARAMETER_BUNDLE_KEY_ITEMS, result);
|
||||
extern const AppManifest manifest;
|
||||
|
||||
void start(std::string title, const std::vector<std::string>& items) {
|
||||
std::string items_joined = string::join(items, PARAMETER_ITEM_CONCATENATION_TOKEN);
|
||||
auto bundle = std::make_shared<Bundle>();
|
||||
bundle->putString(PARAMETER_BUNDLE_KEY_TITLE, title);
|
||||
bundle->putString(PARAMETER_BUNDLE_KEY_ITEMS, items_joined);
|
||||
service::loader::startApp(manifest.id, false, bundle);
|
||||
}
|
||||
|
||||
int32_t getResultIndex(const Bundle& bundle) {
|
||||
@ -31,10 +36,6 @@ void setResultIndex(std::shared_ptr<Bundle> bundle, int32_t index) {
|
||||
bundle->putInt32(RESULT_BUNDLE_KEY_INDEX, index);
|
||||
}
|
||||
|
||||
void setTitleParameter(std::shared_ptr<Bundle> bundle, const std::string& title) {
|
||||
bundle->putString(PARAMETER_BUNDLE_KEY_TITLE, title);
|
||||
}
|
||||
|
||||
static std::string getTitleParameter(std::shared_ptr<const Bundle> bundle) {
|
||||
std::string result;
|
||||
if (bundle->optString(PARAMETER_BUNDLE_KEY_TITLE, result)) {
|
||||
@ -76,7 +77,7 @@ static void onShow(AppContext& app, lv_obj_t* parent) {
|
||||
tt_check(parameters != nullptr, "Parameters missing");
|
||||
std::string items_concatenated;
|
||||
if (parameters->optString(PARAMETER_BUNDLE_KEY_ITEMS, items_concatenated)) {
|
||||
std::vector<std::string> items = string_split(items_concatenated, PARAMETER_ITEM_CONCATENATION_TOKEN);
|
||||
std::vector<std::string> items = string::split(items_concatenated, PARAMETER_ITEM_CONCATENATION_TOKEN);
|
||||
if (items.empty() || items.front().empty()) {
|
||||
TT_LOG_E(TAG, "No items provided");
|
||||
app.setResult(ResultError);
|
||||
|
||||
@ -14,10 +14,7 @@
|
||||
*/
|
||||
namespace tt::app::selectiondialog {
|
||||
|
||||
/** App startup parameters */
|
||||
|
||||
void setTitleParameter(Bundle& bundle, const std::string& title);
|
||||
void setItemsParameter(Bundle& bundle, const std::vector<std::string>& items);
|
||||
void start(std::string title, const std::vector<std::string>& items);
|
||||
|
||||
/** App result data */
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ namespace tt::app::wifimanage {
|
||||
*/
|
||||
class State {
|
||||
|
||||
Mutex mutex = Mutex(MutexTypeRecursive);
|
||||
Mutex mutex = Mutex(Mutex::TypeRecursive);
|
||||
bool scanning;
|
||||
service::wifi::WifiRadioState radioState;
|
||||
std::vector<service::wifi::WifiApRecord> apRecords;
|
||||
|
||||
@ -39,7 +39,7 @@ typedef struct {
|
||||
} Statusbar;
|
||||
|
||||
static void statusbar_init() {
|
||||
statusbar_data.mutex = tt_mutex_alloc(MutexTypeRecursive);
|
||||
statusbar_data.mutex = tt_mutex_alloc(Mutex::TypeRecursive);
|
||||
statusbar_data.pubsub = std::make_shared<PubSub>();
|
||||
for (int i = 0; i < STATUSBAR_ICON_LIMIT; i++) {
|
||||
statusbar_data.icons[i].image = nullptr;
|
||||
@ -83,7 +83,7 @@ static const lv_obj_class_t statusbar_class = {
|
||||
static void statusbar_pubsub_event(TT_UNUSED const void* message, void* obj) {
|
||||
TT_LOG_I(TAG, "event");
|
||||
auto* statusbar = static_cast<Statusbar*>(obj);
|
||||
if (lock(ms_to_ticks(100))) {
|
||||
if (lock(kernel::millisToTicks(100))) {
|
||||
update_main(statusbar);
|
||||
lv_obj_invalidate(&statusbar->obj);
|
||||
unlock();
|
||||
|
||||
@ -36,7 +36,7 @@ Gui* gui_alloc() {
|
||||
&gui_main,
|
||||
nullptr
|
||||
);
|
||||
instance->mutex = tt_mutex_alloc(MutexTypeRecursive);
|
||||
instance->mutex = tt_mutex_alloc(Mutex::TypeRecursive);
|
||||
instance->keyboard = nullptr;
|
||||
instance->loader_pubsub_subscription = tt_pubsub_subscribe(loader::getPubsub(), &loader_callback, instance);
|
||||
tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS));
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
namespace tt::service::loader {
|
||||
|
||||
#define TAG "loader"
|
||||
#define LOADER_EVENT_FLAG 1
|
||||
|
||||
typedef struct {
|
||||
LoaderEventType type;
|
||||
@ -77,7 +78,7 @@ LoaderStatus startApp(const std::string& id, bool blocking, std::shared_ptr<cons
|
||||
/* TODO: Check if task id is not the LVGL one,
|
||||
because otherwise this fails as the apps starting logic will try to lock lvgl
|
||||
to update the UI and fail. */
|
||||
event_flag->wait(TT_API_LOCK_EVENT);
|
||||
event_flag->wait(LOADER_EVENT_FLAG);
|
||||
delete event_flag;
|
||||
}
|
||||
|
||||
@ -330,7 +331,7 @@ static int32_t loader_main(TT_UNUSED void* parameter) {
|
||||
message.payload.start->parameters
|
||||
);
|
||||
if (message.api_lock != nullptr) {
|
||||
message.api_lock->set(TT_API_LOCK_EVENT);
|
||||
message.api_lock->set(LOADER_EVENT_FLAG);
|
||||
}
|
||||
message.cleanup();
|
||||
break;
|
||||
|
||||
@ -43,7 +43,7 @@ ScreenshotTask* alloc() {
|
||||
auto* data = static_cast<ScreenshotTaskData*>(malloc(sizeof(ScreenshotTaskData)));
|
||||
*data = (ScreenshotTaskData) {
|
||||
.thread = nullptr,
|
||||
.mutex = tt_mutex_alloc(MutexTypeRecursive),
|
||||
.mutex = tt_mutex_alloc(Mutex::TypeRecursive),
|
||||
.interrupted = false
|
||||
};
|
||||
return data;
|
||||
@ -76,7 +76,7 @@ static int32_t screenshot_task(void* context) {
|
||||
if (data->work.type == TASK_WORK_TYPE_DELAY) {
|
||||
// Splitting up the delays makes it easier to stop the service
|
||||
for (int i = 0; i < (data->work.delay_in_seconds * 10) && !is_interrupted(data); ++i){
|
||||
delay_ms(100);
|
||||
kernel::delayMillis(100);
|
||||
}
|
||||
|
||||
if (is_interrupted(data)) {
|
||||
@ -102,7 +102,7 @@ static int32_t screenshot_task(void* context) {
|
||||
if (app) {
|
||||
const app::AppManifest& manifest = app->getManifest();
|
||||
if (manifest.id != last_app_id) {
|
||||
delay_ms(100);
|
||||
kernel::delayMillis(100);
|
||||
last_app_id = manifest.id;
|
||||
|
||||
char filename[SCREENSHOT_PATH_LIMIT + 32];
|
||||
@ -116,7 +116,7 @@ static int32_t screenshot_task(void* context) {
|
||||
lvgl::unlock();
|
||||
}
|
||||
}
|
||||
delay_ms(250);
|
||||
kernel::delayMillis(250);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
file(GLOB_RECURSE SOURCES "Source/*.c*")
|
||||
|
||||
@ -23,7 +23,7 @@ private:
|
||||
} Type;
|
||||
|
||||
typedef struct {
|
||||
const char* key;
|
||||
std::string key;
|
||||
Type type;
|
||||
union {
|
||||
bool value_bool;
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
#include "Check.h"
|
||||
|
||||
#include "CoreDefines.h"
|
||||
#include "Log.h"
|
||||
#include "RtosCompatTask.h"
|
||||
|
||||
#define TAG "kernel"
|
||||
|
||||
static void tt_print_memory_info() {
|
||||
static void logMemoryInfo() {
|
||||
#ifdef ESP_PLATFORM
|
||||
TT_LOG_E(TAG, "default caps:");
|
||||
TT_LOG_E(TAG, " total: %u", heap_caps_get_total_size(MALLOC_CAP_DEFAULT));
|
||||
@ -19,19 +18,23 @@ static void tt_print_memory_info() {
|
||||
#endif
|
||||
}
|
||||
|
||||
static void tt_print_task_info() {
|
||||
static void logTaskInfo() {
|
||||
const char* name = pcTaskGetName(nullptr);
|
||||
const char* safe_name = name ? name : "main";
|
||||
TT_LOG_E(TAG, "Task: %s", safe_name);
|
||||
TT_LOG_E(TAG, "Stack watermark: %u", uxTaskGetStackHighWaterMark(NULL) * 4);
|
||||
}
|
||||
|
||||
TT_NORETURN void tt_crash_implementation() {
|
||||
tt_print_task_info();
|
||||
tt_print_memory_info();
|
||||
namespace tt {
|
||||
|
||||
TT_NORETURN void _crash() {
|
||||
logTaskInfo();
|
||||
logMemoryInfo();
|
||||
// TODO: Add breakpoint when debugger is attached.
|
||||
#ifdef ESP_TARGET
|
||||
esp_system_abort("System halted. Connect debugger for more info.");
|
||||
#endif
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -15,17 +15,29 @@
|
||||
|
||||
#include "Log.h"
|
||||
#include <cassert>
|
||||
#include "CoreDefines.h"
|
||||
|
||||
#define TT_NORETURN [[noreturn]]
|
||||
|
||||
/** Crash system */
|
||||
TT_NORETURN void tt_crash_implementation();
|
||||
namespace tt {
|
||||
/**
|
||||
* Don't call this directly. Use tt_crash() as it will trace info.
|
||||
*/
|
||||
TT_NORETURN void _crash();
|
||||
}
|
||||
|
||||
/** Crash system with message. */
|
||||
#define tt_crash(message) \
|
||||
do { \
|
||||
TT_LOG_E("crash", "%s\n\tat %s:%d", ((message) ? (message) : ""), __FILE__, __LINE__); \
|
||||
tt_crash_implementation(); \
|
||||
#define tt_crash(...) TT_ARG_CAT(_tt_crash,TT_ARGCOUNT(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
#define _tt_crash0() do { \
|
||||
TT_LOG_E("crash", "at %s:%d", __FILE__, __LINE__); \
|
||||
tt::_crash(); \
|
||||
} while (0)
|
||||
|
||||
#define _tt_crash1(message) do { \
|
||||
TT_LOG_E("crash", "%s\n\tat %s:%d", message, __FILE__, __LINE__); \
|
||||
tt::_crash(); \
|
||||
} while (0)
|
||||
|
||||
/** Halt system
|
||||
@ -53,7 +65,7 @@ TT_NORETURN void tt_crash_implementation();
|
||||
* @param optional message (const char*)
|
||||
*/
|
||||
|
||||
#define tt_check(x, ...) if (!(x)) { TT_LOG_E("check", "Failed: %s", #x); tt_crash_implementation(); }
|
||||
#define tt_check(x, ...) if (!(x)) { TT_LOG_E("check", "Failed: %s", #x); tt::_crash(); }
|
||||
|
||||
/** Only in debug build: Assert condition and crash if assert failed */
|
||||
#ifdef TT_DEBUG
|
||||
|
||||
@ -31,3 +31,19 @@
|
||||
#define TT_IS_ISR() (TT_IS_IRQ_MODE())
|
||||
|
||||
#define TT_CHECK_RETURN __attribute__((__warn_unused_result__))
|
||||
|
||||
// region Variable arguments support
|
||||
|
||||
// Adapted from https://stackoverflow.com/a/78848701/3848666
|
||||
#define TT_ARG_IGNORE(X)
|
||||
#define TT_ARG_CAT(X,Y) _TT_ARG_CAT(X,Y)
|
||||
#define _TT_ARG_CAT(X,Y) X ## Y
|
||||
#define TT_ARGCOUNT(...) _TT_ARGCOUNT ## __VA_OPT__(1(__VA_ARGS__) TT_ARG_IGNORE) (0)
|
||||
#define _TT_ARGCOUNT1(X,...) _TT_ARGCOUNT ## __VA_OPT__(2(__VA_ARGS__) TT_ARG_IGNORE) (1)
|
||||
#define _TT_ARGCOUNT2(X,...) _TT_ARGCOUNT ## __VA_OPT__(3(__VA_ARGS__) TT_ARG_IGNORE) (2)
|
||||
#define _TT_ARGCOUNT3(X,...) _TT_ARGCOUNT ## __VA_OPT__(4(__VA_ARGS__) TT_ARG_IGNORE) (3)
|
||||
#define _TT_ARGCOUNT4(X,...) _TT_ARGCOUNT ## __VA_OPT__(5(__VA_ARGS__) TT_ARG_IGNORE) (4)
|
||||
#define _TT_ARGCOUNT5(X,...) 5
|
||||
#define _TT_ARGCOUNT(X) X
|
||||
|
||||
// endregion
|
||||
@ -7,7 +7,7 @@ namespace tt {
|
||||
#define BACKPRESSURE_WARNING_COUNT 100
|
||||
|
||||
Dispatcher::Dispatcher() :
|
||||
mutex(MutexTypeNormal)
|
||||
mutex(Mutex::TypeNormal)
|
||||
{}
|
||||
|
||||
Dispatcher::~Dispatcher() {
|
||||
|
||||
@ -5,8 +5,6 @@
|
||||
|
||||
namespace tt {
|
||||
|
||||
#define TT_API_LOCK_EVENT (1U << 0)
|
||||
|
||||
/**
|
||||
* Wrapper for FreeRTOS xEventGroup.
|
||||
*/
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
#include "MessageQueue.h"
|
||||
#include "Check.h"
|
||||
#include "Kernel.h"
|
||||
#include "kernel/Kernel.h"
|
||||
|
||||
namespace tt {
|
||||
|
||||
MessageQueue::MessageQueue(uint32_t msg_count, uint32_t msg_size) {
|
||||
tt_assert((kernel_is_irq() == 0U) && (msg_count > 0U) && (msg_size > 0U));
|
||||
tt_assert((kernel::isIrq() == 0U) && (msg_count > 0U) && (msg_size > 0U));
|
||||
queue_handle = xQueueCreate(msg_count, msg_size);
|
||||
tt_check(queue_handle);
|
||||
}
|
||||
|
||||
MessageQueue::~MessageQueue() {
|
||||
tt_assert(kernel_is_irq() == 0U);
|
||||
tt_assert(kernel::isIrq() == 0U);
|
||||
vQueueDelete(queue_handle);
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ TtStatus MessageQueue::put(const void* msg_ptr, uint32_t timeout) {
|
||||
|
||||
stat = TtStatusOk;
|
||||
|
||||
if (kernel_is_irq() != 0U) {
|
||||
if (kernel::isIrq() != 0U) {
|
||||
if ((queue_handle == nullptr) || (msg_ptr == nullptr) || (timeout != 0U)) {
|
||||
stat = TtStatusErrorParameter;
|
||||
} else {
|
||||
@ -57,7 +57,7 @@ TtStatus MessageQueue::get(void* msg_ptr, uint32_t timeout_ticks) {
|
||||
|
||||
stat = TtStatusOk;
|
||||
|
||||
if (kernel_is_irq() != 0U) {
|
||||
if (kernel::isIrq() != 0U) {
|
||||
if ((queue_handle == nullptr) || (msg_ptr == nullptr) || (timeout_ticks != 0U)) {
|
||||
stat = TtStatusErrorParameter;
|
||||
} else {
|
||||
@ -122,7 +122,7 @@ uint32_t MessageQueue::getCount() const {
|
||||
|
||||
if (queue_handle == nullptr) {
|
||||
count = 0U;
|
||||
} else if (kernel_is_irq() != 0U) {
|
||||
} else if (kernel::isIrq() != 0U) {
|
||||
count = uxQueueMessagesWaitingFromISR(queue_handle);
|
||||
} else {
|
||||
count = uxQueueMessagesWaiting(queue_handle);
|
||||
@ -139,7 +139,7 @@ uint32_t MessageQueue::getSpace() const {
|
||||
|
||||
if (mq == nullptr) {
|
||||
space = 0U;
|
||||
} else if (kernel_is_irq() != 0U) {
|
||||
} else if (kernel::isIrq() != 0U) {
|
||||
isrm = taskENTER_CRITICAL_FROM_ISR();
|
||||
|
||||
/* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */
|
||||
@ -157,7 +157,7 @@ uint32_t MessageQueue::getSpace() const {
|
||||
TtStatus MessageQueue::reset() {
|
||||
TtStatus stat;
|
||||
|
||||
if (kernel_is_irq() != 0U) {
|
||||
if (kernel::isIrq() != 0U) {
|
||||
stat = TtStatusErrorISR;
|
||||
} else if (queue_handle == nullptr) {
|
||||
stat = TtStatusErrorParameter;
|
||||
|
||||
@ -22,13 +22,13 @@ namespace tt {
|
||||
#define tt_mutex_info(mutex, text)
|
||||
#endif
|
||||
|
||||
Mutex::Mutex(MutexType type) : type(type) {
|
||||
Mutex::Mutex(Type type) : type(type) {
|
||||
tt_mutex_info(data, "alloc");
|
||||
switch (type) {
|
||||
case MutexTypeNormal:
|
||||
case TypeNormal:
|
||||
semaphore = xSemaphoreCreateMutex();
|
||||
break;
|
||||
case MutexTypeRecursive:
|
||||
case TypeRecursive:
|
||||
semaphore = xSemaphoreCreateRecursiveMutex();
|
||||
break;
|
||||
default:
|
||||
@ -51,7 +51,7 @@ TtStatus Mutex::acquire(uint32_t timeout) const {
|
||||
tt_mutex_info(mutex, "acquire");
|
||||
|
||||
switch (type) {
|
||||
case MutexTypeNormal:
|
||||
case TypeNormal:
|
||||
if (xSemaphoreTake(semaphore, timeout) != pdPASS) {
|
||||
if (timeout != 0U) {
|
||||
return TtStatusErrorTimeout;
|
||||
@ -62,7 +62,7 @@ TtStatus Mutex::acquire(uint32_t timeout) const {
|
||||
return TtStatusOk;
|
||||
}
|
||||
break;
|
||||
case MutexTypeRecursive:
|
||||
case TypeRecursive:
|
||||
if (xSemaphoreTakeRecursive(semaphore, timeout) != pdPASS) {
|
||||
if (timeout != 0U) {
|
||||
return TtStatusErrorTimeout;
|
||||
@ -84,7 +84,7 @@ TtStatus Mutex::release() const {
|
||||
tt_mutex_info(mutex, "release");
|
||||
|
||||
switch (type) {
|
||||
case MutexTypeNormal: {
|
||||
case TypeNormal: {
|
||||
if (xSemaphoreGive(semaphore) != pdPASS) {
|
||||
return TtStatusErrorResource;
|
||||
} else {
|
||||
@ -92,7 +92,7 @@ TtStatus Mutex::release() const {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MutexTypeRecursive:
|
||||
case TypeRecursive:
|
||||
if (xSemaphoreGiveRecursive(semaphore) != pdPASS) {
|
||||
return TtStatusErrorResource;
|
||||
} else {
|
||||
@ -115,7 +115,7 @@ std::unique_ptr<ScopedMutexUsage> Mutex::scoped() const {
|
||||
return std::move(std::make_unique<ScopedMutexUsage>(*this));
|
||||
}
|
||||
|
||||
Mutex* tt_mutex_alloc(MutexType type) {
|
||||
Mutex* tt_mutex_alloc(Mutex::Type type) {
|
||||
return new Mutex(type);
|
||||
}
|
||||
|
||||
|
||||
@ -14,21 +14,27 @@ namespace tt {
|
||||
|
||||
class ScopedMutexUsage;
|
||||
|
||||
typedef enum {
|
||||
MutexTypeNormal,
|
||||
MutexTypeRecursive,
|
||||
} MutexType;
|
||||
|
||||
/**
|
||||
* Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex
|
||||
* Can be used in IRQ mode (within ISR context)
|
||||
*/
|
||||
class Mutex {
|
||||
private:
|
||||
SemaphoreHandle_t semaphore;
|
||||
MutexType type;
|
||||
|
||||
public:
|
||||
explicit Mutex(MutexType type = MutexTypeNormal);
|
||||
|
||||
enum Type {
|
||||
TypeNormal,
|
||||
TypeRecursive,
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
SemaphoreHandle_t semaphore;
|
||||
Type type;
|
||||
|
||||
public:
|
||||
|
||||
explicit Mutex(Type type = TypeNormal);
|
||||
~Mutex();
|
||||
|
||||
TtStatus acquire(uint32_t timeout) const;
|
||||
@ -68,7 +74,7 @@ public:
|
||||
*/
|
||||
|
||||
[[deprecated("use class")]]
|
||||
Mutex* tt_mutex_alloc(MutexType type);
|
||||
Mutex* tt_mutex_alloc(Mutex::Type type);
|
||||
|
||||
/** Free Mutex
|
||||
*
|
||||
|
||||
@ -3,9 +3,9 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
namespace tt {
|
||||
namespace tt::string {
|
||||
|
||||
int string_find_last_index(const char* text, size_t from_index, char find) {
|
||||
int findLastIndex(const char* text, size_t from_index, char find) {
|
||||
for (size_t i = from_index; i >= 0; i--) {
|
||||
if (text[i] == find) {
|
||||
return (int)i;
|
||||
@ -14,8 +14,8 @@ int string_find_last_index(const char* text, size_t from_index, char find) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool string_get_path_parent(const char* path, char* output) {
|
||||
int index = string_find_last_index(path, strlen(path) - 1, '/');
|
||||
bool getPathParent(const char* path, char* output) {
|
||||
int index = findLastIndex(path, strlen(path) - 1, '/');
|
||||
if (index == -1) {
|
||||
return false;
|
||||
} else if (index == 0) {
|
||||
@ -29,7 +29,7 @@ bool string_get_path_parent(const char* path, char* output) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> string_split(const std::string&input, const std::string&delimiter) {
|
||||
std::vector<std::string> split(const std::string&input, const std::string&delimiter) {
|
||||
size_t token_index = 0;
|
||||
size_t delimiter_index;
|
||||
const size_t delimiter_length = delimiter.length();
|
||||
@ -50,7 +50,7 @@ std::vector<std::string> string_split(const std::string&input, const std::string
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string string_join(const std::vector<std::string>& input, const std::string& delimiter) {
|
||||
std::string join(const std::vector<std::string>& input, const std::string& delimiter) {
|
||||
std::stringstream stream;
|
||||
size_t size = input.size();
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace tt {
|
||||
namespace tt::string {
|
||||
|
||||
/**
|
||||
* Find the last occurrence of a character.
|
||||
@ -13,7 +13,7 @@ namespace tt {
|
||||
* @param[in] find the character to search for
|
||||
* @return the index of the found character, or -1 if none found
|
||||
*/
|
||||
int string_find_last_index(const char* text, size_t from_index, char find);
|
||||
int findLastIndex(const char* text, size_t from_index, char find);
|
||||
|
||||
/**
|
||||
* Given a filesystem path as input, try and get the parent path.
|
||||
@ -21,7 +21,7 @@ int string_find_last_index(const char* text, size_t from_index, char find);
|
||||
* @param[out] output an output buffer that is allocated to at least the size of "current"
|
||||
* @return true when successful
|
||||
*/
|
||||
bool string_get_path_parent(const char* path, char* output);
|
||||
bool getPathParent(const char* path, char* output);
|
||||
|
||||
/**
|
||||
* Splits the provided input into separate pieces with delimiter as separator text.
|
||||
@ -30,7 +30,7 @@ bool string_get_path_parent(const char* path, char* output);
|
||||
* @param input the input to split up
|
||||
* @param delimiter a non-empty string to recognize as separator
|
||||
*/
|
||||
std::vector<std::string> string_split(const std::string& input, const std::string& delimiter);
|
||||
std::vector<std::string> split(const std::string& input, const std::string& delimiter);
|
||||
|
||||
/**
|
||||
* Join a set of tokens into a single string, given a delimiter (separator).
|
||||
@ -40,6 +40,6 @@ std::vector<std::string> string_split(const std::string& input, const std::strin
|
||||
* @param input the tokens to join together
|
||||
* @param delimiter the separator to join with
|
||||
*/
|
||||
std::string string_join(const std::vector<std::string>& input, const std::string& delimiter);
|
||||
std::string join(const std::vector<std::string>& input, const std::string& delimiter);
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -6,7 +6,10 @@
|
||||
#include "CoreDefines.h"
|
||||
#include "CoreExtraDefines.h"
|
||||
#include "CoreTypes.h"
|
||||
#include "critical/Critical.h"
|
||||
#include "EventFlag.h"
|
||||
#include "Kernel.h"
|
||||
#include "kernel/Kernel.h"
|
||||
#include "kernel/critical/Critical.h"
|
||||
#include "kernel/Kernel.h"
|
||||
#include "Log.h"
|
||||
#include "Mutex.h"
|
||||
#include "Thread.h"
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "Check.h"
|
||||
#include "CoreDefines.h"
|
||||
#include "Kernel.h"
|
||||
#include "kernel/Kernel.h"
|
||||
#include "Log.h"
|
||||
|
||||
namespace tt {
|
||||
@ -197,7 +197,7 @@ bool Thread::join() {
|
||||
// If your thread exited, but your app stuck here: some other thread uses
|
||||
// all cpu time, which delays kernel from releasing task handle
|
||||
while (data.taskHandle) {
|
||||
delay_ms(10);
|
||||
kernel::delayMillis(10);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
#include <utility>
|
||||
#include "Check.h"
|
||||
#include "Kernel.h"
|
||||
#include "kernel/Kernel.h"
|
||||
#include "RtosCompat.h"
|
||||
|
||||
namespace tt {
|
||||
@ -16,7 +16,7 @@ static void timer_callback(TimerHandle_t hTimer) {
|
||||
}
|
||||
|
||||
Timer::Timer(Type type, Callback callback, std::shared_ptr<void> callbackContext) {
|
||||
tt_assert((kernel_is_irq() == 0U) && (callback != nullptr));
|
||||
tt_assert((kernel::isIrq() == 0U) && (callback != nullptr));
|
||||
|
||||
this->callback = callback;
|
||||
this->callbackContext = std::move(callbackContext);
|
||||
@ -33,12 +33,12 @@ Timer::Timer(Type type, Callback callback, std::shared_ptr<void> callbackContext
|
||||
}
|
||||
|
||||
Timer::~Timer() {
|
||||
tt_assert(!kernel_is_irq());
|
||||
tt_assert(!kernel::isIrq());
|
||||
tt_check(xTimerDelete(timerHandle, portMAX_DELAY) == pdPASS);
|
||||
}
|
||||
|
||||
TtStatus Timer::start(uint32_t ticks) {
|
||||
tt_assert(!kernel_is_irq());
|
||||
tt_assert(!kernel::isIrq());
|
||||
tt_assert(ticks < portMAX_DELAY);
|
||||
|
||||
if (xTimerChangePeriod(timerHandle, ticks, portMAX_DELAY) == pdPASS) {
|
||||
@ -49,7 +49,7 @@ TtStatus Timer::start(uint32_t ticks) {
|
||||
}
|
||||
|
||||
TtStatus Timer::restart(uint32_t ticks) {
|
||||
tt_assert(!kernel_is_irq());
|
||||
tt_assert(!kernel::isIrq());
|
||||
tt_assert(ticks < portMAX_DELAY);
|
||||
|
||||
if (xTimerChangePeriod(timerHandle, ticks, portMAX_DELAY) == pdPASS &&
|
||||
@ -61,24 +61,24 @@ TtStatus Timer::restart(uint32_t ticks) {
|
||||
}
|
||||
|
||||
TtStatus Timer::stop() {
|
||||
tt_assert(!kernel_is_irq());
|
||||
tt_assert(!kernel::isIrq());
|
||||
tt_check(xTimerStop(timerHandle, portMAX_DELAY) == pdPASS);
|
||||
return TtStatusOk;
|
||||
}
|
||||
|
||||
bool Timer::isRunning() {
|
||||
tt_assert(!kernel_is_irq());
|
||||
tt_assert(!kernel::isIrq());
|
||||
return xTimerIsTimerActive(timerHandle) == pdTRUE;
|
||||
}
|
||||
|
||||
uint32_t Timer::getExpireTime() {
|
||||
tt_assert(!kernel_is_irq());
|
||||
tt_assert(!kernel::isIrq());
|
||||
return (uint32_t)xTimerGetExpiryTime(timerHandle);
|
||||
}
|
||||
|
||||
void Timer::pendingCallback(PendingCallback callback, void* callbackContext, uint32_t arg) {
|
||||
BaseType_t ret = pdFAIL;
|
||||
if (kernel_is_irq()) {
|
||||
if (kernel::isIrq()) {
|
||||
ret = xTimerPendFunctionCallFromISR(callback, callbackContext, arg, nullptr);
|
||||
} else {
|
||||
ret = xTimerPendFunctionCall(callback, callbackContext, arg, TtWaitForever);
|
||||
@ -87,7 +87,7 @@ void Timer::pendingCallback(PendingCallback callback, void* callbackContext, uin
|
||||
}
|
||||
|
||||
void Timer::setThreadPriority(TimerThreadPriority priority) {
|
||||
tt_assert(!kernel_is_irq());
|
||||
tt_assert(!kernel::isIrq());
|
||||
|
||||
TaskHandle_t task_handle = xTimerGetTimerDaemonTaskHandle();
|
||||
tt_assert(task_handle); // Don't call this method before timer task start
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "Log.h"
|
||||
#include "mbedtls/aes.h"
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include "esp_cpu.h"
|
||||
@ -95,7 +96,7 @@ static void get_nvs_key(uint8_t key[32]) {
|
||||
* @param[out] out output buffer for result of XOR
|
||||
* @param[in] length data length (all buffers must be at least this size)
|
||||
*/
|
||||
static void xor_key(const uint8_t* in_left, const uint8_t* in_right, uint8_t* out, size_t length) {
|
||||
static void xorKey(const uint8_t* in_left, const uint8_t* in_right, uint8_t* out, size_t length) {
|
||||
for (int i = 0; i < length; ++i) {
|
||||
out[i] = in_left[i] ^ in_right[i];
|
||||
}
|
||||
@ -105,7 +106,7 @@ static void xor_key(const uint8_t* in_left, const uint8_t* in_right, uint8_t* ou
|
||||
* Combines a stored key and a hardware key into a single reliable key value.
|
||||
* @param[out] key the key output
|
||||
*/
|
||||
static void get_key(uint8_t key[32]) {
|
||||
static void getKey(uint8_t key[32]) {
|
||||
#if !defined(CONFIG_SECURE_BOOT) || !defined(CONFIG_SECURE_FLASH_ENC_ENABLED)
|
||||
TT_LOG_W(TAG, "Using tt_secure_* code with secure boot and/or flash encryption disabled.");
|
||||
TT_LOG_W(TAG, "An attacker with physical access to your ESP32 can decrypt your secure data.");
|
||||
@ -117,14 +118,14 @@ static void get_key(uint8_t key[32]) {
|
||||
#ifdef ESP_PLATFORM
|
||||
get_hardware_key(hardware_key);
|
||||
get_nvs_key(nvs_key);
|
||||
xor_key(hardware_key, nvs_key, key, 32);
|
||||
xorKey(hardware_key, nvs_key, key, 32);
|
||||
#else
|
||||
TT_LOG_W(TAG, "Using unsafe key for debugging purposes.");
|
||||
memset(key, 0, 32);
|
||||
#endif
|
||||
}
|
||||
|
||||
void get_iv_from_data(const void* data, size_t data_length, uint8_t iv[16]) {
|
||||
void getIv(const void* data, size_t data_length, uint8_t iv[16]) {
|
||||
memset((void*)iv, 0, 16);
|
||||
uint8_t* data_bytes = (uint8_t*)data;
|
||||
for (int i = 0; i < data_length; ++i) {
|
||||
@ -133,11 +134,7 @@ void get_iv_from_data(const void* data, size_t data_length, uint8_t iv[16]) {
|
||||
}
|
||||
}
|
||||
|
||||
void get_iv_from_string(const char* input, uint8_t iv[16]) {
|
||||
get_iv_from_data((const void*)input, strlen(input), iv);
|
||||
}
|
||||
|
||||
static int aes256_crypt_cbc(
|
||||
static int aes256CryptCbc(
|
||||
const uint8_t key[32],
|
||||
int mode,
|
||||
size_t length,
|
||||
@ -166,25 +163,25 @@ static int aes256_crypt_cbc(
|
||||
int encrypt(const uint8_t iv[16], uint8_t* in_data, uint8_t* out_data, size_t length) {
|
||||
tt_check(length % 16 == 0, "Length is not a multiple of 16 bytes (for AES 256");
|
||||
uint8_t key[32];
|
||||
get_key(key);
|
||||
getKey(key);
|
||||
|
||||
// TODO: Is this still needed after switching to regular AES functions?
|
||||
uint8_t iv_copy[16];
|
||||
memcpy(iv_copy, iv, sizeof(iv_copy));
|
||||
|
||||
return aes256_crypt_cbc(key, MBEDTLS_AES_ENCRYPT, length, iv_copy, in_data, out_data);
|
||||
return aes256CryptCbc(key, MBEDTLS_AES_ENCRYPT, length, iv_copy, in_data, out_data);
|
||||
}
|
||||
|
||||
int decrypt(const uint8_t iv[16], uint8_t* in_data, uint8_t* out_data, size_t length) {
|
||||
tt_check(length % 16 == 0, "Length is not a multiple of 16 bytes (for AES 256");
|
||||
uint8_t key[32];
|
||||
get_key(key);
|
||||
getKey(key);
|
||||
|
||||
// TODO: Is this still needed after switching to regular AES functions?
|
||||
uint8_t iv_copy[16];
|
||||
memcpy(iv_copy, iv, sizeof(iv_copy));
|
||||
|
||||
return aes256_crypt_cbc(key, MBEDTLS_AES_DECRYPT, length, iv_copy, in_data, out_data);
|
||||
return aes256CryptCbc(key, MBEDTLS_AES_DECRYPT, length, iv_copy, in_data, out_data);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace tt::crypt {
|
||||
|
||||
@ -29,14 +30,7 @@ namespace tt::crypt {
|
||||
* @param data_length input data length
|
||||
* @param iv output IV
|
||||
*/
|
||||
void get_iv_from_data(const void* data, size_t data_length, uint8_t iv[16]);
|
||||
|
||||
/**
|
||||
* @brief Fills the IV with zeros and then creates an IV based on the input data.
|
||||
* @param input input text
|
||||
* @param iv output IV
|
||||
*/
|
||||
void get_iv_from_string(const char* input, uint8_t iv[16]);
|
||||
void getIv(const void* data, size_t data_length, uint8_t iv[16]);
|
||||
|
||||
/**
|
||||
* @brief Encrypt data.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "Kernel.h"
|
||||
#include "kernel/Kernel.h"
|
||||
#include "Check.h"
|
||||
#include "CoreDefines.h"
|
||||
#include "CoreTypes.h"
|
||||
@ -10,18 +10,18 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace tt {
|
||||
namespace tt::kernel {
|
||||
|
||||
bool kernel_is_irq() {
|
||||
bool isIrq() {
|
||||
return TT_IS_IRQ_MODE();
|
||||
}
|
||||
|
||||
bool kernel_is_running() {
|
||||
bool isRunning() {
|
||||
return xTaskGetSchedulerState() != taskSCHEDULER_RUNNING;
|
||||
}
|
||||
|
||||
int32_t kernel_lock() {
|
||||
tt_assert(!kernel_is_irq());
|
||||
int32_t lock() {
|
||||
tt_assert(!isIrq());
|
||||
|
||||
int32_t lock;
|
||||
|
||||
@ -45,8 +45,8 @@ int32_t kernel_lock() {
|
||||
return (lock);
|
||||
}
|
||||
|
||||
int32_t kernel_unlock() {
|
||||
tt_assert(!kernel_is_irq());
|
||||
int32_t unlock() {
|
||||
tt_assert(!isIrq());
|
||||
|
||||
int32_t lock;
|
||||
|
||||
@ -75,8 +75,8 @@ int32_t kernel_unlock() {
|
||||
return (lock);
|
||||
}
|
||||
|
||||
int32_t kernel_restore_lock(int32_t lock) {
|
||||
tt_assert(!kernel_is_irq());
|
||||
int32_t restoreLock(int32_t lock) {
|
||||
tt_assert(!isIrq());
|
||||
|
||||
switch (xTaskGetSchedulerState()) {
|
||||
case taskSCHEDULER_SUSPENDED:
|
||||
@ -106,13 +106,13 @@ int32_t kernel_restore_lock(int32_t lock) {
|
||||
return (lock);
|
||||
}
|
||||
|
||||
uint32_t kernel_get_tick_frequency() {
|
||||
uint32_t getTickFrequency() {
|
||||
/* Return frequency in hertz */
|
||||
return (configTICK_RATE_HZ);
|
||||
}
|
||||
|
||||
void delay_ticks(TickType_t ticks) {
|
||||
tt_assert(!kernel_is_irq());
|
||||
void delayTicks(TickType_t ticks) {
|
||||
tt_assert(!isIrq());
|
||||
if (ticks == 0U) {
|
||||
taskYIELD();
|
||||
} else {
|
||||
@ -120,8 +120,8 @@ void delay_ticks(TickType_t ticks) {
|
||||
}
|
||||
}
|
||||
|
||||
TtStatus delay_until_tick(TickType_t tick) {
|
||||
tt_assert(!kernel_is_irq());
|
||||
TtStatus delayUntilTick(TickType_t tick) {
|
||||
tt_assert(!isIrq());
|
||||
|
||||
TickType_t tcnt, delay;
|
||||
TtStatus stat;
|
||||
@ -147,10 +147,10 @@ TtStatus delay_until_tick(TickType_t tick) {
|
||||
return (stat);
|
||||
}
|
||||
|
||||
TickType_t get_ticks() {
|
||||
TickType_t getTicks() {
|
||||
TickType_t ticks;
|
||||
|
||||
if (kernel_is_irq() != 0U) {
|
||||
if (isIrq() != 0U) {
|
||||
ticks = xTaskGetTickCountFromISR();
|
||||
} else {
|
||||
ticks = xTaskGetTickCount();
|
||||
@ -159,7 +159,7 @@ TickType_t get_ticks() {
|
||||
return ticks;
|
||||
}
|
||||
|
||||
TickType_t ms_to_ticks(uint32_t milliseconds) {
|
||||
TickType_t millisToTicks(uint32_t milliseconds) {
|
||||
#if configTICK_RATE_HZ == 1000
|
||||
return (TickType_t)milliseconds;
|
||||
#else
|
||||
@ -167,7 +167,7 @@ TickType_t ms_to_ticks(uint32_t milliseconds) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void delay_ms(uint32_t milliseconds) {
|
||||
void delayMillis(uint32_t milliseconds) {
|
||||
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
|
||||
if (milliseconds > 0 && milliseconds < portMAX_DELAY - 1) {
|
||||
milliseconds += 1;
|
||||
@ -175,14 +175,14 @@ void delay_ms(uint32_t milliseconds) {
|
||||
#if configTICK_RATE_HZ_RAW == 1000
|
||||
tt_delay_tick(milliseconds);
|
||||
#else
|
||||
delay_ticks(ms_to_ticks(milliseconds));
|
||||
delayTicks(kernel::millisToTicks(milliseconds));
|
||||
#endif
|
||||
} else if (milliseconds > 0) {
|
||||
delay_us(milliseconds * 1000);
|
||||
kernel::delayMicros(milliseconds * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void delay_us(uint32_t microseconds) {
|
||||
void delayMicros(uint32_t microseconds) {
|
||||
#ifdef ESP_PLATFORM
|
||||
ets_delay_us(microseconds);
|
||||
#else
|
||||
@ -190,7 +190,7 @@ void delay_us(uint32_t microseconds) {
|
||||
#endif
|
||||
}
|
||||
|
||||
Platform get_platform() {
|
||||
Platform getPlatform() {
|
||||
#ifdef ESP_PLATFORM
|
||||
return PlatformEsp;
|
||||
#else
|
||||
@ -8,7 +8,7 @@
|
||||
#include "FreeRTOS.h"
|
||||
#endif
|
||||
|
||||
namespace tt {
|
||||
namespace tt::kernel {
|
||||
|
||||
typedef enum {
|
||||
PlatformEsp,
|
||||
@ -30,13 +30,13 @@ typedef enum {
|
||||
*
|
||||
* @return true if CPU is in IRQ or kernel running and IRQ is masked
|
||||
*/
|
||||
bool kernel_is_irq();
|
||||
bool isIrq();
|
||||
|
||||
/** Check if kernel is running
|
||||
*
|
||||
* @return true if running, false otherwise
|
||||
*/
|
||||
bool kernel_is_running();
|
||||
bool isRunning();
|
||||
|
||||
/** Lock kernel, pause process scheduling
|
||||
*
|
||||
@ -44,7 +44,7 @@ bool kernel_is_running();
|
||||
*
|
||||
* @return previous lock state(0 - unlocked, 1 - locked)
|
||||
*/
|
||||
int32_t kernel_lock();
|
||||
int32_t lock();
|
||||
|
||||
/** Unlock kernel, resume process scheduling
|
||||
*
|
||||
@ -52,7 +52,7 @@ int32_t kernel_lock();
|
||||
*
|
||||
* @return previous lock state(0 - unlocked, 1 - locked)
|
||||
*/
|
||||
int32_t kernel_unlock();
|
||||
int32_t unlock();
|
||||
|
||||
/** Restore kernel lock state
|
||||
*
|
||||
@ -62,15 +62,15 @@ int32_t kernel_unlock();
|
||||
*
|
||||
* @return new lock state or error
|
||||
*/
|
||||
int32_t kernel_restore_lock(int32_t lock);
|
||||
int32_t restoreLock(int32_t lock);
|
||||
|
||||
/** Get kernel systick frequency
|
||||
*
|
||||
* @return systick counts per second
|
||||
*/
|
||||
uint32_t kernel_get_tick_frequency();
|
||||
uint32_t getTickFrequency();
|
||||
|
||||
TickType_t get_ticks();
|
||||
TickType_t getTicks();
|
||||
|
||||
/** Delay execution
|
||||
*
|
||||
@ -80,7 +80,7 @@ TickType_t get_ticks();
|
||||
*
|
||||
* @param[in] ticks The ticks count to pause
|
||||
*/
|
||||
void delay_ticks(TickType_t ticks);
|
||||
void delayTicks(TickType_t ticks);
|
||||
|
||||
/** Delay until tick
|
||||
*
|
||||
@ -90,14 +90,14 @@ void delay_ticks(TickType_t ticks);
|
||||
*
|
||||
* @return The status.
|
||||
*/
|
||||
TtStatus delay_until_tick(uint32_t tick);
|
||||
TtStatus delayUntilTick(uint32_t tick);
|
||||
|
||||
/** Convert milliseconds to ticks
|
||||
*
|
||||
* @param[in] milliseconds time in milliseconds
|
||||
* @param[in] milliSeconds time in milliseconds
|
||||
* @return time in ticks
|
||||
*/
|
||||
TickType_t ms_to_ticks(uint32_t milliseconds);
|
||||
TickType_t millisToTicks(uint32_t milliSeconds);
|
||||
|
||||
/** Delay in milliseconds
|
||||
*
|
||||
@ -108,18 +108,18 @@ TickType_t ms_to_ticks(uint32_t milliseconds);
|
||||
*
|
||||
* @warning Cannot be used from ISR
|
||||
*
|
||||
* @param[in] milliseconds milliseconds to wait
|
||||
* @param[in] milliSeconds milliseconds to wait
|
||||
*/
|
||||
void delay_ms(uint32_t milliseconds);
|
||||
void delayMillis(uint32_t milliSeconds);
|
||||
|
||||
/** Delay in microseconds
|
||||
*
|
||||
* Implemented using Cortex DWT counter. Blocking and non aliased.
|
||||
*
|
||||
* @param[in] microseconds microseconds to wait
|
||||
* @param[in] microSeconds microseconds to wait
|
||||
*/
|
||||
void delay_us(uint32_t microseconds);
|
||||
void delayMicros(uint32_t microSeconds);
|
||||
|
||||
Platform get_platform();
|
||||
Platform getPlatform();
|
||||
|
||||
} // namespace
|
||||
@ -9,18 +9,18 @@ static portMUX_TYPE critical_mutex;
|
||||
#define TT_ENTER_CRITICAL() taskENTER_CRITICAL()
|
||||
#endif
|
||||
|
||||
namespace tt::critical {
|
||||
namespace tt::kernel::critical {
|
||||
|
||||
TtCriticalInfo enter() {
|
||||
TtCriticalInfo info;
|
||||
TtCriticalInfo info = {
|
||||
.isrm = 0,
|
||||
.fromIsr = TT_IS_ISR(),
|
||||
.kernelRunning = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING)
|
||||
};
|
||||
|
||||
info.isrm = 0;
|
||||
info.from_isr = TT_IS_ISR();
|
||||
info.kernel_running = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING);
|
||||
|
||||
if (info.from_isr) {
|
||||
if (info.fromIsr) {
|
||||
info.isrm = taskENTER_CRITICAL_FROM_ISR();
|
||||
} else if (info.kernel_running) {
|
||||
} else if (info.kernelRunning) {
|
||||
TT_ENTER_CRITICAL();
|
||||
} else {
|
||||
portDISABLE_INTERRUPTS();
|
||||
@ -30,9 +30,9 @@ TtCriticalInfo enter() {
|
||||
}
|
||||
|
||||
void exit(TtCriticalInfo info) {
|
||||
if (info.from_isr) {
|
||||
if (info.fromIsr) {
|
||||
taskEXIT_CRITICAL_FROM_ISR(info.isrm);
|
||||
} else if (info.kernel_running) {
|
||||
} else if (info.kernelRunning) {
|
||||
TT_ENTER_CRITICAL();
|
||||
} else {
|
||||
portENABLE_INTERRUPTS();
|
||||
@ -10,12 +10,12 @@
|
||||
#define TT_CRITICAL_EXIT() __tt_critical_exit(__tt_critical_info);
|
||||
#endif
|
||||
|
||||
namespace tt::critical {
|
||||
namespace tt::kernel::critical {
|
||||
|
||||
typedef struct {
|
||||
uint32_t isrm;
|
||||
bool from_isr;
|
||||
bool kernel_running;
|
||||
bool fromIsr;
|
||||
bool kernelRunning;
|
||||
} TtCriticalInfo;
|
||||
|
||||
TtCriticalInfo enter();
|
||||
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
|
||||
@ -8,7 +8,7 @@ class ServiceInstance : public ServiceContext {
|
||||
|
||||
private:
|
||||
|
||||
Mutex mutex = Mutex(MutexTypeNormal);
|
||||
Mutex mutex = Mutex(Mutex::TypeNormal);
|
||||
const service::ServiceManifest& manifest;
|
||||
std::shared_ptr<void> data = nullptr;
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "TactilityCore.h"
|
||||
#include "hal/Configuration.h"
|
||||
#include "TactilityHeadlessConfig.h"
|
||||
#include "Dispatcher.h"
|
||||
|
||||
@ -3,10 +3,8 @@
|
||||
/**
|
||||
* This code is based on i2c_manager from https://github.com/ropg/i2c_manager/blob/master/i2c_manager/i2c_manager.c (original has MIT license)
|
||||
*/
|
||||
#include <Kernel.h>
|
||||
#include "TactilityCore.h"
|
||||
#include "I2c.h"
|
||||
#include "Log.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
namespace tt::hal::i2c {
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ namespace tt::hal::sdcard {
|
||||
|
||||
#define TAG "sdcard"
|
||||
|
||||
static Mutex mutex(MutexTypeRecursive);
|
||||
static Mutex mutex(Mutex::TypeRecursive);
|
||||
|
||||
typedef struct {
|
||||
const SdCard* sdcard;
|
||||
|
||||
@ -17,8 +17,8 @@ typedef std::unordered_map<std::string, ServiceInstance*> ServiceInstanceMap;
|
||||
static ManifestMap service_manifest_map;
|
||||
static ServiceInstanceMap service_instance_map;
|
||||
|
||||
static Mutex manifest_mutex(MutexTypeNormal);
|
||||
static Mutex instance_mutex(MutexTypeNormal);
|
||||
static Mutex manifest_mutex(Mutex::TypeNormal);
|
||||
static Mutex instance_mutex(Mutex::TypeNormal);
|
||||
|
||||
void addService(const ServiceManifest* manifest) {
|
||||
TT_LOG_I(TAG, "Adding %s", manifest->id.c_str());
|
||||
|
||||
@ -42,7 +42,7 @@ static void onUpdate(std::shared_ptr<void> context) {
|
||||
|
||||
if (new_state == hal::sdcard::StateError) {
|
||||
TT_LOG_W(TAG, "Sdcard error - unmounting. Did you eject the card in an unsafe manner?");
|
||||
hal::sdcard::unmount(ms_to_ticks(1000));
|
||||
hal::sdcard::unmount(kernel::millisToTicks(1000));
|
||||
}
|
||||
|
||||
if (new_state != data->lastState) {
|
||||
|
||||
@ -2,15 +2,10 @@
|
||||
|
||||
#include "Wifi.h"
|
||||
|
||||
#include "MessageQueue.h"
|
||||
#include "Mutex.h"
|
||||
#include "Check.h"
|
||||
#include "Log.h"
|
||||
#include "TactilityHeadless.h"
|
||||
#include "Timer.h"
|
||||
#include "service/ServiceContext.h"
|
||||
#include "WifiSettings.h"
|
||||
#include "TactilityCore.h"
|
||||
#include "TactilityHeadless.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
||||
@ -47,8 +42,8 @@ private:
|
||||
public:
|
||||
|
||||
/** @brief Locking mechanism for modifying the Wifi instance */
|
||||
Mutex radioMutex = Mutex(MutexTypeRecursive);
|
||||
Mutex dataMutex = Mutex(MutexTypeRecursive);
|
||||
Mutex radioMutex = Mutex(Mutex::TypeRecursive);
|
||||
Mutex dataMutex = Mutex(Mutex::TypeRecursive);
|
||||
std::unique_ptr<Timer> autoConnectTimer;
|
||||
/** @brief The public event bus */
|
||||
std::shared_ptr<PubSub> pubsub = std::make_shared<PubSub>();
|
||||
@ -664,7 +659,7 @@ static void dispatchScan(std::shared_ptr<void> context) {
|
||||
}
|
||||
|
||||
// TODO: Thread safety
|
||||
wifi->last_scan_time = tt::get_ticks();
|
||||
wifi->last_scan_time = tt::kernel::getTicks();
|
||||
|
||||
if (esp_wifi_scan_start(nullptr, false) != ESP_OK) {
|
||||
TT_LOG_I(TAG, "Can't start scan");
|
||||
@ -872,7 +867,7 @@ static bool shouldScanForAutoConnect(std::shared_ptr<Wifi> wifi) {
|
||||
return false;
|
||||
}
|
||||
|
||||
TickType_t current_time = tt::get_ticks();
|
||||
TickType_t current_time = tt::kernel::getTicks();
|
||||
bool scan_time_has_looped = (current_time < wifi->last_scan_time);
|
||||
bool no_recent_scan = (current_time - wifi->last_scan_time) > (AUTO_SCAN_INTERVAL / portTICK_PERIOD_MS);
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ static void publish_event_simple(Wifi* wifi, WifiEventType type) {
|
||||
|
||||
static Wifi* wifi_alloc() {
|
||||
auto* instance = static_cast<Wifi*>(malloc(sizeof(Wifi)));
|
||||
instance->mutex = tt_mutex_alloc(MutexTypeRecursive);
|
||||
instance->mutex = tt_mutex_alloc(Mutex::TypeRecursive);
|
||||
instance->pubsub = std::make_shared<PubSub>();
|
||||
instance->scan_active = false;
|
||||
instance->radio_state = WIFI_RADIO_CONNECTION_ACTIVE;
|
||||
|
||||
@ -54,7 +54,7 @@ bool load(const char* ssid, WifiApSettings* settings) {
|
||||
result = nvs_get_blob(handle, ssid, &encrypted_settings, &length);
|
||||
|
||||
uint8_t iv[16];
|
||||
crypt::get_iv_from_string(ssid, iv);
|
||||
crypt::getIv(ssid, strlen(ssid), iv);
|
||||
int decrypt_result = crypt::decrypt(
|
||||
iv,
|
||||
(uint8_t*)encrypted_settings.password,
|
||||
@ -97,7 +97,7 @@ bool save(const WifiApSettings* settings) {
|
||||
encrypted_settings.password[TT_WIFI_CREDENTIALS_PASSWORD_LIMIT] = 0;
|
||||
|
||||
uint8_t iv[16];
|
||||
crypt::get_iv_from_data(settings->ssid, strlen(settings->ssid), iv);
|
||||
crypt::getIv(settings->ssid, strlen(settings->ssid), iv);
|
||||
int encrypt_result = crypt::encrypt(
|
||||
iv,
|
||||
(uint8_t*)settings->password,
|
||||
|
||||
@ -14,7 +14,7 @@ void increment_callback(TT_UNUSED std::shared_ptr<void> context) {
|
||||
void value_checker(std::shared_ptr<void> context) {
|
||||
auto value = std::static_pointer_cast<uint32_t>(context);
|
||||
if (*value != value_chacker_expected) {
|
||||
tt_crash_implementation();
|
||||
tt_crash("Test error");
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ TEST_CASE("dispatcher should not call callback if consume isn't called") {
|
||||
|
||||
auto context = std::make_shared<uint32_t>();
|
||||
dispatcher.dispatch(&increment_callback, std::move(context));
|
||||
delay_ticks(10);
|
||||
kernel::delayTicks(10);
|
||||
|
||||
CHECK_EQ(counter, 0);
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ static int thread_with_mutex_parameter(void* parameter) {
|
||||
}
|
||||
|
||||
TEST_CASE("a mutex can block a thread") {
|
||||
auto* mutex = tt_mutex_alloc(MutexTypeNormal);
|
||||
auto* mutex = tt_mutex_alloc(Mutex::TypeNormal);
|
||||
tt_mutex_acquire(mutex, TtWaitForever);
|
||||
|
||||
Thread* thread = new Thread(
|
||||
@ -22,12 +22,12 @@ TEST_CASE("a mutex can block a thread") {
|
||||
);
|
||||
thread->start();
|
||||
|
||||
delay_ms(5);
|
||||
kernel::delayMillis(5);
|
||||
CHECK_EQ(thread->getState(), Thread::StateRunning);
|
||||
|
||||
tt_mutex_release(mutex);
|
||||
|
||||
delay_ms(5);
|
||||
kernel::delayMillis(5);
|
||||
CHECK_EQ(thread->getState(), Thread::StateStopped);
|
||||
|
||||
thread->join();
|
||||
|
||||
@ -1,66 +1,63 @@
|
||||
#include "doctest.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace tt;
|
||||
using namespace std;
|
||||
|
||||
// region string_split
|
||||
// region split
|
||||
|
||||
TEST_CASE("splitting an empty string results in an empty vector") {
|
||||
auto result = string_split("", ".");
|
||||
auto result = tt::string::split("", ".");
|
||||
CHECK_EQ(result.empty(), true);
|
||||
}
|
||||
|
||||
TEST_CASE("splitting a string with a single token results in a vector with that token") {
|
||||
auto result = string_split("token", ".");
|
||||
auto result = tt::string::split("token", ".");
|
||||
CHECK_EQ(result.size(), 1);
|
||||
CHECK_EQ(result.front(), "token");
|
||||
}
|
||||
|
||||
TEST_CASE("splitting a string with multiple tokens results in a vector with those tokens") {
|
||||
auto result = string_split("token1;token2;token3;", ";");
|
||||
auto result = tt::string::split("token1;token2;token3;", ";");
|
||||
CHECK_EQ(result.size(), 3);
|
||||
CHECK_EQ(result[0], "token1");
|
||||
CHECK_EQ(result[1], "token2");
|
||||
CHECK_EQ(result[2], "token3");
|
||||
}
|
||||
|
||||
// endregion string_split
|
||||
// endregion split
|
||||
|
||||
// region string_join
|
||||
// region join
|
||||
|
||||
TEST_CASE("joining an empty vector results in an empty string") {
|
||||
vector<string> tokens = {};
|
||||
auto result = string_join(tokens, ".");
|
||||
std::vector<std::string> tokens = {};
|
||||
auto result = tt::string::join(tokens, ".");
|
||||
CHECK_EQ(result, "");
|
||||
}
|
||||
|
||||
TEST_CASE("joining a single token results in a string with that value") {
|
||||
vector<string> tokens = {
|
||||
std::vector<std::string> tokens = {
|
||||
"token"
|
||||
};
|
||||
auto result = string_join(tokens, ".");
|
||||
auto result = tt::string::join(tokens, ".");
|
||||
CHECK_EQ(result, "token");
|
||||
}
|
||||
|
||||
TEST_CASE("joining multiple tokens results in a string with all the tokens and the delimiter") {
|
||||
vector<string> tokens = {
|
||||
std::vector<std::string> tokens = {
|
||||
"token1",
|
||||
"token2",
|
||||
"token3",
|
||||
};
|
||||
auto result = string_join(tokens, ".");
|
||||
auto result = tt::string::join(tokens, ".");
|
||||
CHECK_EQ(result, "token1.token2.token3");
|
||||
}
|
||||
|
||||
TEST_CASE("joining with empty tokens leads to an extra delimiter") {
|
||||
vector<string> tokens = {
|
||||
std::vector<std::string> tokens = {
|
||||
"token1",
|
||||
"",
|
||||
"token2",
|
||||
};
|
||||
auto result = string_join(tokens, ".");
|
||||
auto result = tt::string::join(tokens, ".");
|
||||
CHECK_EQ(result, "token1..token2");
|
||||
}
|
||||
|
||||
// endregion string_join
|
||||
// endregion join
|
||||
|
||||
@ -7,7 +7,7 @@ using namespace tt;
|
||||
static int interruptable_thread(void* parameter) {
|
||||
bool* interrupted = (bool*)parameter;
|
||||
while (!*interrupted) {
|
||||
delay_ms(5);
|
||||
kernel::delayMillis(5);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ TEST_CASE("a timer passes the context correctly") {
|
||||
auto foo = std::make_shared<int>(1);
|
||||
auto* timer = new Timer(Timer::TypeOnce, &timer_callback_with_context, foo);
|
||||
timer->start(1);
|
||||
delay_ticks(10);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
delete timer;
|
||||
|
||||
@ -31,10 +31,10 @@ TEST_CASE("TimerTypePeriodic timers can be stopped and restarted") {
|
||||
auto counter = std::make_shared<int>(0);
|
||||
auto* timer = new Timer(Timer::TypePeriodic, &timer_callback_with_counter, counter);
|
||||
timer->start(1);
|
||||
delay_ticks(10);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
timer->start(1);
|
||||
delay_ticks(10);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
delete timer;
|
||||
|
||||
@ -46,7 +46,7 @@ TEST_CASE("TimerTypePeriodic calls the callback periodically") {
|
||||
int ticks_to_run = 10;
|
||||
auto* timer = new Timer(Timer::TypePeriodic, &timer_callback_with_counter, counter);
|
||||
timer->start(1);
|
||||
delay_ticks(ticks_to_run);
|
||||
kernel::delayTicks(ticks_to_run);
|
||||
timer->stop();
|
||||
delete timer;
|
||||
|
||||
@ -57,10 +57,10 @@ TEST_CASE("restarting TimerTypeOnce timers calls the callback again") {
|
||||
auto counter = std::make_shared<int>(0);
|
||||
auto* timer = new Timer(Timer::TypeOnce, &timer_callback_with_counter, counter);
|
||||
timer->start(1);
|
||||
delay_ticks(10);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
timer->start(1);
|
||||
delay_ticks(10);
|
||||
kernel::delayTicks(10);
|
||||
timer->stop();
|
||||
delete timer;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user