From 069416eee585bc1aa9f4be77cc6602b834a318b8 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sat, 13 Jan 2024 22:12:40 +0100 Subject: [PATCH] Rename furi to tactility-core (#10) * renamed module * renamed code * more renames * cleanup --- CMakeLists.txt | 2 +- README.md | 4 +- boards/lilygo_tdeck/bootstrap.c | 2 +- components/furi/README.md | 7 - components/furi/src/api_lock.h | 19 - components/furi/src/app_manifest_registry.h | 23 - components/furi/src/bundle.h | 34 - components/furi/src/check.c | 96 --- components/furi/src/context.h | 5 - components/furi/src/critical.h | 22 - components/furi/src/event_flag.h | 71 -- components/furi/src/furi_config.h | 3 - components/furi/src/furi_core_defines.h | 40 -- components/furi/src/furi_core_types.h | 44 -- components/furi/src/furi_hal_console.c | 81 --- components/furi/src/furi_hal_console.h | 35 - components/furi/src/furi_string.c | 304 -------- components/furi/src/message_queue.h | 95 --- components/furi/src/mutex.h | 62 -- components/furi/src/pubsub.c | 94 --- components/furi/src/pubsub.h | 68 -- components/furi/src/semaphore.h | 54 -- components/furi/src/service.c | 63 -- components/furi/src/service.h | 18 - components/furi/src/service_registry.h | 25 - components/furi/src/thread.c | 665 ------------------ components/furi/src/thread.h | 339 --------- components/furi/src/timer.h | 106 --- .../{furi => tactility-core}/CMakeLists.txt | 0 .../{furi => tactility-core}/LICENSE.md | 0 components/tactility-core/README.md | 8 + components/tactility-core/src/api_lock.h | 20 + components/{furi => tactility-core}/src/app.c | 68 +- components/{furi => tactility-core}/src/app.h | 20 +- .../{furi => tactility-core}/src/app_i.h | 3 +- .../src/app_manifest.h | 0 .../src/app_manifest_registry.c | 32 +- .../src/app_manifest_registry.h | 20 + .../{furi => tactility-core}/src/bundle.c | 38 +- components/tactility-core/src/bundle.h | 34 + components/tactility-core/src/check.c | 38 + .../{furi => tactility-core}/src/check.h | 66 +- .../src/furi.c => tactility-core/src/core.c} | 18 +- .../src/furi.h => tactility-core/src/core.h} | 6 +- components/tactility-core/src/core_defines.h | 42 ++ .../src/core_extra_defines.h} | 20 +- components/tactility-core/src/core_types.h | 44 ++ .../{furi => tactility-core}/src/critical.c | 10 +- components/tactility-core/src/critical.h | 22 + .../{furi => tactility-core}/src/event_flag.c | 68 +- components/tactility-core/src/event_flag.h | 67 ++ .../{furi => tactility-core}/src/kernel.c | 68 +- .../{furi => tactility-core}/src/kernel.h | 30 +- components/{furi => tactility-core}/src/log.h | 10 +- .../{furi => tactility-core}/src/m_cstr_dup.h | 0 .../src/message_queue.c | 75 +- components/tactility-core/src/message_queue.h | 94 +++ .../{furi => tactility-core}/src/mutex.c | 68 +- components/tactility-core/src/mutex.h | 62 ++ components/tactility-core/src/pubsub.c | 93 +++ components/tactility-core/src/pubsub.h | 68 ++ .../{furi => tactility-core}/src/semaphore.c | 56 +- components/tactility-core/src/semaphore.h | 54 ++ components/tactility-core/src/service.c | 62 ++ components/tactility-core/src/service.h | 18 + .../{furi => tactility-core}/src/service_i.h | 7 +- .../src/service_manifest.h | 1 - .../src/service_registry.c | 70 +- .../tactility-core/src/service_registry.h | 25 + .../src/stream_buffer.c | 44 +- .../src/stream_buffer.h | 38 +- .../src/tactility_core.h} | 8 +- .../src/tactility_core_config.h | 3 + components/tactility-core/src/thread.c | 599 ++++++++++++++++ components/tactility-core/src/thread.h | 334 +++++++++ .../{furi => tactility-core}/src/timer.c | 97 +-- components/tactility-core/src/timer.h | 106 +++ components/tactility-core/src/tt_string.c | 304 ++++++++ .../src/tt_string.h} | 278 ++++---- components/tactility/CMakeLists.txt | 2 +- .../tactility/src/apps/desktop/desktop.c | 6 +- .../src/apps/system/system_info/system_info.c | 6 +- .../apps/system/wifi_connect/wifi_connect.c | 38 +- .../apps/system/wifi_connect/wifi_connect.h | 4 +- .../system/wifi_connect/wifi_connect_view.c | 6 +- .../src/apps/system/wifi_manage/wifi_manage.c | 44 +- .../src/apps/system/wifi_manage/wifi_manage.h | 4 +- .../system/wifi_manage/wifi_manage_view.c | 2 +- components/tactility/src/devices.c | 2 +- components/tactility/src/display.c | 14 +- components/tactility/src/graphics.c | 6 +- components/tactility/src/partitions.c | 10 +- components/tactility/src/services/gui/gui.c | 62 +- .../tactility/src/services/gui/gui_draw.c | 12 +- components/tactility/src/services/gui/gui_i.h | 4 +- .../tactility/src/services/gui/gui_input.c | 81 --- .../tactility/src/services/gui/view_port.c | 8 +- .../tactility/src/services/gui/view_port.h | 1 - .../tactility/src/services/loader/loader.c | 106 +-- .../tactility/src/services/loader/loader.h | 8 +- .../tactility/src/services/loader/loader_i.h | 10 +- components/tactility/src/services/wifi/wifi.c | 148 ++-- components/tactility/src/services/wifi/wifi.h | 4 +- components/tactility/src/tactility.c | 46 +- components/tactility/src/tactility.h | 6 +- components/tactility/src/touch.c | 2 +- 106 files changed, 2992 insertions(+), 3347 deletions(-) delete mode 100644 components/furi/README.md delete mode 100644 components/furi/src/api_lock.h delete mode 100644 components/furi/src/app_manifest_registry.h delete mode 100644 components/furi/src/bundle.h delete mode 100644 components/furi/src/check.c delete mode 100644 components/furi/src/context.h delete mode 100644 components/furi/src/critical.h delete mode 100644 components/furi/src/event_flag.h delete mode 100644 components/furi/src/furi_config.h delete mode 100644 components/furi/src/furi_core_defines.h delete mode 100644 components/furi/src/furi_core_types.h delete mode 100644 components/furi/src/furi_hal_console.c delete mode 100644 components/furi/src/furi_hal_console.h delete mode 100644 components/furi/src/furi_string.c delete mode 100644 components/furi/src/message_queue.h delete mode 100644 components/furi/src/mutex.h delete mode 100644 components/furi/src/pubsub.c delete mode 100644 components/furi/src/pubsub.h delete mode 100644 components/furi/src/semaphore.h delete mode 100644 components/furi/src/service.c delete mode 100644 components/furi/src/service.h delete mode 100644 components/furi/src/service_registry.h delete mode 100644 components/furi/src/thread.c delete mode 100644 components/furi/src/thread.h delete mode 100644 components/furi/src/timer.h rename components/{furi => tactility-core}/CMakeLists.txt (100%) rename components/{furi => tactility-core}/LICENSE.md (100%) create mode 100644 components/tactility-core/README.md create mode 100644 components/tactility-core/src/api_lock.h rename components/{furi => tactility-core}/src/app.c (58%) rename components/{furi => tactility-core}/src/app.h (60%) rename components/{furi => tactility-core}/src/app_i.h (95%) rename components/{furi => tactility-core}/src/app_manifest.h (100%) rename components/{furi => tactility-core}/src/app_manifest_registry.c (71%) create mode 100644 components/tactility-core/src/app_manifest_registry.h rename components/{furi => tactility-core}/src/bundle.c (82%) create mode 100644 components/tactility-core/src/bundle.h create mode 100644 components/tactility-core/src/check.c rename components/{furi => tactility-core}/src/check.h (50%) rename components/{furi/src/furi.c => tactility-core/src/core.c} (58%) rename components/{furi/src/furi.h => tactility-core/src/core.h} (81%) create mode 100644 components/tactility-core/src/core_defines.h rename components/{furi/src/furi_extra_defines.h => tactility-core/src/core_extra_defines.h} (85%) create mode 100644 components/tactility-core/src/core_types.h rename components/{furi => tactility-core}/src/critical.c (76%) create mode 100644 components/tactility-core/src/critical.h rename components/{furi => tactility-core}/src/event_flag.c (62%) create mode 100644 components/tactility-core/src/event_flag.h rename components/{furi => tactility-core}/src/kernel.c (68%) rename components/{furi => tactility-core}/src/kernel.h (82%) rename components/{furi => tactility-core}/src/log.h (61%) rename components/{furi => tactility-core}/src/m_cstr_dup.h (100%) rename components/{furi => tactility-core}/src/message_queue.c (63%) create mode 100644 components/tactility-core/src/message_queue.h rename components/{furi => tactility-core}/src/mutex.c (56%) create mode 100644 components/tactility-core/src/mutex.h create mode 100644 components/tactility-core/src/pubsub.c create mode 100644 components/tactility-core/src/pubsub.h rename components/{furi => tactility-core}/src/semaphore.c (64%) create mode 100644 components/tactility-core/src/semaphore.h create mode 100644 components/tactility-core/src/service.c create mode 100644 components/tactility-core/src/service.h rename components/{furi => tactility-core}/src/service_i.h (52%) rename components/{furi => tactility-core}/src/service_manifest.h (96%) rename components/{furi => tactility-core}/src/service_registry.c (66%) create mode 100644 components/tactility-core/src/service_registry.h rename components/{furi => tactility-core}/src/stream_buffer.c (56%) rename components/{furi => tactility-core}/src/stream_buffer.h (81%) rename components/{furi/src/furi_core.h => tactility-core/src/tactility_core.h} (53%) create mode 100644 components/tactility-core/src/tactility_core_config.h create mode 100644 components/tactility-core/src/thread.c create mode 100644 components/tactility-core/src/thread.h rename components/{furi => tactility-core}/src/timer.c (55%) create mode 100644 components/tactility-core/src/timer.h create mode 100644 components/tactility-core/src/tt_string.c rename components/{furi/src/furi_string.h => tactility-core/src/tt_string.h} (62%) delete mode 100644 components/tactility/src/services/gui/gui_input.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 22de6cfb..be3675cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16) -add_definitions(-DFURI_DEBUG) +add_definitions(-DTT_DEBUG) set(COMPONENTS main) set(EXTRA_COMPONENT_DIRS "boards" "components") diff --git a/README.md b/README.md index 77cb6fa8..c3105098 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,8 @@ Other configurations can be supported, but they require you to set up the driver Until there is proper documentation, here are some pointers: - Sample application: [bootstrap](main/src/main.c) and [app](main/src/hello_world/hello_world.c) -- [Tactility](./components/tactility/): the main platform with default services and apps -- [Furi](./components/furi/): the core platform code, based on Flipper Zero firmware +- [Tactility](./components/tactility): The main platform with default services and apps. +- [Tactility Core](./components/tactility-core): The core platform code. ## Building Firmware diff --git a/boards/lilygo_tdeck/bootstrap.c b/boards/lilygo_tdeck/bootstrap.c index fc4964ba..ee0562b6 100644 --- a/boards/lilygo_tdeck/bootstrap.c +++ b/boards/lilygo_tdeck/bootstrap.c @@ -22,5 +22,5 @@ void lilygo_tdeck_bootstrap() { tdeck_power_on(); // Give keyboard's ESP time to boot // It uses I2C and seems to interfere with the touch driver - furi_delay_ms(500); + tt_delay_ms(500); } diff --git a/components/furi/README.md b/components/furi/README.md deleted file mode 100644 index 62cc957c..00000000 --- a/components/furi/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## Description - -This code is derived from the "Furi" code in the [Flipper Zero firmware](https://github.com/flipperdevices/flipperzero-firmware/). - -## License - -[GNU General Public License Version 3](LICENSE.md) diff --git a/components/furi/src/api_lock.h b/components/furi/src/api_lock.h deleted file mode 100644 index 079a1411..00000000 --- a/components/furi/src/api_lock.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "furi.h" - -typedef FuriEventFlag* FuriApiLock; - -#define API_LOCK_EVENT (1U << 0) - -#define api_lock_alloc_locked() furi_event_flag_alloc() - -#define api_lock_wait_unlock(_lock) \ - furi_event_flag_wait(_lock, API_LOCK_EVENT, FuriFlagWaitAny, FuriWaitForever) - -#define api_lock_free(_lock) furi_event_flag_free(_lock) - -#define api_lock_unlock(_lock) furi_event_flag_set(_lock, API_LOCK_EVENT) - -#define api_lock_wait_unlock_and_free(_lock) \ - api_lock_wait_unlock(_lock); \ - api_lock_free(_lock); diff --git a/components/furi/src/app_manifest_registry.h b/components/furi/src/app_manifest_registry.h deleted file mode 100644 index 701437f1..00000000 --- a/components/furi/src/app_manifest_registry.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "app_manifest.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const AppManifest* const INTERNAL_APP_MANIFESTS[]; -extern const size_t INTERNAL_APP_COUNT; - -typedef void (*AppManifestCallback)(const AppManifest*, void* context); - -void app_manifest_registry_init(); -void app_manifest_registry_add(const AppManifest _Nonnull* manifest); -void app_manifest_registry_remove(const AppManifest _Nonnull* manifest); -const AppManifest _Nullable* app_manifest_registry_find_by_id(const char* id); -void app_manifest_registry_for_each(AppManifestCallback callback, void* _Nullable context); -void app_manifest_registry_for_each_of_type(AppType type, void* _Nullable context, AppManifestCallback callback); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/bundle.h b/components/furi/src/bundle.h deleted file mode 100644 index b33c2c35..00000000 --- a/components/furi/src/bundle.h +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @brief key-value storage for general purpose. - * Maps strings on a fixed set of data types. - */ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* Bundle; - -Bundle bundle_alloc(); -Bundle bundle_alloc_copy(Bundle source); -void bundle_free(Bundle bundle); - -bool bundle_get_bool(Bundle bundle, const char* key); -int bundle_get_int(Bundle bundle, const char* key); -const char* bundle_get_string(Bundle bundle, const char* key); - -bool bundle_opt_bool(Bundle bundle, const char* key, bool* out); -bool bundle_opt_int(Bundle bundle, const char* key, int* out); -bool bundle_opt_string(Bundle bundle, const char* key, char** out); - -void bundle_put_bool(Bundle bundle, const char* key, bool value); -void bundle_put_int(Bundle bundle, const char* key, int value); -void bundle_put_string(Bundle bundle, const char* key, const char* value); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/check.c b/components/furi/src/check.c deleted file mode 100644 index 74093531..00000000 --- a/components/furi/src/check.c +++ /dev/null @@ -1,96 +0,0 @@ -#include "check.h" -#include "furi_core_defines.h" - -#include "furi_hal_console.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include - -static void __furi_put_uint32_as_text(uint32_t data) { - char tmp_str[] = "-2147483648"; - itoa(data, tmp_str, 10); - furi_hal_console_puts(tmp_str); -} - -static void __furi_print_stack_info() { - furi_hal_console_puts("\r\n\tstack watermark: "); - __furi_put_uint32_as_text(uxTaskGetStackHighWaterMark(NULL) * 4); -} - -static void __furi_print_heap_info() { - furi_hal_console_puts("\r\n\theap total: "); - __furi_put_uint32_as_text(heap_caps_get_total_size(MALLOC_CAP_DEFAULT)); - furi_hal_console_puts("\r\n\theap free: "); - __furi_put_uint32_as_text(heap_caps_get_free_size(MALLOC_CAP_DEFAULT)); - furi_hal_console_puts("\r\n\theap min free: "); - __furi_put_uint32_as_text(heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT)); -} - -static void __furi_print_name(bool isr) { - if (isr) { - furi_hal_console_puts("[ISR "); - __furi_put_uint32_as_text(__get_IPSR()); - furi_hal_console_puts("] "); - } else { - const char* name = pcTaskGetName(NULL); - if (name == NULL) { - furi_hal_console_puts("[main] "); - } else { - furi_hal_console_puts("["); - furi_hal_console_puts(name); - furi_hal_console_puts("] "); - } - } -} - -FURI_NORETURN void __furi_crash_implementation() { - __disable_irq(); - // GET_MESSAGE_AND_STORE_REGISTERS(); - - bool isr = FURI_IS_IRQ_MODE(); - - furi_hal_console_puts("\r\n\033[0;31m[CRASH]"); - __furi_print_name(isr); - - if (!isr) { - __furi_print_stack_info(); - } - __furi_print_heap_info(); - - // Check if debug enabled by DAP - // https://developer.arm.com/documentation/ddi0403/d/Debug-Architecture/ARMv7-M-Debug/Debug-register-support-in-the-SCS/Debug-Halting-Control-and-Status-Register--DHCSR?lang=en -// bool debug = CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk; -#ifdef FURI_NDEBUG - if (debug) { -#endif - furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); - furi_hal_console_puts("\033[0m\r\n"); - // furi_hal_debug_enable(); - - esp_system_abort("crash"); -#ifdef FURI_NDEBUG - } else { - uint32_t ptr = (uint32_t)__furi_check_message; - if (ptr < FLASH_BASE || ptr > (FLASH_BASE + FLASH_SIZE)) { - ptr = (uint32_t) "Check serial logs"; - } - furi_hal_rtc_set_fault_data(ptr); - furi_hal_console_puts("\r\nRebooting system.\r\n"); - furi_hal_console_puts("\033[0m\r\n"); - esp_system_abort("crash"); - } -#endif - __builtin_unreachable(); -} -FURI_NORETURN void __furi_halt_implementation() { - __disable_irq(); - - bool isr = FURI_IS_IRQ_MODE(); - - furi_hal_console_puts("\r\n\033[0;31m[HALT]"); - __furi_print_name(isr); - furi_hal_console_puts("\r\nSystem halted. Bye-bye!\r\n"); - furi_hal_console_puts("\033[0m\r\n"); - - __builtin_unreachable(); -} diff --git a/components/furi/src/context.h b/components/furi/src/context.h deleted file mode 100644 index 654ec6ce..00000000 --- a/components/furi/src/context.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -typedef struct { - -} Context; diff --git a/components/furi/src/critical.h b/components/furi/src/critical.h deleted file mode 100644 index 76bc5a2c..00000000 --- a/components/furi/src/critical.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include -#include - -#ifndef FURI_CRITICAL_ENTER -#define FURI_CRITICAL_ENTER() __FuriCriticalInfo __furi_critical_info = __furi_critical_enter(); -#endif - -#ifndef FURI_CRITICAL_EXIT -#define FURI_CRITICAL_EXIT() __furi_critical_exit(__furi_critical_info); -#endif - -typedef struct { - uint32_t isrm; - bool from_isr; - bool kernel_running; -} __FuriCriticalInfo; - -__FuriCriticalInfo __furi_critical_enter(void); - -void __furi_critical_exit(__FuriCriticalInfo info); diff --git a/components/furi/src/event_flag.h b/components/furi/src/event_flag.h deleted file mode 100644 index 0f786249..00000000 --- a/components/furi/src/event_flag.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file event_flag.h - * Furi Event Flag - */ -#pragma once - -#include "furi_core_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void FuriEventFlag; - -/** Allocate FuriEventFlag - * - * @return pointer to FuriEventFlag - */ -FuriEventFlag* furi_event_flag_alloc(); - -/** Deallocate FuriEventFlag - * - * @param instance pointer to FuriEventFlag - */ -void furi_event_flag_free(FuriEventFlag* instance); - -/** Set flags - * - * @param instance pointer to FuriEventFlag - * @param[in] flags The flags - * - * @return Resulting flags or error (FuriStatus) - */ -uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags); - -/** Clear flags - * - * @param instance pointer to FuriEventFlag - * @param[in] flags The flags - * - * @return Resulting flags or error (FuriStatus) - */ -uint32_t furi_event_flag_clear(FuriEventFlag* instance, uint32_t flags); - -/** Get flags - * - * @param instance pointer to FuriEventFlag - * - * @return Resulting flags - */ -uint32_t furi_event_flag_get(FuriEventFlag* instance); - -/** Wait flags - * - * @param instance pointer to FuriEventFlag - * @param[in] flags The flags - * @param[in] options The option flags - * @param[in] timeout The timeout - * - * @return Resulting flags or error (FuriStatus) - */ -uint32_t furi_event_flag_wait( - FuriEventFlag* instance, - uint32_t flags, - uint32_t options, - uint32_t timeout -); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/furi_config.h b/components/furi/src/furi_config.h deleted file mode 100644 index c935611a..00000000 --- a/components/furi/src/furi_config.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#define FURI_CONFIG_THREAD_MAX_PRIORITIES (32) \ No newline at end of file diff --git a/components/furi/src/furi_core_defines.h b/components/furi/src/furi_core_defines.h deleted file mode 100644 index 38526a00..00000000 --- a/components/furi/src/furi_core_defines.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "freertos/portmacro.h" -#include "furi_extra_defines.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifndef FURI_WARN_UNUSED -#define FURI_WARN_UNUSED __attribute__((warn_unused_result)) -#endif - -#ifndef FURI_WEAK -#define FURI_WEAK __attribute__((weak)) -#endif - -#ifndef FURI_PACKED -#define FURI_PACKED __attribute__((packed)) -#endif - -// Used by portENABLE_INTERRUPTS and portDISABLE_INTERRUPTS? -#ifndef FURI_IS_IRQ_MODE -#define FURI_IS_IRQ_MODE() (xPortInIsrContext() == pdTRUE) -#endif - -#ifndef FURI_IS_ISR -#define FURI_IS_ISR() (FURI_IS_IRQ_MODE()) -#endif - -#ifndef FURI_CHECK_RETURN -#define FURI_CHECK_RETURN __attribute__((__warn_unused_result__)) -#endif - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/furi_core_types.h b/components/furi/src/furi_core_types.h deleted file mode 100644 index 478d380d..00000000 --- a/components/furi/src/furi_core_types.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - FuriWaitForever = 0xFFFFFFFFU, -} FuriWait; - -typedef enum { - FuriFlagWaitAny = 0x00000000U, ///< Wait for any flag (default). - FuriFlagWaitAll = 0x00000001U, ///< Wait for all flags. - FuriFlagNoClear = 0x00000002U, ///< Do not clear flags which have been specified to wait for. - - FuriFlagError = 0x80000000U, ///< Error indicator. - FuriFlagErrorUnknown = 0xFFFFFFFFU, ///< FuriStatusError (-1). - FuriFlagErrorTimeout = 0xFFFFFFFEU, ///< FuriStatusErrorTimeout (-2). - FuriFlagErrorResource = 0xFFFFFFFDU, ///< FuriStatusErrorResource (-3). - FuriFlagErrorParameter = 0xFFFFFFFCU, ///< FuriStatusErrorParameter (-4). - FuriFlagErrorISR = 0xFFFFFFFAU, ///< FuriStatusErrorISR (-6). -} FuriFlag; - -typedef enum { - FuriStatusOk = 0, ///< Operation completed successfully. - FuriStatusError = - -1, ///< Unspecified RTOS error: run-time error but no other error message fits. - FuriStatusErrorTimeout = -2, ///< Operation not completed within the timeout period. - FuriStatusErrorResource = -3, ///< Resource not available. - FuriStatusErrorParameter = -4, ///< Parameter error. - FuriStatusErrorNoMemory = - -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. - FuriStatusErrorISR = - -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. - FuriStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. -} FuriStatus; - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/furi_hal_console.c b/components/furi/src/furi_hal_console.c deleted file mode 100644 index 889690fc..00000000 --- a/components/furi/src/furi_hal_console.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "furi_hal_console.h" -#include "furi_core.h" -#include "furi_string.h" - -#include "esp_log.h" // TODO remove - -#define TAG "FuriHalConsole" - -typedef struct { - bool alive; - FuriHalConsoleTxCallback tx_callback; - void* tx_callback_context; -} FuriHalConsole; - -FuriHalConsole furi_hal_console = { - .alive = false, - .tx_callback = NULL, - .tx_callback_context = NULL, -}; - -void furi_hal_console_init() { - furi_hal_console.alive = true; -} - -void furi_hal_console_enable() { - furi_hal_console.alive = true; -} - -void furi_hal_console_disable() { - furi_hal_console.alive = false; -} - -void furi_hal_console_set_tx_callback(FuriHalConsoleTxCallback callback, void* context) { - FURI_CRITICAL_ENTER(); - furi_hal_console.tx_callback = callback; - furi_hal_console.tx_callback_context = context; - FURI_CRITICAL_EXIT(); -} - -void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { - if (!furi_hal_console.alive) return; - - FURI_CRITICAL_ENTER(); - if (furi_hal_console.tx_callback) { - furi_hal_console.tx_callback(buffer, buffer_size, furi_hal_console.tx_callback_context); - } - - char safe_buffer[buffer_size + 1]; - memcpy(safe_buffer, buffer, buffer_size); - safe_buffer[buffer_size] = 0; - - ESP_LOGI(TAG, "%s", safe_buffer); - FURI_CRITICAL_EXIT(); -} - -void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size) { - if (!furi_hal_console.alive) return; - - FURI_CRITICAL_ENTER(); - - char safe_buffer[buffer_size + 1]; - memcpy(safe_buffer, buffer, buffer_size); - safe_buffer[buffer_size] = 0; - ESP_LOGI(TAG, "%s", safe_buffer); - - FURI_CRITICAL_EXIT(); -} - -void furi_hal_console_printf(const char format[], ...) { - FuriString* string; - va_list args; - va_start(args, format); - string = furi_string_alloc_vprintf(format, args); - va_end(args); - furi_hal_console_tx((const uint8_t*)furi_string_get_cstr(string), furi_string_size(string)); - furi_string_free(string); -} - -void furi_hal_console_puts(const char* data) { - furi_hal_console_tx((const uint8_t*)data, strlen(data)); -} diff --git a/components/furi/src/furi_hal_console.h b/components/furi/src/furi_hal_console.h deleted file mode 100644 index 3ce6d3f7..00000000 --- a/components/furi/src/furi_hal_console.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*FuriHalConsoleTxCallback)(const uint8_t* buffer, size_t size, void* context); - -void furi_hal_console_init(); - -void furi_hal_console_enable(); - -void furi_hal_console_disable(); - -void furi_hal_console_set_tx_callback(FuriHalConsoleTxCallback callback, void* context); - -void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size); - -void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size); - -/** - * Printf-like plain uart interface - * @warning Will not work in ISR context - * @param format - * @param ... - */ -void furi_hal_console_printf(const char format[], ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); - -void furi_hal_console_puts(const char* data); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/furi_string.c b/components/furi/src/furi_string.c deleted file mode 100644 index 74633ead..00000000 --- a/components/furi/src/furi_string.c +++ /dev/null @@ -1,304 +0,0 @@ -#include "furi_string.h" -#include - -struct FuriString { - string_t string; -}; - -#undef furi_string_alloc_set -#undef furi_string_set -#undef furi_string_cmp -#undef furi_string_cmpi -#undef furi_string_search -#undef furi_string_search_str -#undef furi_string_equal -#undef furi_string_replace -#undef furi_string_replace_str -#undef furi_string_replace_all -#undef furi_string_start_with -#undef furi_string_end_with -#undef furi_string_search_char -#undef furi_string_search_rchar -#undef furi_string_trim -#undef furi_string_cat - -FuriString* furi_string_alloc() { - FuriString* string = malloc(sizeof(FuriString)); - string_init(string->string); - return string; -} - -FuriString* furi_string_alloc_set(const FuriString* s) { - FuriString* string = malloc(sizeof(FuriString)); //-V799 - string_init_set(string->string, s->string); - return string; -} //-V773 - -FuriString* furi_string_alloc_set_str(const char cstr[]) { - FuriString* string = malloc(sizeof(FuriString)); //-V799 - string_init_set(string->string, cstr); - return string; -} //-V773 - -FuriString* furi_string_alloc_printf(const char format[], ...) { - va_list args; - va_start(args, format); - FuriString* string = furi_string_alloc_vprintf(format, args); - va_end(args); - return string; -} - -FuriString* furi_string_alloc_vprintf(const char format[], va_list args) { - FuriString* string = malloc(sizeof(FuriString)); - string_init_vprintf(string->string, format, args); - return string; -} - -FuriString* furi_string_alloc_move(FuriString* s) { - FuriString* string = malloc(sizeof(FuriString)); - string_init_move(string->string, s->string); - free(s); - return string; -} - -void furi_string_free(FuriString* s) { - string_clear(s->string); - free(s); -} - -void furi_string_reserve(FuriString* s, size_t alloc) { - string_reserve(s->string, alloc); -} - -void furi_string_reset(FuriString* s) { - string_reset(s->string); -} - -void furi_string_swap(FuriString* v1, FuriString* v2) { - string_swap(v1->string, v2->string); -} - -void furi_string_move(FuriString* v1, FuriString* v2) { - string_clear(v1->string); - string_init_move(v1->string, v2->string); - free(v2); -} - -size_t furi_string_hash(const FuriString* v) { - return string_hash(v->string); -} - -char furi_string_get_char(const FuriString* v, size_t index) { - return string_get_char(v->string, index); -} - -const char* furi_string_get_cstr(const FuriString* s) { - return string_get_cstr(s->string); -} - -void furi_string_set(FuriString* s, FuriString* source) { - string_set(s->string, source->string); -} - -void furi_string_set_str(FuriString* s, const char cstr[]) { - string_set(s->string, cstr); -} - -void furi_string_set_strn(FuriString* s, const char str[], size_t n) { - string_set_strn(s->string, str, n); -} - -void furi_string_set_char(FuriString* s, size_t index, const char c) { - string_set_char(s->string, index, c); -} - -int furi_string_cmp(const FuriString* s1, const FuriString* s2) { - return string_cmp(s1->string, s2->string); -} - -int furi_string_cmp_str(const FuriString* s1, const char str[]) { - return string_cmp(s1->string, str); -} - -int furi_string_cmpi(const FuriString* v1, const FuriString* v2) { - return string_cmpi(v1->string, v2->string); -} - -int furi_string_cmpi_str(const FuriString* v1, const char p2[]) { - return string_cmpi_str(v1->string, p2); -} - -size_t furi_string_search(const FuriString* v, const FuriString* needle, size_t start) { - return string_search(v->string, needle->string, start); -} - -size_t furi_string_search_str(const FuriString* v, const char needle[], size_t start) { - return string_search(v->string, needle, start); -} - -bool furi_string_equal(const FuriString* v1, const FuriString* v2) { - return string_equal_p(v1->string, v2->string); -} - -bool furi_string_equal_str(const FuriString* v1, const char v2[]) { - return string_equal_p(v1->string, v2); -} - -void furi_string_push_back(FuriString* v, char c) { - string_push_back(v->string, c); -} - -size_t furi_string_size(const FuriString* s) { - return string_size(s->string); -} - -int furi_string_printf(FuriString* v, const char format[], ...) { - va_list args; - va_start(args, format); - int result = furi_string_vprintf(v, format, args); - va_end(args); - return result; -} - -int furi_string_vprintf(FuriString* v, const char format[], va_list args) { - return string_vprintf(v->string, format, args); -} - -int furi_string_cat_printf(FuriString* v, const char format[], ...) { - va_list args; - va_start(args, format); - int result = furi_string_cat_vprintf(v, format, args); - va_end(args); - return result; -} - -int furi_string_cat_vprintf(FuriString* v, const char format[], va_list args) { - FuriString* string = furi_string_alloc(); - int ret = furi_string_vprintf(string, format, args); - furi_string_cat(v, string); - furi_string_free(string); - return ret; -} - -bool furi_string_empty(const FuriString* v) { - return string_empty_p(v->string); -} - -void furi_string_replace_at(FuriString* v, size_t pos, size_t len, const char str2[]) { - string_replace_at(v->string, pos, len, str2); -} - -size_t -furi_string_replace(FuriString* string, FuriString* needle, FuriString* replace, size_t start) { - return string_replace(string->string, needle->string, replace->string, start); -} - -size_t furi_string_replace_str(FuriString* v, const char str1[], const char str2[], size_t start) { - return string_replace_str(v->string, str1, str2, start); -} - -void furi_string_replace_all_str(FuriString* v, const char str1[], const char str2[]) { - string_replace_all_str(v->string, str1, str2); -} - -void furi_string_replace_all(FuriString* v, const FuriString* str1, const FuriString* str2) { - string_replace_all(v->string, str1->string, str2->string); -} - -bool furi_string_start_with(const FuriString* v, const FuriString* v2) { - return string_start_with_string_p(v->string, v2->string); -} - -bool furi_string_start_with_str(const FuriString* v, const char str[]) { - return string_start_with_str_p(v->string, str); -} - -bool furi_string_end_with(const FuriString* v, const FuriString* v2) { - return string_end_with_string_p(v->string, v2->string); -} - -bool furi_string_end_with_str(const FuriString* v, const char str[]) { - return string_end_with_str_p(v->string, str); -} - -size_t furi_string_search_char(const FuriString* v, char c, size_t start) { - return string_search_char(v->string, c, start); -} - -size_t furi_string_search_rchar(const FuriString* v, char c, size_t start) { - return string_search_rchar(v->string, c, start); -} - -void furi_string_left(FuriString* v, size_t index) { - string_left(v->string, index); -} - -void furi_string_right(FuriString* v, size_t index) { - string_right(v->string, index); -} - -void furi_string_mid(FuriString* v, size_t index, size_t size) { - string_mid(v->string, index, size); -} - -void furi_string_trim(FuriString* v, const char charac[]) { - string_strim(v->string, charac); -} - -void furi_string_cat(FuriString* v, const FuriString* v2) { - string_cat(v->string, v2->string); -} - -void furi_string_cat_str(FuriString* v, const char str[]) { - string_cat(v->string, str); -} - -void furi_string_set_n(FuriString* v, const FuriString* ref, size_t offset, size_t length) { - string_set_n(v->string, ref->string, offset, length); -} - -size_t furi_string_utf8_length(FuriString* str) { - return string_length_u(str->string); -} - -void furi_string_utf8_push(FuriString* str, FuriStringUnicodeValue u) { - string_push_u(str->string, u); -} - -static m_str1ng_utf8_state_e furi_state_to_state(FuriStringUTF8State state) { - switch (state) { - case FuriStringUTF8StateStarting: - return M_STR1NG_UTF8_STARTING; - case FuriStringUTF8StateDecoding1: - return M_STR1NG_UTF8_DECODING_1; - case FuriStringUTF8StateDecoding2: - return M_STR1NG_UTF8_DECODING_2; - case FuriStringUTF8StateDecoding3: - return M_STR1NG_UTF8_DECODING_3; - default: - return M_STR1NG_UTF8_ERROR; - } -} - -static FuriStringUTF8State state_to_furi_state(m_str1ng_utf8_state_e state) { - switch (state) { - case M_STR1NG_UTF8_STARTING: - return FuriStringUTF8StateStarting; - case M_STR1NG_UTF8_DECODING_1: - return FuriStringUTF8StateDecoding1; - case M_STR1NG_UTF8_DECODING_2: - return FuriStringUTF8StateDecoding2; - case M_STR1NG_UTF8_DECODING_3: - return FuriStringUTF8StateDecoding3; - default: - return FuriStringUTF8StateError; - } -} - -void furi_string_utf8_decode(char c, FuriStringUTF8State* state, FuriStringUnicodeValue* unicode) { - string_unicode_t m_u = *unicode; - m_str1ng_utf8_state_e m_state = furi_state_to_state(*state); - m_str1ng_utf8_decode(c, &m_state, &m_u); - *state = state_to_furi_state(m_state); - *unicode = m_u; -} diff --git a/components/furi/src/message_queue.h b/components/furi/src/message_queue.h deleted file mode 100644 index 4b17e7ee..00000000 --- a/components/furi/src/message_queue.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * @file message_queue.h - * FuriMessageQueue - */ -#pragma once - -#include "furi_core_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void FuriMessageQueue; - -/** Allocate furi message queue - * - * @param[in] msg_count The message count - * @param[in] msg_size The message size - * - * @return pointer to FuriMessageQueue instance - */ -FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size); - -/** Free queue - * - * @param instance pointer to FuriMessageQueue instance - */ -void furi_message_queue_free(FuriMessageQueue* instance); - -/** Put message into queue - * - * @param instance pointer to FuriMessageQueue instance - * @param[in] msg_ptr The message pointer - * @param[in] timeout The timeout - * @param[in] msg_prio The message prio - * - * @return The furi status. - */ -FuriStatus -furi_message_queue_put(FuriMessageQueue* instance, const void* msg_ptr, uint32_t timeout); - -/** Get message from queue - * - * @param instance pointer to FuriMessageQueue instance - * @param msg_ptr The message pointer - * @param msg_prio The message prioority - * @param[in] timeout_ticks The timeout - * - * @return The furi status. - */ -FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uint32_t timeout_ticks); - -/** Get queue capacity - * - * @param instance pointer to FuriMessageQueue instance - * - * @return capacity in object count - */ -uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance); - -/** Get message size - * - * @param instance pointer to FuriMessageQueue instance - * - * @return Message size in bytes - */ -uint32_t furi_message_queue_get_message_size(FuriMessageQueue* instance); - -/** Get message count in queue - * - * @param instance pointer to FuriMessageQueue instance - * - * @return Message count - */ -uint32_t furi_message_queue_get_count(FuriMessageQueue* instance); - -/** Get queue available space - * - * @param instance pointer to FuriMessageQueue instance - * - * @return Message count - */ -uint32_t furi_message_queue_get_space(FuriMessageQueue* instance); - -/** Reset queue - * - * @param instance pointer to FuriMessageQueue instance - * - * @return The furi status. - */ -FuriStatus furi_message_queue_reset(FuriMessageQueue* instance); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/mutex.h b/components/furi/src/mutex.h deleted file mode 100644 index bd7c5956..00000000 --- a/components/furi/src/mutex.h +++ /dev/null @@ -1,62 +0,0 @@ -/** - * @file mutex.h - * FuriMutex - */ -#pragma once - -#include "furi_core_types.h" -#include "thread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - FuriMutexTypeNormal, - FuriMutexTypeRecursive, -} FuriMutexType; - -typedef void FuriMutex; - -/** Allocate FuriMutex - * - * @param[in] type The mutex type - * - * @return pointer to FuriMutex instance - */ -FuriMutex* furi_mutex_alloc(FuriMutexType type); - -/** Free FuriMutex - * - * @param instance The pointer to FuriMutex instance - */ -void furi_mutex_free(FuriMutex* instance); - -/** Acquire mutex - * - * @param instance The pointer to FuriMutex instance - * @param[in] timeout The timeout - * - * @return The furi status. - */ -FuriStatus furi_mutex_acquire(FuriMutex* instance, uint32_t timeout); - -/** Release mutex - * - * @param instance The pointer to FuriMutex instance - * - * @return The furi status. - */ -FuriStatus furi_mutex_release(FuriMutex* instance); - -/** Get mutex owner thread id - * - * @param instance The pointer to FuriMutex instance - * - * @return The furi thread identifier. - */ -FuriThreadId furi_mutex_get_owner(FuriMutex* instance); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/pubsub.c b/components/furi/src/pubsub.c deleted file mode 100644 index 4280bdf1..00000000 --- a/components/furi/src/pubsub.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "pubsub.h" -#include "check.h" -#include "mutex.h" - -#include - -struct FuriPubSubSubscription { - FuriPubSubCallback callback; - void* callback_context; -}; - -LIST_DEF(FuriPubSubSubscriptionList, FuriPubSubSubscription, M_POD_OPLIST); - -struct FuriPubSub { - FuriPubSubSubscriptionList_t items; - FuriMutex* mutex; -}; - -FuriPubSub* furi_pubsub_alloc() { - FuriPubSub* pubsub = malloc(sizeof(FuriPubSub)); - - pubsub->mutex = furi_mutex_alloc(FuriMutexTypeRecursive); - furi_assert(pubsub->mutex); - - FuriPubSubSubscriptionList_init(pubsub->items); - - return pubsub; -} - -void furi_pubsub_free(FuriPubSub* pubsub) { - furi_assert(pubsub); - - furi_check(FuriPubSubSubscriptionList_size(pubsub->items) == 0); - - FuriPubSubSubscriptionList_clear(pubsub->items); - - furi_mutex_free(pubsub->mutex); - - free(pubsub); -} - -FuriPubSubSubscription* -furi_pubsub_subscribe(FuriPubSub* pubsub, FuriPubSubCallback callback, void* callback_context) { - furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); - // put uninitialized item to the list - FuriPubSubSubscription* item = FuriPubSubSubscriptionList_push_raw(pubsub->items); - - // initialize item - item->callback = callback; - item->callback_context = callback_context; - - furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); - - return item; -} - -void furi_pubsub_unsubscribe(FuriPubSub* pubsub, FuriPubSubSubscription* pubsub_subscription) { - furi_assert(pubsub); - furi_assert(pubsub_subscription); - - furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); - bool result = false; - - // iterate over items - FuriPubSubSubscriptionList_it_t it; - for (FuriPubSubSubscriptionList_it(it, pubsub->items); !FuriPubSubSubscriptionList_end_p(it); - FuriPubSubSubscriptionList_next(it)) { - const FuriPubSubSubscription* item = FuriPubSubSubscriptionList_cref(it); - - // if the iterator is equal to our element - if (item == pubsub_subscription) { - FuriPubSubSubscriptionList_remove(pubsub->items, it); - result = true; - break; - } - } - - furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); - furi_check(result); -} - -void furi_pubsub_publish(FuriPubSub* pubsub, void* message) { - furi_check(furi_mutex_acquire(pubsub->mutex, FuriWaitForever) == FuriStatusOk); - - // iterate over subscribers - FuriPubSubSubscriptionList_it_t it; - for (FuriPubSubSubscriptionList_it(it, pubsub->items); !FuriPubSubSubscriptionList_end_p(it); - FuriPubSubSubscriptionList_next(it)) { - const FuriPubSubSubscription* item = FuriPubSubSubscriptionList_cref(it); - item->callback(message, item->callback_context); - } - - furi_check(furi_mutex_release(pubsub->mutex) == FuriStatusOk); -} diff --git a/components/furi/src/pubsub.h b/components/furi/src/pubsub.h deleted file mode 100644 index d62755b7..00000000 --- a/components/furi/src/pubsub.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file pubsub.h - * FuriPubSub - */ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -/** FuriPubSub Callback type */ -typedef void (*FuriPubSubCallback)(const void* message, void* context); - -/** FuriPubSub type */ -typedef struct FuriPubSub FuriPubSub; - -/** FuriPubSubSubscription type */ -typedef struct FuriPubSubSubscription FuriPubSubSubscription; - -/** Allocate FuriPubSub - * - * Reentrable, Not threadsafe, one owner - * - * @return pointer to FuriPubSub instance - */ -FuriPubSub* furi_pubsub_alloc(); - -/** Free FuriPubSub - * - * @param pubsub FuriPubSub instance - */ -void furi_pubsub_free(FuriPubSub* pubsub); - -/** Subscribe to FuriPubSub - * - * Threadsafe, Reentrable - * - * @param pubsub pointer to FuriPubSub instance - * @param[in] callback The callback - * @param callback_context The callback context - * - * @return pointer to FuriPubSubSubscription instance - */ -FuriPubSubSubscription* -furi_pubsub_subscribe(FuriPubSub* pubsub, FuriPubSubCallback callback, void* callback_context); - -/** Unsubscribe from FuriPubSub - * - * No use of `pubsub_subscription` allowed after call of this method - * Threadsafe, Reentrable. - * - * @param pubsub pointer to FuriPubSub instance - * @param pubsub_subscription pointer to FuriPubSubSubscription instance - */ -void furi_pubsub_unsubscribe(FuriPubSub* pubsub, FuriPubSubSubscription* pubsub_subscription); - -/** Publish message to FuriPubSub - * - * Threadsafe, Reentrable. - * - * @param pubsub pointer to FuriPubSub instance - * @param message message pointer to publish - */ -void furi_pubsub_publish(FuriPubSub* pubsub, void* message); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/semaphore.h b/components/furi/src/semaphore.h deleted file mode 100644 index dae5d5b4..00000000 --- a/components/furi/src/semaphore.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "furi_core_types.h" -#include "thread.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void FuriSemaphore; - -/** Allocate semaphore - * - * @param[in] max_count The maximum count - * @param[in] initial_count The initial count - * - * @return pointer to FuriSemaphore instance - */ -FuriSemaphore* furi_semaphore_alloc(uint32_t max_count, uint32_t initial_count); - -/** Free semaphore - * - * @param instance The pointer to FuriSemaphore instance - */ -void furi_semaphore_free(FuriSemaphore* instance); - -/** Acquire semaphore - * - * @param instance The pointer to FuriSemaphore instance - * @param[in] timeout The timeout - * - * @return The furi status. - */ -FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout); - -/** Release semaphore - * - * @param instance The pointer to FuriSemaphore instance - * - * @return The furi status. - */ -FuriStatus furi_semaphore_release(FuriSemaphore* instance); - -/** Get semaphore count - * - * @param instance The pointer to FuriSemaphore instance - * - * @return Semaphore count - */ -uint32_t furi_semaphore_get_count(FuriSemaphore* instance); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/service.c b/components/furi/src/service.c deleted file mode 100644 index f71988d4..00000000 --- a/components/furi/src/service.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "service_i.h" -#include "furi_core.h" -#include "log.h" - -// region Alloc/free - -Service service_alloc(const ServiceManifest* _Nonnull manifest) { - ServiceData* data = malloc(sizeof(ServiceData)); - *data = (ServiceData) { - .manifest = manifest, - .mutex = furi_mutex_alloc(FuriMutexTypeRecursive), - .data = NULL - }; - return data; -} - -void service_free(Service service) { - ServiceData* data = (ServiceData*)service; - furi_assert(service); - furi_mutex_free(data->mutex); - free(data); -} - -// endregion Alloc/free - -// region Internal - -static void service_lock(ServiceData * data) { - furi_mutex_acquire(data->mutex, FuriMutexTypeRecursive); -} - -static void service_unlock(ServiceData* data) { - furi_mutex_release(data->mutex); -} - -// endregion Internal - -// region Getters & Setters - -const ServiceManifest* service_get_manifest(Service service) { - ServiceData* data = (ServiceData*)service; - service_lock(data); - const ServiceManifest* manifest = data->manifest; - service_unlock(data); - return manifest; -} - -void service_set_data(Service service, void* value) { - ServiceData* data = (ServiceData*)service; - service_lock(data); - data->data = value; - service_unlock(data); -} - -void* _Nullable service_get_data(Service service) { - ServiceData* data = (ServiceData*)service; - service_lock(data); - void* value = data->data; - service_unlock(data); - return value; -} - -// endregion Getters & Setters \ No newline at end of file diff --git a/components/furi/src/service.h b/components/furi/src/service.h deleted file mode 100644 index f08d471d..00000000 --- a/components/furi/src/service.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "service_manifest.h" - -typedef void* Service; - -const ServiceManifest* service_get_manifest(Service service); - -void service_set_data(Service service, void* value); -void* _Nullable service_get_data(Service service); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/components/furi/src/service_registry.h b/components/furi/src/service_registry.h deleted file mode 100644 index 4a053cf6..00000000 --- a/components/furi/src/service_registry.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "service_manifest.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -typedef void (*ServiceManifestCallback)(const ServiceManifest*, void* context); - -void service_registry_init(); - -void service_registry_add(const ServiceManifest* manifest); -void service_registry_remove(const ServiceManifest* manifest); -const ServiceManifest _Nullable* service_registry_find_manifest_by_id(const char* id); -void service_registry_for_each_manifest(ServiceManifestCallback callback, void* _Nullable context); - -bool service_registry_start(const char* service_id); -bool service_registry_stop(const char* service_id); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/thread.c b/components/furi/src/thread.c deleted file mode 100644 index 8f3a3a73..00000000 --- a/components/furi/src/thread.c +++ /dev/null @@ -1,665 +0,0 @@ -#include "thread.h" -#include "check.h" -#include "furi_core_defines.h" -#include "furi_string.h" -#include "kernel.h" - -#include - -#include - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - -#define TAG "FuriThread" - -#define THREAD_NOTIFY_INDEX 1 // Index 0 is used for stream buffers - -// Limits -#define MAX_BITS_TASK_NOTIFY 31U -#define MAX_BITS_EVENT_GROUPS 24U - -#define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U)) -#define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U)) - -typedef struct FuriThreadStdout FuriThreadStdout; - -struct FuriThreadStdout { - FuriThreadStdoutWriteCallback write_callback; - FuriString* buffer; -}; - -struct FuriThread { - FuriThreadState state; - int32_t ret; - - FuriThreadCallback callback; - void* context; - - FuriThreadStateCallback state_callback; - void* state_context; - - char* name; - char* appid; - - FuriThreadPriority priority; - - TaskHandle_t task_handle; - size_t heap_size; - - FuriThreadStdout output; - - // Keep all non-alignable byte types in one place, - // this ensures that the size of this structure is minimal - bool is_static; - bool heap_trace_enabled; - - configSTACK_DEPTH_TYPE stack_size; -}; - -static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size); -static int32_t __furi_thread_stdout_flush(FuriThread* thread); - -/** Catch threads that are trying to exit wrong way */ -__attribute__((__noreturn__)) void furi_thread_catch() { //-V1082 - // If you're here it means you're probably doing something wrong - // with critical sections or with scheduler state - asm volatile("nop"); // extra magic - furi_crash("You are doing it wrong"); //-V779 - __builtin_unreachable(); -} - -static void furi_thread_set_state(FuriThread* thread, FuriThreadState state) { - furi_assert(thread); - thread->state = state; - if (thread->state_callback) { - thread->state_callback(state, thread->state_context); - } -} - -static void furi_thread_body(void* context) { - furi_assert(context); - FuriThread* thread = context; - - // store thread instance to thread local storage - furi_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) == NULL); - vTaskSetThreadLocalStoragePointer(NULL, 0, thread); - - furi_assert(thread->state == FuriThreadStateStarting); - furi_thread_set_state(thread, FuriThreadStateRunning); - - /* - TaskHandle_t task_handle = xTaskGetCurrentTaskHandle(); - if(thread->heap_trace_enabled == true) { - memmgr_heap_enable_thread_trace((FuriThreadId)task_handle); - } - */ - - thread->ret = thread->callback(thread->context); - - /* - if(thread->heap_trace_enabled == true) { - furi_delay_ms(33); - thread->heap_size = memmgr_heap_get_thread_memory((FuriThreadId)task_handle); - furi_log_print_format( - thread->heap_size ? FuriLogLevelError : FuriLogLevelInfo, - TAG, - "%s allocation balance: %zu", - thread->name ? thread->name : "Thread", - thread->heap_size); - memmgr_heap_disable_thread_trace((FuriThreadId)task_handle); - } - */ - - furi_assert(thread->state == FuriThreadStateRunning); - - if (thread->is_static) { - ESP_LOGI( - TAG, - "%s service thread TCB memory will not be reclaimed", - thread->name ? thread->name : "" - ); - } - - // flush stdout - __furi_thread_stdout_flush(thread); - - furi_thread_set_state(thread, FuriThreadStateStopped); - - vTaskDelete(NULL); - furi_thread_catch(); -} - -FuriThread* furi_thread_alloc() { - FuriThread* thread = malloc(sizeof(FuriThread)); - // TODO: create default struct instead of using memset() - memset(thread, 0, sizeof(FuriThread)); - thread->output.buffer = furi_string_alloc(); - thread->is_static = false; - - FuriThread* parent = NULL; - if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { - // TLS is not available, if we called not from thread context - parent = pvTaskGetThreadLocalStoragePointer(NULL, 0); - - if (parent && parent->appid) { - furi_thread_set_appid(thread, parent->appid); - } else { - furi_thread_set_appid(thread, "unknown"); - } - } else { - // if scheduler is not started, we are starting driver thread - furi_thread_set_appid(thread, "driver"); - } - - /*FuriHalRtcHeapTrackMode mode = furi_hal_rtc_get_heap_track_mode(); - if(mode == FuriHalRtcHeapTrackModeAll) { - thread->heap_trace_enabled = true; - } else if(mode == FuriHalRtcHeapTrackModeTree && furi_thread_get_current_id()) { - if(parent) thread->heap_trace_enabled = parent->heap_trace_enabled; - } else */ - { - thread->heap_trace_enabled = false; - } - - return thread; -} - -FuriThread* furi_thread_alloc_ex( - const char* name, - uint32_t stack_size, - FuriThreadCallback callback, - void* context -) { - FuriThread* thread = furi_thread_alloc(); - furi_thread_set_name(thread, name); - furi_thread_set_stack_size(thread, stack_size); - furi_thread_set_callback(thread, callback); - furi_thread_set_context(thread, context); - return thread; -} - -void furi_thread_free(FuriThread* thread) { - furi_assert(thread); - - // Ensure that use join before free - furi_assert(thread->state == FuriThreadStateStopped); - furi_assert(thread->task_handle == NULL); - - if (thread->name) free(thread->name); - if (thread->appid) free(thread->appid); - furi_string_free(thread->output.buffer); - - free(thread); -} - -void furi_thread_set_name(FuriThread* thread, const char* name) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - if (thread->name) free(thread->name); - thread->name = name ? strdup(name) : NULL; -} - -void furi_thread_set_appid(FuriThread* thread, const char* appid) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - if (thread->appid) free(thread->appid); - thread->appid = appid ? strdup(appid) : NULL; -} - -void furi_thread_mark_as_static(FuriThread* thread) { - thread->is_static = true; -} - -bool furi_thread_mark_is_service(FuriThreadId thread_id) { - TaskHandle_t hTask = (TaskHandle_t)thread_id; - assert(!FURI_IS_IRQ_MODE() && (hTask != NULL)); - FuriThread* thread = (FuriThread*)pvTaskGetThreadLocalStoragePointer(hTask, 0); - assert(thread != NULL); - return thread->is_static; -} - -void furi_thread_set_stack_size(FuriThread* thread, size_t stack_size) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - furi_assert(stack_size % 4 == 0); - thread->stack_size = stack_size; -} - -void furi_thread_set_callback(FuriThread* thread, FuriThreadCallback callback) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - thread->callback = callback; -} - -void furi_thread_set_context(FuriThread* thread, void* context) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - thread->context = context; -} - -void furi_thread_set_priority(FuriThread* thread, FuriThreadPriority priority) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - furi_assert(priority >= FuriThreadPriorityIdle && priority <= FuriThreadPriorityIsr); - thread->priority = priority; -} - -void furi_thread_set_current_priority(FuriThreadPriority priority) { - UBaseType_t new_priority = priority ? priority : FuriThreadPriorityNormal; - vTaskPrioritySet(NULL, new_priority); -} - -FuriThreadPriority furi_thread_get_current_priority() { - return (FuriThreadPriority)uxTaskPriorityGet(NULL); -} - -void furi_thread_set_state_callback(FuriThread* thread, FuriThreadStateCallback callback) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - thread->state_callback = callback; -} - -void furi_thread_set_state_context(FuriThread* thread, void* context) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - thread->state_context = context; -} - -FuriThreadState furi_thread_get_state(FuriThread* thread) { - furi_assert(thread); - return thread->state; -} - -void furi_thread_start(FuriThread* thread) { - furi_assert(thread); - furi_assert(thread->callback); - furi_assert(thread->state == FuriThreadStateStopped); - furi_assert(thread->stack_size > 0 && thread->stack_size < (UINT16_MAX * sizeof(StackType_t))); - - furi_thread_set_state(thread, FuriThreadStateStarting); - - uint32_t stack = thread->stack_size / sizeof(StackType_t); - UBaseType_t priority = thread->priority ? thread->priority : FuriThreadPriorityNormal; - if (thread->is_static) { - thread->task_handle = xTaskCreateStatic( - furi_thread_body, - thread->name, - stack, - thread, - priority, - malloc(sizeof(StackType_t) * stack), - malloc(sizeof(StaticTask_t)) - ); - } else { - BaseType_t ret = xTaskCreate( - furi_thread_body, thread->name, stack, thread, priority, &thread->task_handle - ); - furi_check(ret == pdPASS); - } - - furi_check(thread->task_handle); -} - -void furi_thread_cleanup_tcb_event(TaskHandle_t task) { - FuriThread* thread = pvTaskGetThreadLocalStoragePointer(task, 0); - if (thread) { - // clear thread local storage - vTaskSetThreadLocalStoragePointer(task, 0, NULL); - furi_assert(thread->task_handle == task); - thread->task_handle = NULL; - } -} - -bool furi_thread_join(FuriThread* thread) { - furi_assert(thread); - - furi_check(furi_thread_get_current() != thread); - - // !!! IMPORTANT NOTICE !!! - // - // If your thread exited, but your app stuck here: some other thread uses - // all cpu time, which delays kernel from releasing task handle - while (thread->task_handle) { - furi_delay_ms(10); - } - - return true; -} - -FuriThreadId furi_thread_get_id(FuriThread* thread) { - furi_assert(thread); - return thread->task_handle; -} - -void furi_thread_enable_heap_trace(FuriThread* thread) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - thread->heap_trace_enabled = true; -} - -void furi_thread_disable_heap_trace(FuriThread* thread) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - thread->heap_trace_enabled = false; -} - -size_t furi_thread_get_heap_size(FuriThread* thread) { - furi_assert(thread); - furi_assert(thread->heap_trace_enabled == true); - return thread->heap_size; -} - -int32_t furi_thread_get_return_code(FuriThread* thread) { - furi_assert(thread); - furi_assert(thread->state == FuriThreadStateStopped); - return thread->ret; -} - -FuriThreadId furi_thread_get_current_id() { - return xTaskGetCurrentTaskHandle(); -} - -FuriThread* furi_thread_get_current() { - FuriThread* thread = pvTaskGetThreadLocalStoragePointer(NULL, 0); - return thread; -} - -void furi_thread_yield() { - furi_assert(!FURI_IS_IRQ_MODE()); - taskYIELD(); -} - -uint32_t furi_thread_flags_set(FuriThreadId thread_id, uint32_t flags) { - TaskHandle_t hTask = (TaskHandle_t)thread_id; - uint32_t rflags; - BaseType_t yield; - - if ((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) { - rflags = (uint32_t)FuriStatusErrorParameter; - } else { - rflags = (uint32_t)FuriStatusError; - - if (FURI_IS_IRQ_MODE()) { - yield = pdFALSE; - - (void)xTaskNotifyIndexedFromISR(hTask, THREAD_NOTIFY_INDEX, flags, eSetBits, &yield); - (void)xTaskNotifyAndQueryIndexedFromISR( - hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags, NULL - ); - - portYIELD_FROM_ISR(yield); - } else { - (void)xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, flags, eSetBits); - (void)xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags); - } - } - /* Return flags after setting */ - return (rflags); -} - -uint32_t furi_thread_flags_clear(uint32_t flags) { - TaskHandle_t hTask; - uint32_t rflags, cflags; - - if (FURI_IS_IRQ_MODE()) { - rflags = (uint32_t)FuriStatusErrorISR; - } else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) { - rflags = (uint32_t)FuriStatusErrorParameter; - } else { - hTask = xTaskGetCurrentTaskHandle(); - - if (xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &cflags) == - pdPASS) { - rflags = cflags; - cflags &= ~flags; - - if (xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, cflags, eSetValueWithOverwrite) != - pdPASS) { - rflags = (uint32_t)FuriStatusError; - } - } else { - rflags = (uint32_t)FuriStatusError; - } - } - - /* Return flags before clearing */ - return (rflags); -} - -uint32_t furi_thread_flags_get(void) { - TaskHandle_t hTask; - uint32_t rflags; - - if (FURI_IS_IRQ_MODE()) { - rflags = (uint32_t)FuriStatusErrorISR; - } else { - hTask = xTaskGetCurrentTaskHandle(); - - if (xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags) != - pdPASS) { - rflags = (uint32_t)FuriStatusError; - } - } - - return (rflags); -} - -uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeout) { - uint32_t rflags, nval; - uint32_t clear; - TickType_t t0, td, tout; - BaseType_t rval; - - if (FURI_IS_IRQ_MODE()) { - rflags = (uint32_t)FuriStatusErrorISR; - } else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) { - rflags = (uint32_t)FuriStatusErrorParameter; - } else { - if ((options & FuriFlagNoClear) == FuriFlagNoClear) { - clear = 0U; - } else { - clear = flags; - } - - rflags = 0U; - tout = timeout; - - t0 = xTaskGetTickCount(); - do { - rval = xTaskNotifyWaitIndexed(THREAD_NOTIFY_INDEX, 0, clear, &nval, tout); - - if (rval == pdPASS) { - rflags &= flags; - rflags |= nval; - - if ((options & FuriFlagWaitAll) == FuriFlagWaitAll) { - if ((flags & rflags) == flags) { - break; - } else { - if (timeout == 0U) { - rflags = (uint32_t)FuriStatusErrorResource; - break; - } - } - } else { - if ((flags & rflags) != 0) { - break; - } else { - if (timeout == 0U) { - rflags = (uint32_t)FuriStatusErrorResource; - break; - } - } - } - - /* Update timeout */ - td = xTaskGetTickCount() - t0; - - if (td > tout) { - tout = 0; - } else { - tout -= td; - } - } else { - if (timeout == 0) { - rflags = (uint32_t)FuriStatusErrorResource; - } else { - rflags = (uint32_t)FuriStatusErrorTimeout; - } - } - } while (rval != pdFAIL); - } - - /* Return flags before clearing */ - return (rflags); -} - -uint32_t furi_thread_enumerate(FuriThreadId* thread_array, uint32_t array_items) { - uint32_t i, count; - TaskStatus_t* task; - - if (FURI_IS_IRQ_MODE() || (thread_array == NULL) || (array_items == 0U)) { - count = 0U; - } else { - vTaskSuspendAll(); - - count = uxTaskGetNumberOfTasks(); - task = pvPortMalloc(count * sizeof(TaskStatus_t)); - - if (task != NULL) { - count = uxTaskGetSystemState(task, count, NULL); - - for (i = 0U; (i < count) && (i < array_items); i++) { - thread_array[i] = (FuriThreadId)task[i].xHandle; - } - count = i; - } - (void)xTaskResumeAll(); - - vPortFree(task); - } - - return (count); -} - -const char* furi_thread_get_name(FuriThreadId thread_id) { - TaskHandle_t hTask = (TaskHandle_t)thread_id; - const char* name; - - if (FURI_IS_IRQ_MODE() || (hTask == NULL)) { - name = NULL; - } else { - name = pcTaskGetName(hTask); - } - - return (name); -} - -const char* furi_thread_get_appid(FuriThreadId thread_id) { - TaskHandle_t hTask = (TaskHandle_t)thread_id; - const char* appid = "system"; - - if (!FURI_IS_IRQ_MODE() && (hTask != NULL)) { - FuriThread* thread = (FuriThread*)pvTaskGetThreadLocalStoragePointer(hTask, 0); - if (thread) { - appid = thread->appid; - } - } - - return (appid); -} - -uint32_t furi_thread_get_stack_space(FuriThreadId thread_id) { - TaskHandle_t hTask = (TaskHandle_t)thread_id; - uint32_t sz; - - if (FURI_IS_IRQ_MODE() || (hTask == NULL)) { - sz = 0U; - } else { - sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t)); - } - - return (sz); -} - -static size_t __furi_thread_stdout_write(FuriThread* thread, const char* data, size_t size) { - if (thread->output.write_callback != NULL) { - thread->output.write_callback(data, size); - } else { - furi_hal_console_tx((const uint8_t*)data, size); - } - return size; -} - -static int32_t __furi_thread_stdout_flush(FuriThread* thread) { - FuriString* buffer = thread->output.buffer; - size_t size = furi_string_size(buffer); - if (size > 0) { - __furi_thread_stdout_write(thread, furi_string_get_cstr(buffer), size); - furi_string_reset(buffer); - } - return 0; -} - -void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback) { - FuriThread* thread = furi_thread_get_current(); - furi_assert(thread); - __furi_thread_stdout_flush(thread); - thread->output.write_callback = callback; -} - -FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback() { - FuriThread* thread = furi_thread_get_current(); - furi_assert(thread); - return thread->output.write_callback; -} - -size_t furi_thread_stdout_write(const char* data, size_t size) { - FuriThread* thread = furi_thread_get_current(); - furi_assert(thread); - if (size == 0 || data == NULL) { - return __furi_thread_stdout_flush(thread); - } else { - if (data[size - 1] == '\n') { - // if the last character is a newline, we can flush buffer and write data as is, wo buffers - __furi_thread_stdout_flush(thread); - __furi_thread_stdout_write(thread, data, size); - } else { - // string_cat doesn't work here because we need to write the exact size data - for (size_t i = 0; i < size; i++) { - furi_string_push_back(thread->output.buffer, data[i]); - if (data[i] == '\n') { - __furi_thread_stdout_flush(thread); - } - } - } - } - - return size; -} - -int32_t furi_thread_stdout_flush() { - FuriThread* thread = furi_thread_get_current(); - furi_assert(thread); - return __furi_thread_stdout_flush(thread); -} - -void furi_thread_suspend(FuriThreadId thread_id) { - TaskHandle_t hTask = (TaskHandle_t)thread_id; - vTaskSuspend(hTask); -} - -void furi_thread_resume(FuriThreadId thread_id) { - TaskHandle_t hTask = (TaskHandle_t)thread_id; - if (FURI_IS_IRQ_MODE()) { - xTaskResumeFromISR(hTask); - } else { - vTaskResume(hTask); - } -} - -bool furi_thread_is_suspended(FuriThreadId thread_id) { - TaskHandle_t hTask = (TaskHandle_t)thread_id; - return eTaskGetState(hTask) == eSuspended; -} diff --git a/components/furi/src/thread.h b/components/furi/src/thread.h deleted file mode 100644 index efbf48d4..00000000 --- a/components/furi/src/thread.h +++ /dev/null @@ -1,339 +0,0 @@ -/** - * @file thread.h - * Furi: Furi Thread API - */ - -#pragma once - -#include "furi_core_defines.h" -#include "furi_core_types.h" - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** FuriThreadState */ -typedef enum { - FuriThreadStateStopped, - FuriThreadStateStarting, - FuriThreadStateRunning, -} FuriThreadState; - -/** FuriThreadPriority */ -typedef enum { - FuriThreadPriorityNone = 0, /**< Uninitialized, choose system default */ - FuriThreadPriorityIdle = 1, /**< Idle priority */ - FuriThreadPriorityLowest = 14, /**< Lowest */ - FuriThreadPriorityLow = 15, /**< Low */ - FuriThreadPriorityNormal = 16, /**< Normal */ - FuriThreadPriorityHigh = 17, /**< High */ - FuriThreadPriorityHighest = 18, /**< Highest */ - FuriThreadPriorityIsr = - (FURI_CONFIG_THREAD_MAX_PRIORITIES - 1), /**< Deferred ISR (highest possible) */ -} FuriThreadPriority; - -/** FuriThread anonymous structure */ -typedef struct FuriThread FuriThread; - -/** FuriThreadId proxy type to OS low level functions */ -typedef void* FuriThreadId; - -/** FuriThreadCallback Your callback to run in new thread - * @warning never use osThreadExit in FuriThread - */ -typedef int32_t (*FuriThreadCallback)(void* context); - -/** Write to stdout callback - * @param data pointer to data - * @param size data size @warning your handler must consume everything - */ -typedef void (*FuriThreadStdoutWriteCallback)(const char* data, size_t size); - -/** FuriThread state change callback called upon thread state change - * @param state new thread state - * @param context callback context - */ -typedef void (*FuriThreadStateCallback)(FuriThreadState state, void* context); - -/** Allocate FuriThread - * - * @return FuriThread instance - */ -FuriThread* furi_thread_alloc(); - -/** Allocate FuriThread, shortcut version - * - * @param name - * @param stack_size - * @param callback - * @param context - * @return FuriThread* - */ -FuriThread* furi_thread_alloc_ex( - const char* name, - uint32_t stack_size, - FuriThreadCallback callback, - void* context -); - -/** Release FuriThread - * - * @warning see furi_thread_join - * - * @param thread FuriThread instance - */ -void furi_thread_free(FuriThread* thread); - -/** Set FuriThread name - * - * @param thread FuriThread instance - * @param name string - */ -void furi_thread_set_name(FuriThread* thread, const char* name); - -/** - * @brief Set FuriThread appid - * Technically, it is like a "process id", but it is not a system-wide unique identifier. - * All threads spawned by the same app will have the same appid. - * - * @param thread - * @param appid - */ -void furi_thread_set_appid(FuriThread* thread, const char* appid); - -/** Mark thread as service - * The service cannot be stopped or removed, and cannot exit from the thread body - * - * @param thread - */ -void furi_thread_mark_as_static(FuriThread* thread); - -/** Set FuriThread stack size - * - * @param thread FuriThread instance - * @param stack_size stack size in bytes - */ -void furi_thread_set_stack_size(FuriThread* thread, size_t stack_size); - -/** Set FuriThread callback - * - * @param thread FuriThread instance - * @param callback FuriThreadCallback, called upon thread run - */ -void furi_thread_set_callback(FuriThread* thread, FuriThreadCallback callback); - -/** Set FuriThread context - * - * @param thread FuriThread instance - * @param context pointer to context for thread callback - */ -void furi_thread_set_context(FuriThread* thread, void* context); - -/** Set FuriThread priority - * - * @param thread FuriThread instance - * @param priority FuriThreadPriority value - */ -void furi_thread_set_priority(FuriThread* thread, FuriThreadPriority priority); - -/** Set current thread priority - * - * @param priority FuriThreadPriority value - */ -void furi_thread_set_current_priority(FuriThreadPriority priority); - -/** Get current thread priority - * - * @return FuriThreadPriority value - */ -FuriThreadPriority furi_thread_get_current_priority(); - -/** Set FuriThread state change callback - * - * @param thread FuriThread instance - * @param callback state change callback - */ -void furi_thread_set_state_callback(FuriThread* thread, FuriThreadStateCallback callback); - -/** Set FuriThread state change context - * - * @param thread FuriThread instance - * @param context pointer to context - */ -void furi_thread_set_state_context(FuriThread* thread, void* context); - -/** Get FuriThread state - * - * @param thread FuriThread instance - * - * @return thread state from FuriThreadState - */ -FuriThreadState furi_thread_get_state(FuriThread* thread); - -/** Start FuriThread - * - * @param thread FuriThread instance - */ -void furi_thread_start(FuriThread* thread); - -/** Join FuriThread - * - * @warning Use this method only when CPU is not busy(Idle task receives - * control), otherwise it will wait forever. - * - * @param thread FuriThread instance - * - * @return bool - */ -bool furi_thread_join(FuriThread* thread); - -/** Get FreeRTOS FuriThreadId for FuriThread instance - * - * @param thread FuriThread instance - * - * @return FuriThreadId or NULL - */ -FuriThreadId furi_thread_get_id(FuriThread* thread); - -/** Enable heap tracing - * - * @param thread FuriThread instance - */ -void furi_thread_enable_heap_trace(FuriThread* thread); - -/** Disable heap tracing - * - * @param thread FuriThread instance - */ -void furi_thread_disable_heap_trace(FuriThread* thread); - -/** Get thread heap size - * - * @param thread FuriThread instance - * - * @return size in bytes - */ -size_t furi_thread_get_heap_size(FuriThread* thread); - -/** Get thread return code - * - * @param thread FuriThread instance - * - * @return return code - */ -int32_t furi_thread_get_return_code(FuriThread* thread); - -/** Thread related methods that doesn't involve FuriThread directly */ - -/** Get FreeRTOS FuriThreadId for current thread - * - * @param thread FuriThread instance - * - * @return FuriThreadId or NULL - */ -FuriThreadId furi_thread_get_current_id(); - -/** Get FuriThread instance for current thread - * - * @return pointer to FuriThread or NULL if this thread doesn't belongs to Furi - */ -FuriThread* furi_thread_get_current(); - -/** Return control to scheduler */ -void furi_thread_yield(); - -uint32_t furi_thread_flags_set(FuriThreadId thread_id, uint32_t flags); - -uint32_t furi_thread_flags_clear(uint32_t flags); - -uint32_t furi_thread_flags_get(void); - -uint32_t furi_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeout); - -/** - * @brief Enumerate threads - * - * @param thread_array array of FuriThreadId, where thread ids will be stored - * @param array_items array size - * @return uint32_t threads count - */ -uint32_t furi_thread_enumerate(FuriThreadId* thread_array, uint32_t array_items); - -/** - * @brief Get thread name - * - * @param thread_id - * @return const char* name or NULL - */ -const char* furi_thread_get_name(FuriThreadId thread_id); - -/** - * @brief Get thread appid - * - * @param thread_id - * @return const char* appid - */ -const char* furi_thread_get_appid(FuriThreadId thread_id); - -/** - * @brief Get thread stack watermark - * - * @param thread_id - * @return uint32_t - */ -uint32_t furi_thread_get_stack_space(FuriThreadId thread_id); - -/** Get STDOUT callback for thead - * - * @return STDOUT callback - */ -FuriThreadStdoutWriteCallback furi_thread_get_stdout_callback(); - -/** Set STDOUT callback for thread - * - * @param callback callback or NULL to clear - */ -void furi_thread_set_stdout_callback(FuriThreadStdoutWriteCallback callback); - -/** Write data to buffered STDOUT - * - * @param data input data - * @param size input data size - * - * @return size_t written data size - */ -size_t furi_thread_stdout_write(const char* data, size_t size); - -/** Flush data to STDOUT - * - * @return int32_t error code - */ -int32_t furi_thread_stdout_flush(); - -/** Suspend thread - * - * @param thread_id thread id - */ -void furi_thread_suspend(FuriThreadId thread_id); - -/** Resume thread - * - * @param thread_id thread id - */ -void furi_thread_resume(FuriThreadId thread_id); - -/** Get thread suspended state - * - * @param thread_id thread id - * @return true if thread is suspended - */ -bool furi_thread_is_suspended(FuriThreadId thread_id); - -bool furi_thread_mark_is_service(FuriThreadId thread_id); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/src/timer.h b/components/furi/src/timer.h deleted file mode 100644 index 9d381930..00000000 --- a/components/furi/src/timer.h +++ /dev/null @@ -1,106 +0,0 @@ -#pragma once - -#include "furi_core_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*FuriTimerCallback)(void* context); - -typedef enum { - FuriTimerTypeOnce = 0, ///< One-shot timer. - FuriTimerTypePeriodic = 1 ///< Repeating timer. -} FuriTimerType; - -typedef void FuriTimer; - -/** Allocate timer - * - * @param[in] func The callback function - * @param[in] type The timer type - * @param context The callback context - * - * @return The pointer to FuriTimer instance - */ -FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* context); - -/** Free timer - * - * @param instance The pointer to FuriTimer instance - */ -void furi_timer_free(FuriTimer* instance); - -/** Start timer - * - * @warning This is asynchronous call, real operation will happen as soon as - * timer service process this request. - * - * @param instance The pointer to FuriTimer instance - * @param[in] ticks The interval in ticks - * - * @return The furi status. - */ -FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks); - -/** Restart timer with previous timeout value - * - * @warning This is asynchronous call, real operation will happen as soon as - * timer service process this request. - * - * @param instance The pointer to FuriTimer instance - * @param[in] ticks The interval in ticks - * - * @return The furi status. - */ -FuriStatus furi_timer_restart(FuriTimer* instance, uint32_t ticks); - -/** Stop timer - * - * @warning This is asynchronous call, real operation will happen as soon as - * timer service process this request. - * - * @param instance The pointer to FuriTimer instance - * - * @return The furi status. - */ -FuriStatus furi_timer_stop(FuriTimer* instance); - -/** Is timer running - * - * @warning This cal may and will return obsolete timer state if timer - * commands are still in the queue. Please read FreeRTOS timer - * documentation first. - * - * @param instance The pointer to FuriTimer instance - * - * @return 0: not running, 1: running - */ -uint32_t furi_timer_is_running(FuriTimer* instance); - -/** Get timer expire time - * - * @param instance The Timer instance - * - * @return expire tick - */ -uint32_t furi_timer_get_expire_time(FuriTimer* instance); - -typedef void (*FuriTimerPendigCallback)(void* context, uint32_t arg); - -void furi_timer_pending_callback(FuriTimerPendigCallback callback, void* context, uint32_t arg); - -typedef enum { - FuriTimerThreadPriorityNormal, /**< Lower then other threads */ - FuriTimerThreadPriorityElevated, /**< Same as other threads */ -} FuriTimerThreadPriority; - -/** Set Timer thread priority - * - * @param[in] priority The priority - */ -void furi_timer_set_thread_priority(FuriTimerThreadPriority priority); - -#ifdef __cplusplus -} -#endif diff --git a/components/furi/CMakeLists.txt b/components/tactility-core/CMakeLists.txt similarity index 100% rename from components/furi/CMakeLists.txt rename to components/tactility-core/CMakeLists.txt diff --git a/components/furi/LICENSE.md b/components/tactility-core/LICENSE.md similarity index 100% rename from components/furi/LICENSE.md rename to components/tactility-core/LICENSE.md diff --git a/components/tactility-core/README.md b/components/tactility-core/README.md new file mode 100644 index 00000000..6f13faff --- /dev/null +++ b/components/tactility-core/README.md @@ -0,0 +1,8 @@ +## Description + +A good portion of this code is derived from the "Furi" code in the [Flipper Zero firmware](https://github.com/flipperdevices/flipperzero-firmware/). +Some of it is also inspired by the Android operating system. + +## License + +[GNU General Public License Version 3](LICENSE.md) diff --git a/components/tactility-core/src/api_lock.h b/components/tactility-core/src/api_lock.h new file mode 100644 index 00000000..e47f65b0 --- /dev/null +++ b/components/tactility-core/src/api_lock.h @@ -0,0 +1,20 @@ +#pragma once + +#include "core.h" + +typedef EventFlag* ApiLock; + +#define TT_API_LOCK_EVENT (1U << 0) + +#define tt_api_lock_alloc_locked() tt_event_flag_alloc() + +#define tt_api_lock_wait_unlock(_lock) \ + tt_event_flag_wait(_lock, TT_API_LOCK_EVENT, TtFlagWaitAny, TtWaitForever) + +#define tt_api_lock_free(_lock) tt_event_flag_free(_lock) + +#define tt_api_lock_unlock(_lock) tt_event_flag_set(_lock, TT_API_LOCK_EVENT) + +#define tt_api_lock_wait_unlock_and_free(_lock) \ + tt_api_lock_wait_unlock(_lock); \ + tt_api_lock_free(_lock); diff --git a/components/furi/src/app.c b/components/tactility-core/src/app.c similarity index 58% rename from components/furi/src/app.c rename to components/tactility-core/src/app.c index 6c85c40f..abac0f8e 100644 --- a/components/furi/src/app.c +++ b/components/tactility-core/src/app.c @@ -2,16 +2,16 @@ #include -static AppFlags app_get_flags_default(AppType type); +static AppFlags tt_app_get_flags_default(AppType type); // region Alloc/free -App app_alloc(const AppManifest* manifest, Bundle* _Nullable parameters) { +App tt_app_alloc(const AppManifest* manifest, Bundle* _Nullable parameters) { AppData* data = malloc(sizeof(AppData)); *data = (AppData) { - .mutex = furi_mutex_alloc(FuriMutexTypeRecursive), + .mutex = tt_mutex_alloc(MutexTypeRecursive), .state = APP_STATE_INITIAL, - .flags = app_get_flags_default(manifest->type), + .flags = tt_app_get_flags_default(manifest->type), .manifest = manifest, .parameters = parameters, .data = NULL @@ -19,12 +19,12 @@ App app_alloc(const AppManifest* manifest, Bundle* _Nullable parameters) { return (App*)data; } -void app_free(App app) { +void tt_app_free(App app) { AppData* data = (AppData*)app; if (data->parameters) { - bundle_free(data->parameters); + tt_bundle_free(data->parameters); } - furi_mutex_free(data->mutex); + tt_mutex_free(data->mutex); free(data); } @@ -32,15 +32,15 @@ void app_free(App app) { // region Internal -static void app_lock(AppData* data) { - furi_mutex_acquire(data->mutex, FuriMutexTypeRecursive); +static void tt_app_lock(AppData* data) { + tt_mutex_acquire(data->mutex, MutexTypeRecursive); } -static void app_unlock(AppData* data) { - furi_mutex_release(data->mutex); +static void tt_app_unlock(AppData* data) { + tt_mutex_release(data->mutex); } -static AppFlags app_get_flags_default(AppType type) { +static AppFlags tt_app_get_flags_default(AppType type) { static const AppFlags DEFAULT_DESKTOP_FLAGS = { .show_toolbar = false, .show_statusbar = true @@ -60,55 +60,55 @@ static AppFlags app_get_flags_default(AppType type) { // region Public getters & setters -void app_set_state(App app, AppState state) { +void tt_app_set_state(App app, AppState state) { AppData* data = (AppData*)app; - app_lock(data); + tt_app_lock(data); data->state = state; - app_unlock(data); + tt_app_unlock(data); } -AppState app_get_state(App app) { +AppState tt_app_get_state(App app) { AppData* data = (AppData*)app; - app_lock(data); + tt_app_lock(data); AppState state = data->state; - app_unlock(data); + tt_app_unlock(data); return state; } -const AppManifest* app_get_manifest(App app) { +const AppManifest* tt_app_get_manifest(App app) { AppData* data = (AppData*)app; // No need to lock const data; return data->manifest; } -AppFlags app_get_flags(App app) { +AppFlags tt_app_get_flags(App app) { AppData* data = (AppData*)app; - app_lock(data); + tt_app_lock(data); AppFlags flags = data->flags; - app_unlock(data); + tt_app_unlock(data); return flags; } -void app_set_flags(App app, AppFlags flags) { +void tt_app_set_flags(App app, AppFlags flags) { AppData* data = (AppData*)app; - app_lock(data); + tt_app_lock(data); data->flags = flags; - app_unlock(data); + tt_app_unlock(data); } -void* app_get_data(App app) { +void* tt_app_get_data(App app) { AppData* data = (AppData*)app; - app_lock(data); + tt_app_lock(data); void* value = data->data; - app_unlock(data); + tt_app_unlock(data); return value; } -void app_set_data(App app, void* value) { +void tt_app_set_data(App app, void* value) { AppData* data = (AppData*)app; - app_lock(data); + tt_app_lock(data); data->data = value; - app_unlock(data); + tt_app_unlock(data); } /** TODO: Make this thread-safe. @@ -117,11 +117,11 @@ void app_set_data(App app, void* value) { * Consider creating MutableBundle vs Bundle. * Consider not exposing bundle, but expose `app_get_bundle_int(key)` methods with locking in it. */ -Bundle* _Nullable app_get_parameters(App app) { +Bundle* _Nullable tt_app_get_parameters(App app) { AppData* data = (AppData*)app; - app_lock(data); + tt_app_lock(data); Bundle* bundle = data->parameters; - app_unlock(data); + tt_app_unlock(data); return bundle; } diff --git a/components/furi/src/app.h b/components/tactility-core/src/app.h similarity index 60% rename from components/furi/src/app.h rename to components/tactility-core/src/app.h index b22a331e..d93d04a8 100644 --- a/components/furi/src/app.h +++ b/components/tactility-core/src/app.h @@ -30,21 +30,21 @@ typedef void* App; * @param parameters optional bundle. memory ownership is transferred to App * @return */ -App app_alloc(const AppManifest* manifest, Bundle* _Nullable parameters); -void app_free(App app); +App tt_app_alloc(const AppManifest* manifest, Bundle* _Nullable parameters); +void tt_app_free(App app); -void app_set_state(App app, AppState state); -AppState app_get_state(App app); +void tt_app_set_state(App app, AppState state); +AppState tt_app_get_state(App app); -const AppManifest* app_get_manifest(App app); +const AppManifest* tt_app_get_manifest(App app); -AppFlags app_get_flags(App app); -void app_set_flags(App app, AppFlags flags); +AppFlags tt_app_get_flags(App app); +void tt_app_set_flags(App app, AppFlags flags); -void* _Nullable app_get_data(App app); -void app_set_data(App app, void* data); +void* _Nullable tt_app_get_data(App app); +void tt_app_set_data(App app, void* data); -Bundle* _Nullable app_get_parameters(App app); +Bundle* _Nullable tt_app_get_parameters(App app); #ifdef __cplusplus } diff --git a/components/furi/src/app_i.h b/components/tactility-core/src/app_i.h similarity index 95% rename from components/furi/src/app_i.h rename to components/tactility-core/src/app_i.h index 44544b03..127661c8 100644 --- a/components/furi/src/app_i.h +++ b/components/tactility-core/src/app_i.h @@ -3,7 +3,6 @@ #include "app.h" #include "app_manifest.h" -#include "context.h" #include "mutex.h" #include @@ -12,7 +11,7 @@ extern "C" { #endif typedef struct { - FuriMutex* mutex; + Mutex* mutex; const AppManifest* manifest; AppState state; AppFlags flags; diff --git a/components/furi/src/app_manifest.h b/components/tactility-core/src/app_manifest.h similarity index 100% rename from components/furi/src/app_manifest.h rename to components/tactility-core/src/app_manifest.h diff --git a/components/furi/src/app_manifest_registry.c b/components/tactility-core/src/app_manifest_registry.c similarity index 71% rename from components/furi/src/app_manifest_registry.c rename to components/tactility-core/src/app_manifest_registry.c index 80d8bce7..7345a975 100644 --- a/components/furi/src/app_manifest_registry.c +++ b/components/tactility-core/src/app_manifest_registry.c @@ -1,9 +1,9 @@ #include "app_manifest_registry.h" -#include "furi_core.h" #include "m-dict.h" #include "m_cstr_dup.h" #include "mutex.h" +#include "tactility_core.h" #define TAG "app_registry" @@ -21,47 +21,47 @@ DICT_DEF2(AppManifestDict, const char*, M_CSTR_DUP_OPLIST, const AppManifest*, M } AppManifestDict_t app_manifest_dict; -FuriMutex* mutex = NULL; +Mutex* mutex = NULL; -void app_manifest_registry_init() { - furi_assert(mutex == NULL); - mutex = furi_mutex_alloc(FuriMutexTypeNormal); +void tt_app_manifest_registry_init() { + tt_assert(mutex == NULL); + mutex = tt_mutex_alloc(MutexTypeNormal); AppManifestDict_init(app_manifest_dict); } void app_registry_lock() { - furi_assert(mutex != NULL); - furi_mutex_acquire(mutex, FuriWaitForever); + tt_assert(mutex != NULL); + tt_mutex_acquire(mutex, TtWaitForever); } void app_registry_unlock() { - furi_assert(mutex != NULL); - furi_mutex_release(mutex); + tt_assert(mutex != NULL); + tt_mutex_release(mutex); } -void app_manifest_registry_add(const AppManifest _Nonnull* manifest) { - FURI_LOG_I(TAG, "adding %s", manifest->id); +void tt_app_manifest_registry_add(const AppManifest _Nonnull* manifest) { + TT_LOG_I(TAG, "adding %s", manifest->id); app_registry_lock(); AppManifestDict_set_at(app_manifest_dict, manifest->id, manifest); app_registry_unlock(); } -void app_manifest_registry_remove(const AppManifest _Nonnull* manifest) { - FURI_LOG_I(TAG, "removing %s", manifest->id); +void tt_app_manifest_registry_remove(const AppManifest _Nonnull* manifest) { + TT_LOG_I(TAG, "removing %s", manifest->id); app_registry_lock(); AppManifestDict_erase(app_manifest_dict, manifest->id); app_registry_unlock(); } -const AppManifest _Nullable* app_manifest_registry_find_by_id(const char* id) { +const AppManifest _Nullable* tt_app_manifest_registry_find_by_id(const char* id) { app_registry_lock(); const AppManifest _Nullable** manifest = AppManifestDict_get(app_manifest_dict, id); app_registry_unlock(); return (manifest != NULL) ? *manifest : NULL; } -void app_manifest_registry_for_each_of_type(AppType type, void* _Nullable context, AppManifestCallback callback) { +void tt_app_manifest_registry_for_each_of_type(AppType type, void* _Nullable context, AppManifestCallback callback) { APP_REGISTRY_FOR_EACH(manifest, { if (manifest->type == type) { callback(manifest, context); @@ -69,7 +69,7 @@ void app_manifest_registry_for_each_of_type(AppType type, void* _Nullable contex }); } -void app_manifest_registry_for_each(AppManifestCallback callback, void* _Nullable context) { +void tt_app_manifest_registry_for_each(AppManifestCallback callback, void* _Nullable context) { APP_REGISTRY_FOR_EACH(manifest, { callback(manifest, context); }); diff --git a/components/tactility-core/src/app_manifest_registry.h b/components/tactility-core/src/app_manifest_registry.h new file mode 100644 index 00000000..068a8f5b --- /dev/null +++ b/components/tactility-core/src/app_manifest_registry.h @@ -0,0 +1,20 @@ +#pragma once + +#include "app_manifest.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*AppManifestCallback)(const AppManifest*, void* context); + +void tt_app_manifest_registry_init(); +void tt_app_manifest_registry_add(const AppManifest _Nonnull* manifest); +void tt_app_manifest_registry_remove(const AppManifest _Nonnull* manifest); +const AppManifest _Nullable* tt_app_manifest_registry_find_by_id(const char* id); +void tt_app_manifest_registry_for_each(AppManifestCallback callback, void* _Nullable context); +void tt_app_manifest_registry_for_each_of_type(AppType type, void* _Nullable context, AppManifestCallback callback); + +#ifdef __cplusplus +} +#endif diff --git a/components/furi/src/bundle.c b/components/tactility-core/src/bundle.c similarity index 82% rename from components/furi/src/bundle.c rename to components/tactility-core/src/bundle.c index da6a4fb6..bac8e427 100644 --- a/components/furi/src/bundle.c +++ b/components/tactility-core/src/bundle.c @@ -72,15 +72,15 @@ typedef struct { BundleDict_t dict; } BundleData; -Bundle bundle_alloc() { +Bundle tt_bundle_alloc() { BundleData* bundle = malloc(sizeof(BundleData)); BundleDict_init(bundle->dict); return bundle; } -Bundle bundle_alloc_copy(Bundle source) { +Bundle tt_bundle_alloc_copy(Bundle source) { BundleData* source_data = (BundleData*)source; - BundleData* target_data = bundle_alloc(); + BundleData* target_data = tt_bundle_alloc(); BundleDict_it_t it; for (BundleDict_it(it, source_data->dict); !BundleDict_end_p(it); BundleDict_next(it)) { @@ -93,7 +93,7 @@ Bundle bundle_alloc_copy(Bundle source) { return target_data; } -void bundle_free(Bundle bundle) { +void tt_bundle_free(Bundle bundle) { BundleData* data = (BundleData*)bundle; BundleDict_it_t it; @@ -105,28 +105,28 @@ void bundle_free(Bundle bundle) { free(data); } -bool bundle_get_bool(Bundle bundle, const char* key) { +bool tt_bundle_get_bool(Bundle bundle, const char* key) { BundleData* data = (BundleData*)bundle; BundleEntry** entry = BundleDict_get(data->dict, key); - furi_check(entry != NULL); + tt_check(entry != NULL); return (*entry)->bool_value; } -int bundle_get_int(Bundle bundle, const char* key) { +int tt_bundle_get_int(Bundle bundle, const char* key) { BundleData* data = (BundleData*)bundle; BundleEntry** entry = BundleDict_get(data->dict, key); - furi_check(entry != NULL); + tt_check(entry != NULL); return (*entry)->int_value; } -const char* bundle_get_string(Bundle bundle, const char* key) { +const char* tt_bundle_get_string(Bundle bundle, const char* key) { BundleData* data = (BundleData*)bundle; BundleEntry** entry = BundleDict_get(data->dict, key); - furi_check(entry != NULL); + tt_check(entry != NULL); return (*entry)->string_ptr; } -bool bundle_opt_bool(Bundle bundle, const char* key, bool* out) { +bool tt_bundle_opt_bool(Bundle bundle, const char* key, bool* out) { BundleData* data = (BundleData*)bundle; BundleEntry** entry = BundleDict_get(data->dict, key); if (entry != NULL) { @@ -137,7 +137,7 @@ bool bundle_opt_bool(Bundle bundle, const char* key, bool* out) { } } -bool bundle_opt_int(Bundle bundle, const char* key, int* out) { +bool tt_bundle_opt_int(Bundle bundle, const char* key, int* out) { BundleData* data = (BundleData*)bundle; BundleEntry** entry = BundleDict_get(data->dict, key); if (entry != NULL) { @@ -148,7 +148,7 @@ bool bundle_opt_int(Bundle bundle, const char* key, int* out) { } } -bool bundle_opt_string(Bundle bundle, const char* key, char** out) { +bool tt_bundle_opt_string(Bundle bundle, const char* key, char** out) { BundleData* data = (BundleData*)bundle; BundleEntry** entry = BundleDict_get(data->dict, key); if (entry != NULL) { @@ -159,12 +159,12 @@ bool bundle_opt_string(Bundle bundle, const char* key, char** out) { } } -void bundle_put_bool(Bundle bundle, const char* key, bool value) { +void tt_bundle_put_bool(Bundle bundle, const char* key, bool value) { BundleData* data = (BundleData*)bundle; BundleEntry** entry_handle = BundleDict_get(data->dict, key); if (entry_handle != NULL) { BundleEntry* entry = *entry_handle; - furi_assert(entry->type == BUNDLE_ENTRY_TYPE_BOOL); + tt_assert(entry->type == BUNDLE_ENTRY_TYPE_BOOL); entry->bool_value = value; } else { BundleEntry* entry = bundle_entry_alloc_bool(value); @@ -172,12 +172,12 @@ void bundle_put_bool(Bundle bundle, const char* key, bool value) { } } -void bundle_put_int(Bundle bundle, const char* key, int value) { +void tt_bundle_put_int(Bundle bundle, const char* key, int value) { BundleData* data = (BundleData*)bundle; BundleEntry** entry_handle = BundleDict_get(data->dict, key); if (entry_handle != NULL) { BundleEntry* entry = *entry_handle; - furi_assert(entry->type == BUNDLE_ENTRY_TYPE_INT); + tt_assert(entry->type == BUNDLE_ENTRY_TYPE_INT); entry->int_value = value; } else { BundleEntry* entry = bundle_entry_alloc_int(value); @@ -185,12 +185,12 @@ void bundle_put_int(Bundle bundle, const char* key, int value) { } } -void bundle_put_string(Bundle bundle, const char* key, const char* value) { +void tt_bundle_put_string(Bundle bundle, const char* key, const char* value) { BundleData* data = (BundleData*)bundle; BundleEntry** entry_handle = BundleDict_get(data->dict, key); if (entry_handle != NULL) { BundleEntry* entry = *entry_handle; - furi_assert(entry->type == BUNDLE_ENTRY_TYPE_STRING); + tt_assert(entry->type == BUNDLE_ENTRY_TYPE_STRING); if (entry->string_ptr != NULL) { free(entry->string_ptr); } diff --git a/components/tactility-core/src/bundle.h b/components/tactility-core/src/bundle.h new file mode 100644 index 00000000..fc8c3af1 --- /dev/null +++ b/components/tactility-core/src/bundle.h @@ -0,0 +1,34 @@ +/** + * @brief key-value storage for general purpose. + * Maps strings on a fixed set of data types. + */ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void* Bundle; + +Bundle tt_bundle_alloc(); +Bundle tt_bundle_alloc_copy(Bundle source); +void tt_bundle_free(Bundle bundle); + +bool tt_bundle_get_bool(Bundle bundle, const char* key); +int tt_bundle_get_int(Bundle bundle, const char* key); +const char* tt_bundle_get_string(Bundle bundle, const char* key); + +bool tt_bundle_opt_bool(Bundle bundle, const char* key, bool* out); +bool tt_bundle_opt_int(Bundle bundle, const char* key, int* out); +bool tt_bundle_opt_string(Bundle bundle, const char* key, char** out); + +void tt_bundle_put_bool(Bundle bundle, const char* key, bool value); +void tt_bundle_put_int(Bundle bundle, const char* key, int value); +void tt_bundle_put_string(Bundle bundle, const char* key, const char* value); + +#ifdef __cplusplus +} +#endif diff --git a/components/tactility-core/src/check.c b/components/tactility-core/src/check.c new file mode 100644 index 00000000..2a7588e0 --- /dev/null +++ b/components/tactility-core/src/check.c @@ -0,0 +1,38 @@ +#include "check.h" +#include "core_defines.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "log.h" + +#define TAG "kernel" + +static void tt_print_memory_info() { + TT_LOG_E(TAG, "default caps:"); + TT_LOG_E(TAG, " total: %u", heap_caps_get_total_size(MALLOC_CAP_DEFAULT)); + TT_LOG_E(TAG, " free: %u", heap_caps_get_free_size(MALLOC_CAP_DEFAULT)); + TT_LOG_E(TAG, " min free: %u", heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT)); + TT_LOG_E(TAG, "internal caps:"); + TT_LOG_E(TAG, " total: %u", heap_caps_get_total_size(MALLOC_CAP_INTERNAL)); + TT_LOG_E(TAG, " free: %u", heap_caps_get_free_size(MALLOC_CAP_INTERNAL)); + TT_LOG_E(TAG, " min free: %u", heap_caps_get_minimum_free_size(MALLOC_CAP_INTERNAL)); +} + +static void tt_print_task_info() { + if (TT_IS_IRQ_MODE()) { + TT_LOG_E(TAG, "Task: ISR %lu", __get_IPSR()); + } else { + const char* name = pcTaskGetName(NULL); + 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(); + // TODO: Add breakpoint when debugger is attached. + esp_system_abort("System halted. Connect debugger for more info."); + __builtin_unreachable(); +} diff --git a/components/furi/src/check.h b/components/tactility-core/src/check.h similarity index 50% rename from components/furi/src/check.h rename to components/tactility-core/src/check.h index 122819bd..2097e18a 100644 --- a/components/furi/src/check.h +++ b/components/tactility-core/src/check.h @@ -1,7 +1,7 @@ /** * @file check.h * - * Furi crash and assert functions. + * Tactility crash and assert 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. @@ -18,54 +18,44 @@ #ifdef __cplusplus extern "C" { -#define FURI_NORETURN [[noreturn]] +#define TT_NORETURN [[noreturn]] #else #include -#define FURI_NORETURN noreturn +#define TT_NORETURN noreturn #endif -// Flags instead of pointers will save ~4 bytes on furi_assert and furi_check calls. -#define __FURI_ASSERT_MESSAGE_FLAG (0x01) -#define __FURI_CHECK_MESSAGE_FLAG (0x02) - /** Crash system */ -FURI_NORETURN void __furi_crash_implementation(); - -/** Halt system */ -FURI_NORETURN void __furi_halt_implementation(); +TT_NORETURN void tt_crash_implementation(); /** Crash system with message. */ -#define __furi_crash(message) \ - do { \ +#define __tt_crash(message) \ + do { \ ESP_LOGE("crash", "%s\n\tat %s:%d", ((message) ? (message) : ""), __FILE__, __LINE__); \ - __furi_crash_implementation(); \ + tt_crash_implementation(); \ } while (0) /** Crash system * * @param optional message (const char*) */ -#define furi_crash(...) M_APPLY(__furi_crash, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__))) - -/** Halt system with message. */ -#define __furi_halt(message) \ - do { \ - ESP_LOGE("halt", "%s\n\tat %s:%d", ((message) ? (message) : ""), __FILE__, __LINE__); \ - __furi_halt_implementation(); \ - } while (0) +#define tt_crash(...) M_APPLY(__tt_crash, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__))) /** Halt system * * @param optional message (const char*) */ -#define furi_halt(...) M_APPLY(__furi_halt, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__))) +#define tt_halt(...) M_APPLY(__tt_halt, M_IF_EMPTY(__VA_ARGS__)((NULL), (__VA_ARGS__))) /** Check condition and crash if check failed */ -#define __furi_check(__e, __m) \ +#define __tt_check(__e, __m) \ do { \ if (!(__e)) { \ ESP_LOGE("check", "%s", #__e); \ - __furi_crash(#__m); \ + if (__m) { \ + __tt_crash(#__m); \ + } else { \ + __tt_crash(""); \ + } \ } \ } while (0) @@ -74,23 +64,27 @@ FURI_NORETURN void __furi_halt_implementation(); * @param condition to check * @param optional message (const char*) */ -#define furi_check(...) \ - M_APPLY(__furi_check, M_DEFAULT_ARGS(2, (__FURI_CHECK_MESSAGE_FLAG), __VA_ARGS__)) +#define tt_check(...) \ + M_APPLY(__tt_check, M_DEFAULT_ARGS(2, NULL, __VA_ARGS__)) /** Only in debug build: Assert condition and crash if assert failed */ -#ifdef FURI_DEBUG -#define __furi_assert(__e, __m) \ +#ifdef TT_DEBUG +#define __tt_assert(__e, __m) \ do { \ if (!(__e)) { \ ESP_LOGE("assert", "%s", #__e); \ - __furi_crash(#__m); \ + if (__m) { \ + __tt_crash(#__m); \ + } else { \ + __tt_crash(""); \ + } \ } \ } while (0) #else -#define __furi_assert(__e, __m) \ - do { \ - ((void)(__e)); \ - ((void)(__m)); \ +#define __tt_assert(__e, __m) \ + do { \ + ((void)(__e)); \ + ((void)(__m)); \ } while (0) #endif @@ -101,8 +95,8 @@ FURI_NORETURN void __furi_halt_implementation(); * @param condition to check * @param optional message (const char*) */ -#define furi_assert(...) \ - M_APPLY(__furi_assert, M_DEFAULT_ARGS(2, (__FURI_ASSERT_MESSAGE_FLAG), __VA_ARGS__)) +#define tt_assert(...) \ + M_APPLY(__tt_assert, M_DEFAULT_ARGS(2, NULL, __VA_ARGS__)) #ifdef __cplusplus } diff --git a/components/furi/src/furi.c b/components/tactility-core/src/core.c similarity index 58% rename from components/furi/src/furi.c rename to components/tactility-core/src/core.c index 6822d167..2b748517 100644 --- a/components/furi/src/furi.c +++ b/components/tactility-core/src/core.c @@ -1,15 +1,13 @@ -#include "furi.h" +#include "core.h" #include "app_manifest_registry.h" -#include "freertos/FreeRTOS.h" -#include "freertos/queue.h" #include "service_registry.h" -#define TAG "furi" +#define TAG "tactility" -void furi_init() { - FURI_LOG_I(TAG, "init start"); - furi_assert(!furi_kernel_is_irq()); +void tt_core_init() { + TT_LOG_I(TAG, "core init start"); + tt_assert(!tt_kernel_is_irq()); #if defined(__ARM_ARCH_7A__) && (__ARM_ARCH_7A__ == 0U) /* Service Call interrupt might be configured before kernel start */ @@ -18,7 +16,7 @@ void furi_init() { NVIC_SetPriority(SVCall_IRQn, 0U); #endif - service_registry_init(); - app_manifest_registry_init(); - FURI_LOG_I(TAG, "init complete"); + tt_service_registry_init(); + tt_app_manifest_registry_init(); + TT_LOG_I(TAG, "core init complete"); } diff --git a/components/furi/src/furi.h b/components/tactility-core/src/core.h similarity index 81% rename from components/furi/src/furi.h rename to components/tactility-core/src/core.h index 9e20f726..c7da5bfc 100644 --- a/components/furi/src/furi.h +++ b/components/tactility-core/src/core.h @@ -2,9 +2,8 @@ #include -#include "furi_core.h" +#include "tactility_core.h" -#include "furi_string.h" #include "event_flag.h" #include "kernel.h" #include "message_queue.h" @@ -15,12 +14,13 @@ #include "string.h" #include "thread.h" #include "timer.h" +#include "tt_string.h" #ifdef __cplusplus extern "C" { #endif -void furi_init(); +void tt_core_init(); #ifdef __cplusplus } diff --git a/components/tactility-core/src/core_defines.h b/components/tactility-core/src/core_defines.h new file mode 100644 index 00000000..d5b47fd0 --- /dev/null +++ b/components/tactility-core/src/core_defines.h @@ -0,0 +1,42 @@ +#pragma once + +#include "core_extra_defines.h" +#include "freertos/portmacro.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define TT_RETURNS_NONNULL __attribute__((returns_nonnull)) + +#ifndef TT_WARN_UNUSED +#define TT_WARN_UNUSED __attribute__((warn_unused_result)) +#endif + +#ifndef TT_WEAK +#define TT_WEAK __attribute__((weak)) +#endif + +#ifndef TT_PACKED +#define TT_PACKED __attribute__((packed)) +#endif + +// Used by portENABLE_INTERRUPTS and portDISABLE_INTERRUPTS? +#ifndef TT_IS_IRQ_MODE +#define TT_IS_IRQ_MODE() (xPortInIsrContext() == pdTRUE) +#endif + +#ifndef TT_IS_ISR +#define TT_IS_ISR() (TT_IS_IRQ_MODE()) +#endif + +#ifndef TT_CHECK_RETURN +#define TT_CHECK_RETURN __attribute__((__warn_unused_result__)) +#endif + +#ifdef __cplusplus +} +#endif diff --git a/components/furi/src/furi_extra_defines.h b/components/tactility-core/src/core_extra_defines.h similarity index 85% rename from components/furi/src/furi_extra_defines.h rename to components/tactility-core/src/core_extra_defines.h index b828644d..9a231694 100644 --- a/components/furi/src/furi_extra_defines.h +++ b/components/tactility-core/src/core_extra_defines.h @@ -4,8 +4,6 @@ extern "C" { #endif -#define FURI_RETURNS_NONNULL __attribute__((returns_nonnull)) - #ifndef MAX #define MAX(a, b) \ ({ \ @@ -45,8 +43,8 @@ extern "C" { #define COUNT_OF(x) (sizeof(x) / sizeof(x[0])) #endif -#ifndef FURI_SWAP -#define FURI_SWAP(x, y) \ +#ifndef TT_SWAP +#define TT_SWAP(x, y) \ do { \ typeof(x) SWAP = x; \ x = y; \ @@ -89,27 +87,27 @@ extern "C" { (((x) & 0xFF000000) >> 24)) #endif -#ifndef FURI_BIT -#define FURI_BIT(x, n) (((x) >> (n)) & 1) +#ifndef TT_BIT +#define TT_BIT(x, n) (((x) >> (n)) & 1) #endif -#ifndef FURI_BIT_SET -#define FURI_BIT_SET(x, n) \ +#ifndef TT_BIT_SET +#define TT_BIT_SET(x, n) \ ({ \ __typeof__(x) _x = (1); \ (x) |= (_x << (n)); \ }) #endif -#ifndef FURI_BIT_CLEAR -#define FURI_BIT_CLEAR(x, n) \ +#ifndef TT_BIT_CLEAR +#define TT_BIT_CLEAR(x, n) \ ({ \ __typeof__(x) _x = (1); \ (x) &= ~(_x << (n)); \ }) #endif -#define FURI_SW_MEMBARRIER() asm volatile("" : : : "memory") +#define TT_SW_MEMBARRIER() asm volatile("" : : : "memory") #ifdef __cplusplus } diff --git a/components/tactility-core/src/core_types.h b/components/tactility-core/src/core_types.h new file mode 100644 index 00000000..372982dd --- /dev/null +++ b/components/tactility-core/src/core_types.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + TtWaitForever = 0xFFFFFFFFU, +} TtWait; + +typedef enum { + TtFlagWaitAny = 0x00000000U, ///< Wait for any flag (default). + TtFlagWaitAll = 0x00000001U, ///< Wait for all flags. + TtFlagNoClear = 0x00000002U, ///< Do not clear flags which have been specified to wait for. + + TtFlagError = 0x80000000U, ///< Error indicator. + TtFlagErrorUnknown = 0xFFFFFFFFU, ///< TtStatusError (-1). + TtFlagErrorTimeout = 0xFFFFFFFEU, ///< TtStatusErrorTimeout (-2). + TtFlagErrorResource = 0xFFFFFFFDU, ///< TtStatusErrorResource (-3). + TtFlagErrorParameter = 0xFFFFFFFCU, ///< TtStatusErrorParameter (-4). + TtFlagErrorISR = 0xFFFFFFFAU, ///< TtStatusErrorISR (-6). +} TtFlag; + +typedef enum { + TtStatusOk = 0, ///< Operation completed successfully. + TtStatusError = + -1, ///< Unspecified RTOS error: run-time error but no other error message fits. + TtStatusErrorTimeout = -2, ///< Operation not completed within the timeout period. + TtStatusErrorResource = -3, ///< Resource not available. + TtStatusErrorParameter = -4, ///< Parameter error. + TtStatusErrorNoMemory = + -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + TtStatusErrorISR = + -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + TtStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} TtStatus; + +#ifdef __cplusplus +} +#endif diff --git a/components/furi/src/critical.c b/components/tactility-core/src/critical.c similarity index 76% rename from components/furi/src/critical.c rename to components/tactility-core/src/critical.c index d434a16e..18e0c177 100644 --- a/components/furi/src/critical.c +++ b/components/tactility-core/src/critical.c @@ -1,16 +1,16 @@ #include "critical.h" -#include "furi_core_defines.h" +#include "core_defines.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" static portMUX_TYPE critical_mutex; -__FuriCriticalInfo __furi_critical_enter(void) { - __FuriCriticalInfo info; +__TtCriticalInfo __tt_critical_enter(void) { + __TtCriticalInfo info; info.isrm = 0; - info.from_isr = FURI_IS_ISR(); + info.from_isr = TT_IS_ISR(); info.kernel_running = (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING); if (info.from_isr) { @@ -24,7 +24,7 @@ __FuriCriticalInfo __furi_critical_enter(void) { return info; } -void __furi_critical_exit(__FuriCriticalInfo info) { +void __tt_critical_exit(__TtCriticalInfo info) { if (info.from_isr) { taskEXIT_CRITICAL_FROM_ISR(info.isrm); } else if (info.kernel_running) { diff --git a/components/tactility-core/src/critical.h b/components/tactility-core/src/critical.h new file mode 100644 index 00000000..900eb839 --- /dev/null +++ b/components/tactility-core/src/critical.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#ifndef TT_CRITICAL_ENTER +#define TT_CRITICAL_ENTER() __TtCriticalInfo __tt_critical_info = __tt_critical_enter(); +#endif + +#ifndef TT_CRITICAL_EXIT +#define TT_CRITICAL_EXIT() __tt_critical_exit(__tt_critical_info); +#endif + +typedef struct { + uint32_t isrm; + bool from_isr; + bool kernel_running; +} __TtCriticalInfo; + +__TtCriticalInfo __tt_critical_enter(void); + +void __tt_critical_exit(__TtCriticalInfo info); diff --git a/components/furi/src/event_flag.c b/components/tactility-core/src/event_flag.c similarity index 62% rename from components/furi/src/event_flag.c rename to components/tactility-core/src/event_flag.c index bbe26a92..8ac47896 100644 --- a/components/furi/src/event_flag.c +++ b/components/tactility-core/src/event_flag.c @@ -1,39 +1,39 @@ #include "event_flag.h" #include "check.h" -#include "furi_core_defines.h" +#include "core_defines.h" #include "freertos/FreeRTOS.h" #include "freertos/event_groups.h" -#define FURI_EVENT_FLAG_MAX_BITS_EVENT_GROUPS 24U -#define FURI_EVENT_FLAG_INVALID_BITS (~((1UL << FURI_EVENT_FLAG_MAX_BITS_EVENT_GROUPS) - 1U)) +#define TT_EVENT_FLAG_MAX_BITS_EVENT_GROUPS 24U +#define TT_EVENT_FLAG_INVALID_BITS (~((1UL << TT_EVENT_FLAG_MAX_BITS_EVENT_GROUPS) - 1U)) -FuriEventFlag* furi_event_flag_alloc() { - furi_assert(!FURI_IS_IRQ_MODE()); +EventFlag* tt_event_flag_alloc() { + tt_assert(!TT_IS_IRQ_MODE()); EventGroupHandle_t handle = xEventGroupCreate(); - furi_check(handle); + tt_check(handle); - return ((FuriEventFlag*)handle); + return ((EventFlag*)handle); } -void furi_event_flag_free(FuriEventFlag* instance) { - furi_assert(!FURI_IS_IRQ_MODE()); +void tt_event_flag_free(EventFlag* instance) { + tt_assert(!TT_IS_IRQ_MODE()); vEventGroupDelete((EventGroupHandle_t)instance); } -uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags) { - furi_assert(instance); - furi_assert((flags & FURI_EVENT_FLAG_INVALID_BITS) == 0U); +uint32_t tt_event_flag_set(EventFlag* instance, uint32_t flags) { + tt_assert(instance); + tt_assert((flags & TT_EVENT_FLAG_INVALID_BITS) == 0U); EventGroupHandle_t hEventGroup = (EventGroupHandle_t)instance; uint32_t rflags; BaseType_t yield; - if (FURI_IS_IRQ_MODE()) { + if (TT_IS_IRQ_MODE()) { yield = pdFALSE; if (xEventGroupSetBitsFromISR(hEventGroup, (EventBits_t)flags, &yield) == pdFAIL) { - rflags = (uint32_t)FuriFlagErrorResource; + rflags = (uint32_t)TtFlagErrorResource; } else { rflags = flags; portYIELD_FROM_ISR(yield); @@ -46,18 +46,18 @@ uint32_t furi_event_flag_set(FuriEventFlag* instance, uint32_t flags) { return (rflags); } -uint32_t furi_event_flag_clear(FuriEventFlag* instance, uint32_t flags) { - furi_assert(instance); - furi_assert((flags & FURI_EVENT_FLAG_INVALID_BITS) == 0U); +uint32_t tt_event_flag_clear(EventFlag* instance, uint32_t flags) { + tt_assert(instance); + tt_assert((flags & TT_EVENT_FLAG_INVALID_BITS) == 0U); EventGroupHandle_t hEventGroup = (EventGroupHandle_t)instance; uint32_t rflags; - if (FURI_IS_IRQ_MODE()) { + if (TT_IS_IRQ_MODE()) { rflags = xEventGroupGetBitsFromISR(hEventGroup); if (xEventGroupClearBitsFromISR(hEventGroup, (EventBits_t)flags) == pdFAIL) { - rflags = (uint32_t)FuriStatusErrorResource; + rflags = (uint32_t)TtStatusErrorResource; } else { /* xEventGroupClearBitsFromISR only registers clear operation in the timer command queue. */ /* Yield is required here otherwise clear operation might not execute in the right order. */ @@ -72,13 +72,13 @@ uint32_t furi_event_flag_clear(FuriEventFlag* instance, uint32_t flags) { return (rflags); } -uint32_t furi_event_flag_get(FuriEventFlag* instance) { - furi_assert(instance); +uint32_t tt_event_flag_get(EventFlag* instance) { + tt_assert(instance); EventGroupHandle_t hEventGroup = (EventGroupHandle_t)instance; uint32_t rflags; - if (FURI_IS_IRQ_MODE()) { + if (TT_IS_IRQ_MODE()) { rflags = xEventGroupGetBitsFromISR(hEventGroup); } else { rflags = xEventGroupGetBits(hEventGroup); @@ -88,28 +88,28 @@ uint32_t furi_event_flag_get(FuriEventFlag* instance) { return (rflags); } -uint32_t furi_event_flag_wait( - FuriEventFlag* instance, +uint32_t tt_event_flag_wait( + EventFlag* instance, uint32_t flags, uint32_t options, uint32_t timeout ) { - furi_assert(!FURI_IS_IRQ_MODE()); - furi_assert(instance); - furi_assert((flags & FURI_EVENT_FLAG_INVALID_BITS) == 0U); + tt_assert(!TT_IS_IRQ_MODE()); + tt_assert(instance); + tt_assert((flags & TT_EVENT_FLAG_INVALID_BITS) == 0U); EventGroupHandle_t hEventGroup = (EventGroupHandle_t)instance; BaseType_t wait_all; BaseType_t exit_clr; uint32_t rflags; - if (options & FuriFlagWaitAll) { + if (options & TtFlagWaitAll) { wait_all = pdTRUE; } else { wait_all = pdFAIL; } - if (options & FuriFlagNoClear) { + if (options & TtFlagNoClear) { exit_clr = pdFAIL; } else { exit_clr = pdTRUE; @@ -123,20 +123,20 @@ uint32_t furi_event_flag_wait( (TickType_t)timeout ); - if (options & FuriFlagWaitAll) { + if (options & TtFlagWaitAll) { if ((flags & rflags) != flags) { if (timeout > 0U) { - rflags = (uint32_t)FuriStatusErrorTimeout; + rflags = (uint32_t)TtStatusErrorTimeout; } else { - rflags = (uint32_t)FuriStatusErrorResource; + rflags = (uint32_t)TtStatusErrorResource; } } } else { if ((flags & rflags) == 0U) { if (timeout > 0U) { - rflags = (uint32_t)FuriStatusErrorTimeout; + rflags = (uint32_t)TtStatusErrorTimeout; } else { - rflags = (uint32_t)FuriStatusErrorResource; + rflags = (uint32_t)TtStatusErrorResource; } } } diff --git a/components/tactility-core/src/event_flag.h b/components/tactility-core/src/event_flag.h new file mode 100644 index 00000000..881c9614 --- /dev/null +++ b/components/tactility-core/src/event_flag.h @@ -0,0 +1,67 @@ +#pragma once + +#include "core_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void EventFlag; + +/** Allocate EventFlag + * + * @return pointer to EventFlag + */ +EventFlag* tt_event_flag_alloc(); + +/** Deallocate EventFlag + * + * @param instance pointer to EventFlag + */ +void tt_event_flag_free(EventFlag* instance); + +/** Set flags + * + * @param instance pointer to EventFlag + * @param[in] flags The flags + * + * @return Resulting flags or error (TtStatus) + */ +uint32_t tt_event_flag_set(EventFlag* instance, uint32_t flags); + +/** Clear flags + * + * @param instance pointer to EventFlag + * @param[in] flags The flags + * + * @return Resulting flags or error (TtStatus) + */ +uint32_t tt_event_flag_clear(EventFlag* instance, uint32_t flags); + +/** Get flags + * + * @param instance pointer to EventFlag + * + * @return Resulting flags + */ +uint32_t tt_event_flag_get(EventFlag* instance); + +/** Wait flags + * + * @param instance pointer to EventFlag + * @param[in] flags The flags + * @param[in] options The option flags + * @param[in] timeout The timeout + * + * @return Resulting flags or error (TtStatus) + */ +uint32_t tt_event_flag_wait( + EventFlag* instance, + uint32_t flags, + uint32_t options, + uint32_t timeout +); + +#ifdef __cplusplus +} +#endif diff --git a/components/furi/src/kernel.c b/components/tactility-core/src/kernel.c similarity index 68% rename from components/furi/src/kernel.c rename to components/tactility-core/src/kernel.c index d14b7953..fe4c17ce 100644 --- a/components/furi/src/kernel.c +++ b/components/tactility-core/src/kernel.c @@ -1,22 +1,22 @@ #include "kernel.h" #include "check.h" -#include "furi_core_defines.h" -#include "furi_core_types.h" +#include "core_defines.h" +#include "core_types.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include -bool furi_kernel_is_irq() { - return FURI_IS_IRQ_MODE(); +bool tt_kernel_is_irq() { + return TT_IS_IRQ_MODE(); } -bool furi_kernel_is_running() { +bool tt_kernel_is_running() { return xTaskGetSchedulerState() != taskSCHEDULER_RUNNING; } -int32_t furi_kernel_lock() { - furi_assert(!furi_kernel_is_irq()); +int32_t tt_kernel_lock() { + tt_assert(!tt_kernel_is_irq()); int32_t lock; @@ -32,7 +32,7 @@ int32_t furi_kernel_lock() { case taskSCHEDULER_NOT_STARTED: default: - lock = (int32_t)FuriStatusError; + lock = (int32_t)TtStatusError; break; } @@ -40,8 +40,8 @@ int32_t furi_kernel_lock() { return (lock); } -int32_t furi_kernel_unlock() { - furi_assert(!furi_kernel_is_irq()); +int32_t tt_kernel_unlock() { + tt_assert(!tt_kernel_is_irq()); int32_t lock; @@ -51,7 +51,7 @@ int32_t furi_kernel_unlock() { if (xTaskResumeAll() != pdTRUE) { if (xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED) { - lock = (int32_t)FuriStatusError; + lock = (int32_t)TtStatusError; } } break; @@ -62,7 +62,7 @@ int32_t furi_kernel_unlock() { case taskSCHEDULER_NOT_STARTED: default: - lock = (int32_t)FuriStatusError; + lock = (int32_t)TtStatusError; break; } @@ -70,8 +70,8 @@ int32_t furi_kernel_unlock() { return (lock); } -int32_t furi_kernel_restore_lock(int32_t lock) { - furi_assert(!furi_kernel_is_irq()); +int32_t tt_kernel_restore_lock(int32_t lock) { + tt_assert(!tt_kernel_is_irq()); switch (xTaskGetSchedulerState()) { case taskSCHEDULER_SUSPENDED: @@ -80,11 +80,11 @@ int32_t furi_kernel_restore_lock(int32_t lock) { vTaskSuspendAll(); } else { if (lock != 0) { - lock = (int32_t)FuriStatusError; + lock = (int32_t)TtStatusError; } else { if (xTaskResumeAll() != pdTRUE) { if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) { - lock = (int32_t)FuriStatusError; + lock = (int32_t)TtStatusError; } } } @@ -93,7 +93,7 @@ int32_t furi_kernel_restore_lock(int32_t lock) { case taskSCHEDULER_NOT_STARTED: default: - lock = (int32_t)FuriStatusError; + lock = (int32_t)TtStatusError; break; } @@ -101,13 +101,13 @@ int32_t furi_kernel_restore_lock(int32_t lock) { return (lock); } -uint32_t furi_kernel_get_tick_frequency() { +uint32_t tt_kernel_get_tick_frequency() { /* Return frequency in hertz */ return (configTICK_RATE_HZ_RAW); } -void furi_delay_tick(uint32_t ticks) { - furi_assert(!furi_kernel_is_irq()); +void tt_delay_tick(uint32_t ticks) { + tt_assert(!tt_kernel_is_irq()); if (ticks == 0U) { taskYIELD(); } else { @@ -115,13 +115,13 @@ void furi_delay_tick(uint32_t ticks) { } } -FuriStatus furi_delay_until_tick(uint32_t tick) { - furi_assert(!furi_kernel_is_irq()); +TtStatus tt_delay_until_tick(uint32_t tick) { + tt_assert(!tt_kernel_is_irq()); TickType_t tcnt, delay; - FuriStatus stat; + TtStatus stat; - stat = FuriStatusOk; + stat = TtStatusOk; tcnt = xTaskGetTickCount(); /* Determine remaining number of tick to delay */ @@ -131,21 +131,21 @@ FuriStatus furi_delay_until_tick(uint32_t tick) { if ((delay != 0U) && (0 == (delay >> (8 * sizeof(TickType_t) - 1)))) { if (xTaskDelayUntil(&tcnt, delay) == pdFALSE) { /* Did not delay */ - stat = FuriStatusError; + stat = TtStatusError; } } else { /* No delay or already expired */ - stat = FuriStatusErrorParameter; + stat = TtStatusErrorParameter; } /* Return execution status */ return (stat); } -uint32_t furi_get_tick() { +uint32_t tt_get_tick() { TickType_t ticks; - if (furi_kernel_is_irq() != 0U) { + if (tt_kernel_is_irq() != 0U) { ticks = xTaskGetTickCountFromISR(); } else { ticks = xTaskGetTickCount(); @@ -154,7 +154,7 @@ uint32_t furi_get_tick() { return ticks; } -uint32_t furi_ms_to_ticks(uint32_t milliseconds) { +uint32_t tt_ms_to_ticks(uint32_t milliseconds) { #if configTICK_RATE_HZ_RAW == 1000 return milliseconds; #else @@ -162,21 +162,21 @@ uint32_t furi_ms_to_ticks(uint32_t milliseconds) { #endif } -void furi_delay_ms(uint32_t milliseconds) { +void tt_delay_ms(uint32_t milliseconds) { if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) { if (milliseconds > 0 && milliseconds < portMAX_DELAY - 1) { milliseconds += 1; } #if configTICK_RATE_HZ_RAW == 1000 - furi_delay_tick(milliseconds); + tt_delay_tick(milliseconds); #else - furi_delay_tick(furi_ms_to_ticks(milliseconds)); + tt_delay_tick(tt_ms_to_ticks(milliseconds)); #endif } else if (milliseconds > 0) { - furi_delay_us(milliseconds * 1000); + tt_delay_us(milliseconds * 1000); } } -void furi_delay_us(uint32_t microseconds) { +void tt_delay_us(uint32_t microseconds) { ets_delay_us(microseconds); } diff --git a/components/furi/src/kernel.h b/components/tactility-core/src/kernel.h similarity index 82% rename from components/furi/src/kernel.h rename to components/tactility-core/src/kernel.h index c1236634..c1a430a7 100644 --- a/components/furi/src/kernel.h +++ b/components/tactility-core/src/kernel.h @@ -1,6 +1,6 @@ #pragma once -#include "furi_core_types.h" +#include "core_types.h" #define configTICK_RATE_HZ_RAW CONFIG_FREERTOS_HZ @@ -23,13 +23,13 @@ extern "C" { * * @return true if CPU is in IRQ or kernel running and IRQ is masked */ -bool furi_kernel_is_irq(); +bool tt_kernel_is_irq(); /** Check if kernel is running * * @return true if running, false otherwise */ -bool furi_kernel_is_running(); +bool tt_kernel_is_running(); /** Lock kernel, pause process scheduling * @@ -37,7 +37,7 @@ bool furi_kernel_is_running(); * * @return previous lock state(0 - unlocked, 1 - locked) */ -int32_t furi_kernel_lock(); +int32_t tt_kernel_lock(); /** Unlock kernel, resume process scheduling * @@ -45,7 +45,7 @@ int32_t furi_kernel_lock(); * * @return previous lock state(0 - unlocked, 1 - locked) */ -int32_t furi_kernel_unlock(); +int32_t tt_kernel_unlock(); /** Restore kernel lock state * @@ -55,13 +55,13 @@ int32_t furi_kernel_unlock(); * * @return new lock state or error */ -int32_t furi_kernel_restore_lock(int32_t lock); +int32_t tt_kernel_restore_lock(int32_t lock); /** Get kernel systick frequency * * @return systick counts per second */ -uint32_t furi_kernel_get_tick_frequency(); +uint32_t tt_kernel_get_tick_frequency(); /** Delay execution * @@ -71,7 +71,7 @@ uint32_t furi_kernel_get_tick_frequency(); * * @param[in] ticks The ticks count to pause */ -void furi_delay_tick(uint32_t ticks); +void tt_delay_tick(uint32_t ticks); /** Delay until tick * @@ -79,9 +79,9 @@ void furi_delay_tick(uint32_t ticks); * * @param[in] ticks The tick until which kerel should delay task execution * - * @return The furi status. + * @return The status. */ -FuriStatus furi_delay_until_tick(uint32_t tick); +TtStatus tt_delay_until_tick(uint32_t tick); /** Get current tick counter * @@ -89,27 +89,27 @@ FuriStatus furi_delay_until_tick(uint32_t tick); * * @return Current ticks in milliseconds */ -uint32_t furi_get_tick(void); +uint32_t tt_get_tick(void); /** Convert milliseconds to ticks * * @param[in] milliseconds time in milliseconds * @return time in ticks */ -uint32_t furi_ms_to_ticks(uint32_t milliseconds); +uint32_t tt_ms_to_ticks(uint32_t milliseconds); /** Delay in milliseconds * * This method uses kernel ticks on the inside, which causes delay to be aliased to scheduler timer intervals. * Real wait time will be between X+ milliseconds. * Special value: 0, will cause task yield. - * Also if used when kernel is not running will fall back to `furi_delay_us`. + * Also if used when kernel is not running will fall back to `tt_delay_us`. * * @warning Cannot be used from ISR * * @param[in] milliseconds milliseconds to wait */ -void furi_delay_ms(uint32_t milliseconds); +void tt_delay_ms(uint32_t milliseconds); /** Delay in microseconds * @@ -117,7 +117,7 @@ void furi_delay_ms(uint32_t milliseconds); * * @param[in] microseconds microseconds to wait */ -void furi_delay_us(uint32_t microseconds); +void tt_delay_us(uint32_t microseconds); #ifdef __cplusplus } diff --git a/components/furi/src/log.h b/components/tactility-core/src/log.h similarity index 61% rename from components/furi/src/log.h rename to components/tactility-core/src/log.h index 09155ac8..7e604505 100644 --- a/components/furi/src/log.h +++ b/components/tactility-core/src/log.h @@ -6,15 +6,15 @@ extern "C" { #endif -#define FURI_LOG_E(tag, format, ...) \ +#define TT_LOG_E(tag, format, ...) \ ESP_LOGE(tag, format, ##__VA_ARGS__) -#define FURI_LOG_W(tag, format, ...) \ +#define TT_LOG_W(tag, format, ...) \ ESP_LOGW(tag, format, ##__VA_ARGS__) -#define FURI_LOG_I(tag, format, ...) \ +#define TT_LOG_I(tag, format, ...) \ ESP_LOGI(tag, format, ##__VA_ARGS__) -#define FURI_LOG_D(tag, format, ...) \ +#define TT_LOG_D(tag, format, ...) \ ESP_LOGD(tag, format, ##__VA_ARGS__) -#define FURI_LOG_T(tag, format, ...) \ +#define TT_LOG_T(tag, format, ...) \ ESP_LOGT(tag, format, ##__VA_ARGS__) #ifdef __cplusplus diff --git a/components/furi/src/m_cstr_dup.h b/components/tactility-core/src/m_cstr_dup.h similarity index 100% rename from components/furi/src/m_cstr_dup.h rename to components/tactility-core/src/m_cstr_dup.h diff --git a/components/furi/src/message_queue.c b/components/tactility-core/src/message_queue.c similarity index 63% rename from components/furi/src/message_queue.c rename to components/tactility-core/src/message_queue.c index 5b50e740..e16332a8 100644 --- a/components/furi/src/message_queue.c +++ b/components/tactility-core/src/message_queue.c @@ -5,51 +5,50 @@ #include "freertos/FreeRTOS.h" #include "freertos/queue.h" -FuriMessageQueue* furi_message_queue_alloc(uint32_t msg_count, uint32_t msg_size) { - furi_assert((furi_kernel_is_irq() == 0U) && (msg_count > 0U) && (msg_size > 0U)); +MessageQueue* tt_message_queue_alloc(uint32_t msg_count, uint32_t msg_size) { + tt_assert((tt_kernel_is_irq() == 0U) && (msg_count > 0U) && (msg_size > 0U)); QueueHandle_t handle = xQueueCreate(msg_count, msg_size); - furi_check(handle); + tt_check(handle); - return ((FuriMessageQueue*)handle); + return ((MessageQueue*)handle); } -void furi_message_queue_free(FuriMessageQueue* instance) { - furi_assert(furi_kernel_is_irq() == 0U); - furi_assert(instance); +void tt_message_queue_free(MessageQueue* instance) { + tt_assert(tt_kernel_is_irq() == 0U); + tt_assert(instance); vQueueDelete((QueueHandle_t)instance); } -FuriStatus -furi_message_queue_put(FuriMessageQueue* instance, const void* msg_ptr, uint32_t timeout) { +TtStatus tt_message_queue_put(MessageQueue* instance, const void* msg_ptr, uint32_t timeout) { QueueHandle_t hQueue = (QueueHandle_t)instance; - FuriStatus stat; + TtStatus stat; BaseType_t yield; - stat = FuriStatusOk; + stat = TtStatusOk; - if (furi_kernel_is_irq() != 0U) { + if (tt_kernel_is_irq() != 0U) { if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout != 0U)) { - stat = FuriStatusErrorParameter; + stat = TtStatusErrorParameter; } else { yield = pdFALSE; if (xQueueSendToBackFromISR(hQueue, msg_ptr, &yield) != pdTRUE) { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } else { portYIELD_FROM_ISR(yield); } } } else { if ((hQueue == NULL) || (msg_ptr == NULL)) { - stat = FuriStatusErrorParameter; + stat = TtStatusErrorParameter; } else { if (xQueueSendToBack(hQueue, msg_ptr, (TickType_t)timeout) != pdPASS) { if (timeout != 0U) { - stat = FuriStatusErrorTimeout; + stat = TtStatusErrorTimeout; } else { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } } } @@ -59,34 +58,34 @@ furi_message_queue_put(FuriMessageQueue* instance, const void* msg_ptr, uint32_t return (stat); } -FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uint32_t timeout_ticks) { +TtStatus tt_message_queue_get(MessageQueue* instance, void* msg_ptr, uint32_t timeout_ticks) { QueueHandle_t hQueue = (QueueHandle_t)instance; - FuriStatus stat; + TtStatus stat; BaseType_t yield; - stat = FuriStatusOk; + stat = TtStatusOk; - if (furi_kernel_is_irq() != 0U) { + if (tt_kernel_is_irq() != 0U) { if ((hQueue == NULL) || (msg_ptr == NULL) || (timeout_ticks != 0U)) { - stat = FuriStatusErrorParameter; + stat = TtStatusErrorParameter; } else { yield = pdFALSE; if (xQueueReceiveFromISR(hQueue, msg_ptr, &yield) != pdPASS) { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } else { portYIELD_FROM_ISR(yield); } } } else { if ((hQueue == NULL) || (msg_ptr == NULL)) { - stat = FuriStatusErrorParameter; + stat = TtStatusErrorParameter; } else { if (xQueueReceive(hQueue, msg_ptr, (TickType_t)timeout_ticks) != pdPASS) { if (timeout_ticks != 0U) { - stat = FuriStatusErrorTimeout; + stat = TtStatusErrorTimeout; } else { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } } } @@ -96,7 +95,7 @@ FuriStatus furi_message_queue_get(FuriMessageQueue* instance, void* msg_ptr, uin return (stat); } -uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance) { +uint32_t tt_message_queue_get_capacity(MessageQueue* instance) { StaticQueue_t* mq = (StaticQueue_t*)instance; uint32_t capacity; @@ -111,7 +110,7 @@ uint32_t furi_message_queue_get_capacity(FuriMessageQueue* instance) { return (capacity); } -uint32_t furi_message_queue_get_message_size(FuriMessageQueue* instance) { +uint32_t tt_message_queue_get_message_size(MessageQueue* instance) { StaticQueue_t* mq = (StaticQueue_t*)instance; uint32_t size; @@ -126,13 +125,13 @@ uint32_t furi_message_queue_get_message_size(FuriMessageQueue* instance) { return (size); } -uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) { +uint32_t tt_message_queue_get_count(MessageQueue* instance) { QueueHandle_t hQueue = (QueueHandle_t)instance; UBaseType_t count; if (hQueue == NULL) { count = 0U; - } else if (furi_kernel_is_irq() != 0U) { + } else if (tt_kernel_is_irq() != 0U) { count = uxQueueMessagesWaitingFromISR(hQueue); } else { count = uxQueueMessagesWaiting(hQueue); @@ -142,14 +141,14 @@ uint32_t furi_message_queue_get_count(FuriMessageQueue* instance) { return ((uint32_t)count); } -uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) { +uint32_t tt_message_queue_get_space(MessageQueue* instance) { StaticQueue_t* mq = (StaticQueue_t*)instance; uint32_t space; uint32_t isrm; if (mq == NULL) { space = 0U; - } else if (furi_kernel_is_irq() != 0U) { + } else if (tt_kernel_is_irq() != 0U) { isrm = taskENTER_CRITICAL_FROM_ISR(); /* space = pxQueue->uxLength - pxQueue->uxMessagesWaiting; */ @@ -164,16 +163,16 @@ uint32_t furi_message_queue_get_space(FuriMessageQueue* instance) { return (space); } -FuriStatus furi_message_queue_reset(FuriMessageQueue* instance) { +TtStatus tt_message_queue_reset(MessageQueue* instance) { QueueHandle_t hQueue = (QueueHandle_t)instance; - FuriStatus stat; + TtStatus stat; - if (furi_kernel_is_irq() != 0U) { - stat = FuriStatusErrorISR; + if (tt_kernel_is_irq() != 0U) { + stat = TtStatusErrorISR; } else if (hQueue == NULL) { - stat = FuriStatusErrorParameter; + stat = TtStatusErrorParameter; } else { - stat = FuriStatusOk; + stat = TtStatusOk; (void)xQueueReset(hQueue); } diff --git a/components/tactility-core/src/message_queue.h b/components/tactility-core/src/message_queue.h new file mode 100644 index 00000000..d66be7fb --- /dev/null +++ b/components/tactility-core/src/message_queue.h @@ -0,0 +1,94 @@ +/** + * @file message_queue.h + * MessageQueue + */ +#pragma once + +#include "core_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void MessageQueue; + +/** Allocate message queue + * + * @param[in] msg_count The message count + * @param[in] msg_size The message size + * + * @return pointer to MessageQueue instance + */ +MessageQueue* tt_message_queue_alloc(uint32_t msg_count, uint32_t msg_size); + +/** Free queue + * + * @param instance pointer to MessageQueue instance + */ +void tt_message_queue_free(MessageQueue* instance); + +/** Put message into queue + * + * @param instance pointer to MessageQueue instance + * @param[in] msg_ptr The message pointer + * @param[in] timeout The timeout + * @param[in] msg_prio The message prio + * + * @return The status. + */ +TtStatus tt_message_queue_put(MessageQueue* instance, const void* msg_ptr, uint32_t timeout); + +/** Get message from queue + * + * @param instance pointer to MessageQueue instance + * @param msg_ptr The message pointer + * @param msg_prio The message prioority + * @param[in] timeout_ticks The timeout + * + * @return The status. + */ +TtStatus tt_message_queue_get(MessageQueue* instance, void* msg_ptr, uint32_t timeout_ticks); + +/** Get queue capacity + * + * @param instance pointer to MessageQueue instance + * + * @return capacity in object count + */ +uint32_t tt_message_queue_get_capacity(MessageQueue* instance); + +/** Get message size + * + * @param instance pointer to MessageQueue instance + * + * @return Message size in bytes + */ +uint32_t tt_message_queue_get_message_size(MessageQueue* instance); + +/** Get message count in queue + * + * @param instance pointer to MessageQueue instance + * + * @return Message count + */ +uint32_t tt_message_queue_get_count(MessageQueue* instance); + +/** Get queue available space + * + * @param instance pointer to MessageQueue instance + * + * @return Message count + */ +uint32_t tt_message_queue_get_space(MessageQueue* instance); + +/** Reset queue + * + * @param instance pointer to MessageQueue instance + * + * @return The status. + */ +TtStatus tt_message_queue_reset(MessageQueue* instance); + +#ifdef __cplusplus +} +#endif diff --git a/components/furi/src/mutex.c b/components/tactility-core/src/mutex.c similarity index 56% rename from components/furi/src/mutex.c rename to components/tactility-core/src/mutex.c index ee190caf..b0b427a2 100644 --- a/components/furi/src/mutex.c +++ b/components/tactility-core/src/mutex.c @@ -1,45 +1,45 @@ #include "mutex.h" #include "check.h" -#include "furi_core_defines.h" +#include "core_defines.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "log.h" -FuriMutex* furi_mutex_alloc(FuriMutexType type) { - furi_assert(!FURI_IS_IRQ_MODE()); +Mutex* tt_mutex_alloc(MutexType type) { + tt_assert(!TT_IS_IRQ_MODE()); SemaphoreHandle_t hMutex = NULL; - if (type == FuriMutexTypeNormal) { + if (type == MutexTypeNormal) { hMutex = xSemaphoreCreateMutex(); - } else if (type == FuriMutexTypeRecursive) { + } else if (type == MutexTypeRecursive) { hMutex = xSemaphoreCreateRecursiveMutex(); } else { - furi_crash("Programming error"); + tt_crash("Programming error"); } - furi_check(hMutex != NULL); + tt_check(hMutex != NULL); - if (type == FuriMutexTypeRecursive) { + if (type == MutexTypeRecursive) { /* Set LSB as 'recursive mutex flag' */ hMutex = (SemaphoreHandle_t)((uint32_t)hMutex | 1U); } /* Return mutex ID */ - return ((FuriMutex*)hMutex); + return ((Mutex*)hMutex); } -void furi_mutex_free(FuriMutex* instance) { - furi_assert(!FURI_IS_IRQ_MODE()); - furi_assert(instance); +void tt_mutex_free(Mutex* instance) { + tt_assert(!TT_IS_IRQ_MODE()); + tt_assert(instance); vSemaphoreDelete((SemaphoreHandle_t)((uint32_t)instance & ~1U)); } -FuriStatus furi_mutex_acquire(FuriMutex* instance, uint32_t timeout) { +TtStatus tt_mutex_acquire(Mutex* instance, uint32_t timeout) { SemaphoreHandle_t hMutex; - FuriStatus stat; + TtStatus stat; uint32_t rmtx; hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); @@ -47,27 +47,27 @@ FuriStatus furi_mutex_acquire(FuriMutex* instance, uint32_t timeout) { /* Extract recursive mutex flag */ rmtx = (uint32_t)instance & 1U; - stat = FuriStatusOk; + stat = TtStatusOk; - if (FURI_IS_IRQ_MODE()) { - stat = FuriStatusErrorISR; + if (TT_IS_IRQ_MODE()) { + stat = TtStatusErrorISR; } else if (hMutex == NULL) { - stat = FuriStatusErrorParameter; + stat = TtStatusErrorParameter; } else { if (rmtx != 0U) { if (xSemaphoreTakeRecursive(hMutex, timeout) != pdPASS) { if (timeout != 0U) { - stat = FuriStatusErrorTimeout; + stat = TtStatusErrorTimeout; } else { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } } } else { if (xSemaphoreTake(hMutex, timeout) != pdPASS) { if (timeout != 0U) { - stat = FuriStatusErrorTimeout; + stat = TtStatusErrorTimeout; } else { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } } } @@ -77,9 +77,9 @@ FuriStatus furi_mutex_acquire(FuriMutex* instance, uint32_t timeout) { return (stat); } -FuriStatus furi_mutex_release(FuriMutex* instance) { +TtStatus tt_mutex_release(Mutex* instance) { SemaphoreHandle_t hMutex; - FuriStatus stat; + TtStatus stat; uint32_t rmtx; hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); @@ -87,20 +87,20 @@ FuriStatus furi_mutex_release(FuriMutex* instance) { /* Extract recursive mutex flag */ rmtx = (uint32_t)instance & 1U; - stat = FuriStatusOk; + stat = TtStatusOk; - if (FURI_IS_IRQ_MODE()) { - stat = FuriStatusErrorISR; + if (TT_IS_IRQ_MODE()) { + stat = TtStatusErrorISR; } else if (hMutex == NULL) { - stat = FuriStatusErrorParameter; + stat = TtStatusErrorParameter; } else { if (rmtx != 0U) { if (xSemaphoreGiveRecursive(hMutex) != pdPASS) { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } } else { if (xSemaphoreGive(hMutex) != pdPASS) { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } } } @@ -109,16 +109,16 @@ FuriStatus furi_mutex_release(FuriMutex* instance) { return (stat); } -FuriThreadId furi_mutex_get_owner(FuriMutex* instance) { +ThreadId tt_mutex_get_owner(Mutex* instance) { SemaphoreHandle_t hMutex; - FuriThreadId owner; + ThreadId owner; hMutex = (SemaphoreHandle_t)((uint32_t)instance & ~1U); - if ((FURI_IS_IRQ_MODE()) || (hMutex == NULL)) { + if ((TT_IS_IRQ_MODE()) || (hMutex == NULL)) { owner = 0; } else { - owner = (FuriThreadId)xSemaphoreGetMutexHolder(hMutex); + owner = (ThreadId)xSemaphoreGetMutexHolder(hMutex); } /* Return owner thread ID */ diff --git a/components/tactility-core/src/mutex.h b/components/tactility-core/src/mutex.h new file mode 100644 index 00000000..79fcc86c --- /dev/null +++ b/components/tactility-core/src/mutex.h @@ -0,0 +1,62 @@ +/** + * @file mutex.h + * Mutex + */ +#pragma once + +#include "core_types.h" +#include "thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + MutexTypeNormal, + MutexTypeRecursive, +} MutexType; + +typedef void Mutex; + +/** Allocate Mutex + * + * @param[in] type The mutex type + * + * @return pointer to Mutex instance + */ +Mutex* tt_mutex_alloc(MutexType type); + +/** Free Mutex + * + * @param instance The pointer to Mutex instance + */ +void tt_mutex_free(Mutex* instance); + +/** Acquire mutex + * + * @param instance The pointer to Mutex instance + * @param[in] timeout The timeout + * + * @return The status. + */ +TtStatus tt_mutex_acquire(Mutex* instance, uint32_t timeout); + +/** Release mutex + * + * @param instance The pointer to Mutex instance + * + * @return The status. + */ +TtStatus tt_mutex_release(Mutex* instance); + +/** Get mutex owner thread id + * + * @param instance The pointer to Mutex instance + * + * @return The thread identifier. + */ +ThreadId tt_mutex_get_owner(Mutex* instance); + +#ifdef __cplusplus +} +#endif diff --git a/components/tactility-core/src/pubsub.c b/components/tactility-core/src/pubsub.c new file mode 100644 index 00000000..5f193202 --- /dev/null +++ b/components/tactility-core/src/pubsub.c @@ -0,0 +1,93 @@ +#include "pubsub.h" +#include "check.h" +#include "mutex.h" + +#include + +struct PubSubSubscription { + PubSubCallback callback; + void* callback_context; +}; + +LIST_DEF(PubSubSubscriptionList, PubSubSubscription, M_POD_OPLIST); + +struct PubSub { + PubSubSubscriptionList_t items; + Mutex* mutex; +}; + +PubSub* tt_pubsub_alloc() { + PubSub* pubsub = malloc(sizeof(PubSub)); + + pubsub->mutex = tt_mutex_alloc(MutexTypeRecursive); + tt_assert(pubsub->mutex); + + PubSubSubscriptionList_init(pubsub->items); + + return pubsub; +} + +void tt_pubsub_free(PubSub* pubsub) { + tt_assert(pubsub); + + tt_check(PubSubSubscriptionList_size(pubsub->items) == 0); + + PubSubSubscriptionList_clear(pubsub->items); + + tt_mutex_free(pubsub->mutex); + + free(pubsub); +} + +PubSubSubscription* tt_pubsub_subscribe(PubSub* pubsub, PubSubCallback callback, void* callback_context) { + tt_check(tt_mutex_acquire(pubsub->mutex, TtWaitForever) == TtStatusOk); + // put uninitialized item to the list + PubSubSubscription* item = PubSubSubscriptionList_push_raw(pubsub->items); + + // initialize item + item->callback = callback; + item->callback_context = callback_context; + + tt_check(tt_mutex_release(pubsub->mutex) == TtStatusOk); + + return item; +} + +void tt_pubsub_unsubscribe(PubSub* pubsub, PubSubSubscription* pubsub_subscription) { + tt_assert(pubsub); + tt_assert(pubsub_subscription); + + tt_check(tt_mutex_acquire(pubsub->mutex, TtWaitForever) == TtStatusOk); + bool result = false; + + // iterate over items + PubSubSubscriptionList_it_t it; + for (PubSubSubscriptionList_it(it, pubsub->items); !PubSubSubscriptionList_end_p(it); + PubSubSubscriptionList_next(it)) { + const PubSubSubscription* item = PubSubSubscriptionList_cref(it); + + // if the iterator is equal to our element + if (item == pubsub_subscription) { + PubSubSubscriptionList_remove(pubsub->items, it); + result = true; + break; + } + } + + tt_check(tt_mutex_release(pubsub->mutex) == TtStatusOk); + tt_check(result); +} + +void tt_pubsub_publish(PubSub* pubsub, void* message) { + tt_check(tt_mutex_acquire(pubsub->mutex, TtWaitForever) == TtStatusOk); + + // iterate over subscribers + PubSubSubscriptionList_it_t it; + for (PubSubSubscriptionList_it(it, pubsub->items); !PubSubSubscriptionList_end_p(it); + PubSubSubscriptionList_next(it)) { + const PubSubSubscription* item = PubSubSubscriptionList_cref(it); + item->callback(message, item->callback_context); + } + + tt_check(tt_mutex_release(pubsub->mutex) == TtStatusOk); +} diff --git a/components/tactility-core/src/pubsub.h b/components/tactility-core/src/pubsub.h new file mode 100644 index 00000000..15e58e1b --- /dev/null +++ b/components/tactility-core/src/pubsub.h @@ -0,0 +1,68 @@ +/** + * @file pubsub.h + * PubSub + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/** PubSub Callback type */ +typedef void (*PubSubCallback)(const void* message, void* context); + +/** PubSub type */ +typedef struct PubSub PubSub; + +/** PubSubSubscription type */ +typedef struct PubSubSubscription PubSubSubscription; + +/** Allocate PubSub + * + * Reentrable, Not threadsafe, one owner + * + * @return pointer to PubSub instance + */ +PubSub* tt_pubsub_alloc(); + +/** Free PubSub + * + * @param pubsub PubSub instance + */ +void tt_pubsub_free(PubSub* pubsub); + +/** Subscribe to PubSub + * + * Threadsafe, Reentrable + * + * @param pubsub pointer to PubSub instance + * @param[in] callback The callback + * @param callback_context The callback context + * + * @return pointer to PubSubSubscription instance + */ +PubSubSubscription* +tt_pubsub_subscribe(PubSub* pubsub, PubSubCallback callback, void* callback_context); + +/** Unsubscribe from PubSub + * + * No use of `pubsub_subscription` allowed after call of this method + * Threadsafe, Reentrable. + * + * @param pubsub pointer to PubSub instance + * @param pubsub_subscription pointer to PubSubSubscription instance + */ +void tt_pubsub_unsubscribe(PubSub* pubsub, PubSubSubscription* pubsub_subscription); + +/** Publish message to PubSub + * + * Threadsafe, Reentrable. + * + * @param pubsub pointer to PubSub instance + * @param message message pointer to publish + */ +void tt_pubsub_publish(PubSub* pubsub, void* message); + +#ifdef __cplusplus +} +#endif diff --git a/components/furi/src/semaphore.c b/components/tactility-core/src/semaphore.c similarity index 64% rename from components/furi/src/semaphore.c rename to components/tactility-core/src/semaphore.c index 677e0133..85abb5b0 100644 --- a/components/furi/src/semaphore.c +++ b/components/tactility-core/src/semaphore.c @@ -1,13 +1,13 @@ #include "semaphore.h" #include "check.h" -#include "furi_core_defines.h" +#include "core_defines.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" -FuriSemaphore* furi_semaphore_alloc(uint32_t max_count, uint32_t initial_count) { - furi_assert(!FURI_IS_IRQ_MODE()); - furi_assert((max_count > 0U) && (initial_count <= max_count)); +Semaphore* tt_semaphore_alloc(uint32_t max_count, uint32_t initial_count) { + tt_assert(!TT_IS_IRQ_MODE()); + tt_assert((max_count > 0U) && (initial_count <= max_count)); SemaphoreHandle_t hSemaphore = NULL; if (max_count == 1U) { @@ -22,37 +22,37 @@ FuriSemaphore* furi_semaphore_alloc(uint32_t max_count, uint32_t initial_count) hSemaphore = xSemaphoreCreateCounting(max_count, initial_count); } - furi_check(hSemaphore); + tt_check(hSemaphore); - return (FuriSemaphore*)hSemaphore; + return (Semaphore*)hSemaphore; } -void furi_semaphore_free(FuriSemaphore* instance) { - furi_assert(instance); - furi_assert(!FURI_IS_IRQ_MODE()); +void tt_semaphore_free(Semaphore* instance) { + tt_assert(instance); + tt_assert(!TT_IS_IRQ_MODE()); SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; vSemaphoreDelete(hSemaphore); } -FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout) { - furi_assert(instance); +TtStatus tt_semaphore_acquire(Semaphore* instance, uint32_t timeout) { + tt_assert(instance); SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; - FuriStatus status; + TtStatus status; BaseType_t yield; - status = FuriStatusOk; + status = TtStatusOk; - if (FURI_IS_IRQ_MODE()) { + if (TT_IS_IRQ_MODE()) { if (timeout != 0U) { - status = FuriStatusErrorParameter; + status = TtStatusErrorParameter; } else { yield = pdFALSE; if (xSemaphoreTakeFromISR(hSemaphore, &yield) != pdPASS) { - status = FuriStatusErrorResource; + status = TtStatusErrorResource; } else { portYIELD_FROM_ISR(yield); } @@ -60,9 +60,9 @@ FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout) { } else { if (xSemaphoreTake(hSemaphore, (TickType_t)timeout) != pdPASS) { if (timeout != 0U) { - status = FuriStatusErrorTimeout; + status = TtStatusErrorTimeout; } else { - status = FuriStatusErrorResource; + status = TtStatusErrorResource; } } } @@ -70,26 +70,26 @@ FuriStatus furi_semaphore_acquire(FuriSemaphore* instance, uint32_t timeout) { return status; } -FuriStatus furi_semaphore_release(FuriSemaphore* instance) { - furi_assert(instance); +TtStatus tt_semaphore_release(Semaphore* instance) { + tt_assert(instance); SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; - FuriStatus stat; + TtStatus stat; BaseType_t yield; - stat = FuriStatusOk; + stat = TtStatusOk; - if (FURI_IS_IRQ_MODE()) { + if (TT_IS_IRQ_MODE()) { yield = pdFALSE; if (xSemaphoreGiveFromISR(hSemaphore, &yield) != pdTRUE) { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } else { portYIELD_FROM_ISR(yield); } } else { if (xSemaphoreGive(hSemaphore) != pdPASS) { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } } @@ -97,13 +97,13 @@ FuriStatus furi_semaphore_release(FuriSemaphore* instance) { return (stat); } -uint32_t furi_semaphore_get_count(FuriSemaphore* instance) { - furi_assert(instance); +uint32_t tt_semaphore_get_count(Semaphore* instance) { + tt_assert(instance); SemaphoreHandle_t hSemaphore = (SemaphoreHandle_t)instance; uint32_t count; - if (FURI_IS_IRQ_MODE()) { + if (TT_IS_IRQ_MODE()) { // TODO: uxSemaphoreGetCountFromISR is not supported on esp-idf 5.1.2 - perhaps later on? #ifdef uxSemaphoreGetCountFromISR count = (uint32_t)uxSemaphoreGetCountFromISR(hSemaphore); diff --git a/components/tactility-core/src/semaphore.h b/components/tactility-core/src/semaphore.h new file mode 100644 index 00000000..0330fa5a --- /dev/null +++ b/components/tactility-core/src/semaphore.h @@ -0,0 +1,54 @@ +#pragma once + +#include "core_types.h" +#include "thread.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void Semaphore; + +/** Allocate semaphore + * + * @param[in] max_count The maximum count + * @param[in] initial_count The initial count + * + * @return pointer to Semaphore instance + */ +Semaphore* tt_semaphore_alloc(uint32_t max_count, uint32_t initial_count); + +/** Free semaphore + * + * @param instance The pointer to Semaphore instance + */ +void tt_semaphore_free(Semaphore* instance); + +/** Acquire semaphore + * + * @param instance The pointer to Semaphore instance + * @param[in] timeout The timeout + * + * @return The status. + */ +TtStatus tt_semaphore_acquire(Semaphore* instance, uint32_t timeout); + +/** Release semaphore + * + * @param instance The pointer to Semaphore instance + * + * @return The status. + */ +TtStatus tt_semaphore_release(Semaphore* instance); + +/** Get semaphore count + * + * @param instance The pointer to Semaphore instance + * + * @return Semaphore count + */ +uint32_t tt_semaphore_get_count(Semaphore* instance); + +#ifdef __cplusplus +} +#endif diff --git a/components/tactility-core/src/service.c b/components/tactility-core/src/service.c new file mode 100644 index 00000000..bb3bbe9c --- /dev/null +++ b/components/tactility-core/src/service.c @@ -0,0 +1,62 @@ +#include "log.h" +#include "service_i.h" +#include "tactility_core.h" + +// region Alloc/free + +ServiceData* tt_service_alloc(const ServiceManifest* _Nonnull manifest) { + ServiceData* data = malloc(sizeof(ServiceData)); + *data = (ServiceData) { + .manifest = manifest, + .mutex = tt_mutex_alloc(MutexTypeRecursive), + .data = NULL + }; + return data; +} + +void tt_service_free(ServiceData* data) { + tt_assert(data); + tt_mutex_free(data->mutex); + free(data); +} + +// endregion Alloc/free + +// region Internal + +static void tt_service_lock(ServiceData * data) { + tt_mutex_acquire(data->mutex, MutexTypeRecursive); +} + +static void tt_service_unlock(ServiceData* data) { + tt_mutex_release(data->mutex); +} + +// endregion Internal + +// region Getters & Setters + +const ServiceManifest* tt_service_get_manifest(Service service) { + ServiceData* data = (ServiceData*)service; + tt_service_lock(data); + const ServiceManifest* manifest = data->manifest; + tt_service_unlock(data); + return manifest; +} + +void tt_service_set_data(Service service, void* value) { + ServiceData* data = (ServiceData*)service; + tt_service_lock(data); + data->data = value; + tt_service_unlock(data); +} + +void* _Nullable tt_service_get_data(Service service) { + ServiceData* data = (ServiceData*)service; + tt_service_lock(data); + void* value = data->data; + tt_service_unlock(data); + return value; +} + +// endregion Getters & Setters \ No newline at end of file diff --git a/components/tactility-core/src/service.h b/components/tactility-core/src/service.h new file mode 100644 index 00000000..9d3fba1f --- /dev/null +++ b/components/tactility-core/src/service.h @@ -0,0 +1,18 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "service_manifest.h" + +typedef void* Service; + +const ServiceManifest* tt_service_get_manifest(Service service); + +void tt_service_set_data(Service service, void* value); +void* _Nullable tt_service_get_data(Service service); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/components/furi/src/service_i.h b/components/tactility-core/src/service_i.h similarity index 52% rename from components/furi/src/service_i.h rename to components/tactility-core/src/service_i.h index d836e6dd..54a6b91e 100644 --- a/components/furi/src/service_i.h +++ b/components/tactility-core/src/service_i.h @@ -2,15 +2,14 @@ #include "service.h" -#include "context.h" #include "mutex.h" #include "service_manifest.h" typedef struct { - FuriMutex* mutex; + Mutex* mutex; const ServiceManifest* manifest; void* data; } ServiceData; -Service service_alloc(const ServiceManifest* _Nonnull manifest); -void service_free(Service _Nonnull service); +ServiceData* tt_service_alloc(const ServiceManifest* _Nonnull manifest); +void tt_service_free(ServiceData* _Nonnull service); diff --git a/components/furi/src/service_manifest.h b/components/tactility-core/src/service_manifest.h similarity index 96% rename from components/furi/src/service_manifest.h rename to components/tactility-core/src/service_manifest.h index 3db1fead..7c656cec 100644 --- a/components/furi/src/service_manifest.h +++ b/components/tactility-core/src/service_manifest.h @@ -1,7 +1,6 @@ #pragma once #include -#include "context.h" #ifdef __cplusplus extern "C" { diff --git a/components/furi/src/service_registry.c b/components/tactility-core/src/service_registry.c similarity index 66% rename from components/furi/src/service_registry.c rename to components/tactility-core/src/service_registry.c index c7ef891a..e5e5f0b8 100644 --- a/components/furi/src/service_registry.c +++ b/components/tactility-core/src/service_registry.c @@ -1,10 +1,10 @@ #include "service_registry.h" -#include "furi_core.h" #include "m-dict.h" #include "m_cstr_dup.h" #include "mutex.h" #include "service_i.h" +#include "tactility_core.h" #define TAG "service_registry" @@ -22,56 +22,56 @@ DICT_DEF2(ServiceInstanceDict, const char*, M_CSTR_DUP_OPLIST, const ServiceData service_registry_manifest_unlock(); \ } -ServiceManifestDict_t service_manifest_dict; -ServiceInstanceDict_t service_instance_dict; -FuriMutex* manifest_mutex = NULL; -FuriMutex* instance_mutex = NULL; +static ServiceManifestDict_t service_manifest_dict; +static ServiceInstanceDict_t service_instance_dict; +static Mutex* manifest_mutex = NULL; +static Mutex* instance_mutex = NULL; -void service_registry_init() { - furi_assert(manifest_mutex == NULL); - manifest_mutex = furi_mutex_alloc(FuriMutexTypeNormal); +void tt_service_registry_init() { + tt_assert(manifest_mutex == NULL); + manifest_mutex = tt_mutex_alloc(MutexTypeNormal); ServiceManifestDict_init(service_manifest_dict); - furi_assert(instance_mutex == NULL); - instance_mutex = furi_mutex_alloc(FuriMutexTypeNormal); + tt_assert(instance_mutex == NULL); + instance_mutex = tt_mutex_alloc(MutexTypeNormal); ServiceInstanceDict_init(service_instance_dict); } void service_registry_instance_lock() { - furi_assert(instance_mutex != NULL); - furi_mutex_acquire(instance_mutex, FuriWaitForever); + tt_assert(instance_mutex != NULL); + tt_mutex_acquire(instance_mutex, TtWaitForever); } void service_registry_instance_unlock() { - furi_assert(instance_mutex != NULL); - furi_mutex_release(instance_mutex); + tt_assert(instance_mutex != NULL); + tt_mutex_release(instance_mutex); } void service_registry_manifest_lock() { - furi_assert(manifest_mutex != NULL); - furi_mutex_acquire(manifest_mutex, FuriWaitForever); + tt_assert(manifest_mutex != NULL); + tt_mutex_acquire(manifest_mutex, TtWaitForever); } void service_registry_manifest_unlock() { - furi_assert(manifest_mutex != NULL); - furi_mutex_release(manifest_mutex); + tt_assert(manifest_mutex != NULL); + tt_mutex_release(manifest_mutex); } -void service_registry_add(const ServiceManifest _Nonnull* manifest) { - FURI_LOG_I(TAG, "adding %s", manifest->id); +void tt_service_registry_add(const ServiceManifest _Nonnull* manifest) { + TT_LOG_I(TAG, "adding %s", manifest->id); service_registry_manifest_lock(); ServiceManifestDict_set_at(service_manifest_dict, manifest->id, manifest); service_registry_manifest_unlock(); } -void service_registry_remove(const ServiceManifest _Nonnull* manifest) { - FURI_LOG_I(TAG, "removing %s", manifest->id); +void tt_service_registry_remove(const ServiceManifest _Nonnull* manifest) { + TT_LOG_I(TAG, "removing %s", manifest->id); service_registry_manifest_lock(); ServiceManifestDict_erase(service_manifest_dict, manifest->id); service_registry_manifest_unlock(); } -const ServiceManifest* _Nullable service_registry_find_manifest_by_id(const char* id) { +const ServiceManifest* _Nullable tt_service_registry_find_manifest_by_id(const char* id) { service_registry_manifest_lock(); const ServiceManifest** _Nullable manifest = ServiceManifestDict_get(service_manifest_dict, id); service_registry_manifest_unlock(); @@ -89,48 +89,48 @@ ServiceData* _Nullable service_registry_find_instance_by_id(const char* id) { return service; } -void service_registry_for_each_manifest(ServiceManifestCallback callback, void* _Nullable context) { +void tt_service_registry_for_each_manifest(ServiceManifestCallback callback, void* _Nullable context) { APP_REGISTRY_FOR_EACH(manifest, { callback(manifest, context); }); } // TODO: return proper error/status instead of BOOL -bool service_registry_start(const char* service_id) { - FURI_LOG_I(TAG, "starting %s", service_id); - const ServiceManifest* manifest = service_registry_find_manifest_by_id(service_id); +bool tt_service_registry_start(const char* service_id) { + TT_LOG_I(TAG, "starting %s", service_id); + const ServiceManifest* manifest = tt_service_registry_find_manifest_by_id(service_id); if (manifest == NULL) { - FURI_LOG_E(TAG, "manifest not found for service %s", service_id); + TT_LOG_E(TAG, "manifest not found for service %s", service_id); return false; } - Service service = service_alloc(manifest); + Service service = tt_service_alloc(manifest); manifest->on_start(service); service_registry_instance_lock(); ServiceInstanceDict_set_at(service_instance_dict, manifest->id, service); service_registry_instance_unlock(); - FURI_LOG_I(TAG, "started %s", service_id); + TT_LOG_I(TAG, "started %s", service_id); return true; } -bool service_registry_stop(const char* service_id) { - FURI_LOG_I(TAG, "stopping %s", service_id); +bool tt_service_registry_stop(const char* service_id) { + TT_LOG_I(TAG, "stopping %s", service_id); ServiceData* service = service_registry_find_instance_by_id(service_id); if (service == NULL) { - FURI_LOG_W(TAG, "service not running: %s", service_id); + TT_LOG_W(TAG, "service not running: %s", service_id); return false; } service->manifest->on_stop(service); - service_free(service); + tt_service_free(service); service_registry_instance_lock(); ServiceInstanceDict_erase(service_instance_dict, service_id); service_registry_instance_unlock(); - FURI_LOG_I(TAG, "stopped %s", service_id); + TT_LOG_I(TAG, "stopped %s", service_id); return true; } diff --git a/components/tactility-core/src/service_registry.h b/components/tactility-core/src/service_registry.h new file mode 100644 index 00000000..6defbac0 --- /dev/null +++ b/components/tactility-core/src/service_registry.h @@ -0,0 +1,25 @@ +#pragma once + +#include "service_manifest.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef void (*ServiceManifestCallback)(const ServiceManifest*, void* context); + +void tt_service_registry_init(); + +void tt_service_registry_add(const ServiceManifest* manifest); +void tt_service_registry_remove(const ServiceManifest* manifest); +const ServiceManifest _Nullable* tt_service_registry_find_manifest_by_id(const char* id); +void tt_service_registry_for_each_manifest(ServiceManifestCallback callback, void* _Nullable context); + +bool tt_service_registry_start(const char* service_id); +bool tt_service_registry_stop(const char* service_id); + +#ifdef __cplusplus +} +#endif diff --git a/components/furi/src/stream_buffer.c b/components/tactility-core/src/stream_buffer.c similarity index 56% rename from components/furi/src/stream_buffer.c rename to components/tactility-core/src/stream_buffer.c index 2f85630a..c274cb56 100644 --- a/components/furi/src/stream_buffer.c +++ b/components/tactility-core/src/stream_buffer.c @@ -1,39 +1,39 @@ #include "stream_buffer.h" #include "check.h" -#include "furi_core_defines.h" -#include "furi_core_types.h" +#include "core_defines.h" +#include "core_types.h" #include "freertos/FreeRTOS.h" #include "freertos/stream_buffer.h" -FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level) { - furi_assert(size != 0); +StreamBuffer* tt_stream_buffer_alloc(size_t size, size_t trigger_level) { + tt_assert(size != 0); StreamBufferHandle_t handle = xStreamBufferCreate(size, trigger_level); - furi_check(handle); + tt_check(handle); return handle; }; -void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer) { - furi_assert(stream_buffer); +void tt_stream_buffer_free(StreamBuffer* stream_buffer) { + tt_assert(stream_buffer); vStreamBufferDelete(stream_buffer); }; -bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level) { - furi_assert(stream_buffer); +bool tt_stream_set_trigger_level(StreamBuffer* stream_buffer, size_t trigger_level) { + tt_assert(stream_buffer); return xStreamBufferSetTriggerLevel(stream_buffer, trigger_level) == pdTRUE; }; -size_t furi_stream_buffer_send( - FuriStreamBuffer* stream_buffer, +size_t tt_stream_buffer_send( + StreamBuffer* stream_buffer, const void* data, size_t length, uint32_t timeout ) { size_t ret; - if (FURI_IS_IRQ_MODE()) { + if (TT_IS_IRQ_MODE()) { BaseType_t yield; ret = xStreamBufferSendFromISR(stream_buffer, data, length, &yield); portYIELD_FROM_ISR(yield); @@ -44,15 +44,15 @@ size_t furi_stream_buffer_send( return ret; }; -size_t furi_stream_buffer_receive( - FuriStreamBuffer* stream_buffer, +size_t tt_stream_buffer_receive( + StreamBuffer* stream_buffer, void* data, size_t length, uint32_t timeout ) { size_t ret; - if (FURI_IS_IRQ_MODE()) { + if (TT_IS_IRQ_MODE()) { BaseType_t yield; ret = xStreamBufferReceiveFromISR(stream_buffer, data, length, &yield); portYIELD_FROM_ISR(yield); @@ -63,26 +63,26 @@ size_t furi_stream_buffer_receive( return ret; } -size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer) { +size_t tt_stream_buffer_bytes_available(StreamBuffer* stream_buffer) { return xStreamBufferBytesAvailable(stream_buffer); }; -size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer) { +size_t tt_stream_buffer_spaces_available(StreamBuffer* stream_buffer) { return xStreamBufferSpacesAvailable(stream_buffer); }; -bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer) { +bool tt_stream_buffer_is_full(StreamBuffer* stream_buffer) { return xStreamBufferIsFull(stream_buffer) == pdTRUE; }; -bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer) { +bool tt_stream_buffer_is_empty(StreamBuffer* stream_buffer) { return (xStreamBufferIsEmpty(stream_buffer) == pdTRUE); }; -FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer) { +TtStatus tt_stream_buffer_reset(StreamBuffer* stream_buffer) { if (xStreamBufferReset(stream_buffer) == pdPASS) { - return FuriStatusOk; + return TtStatusOk; } else { - return FuriStatusError; + return TtStatusError; } } \ No newline at end of file diff --git a/components/furi/src/stream_buffer.h b/components/tactility-core/src/stream_buffer.h similarity index 81% rename from components/furi/src/stream_buffer.h rename to components/tactility-core/src/stream_buffer.h index b0e2ae70..6036ae37 100644 --- a/components/furi/src/stream_buffer.h +++ b/components/tactility-core/src/stream_buffer.h @@ -1,6 +1,6 @@ /** * @file stream_buffer.h - * Furi stream buffer primitive. + * Tactility stream buffer primitive. * * Stream buffers are used to send a continuous stream of data from one task or * interrupt to another. Their implementation is light weight, making them @@ -12,7 +12,7 @@ * interrupt that will read from the buffer (the reader). */ #pragma once -#include "furi_core_types.h" +#include "core_types.h" #include #include #include @@ -21,7 +21,7 @@ extern "C" { #endif -typedef void FuriStreamBuffer; +typedef void StreamBuffer; /** * @brief Allocate stream buffer instance. @@ -34,14 +34,14 @@ typedef void FuriStreamBuffer; * before a task that is blocked on the stream buffer to wait for data is moved out of the blocked state. * @return The stream buffer instance. */ -FuriStreamBuffer* furi_stream_buffer_alloc(size_t size, size_t trigger_level); +StreamBuffer* tt_stream_buffer_alloc(size_t size, size_t trigger_level); /** * @brief Free stream buffer instance * * @param stream_buffer The stream buffer instance. */ -void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer); +void tt_stream_buffer_free(StreamBuffer* stream_buffer); /** * @brief Set trigger level for stream buffer. @@ -54,7 +54,7 @@ void furi_stream_buffer_free(FuriStreamBuffer* stream_buffer); * @return true if trigger level can be be updated (new trigger level was less than or equal to the stream buffer's length). * @return false if trigger level can't be be updated (new trigger level was greater than the stream buffer's length). */ -bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigger_level); +bool tt_stream_set_trigger_level(StreamBuffer* stream_buffer, size_t trigger_level); /** * @brief Sends bytes to a stream buffer. The bytes are copied into the stream buffer. @@ -66,12 +66,12 @@ bool furi_stream_set_trigger_level(FuriStreamBuffer* stream_buffer, size_t trigg * @param timeout The maximum amount of time the task should remain in the * Blocked state to wait for space to become available if the stream buffer is full. * Will return immediately if timeout is zero. - * Setting timeout to FuriWaitForever will cause the task to wait indefinitely. + * Setting timeout to TtWaitForever will cause the task to wait indefinitely. * Ignored if called from ISR. * @return The number of bytes actually written to the stream buffer. */ -size_t furi_stream_buffer_send( - FuriStreamBuffer* stream_buffer, +size_t tt_stream_buffer_send( + StreamBuffer* stream_buffer, const void* data, size_t length, uint32_t timeout @@ -88,12 +88,12 @@ size_t furi_stream_buffer_send( * @param timeout The maximum amount of time the task should remain in the * Blocked state to wait for data to become available if the stream buffer is empty. * Will return immediately if timeout is zero. - * Setting timeout to FuriWaitForever will cause the task to wait indefinitely. + * Setting timeout to TtWaitForever will cause the task to wait indefinitely. * Ignored if called from ISR. * @return The number of bytes read from the stream buffer, if any. */ -size_t furi_stream_buffer_receive( - FuriStreamBuffer* stream_buffer, +size_t tt_stream_buffer_receive( + StreamBuffer* stream_buffer, void* data, size_t length, uint32_t timeout @@ -108,7 +108,7 @@ size_t furi_stream_buffer_receive( * @return The number of bytes that can be read from the stream buffer before * the stream buffer would be empty. */ -size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer); +size_t tt_stream_buffer_bytes_available(StreamBuffer* stream_buffer); /** * @brief Queries a stream buffer to see how much free space it contains, which is @@ -119,7 +119,7 @@ size_t furi_stream_buffer_bytes_available(FuriStreamBuffer* stream_buffer); * @return The number of bytes that can be written to the stream buffer before * the stream buffer would be full. */ -size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer); +size_t tt_stream_buffer_spaces_available(StreamBuffer* stream_buffer); /** * @brief Queries a stream buffer to see if it is full. @@ -128,7 +128,7 @@ size_t furi_stream_buffer_spaces_available(FuriStreamBuffer* stream_buffer); * @return true if the stream buffer is full. * @return false if the stream buffer is not full. */ -bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer); +bool tt_stream_buffer_is_full(StreamBuffer* stream_buffer); /** * @brief Queries a stream buffer to see if it is empty. @@ -137,7 +137,7 @@ bool furi_stream_buffer_is_full(FuriStreamBuffer* stream_buffer); * @return true if the stream buffer is empty. * @return false if the stream buffer is not empty. */ -bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer); +bool tt_stream_buffer_is_empty(StreamBuffer* stream_buffer); /** * @brief Resets a stream buffer to its initial, empty, state. Any data that was @@ -145,11 +145,11 @@ bool furi_stream_buffer_is_empty(FuriStreamBuffer* stream_buffer); * are no tasks blocked waiting to either send to or receive from the stream buffer. * * @param stream_buffer The stream buffer instance. - * @return FuriStatusOk if the stream buffer is reset. - * @return FuriStatusError if there was a task blocked waiting to send to or read + * @return TtStatusOk if the stream buffer is reset. + * @return TtStatusError if there was a task blocked waiting to send to or read * from the stream buffer then the stream buffer is not reset. */ -FuriStatus furi_stream_buffer_reset(FuriStreamBuffer* stream_buffer); +TtStatus tt_stream_buffer_reset(StreamBuffer* stream_buffer); #ifdef __cplusplus } diff --git a/components/furi/src/furi_core.h b/components/tactility-core/src/tactility_core.h similarity index 53% rename from components/furi/src/furi_core.h rename to components/tactility-core/src/tactility_core.h index 0bb659d5..7ce9b585 100644 --- a/components/furi/src/furi_core.h +++ b/components/tactility-core/src/tactility_core.h @@ -3,10 +3,12 @@ #include #include +#include "app.h" #include "check.h" +#include "core_defines.h" +#include "core_extra_defines.h" +#include "core_types.h" #include "critical.h" #include "event_flag.h" -#include "furi_core_defines.h" -#include "furi_core_types.h" -#include "furi_extra_defines.h" #include "log.h" +#include "service.h" diff --git a/components/tactility-core/src/tactility_core_config.h b/components/tactility-core/src/tactility_core_config.h new file mode 100644 index 00000000..a47fbfbd --- /dev/null +++ b/components/tactility-core/src/tactility_core_config.h @@ -0,0 +1,3 @@ +#pragma once + +#define TT_CONFIG_THREAD_MAX_PRIORITIES (32) \ No newline at end of file diff --git a/components/tactility-core/src/thread.c b/components/tactility-core/src/thread.c new file mode 100644 index 00000000..baffd7a5 --- /dev/null +++ b/components/tactility-core/src/thread.c @@ -0,0 +1,599 @@ +#include "thread.h" + +#include "check.h" +#include "core_defines.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "kernel.h" +#include "log.h" +#include "tt_string.h" +#include + +#define TAG "Thread" + +#define THREAD_NOTIFY_INDEX 1 // Index 0 is used for stream buffers + +// Limits +#define MAX_BITS_TASK_NOTIFY 31U +#define MAX_BITS_EVENT_GROUPS 24U + +#define THREAD_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_TASK_NOTIFY) - 1U)) +#define EVENT_FLAGS_INVALID_BITS (~((1UL << MAX_BITS_EVENT_GROUPS) - 1U)) + +typedef struct ThreadStdout ThreadStdout; + +struct ThreadStdout { + ThreadStdoutWriteCallback write_callback; + TtString* buffer; +}; + +struct Thread { + ThreadState state; + int32_t ret; + + ThreadCallback callback; + void* context; + + ThreadStateCallback state_callback; + void* state_context; + + char* name; + char* appid; + + ThreadPriority priority; + + TaskHandle_t task_handle; + size_t heap_size; + + ThreadStdout output; + + // Keep all non-alignable byte types in one place, + // this ensures that the size of this structure is minimal + bool is_static; + bool heap_trace_enabled; + + configSTACK_DEPTH_TYPE stack_size; +}; + +static size_t __tt_thread_stdout_write(Thread* thread, const char* data, size_t size); +static int32_t __tt_thread_stdout_flush(Thread* thread); + +/** Catch threads that are trying to exit wrong way */ +__attribute__((__noreturn__)) void tt_thread_catch() { //-V1082 + // If you're here it means you're probably doing something wrong + // with critical sections or with scheduler state + asm volatile("nop"); // extra magic + tt_crash("You are doing it wrong"); //-V779 + __builtin_unreachable(); +} + +static void tt_thread_set_state(Thread* thread, ThreadState state) { + tt_assert(thread); + thread->state = state; + if (thread->state_callback) { + thread->state_callback(state, thread->state_context); + } +} + +static void tt_thread_body(void* context) { + tt_assert(context); + Thread* thread = context; + + // store thread instance to thread local storage + tt_assert(pvTaskGetThreadLocalStoragePointer(NULL, 0) == NULL); + vTaskSetThreadLocalStoragePointer(NULL, 0, thread); + + tt_assert(thread->state == ThreadStateStarting); + tt_thread_set_state(thread, ThreadStateRunning); + + thread->ret = thread->callback(thread->context); + + tt_assert(thread->state == ThreadStateRunning); + + if (thread->is_static) { + ESP_LOGI( + TAG, + "%s service thread TCB memory will not be reclaimed", + thread->name ? thread->name : "" + ); + } + + // flush stdout + __tt_thread_stdout_flush(thread); + + tt_thread_set_state(thread, ThreadStateStopped); + + vTaskDelete(NULL); + tt_thread_catch(); +} + +Thread* tt_thread_alloc() { + Thread* thread = malloc(sizeof(Thread)); + // TODO: create default struct instead of using memset() + memset(thread, 0, sizeof(Thread)); + thread->output.buffer = tt_string_alloc(); + thread->is_static = false; + + Thread* parent = NULL; + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { + // TLS is not available, if we called not from thread context + parent = pvTaskGetThreadLocalStoragePointer(NULL, 0); + + if (parent && parent->appid) { + tt_thread_set_appid(thread, parent->appid); + } else { + tt_thread_set_appid(thread, "unknown"); + } + } else { + // if scheduler is not started, we are starting driver thread + tt_thread_set_appid(thread, "driver"); + } + + /*HalRtcHeapTrackMode mode = tt_hal_rtc_get_heap_track_mode(); + if(mode == HalRtcHeapTrackModeAll) { + thread->heap_trace_enabled = true; + } else if(mode == HalRtcHeapTrackModeTree && tt_thread_get_current_id()) { + if(parent) thread->heap_trace_enabled = parent->heap_trace_enabled; + } else */ + { + thread->heap_trace_enabled = false; + } + + return thread; +} + +Thread* tt_thread_alloc_ex( + const char* name, + uint32_t stack_size, + ThreadCallback callback, + void* context +) { + Thread* thread = tt_thread_alloc(); + tt_thread_set_name(thread, name); + tt_thread_set_stack_size(thread, stack_size); + tt_thread_set_callback(thread, callback); + tt_thread_set_context(thread, context); + return thread; +} + +void tt_thread_free(Thread* thread) { + tt_assert(thread); + + // Ensure that use join before free + tt_assert(thread->state == ThreadStateStopped); + tt_assert(thread->task_handle == NULL); + + if (thread->name) free(thread->name); + if (thread->appid) free(thread->appid); + tt_string_free(thread->output.buffer); + + free(thread); +} + +void tt_thread_set_name(Thread* thread, const char* name) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + if (thread->name) free(thread->name); + thread->name = name ? strdup(name) : NULL; +} + +void tt_thread_set_appid(Thread* thread, const char* appid) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + if (thread->appid) free(thread->appid); + thread->appid = appid ? strdup(appid) : NULL; +} + +void tt_thread_mark_as_static(Thread* thread) { + thread->is_static = true; +} + +bool tt_thread_mark_is_service(ThreadId thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + assert(!TT_IS_IRQ_MODE() && (hTask != NULL)); + Thread* thread = (Thread*)pvTaskGetThreadLocalStoragePointer(hTask, 0); + assert(thread != NULL); + return thread->is_static; +} + +void tt_thread_set_stack_size(Thread* thread, size_t stack_size) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + tt_assert(stack_size % 4 == 0); + thread->stack_size = stack_size; +} + +void tt_thread_set_callback(Thread* thread, ThreadCallback callback) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + thread->callback = callback; +} + +void tt_thread_set_context(Thread* thread, void* context) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + thread->context = context; +} + +void tt_thread_set_priority(Thread* thread, ThreadPriority priority) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + tt_assert(priority >= ThreadPriorityIdle && priority <= ThreadPriorityIsr); + thread->priority = priority; +} + +void tt_thread_set_current_priority(ThreadPriority priority) { + UBaseType_t new_priority = priority ? priority : ThreadPriorityNormal; + vTaskPrioritySet(NULL, new_priority); +} + +ThreadPriority tt_thread_get_current_priority() { + return (ThreadPriority)uxTaskPriorityGet(NULL); +} + +void tt_thread_set_state_callback(Thread* thread, ThreadStateCallback callback) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + thread->state_callback = callback; +} + +void tt_thread_set_state_context(Thread* thread, void* context) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + thread->state_context = context; +} + +ThreadState tt_thread_get_state(Thread* thread) { + tt_assert(thread); + return thread->state; +} + +void tt_thread_start(Thread* thread) { + tt_assert(thread); + tt_assert(thread->callback); + tt_assert(thread->state == ThreadStateStopped); + tt_assert(thread->stack_size > 0 && thread->stack_size < (UINT16_MAX * sizeof(StackType_t))); + + tt_thread_set_state(thread, ThreadStateStarting); + + uint32_t stack = thread->stack_size / sizeof(StackType_t); + UBaseType_t priority = thread->priority ? thread->priority : ThreadPriorityNormal; + if (thread->is_static) { + thread->task_handle = xTaskCreateStatic( + tt_thread_body, + thread->name, + stack, + thread, + priority, + malloc(sizeof(StackType_t) * stack), + malloc(sizeof(StaticTask_t)) + ); + } else { + BaseType_t ret = xTaskCreate( + tt_thread_body, thread->name, stack, thread, priority, &thread->task_handle + ); + tt_check(ret == pdPASS); + } + + tt_check(thread->task_handle); +} + +void tt_thread_cleanup_tcb_event(TaskHandle_t task) { + Thread* thread = pvTaskGetThreadLocalStoragePointer(task, 0); + if (thread) { + // clear thread local storage + vTaskSetThreadLocalStoragePointer(task, 0, NULL); + tt_assert(thread->task_handle == task); + thread->task_handle = NULL; + } +} + +bool tt_thread_join(Thread* thread) { + tt_assert(thread); + + tt_check(tt_thread_get_current() != thread); + + // !!! IMPORTANT NOTICE !!! + // + // If your thread exited, but your app stuck here: some other thread uses + // all cpu time, which delays kernel from releasing task handle + while (thread->task_handle) { + tt_delay_ms(10); + } + + return true; +} + +ThreadId tt_thread_get_id(Thread* thread) { + tt_assert(thread); + return thread->task_handle; +} + +void tt_thread_enable_heap_trace(Thread* thread) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + thread->heap_trace_enabled = true; +} + +void tt_thread_disable_heap_trace(Thread* thread) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + thread->heap_trace_enabled = false; +} + +size_t tt_thread_get_heap_size(Thread* thread) { + tt_assert(thread); + tt_assert(thread->heap_trace_enabled == true); + return thread->heap_size; +} + +int32_t tt_thread_get_return_code(Thread* thread) { + tt_assert(thread); + tt_assert(thread->state == ThreadStateStopped); + return thread->ret; +} + +ThreadId tt_thread_get_current_id() { + return xTaskGetCurrentTaskHandle(); +} + +Thread* tt_thread_get_current() { + Thread* thread = pvTaskGetThreadLocalStoragePointer(NULL, 0); + return thread; +} + +void tt_thread_yield() { + tt_assert(!TT_IS_IRQ_MODE()); + taskYIELD(); +} + +uint32_t tt_thread_flags_set(ThreadId thread_id, uint32_t flags) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + uint32_t rflags; + BaseType_t yield; + + if ((hTask == NULL) || ((flags & THREAD_FLAGS_INVALID_BITS) != 0U)) { + rflags = (uint32_t)TtStatusErrorParameter; + } else { + rflags = (uint32_t)TtStatusError; + + if (TT_IS_IRQ_MODE()) { + yield = pdFALSE; + + (void)xTaskNotifyIndexedFromISR(hTask, THREAD_NOTIFY_INDEX, flags, eSetBits, &yield); + (void)xTaskNotifyAndQueryIndexedFromISR( + hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags, NULL + ); + + portYIELD_FROM_ISR(yield); + } else { + (void)xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, flags, eSetBits); + (void)xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags); + } + } + /* Return flags after setting */ + return (rflags); +} + +uint32_t tt_thread_flags_clear(uint32_t flags) { + TaskHandle_t hTask; + uint32_t rflags, cflags; + + if (TT_IS_IRQ_MODE()) { + rflags = (uint32_t)TtStatusErrorISR; + } else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) { + rflags = (uint32_t)TtStatusErrorParameter; + } else { + hTask = xTaskGetCurrentTaskHandle(); + + if (xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &cflags) == + pdPASS) { + rflags = cflags; + cflags &= ~flags; + + if (xTaskNotifyIndexed(hTask, THREAD_NOTIFY_INDEX, cflags, eSetValueWithOverwrite) != + pdPASS) { + rflags = (uint32_t)TtStatusError; + } + } else { + rflags = (uint32_t)TtStatusError; + } + } + + /* Return flags before clearing */ + return (rflags); +} + +uint32_t tt_thread_flags_get(void) { + TaskHandle_t hTask; + uint32_t rflags; + + if (TT_IS_IRQ_MODE()) { + rflags = (uint32_t)TtStatusErrorISR; + } else { + hTask = xTaskGetCurrentTaskHandle(); + + if (xTaskNotifyAndQueryIndexed(hTask, THREAD_NOTIFY_INDEX, 0, eNoAction, &rflags) != + pdPASS) { + rflags = (uint32_t)TtStatusError; + } + } + + return (rflags); +} + +uint32_t tt_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeout) { + uint32_t rflags, nval; + uint32_t clear; + TickType_t t0, td, tout; + BaseType_t rval; + + if (TT_IS_IRQ_MODE()) { + rflags = (uint32_t)TtStatusErrorISR; + } else if ((flags & THREAD_FLAGS_INVALID_BITS) != 0U) { + rflags = (uint32_t)TtStatusErrorParameter; + } else { + if ((options & TtFlagNoClear) == TtFlagNoClear) { + clear = 0U; + } else { + clear = flags; + } + + rflags = 0U; + tout = timeout; + + t0 = xTaskGetTickCount(); + do { + rval = xTaskNotifyWaitIndexed(THREAD_NOTIFY_INDEX, 0, clear, &nval, tout); + + if (rval == pdPASS) { + rflags &= flags; + rflags |= nval; + + if ((options & TtFlagWaitAll) == TtFlagWaitAll) { + if ((flags & rflags) == flags) { + break; + } else { + if (timeout == 0U) { + rflags = (uint32_t)TtStatusErrorResource; + break; + } + } + } else { + if ((flags & rflags) != 0) { + break; + } else { + if (timeout == 0U) { + rflags = (uint32_t)TtStatusErrorResource; + break; + } + } + } + + /* Update timeout */ + td = xTaskGetTickCount() - t0; + + if (td > tout) { + tout = 0; + } else { + tout -= td; + } + } else { + if (timeout == 0) { + rflags = (uint32_t)TtStatusErrorResource; + } else { + rflags = (uint32_t)TtStatusErrorTimeout; + } + } + } while (rval != pdFAIL); + } + + /* Return flags before clearing */ + return (rflags); +} + +uint32_t tt_thread_enumerate(ThreadId* thread_array, uint32_t array_items) { + uint32_t i, count; + TaskStatus_t* task; + + if (TT_IS_IRQ_MODE() || (thread_array == NULL) || (array_items == 0U)) { + count = 0U; + } else { + vTaskSuspendAll(); + + count = uxTaskGetNumberOfTasks(); + task = pvPortMalloc(count * sizeof(TaskStatus_t)); + + if (task != NULL) { + count = uxTaskGetSystemState(task, count, NULL); + + for (i = 0U; (i < count) && (i < array_items); i++) { + thread_array[i] = (ThreadId)task[i].xHandle; + } + count = i; + } + (void)xTaskResumeAll(); + + vPortFree(task); + } + + return (count); +} + +const char* tt_thread_get_name(ThreadId thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + const char* name; + + if (TT_IS_IRQ_MODE() || (hTask == NULL)) { + name = NULL; + } else { + name = pcTaskGetName(hTask); + } + + return (name); +} + +const char* tt_thread_get_appid(ThreadId thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + const char* appid = "system"; + + if (!TT_IS_IRQ_MODE() && (hTask != NULL)) { + Thread* thread = (Thread*)pvTaskGetThreadLocalStoragePointer(hTask, 0); + if (thread) { + appid = thread->appid; + } + } + + return (appid); +} + +uint32_t tt_thread_get_stack_space(ThreadId thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + uint32_t sz; + + if (TT_IS_IRQ_MODE() || (hTask == NULL)) { + sz = 0U; + } else { + sz = (uint32_t)(uxTaskGetStackHighWaterMark(hTask) * sizeof(StackType_t)); + } + + return (sz); +} + +static size_t __tt_thread_stdout_write(Thread* thread, const char* data, size_t size) { + if (thread->output.write_callback != NULL) { + thread->output.write_callback(data, size); + } else { + TT_LOG_I(thread->name, "%s", data); + } + return size; +} + +static int32_t __tt_thread_stdout_flush(Thread* thread) { + TtString* buffer = thread->output.buffer; + size_t size = tt_string_size(buffer); + if (size > 0) { + __tt_thread_stdout_write(thread, tt_string_get_cstr(buffer), size); + tt_string_reset(buffer); + } + return 0; +} + +void tt_thread_suspend(ThreadId thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + vTaskSuspend(hTask); +} + +void tt_thread_resume(ThreadId thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + if (TT_IS_IRQ_MODE()) { + xTaskResumeFromISR(hTask); + } else { + vTaskResume(hTask); + } +} + +bool tt_thread_is_suspended(ThreadId thread_id) { + TaskHandle_t hTask = (TaskHandle_t)thread_id; + return eTaskGetState(hTask) == eSuspended; +} diff --git a/components/tactility-core/src/thread.h b/components/tactility-core/src/thread.h new file mode 100644 index 00000000..f1196d37 --- /dev/null +++ b/components/tactility-core/src/thread.h @@ -0,0 +1,334 @@ +#pragma once + +#include "core_defines.h" +#include "core_types.h" + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** ThreadState */ +typedef enum { + ThreadStateStopped, + ThreadStateStarting, + ThreadStateRunning, +} ThreadState; + +/** ThreadPriority */ +typedef enum { + ThreadPriorityNone = 0, /**< Uninitialized, choose system default */ + ThreadPriorityIdle = 1, /**< Idle priority */ + ThreadPriorityLowest = 14, /**< Lowest */ + ThreadPriorityLow = 15, /**< Low */ + ThreadPriorityNormal = 16, /**< Normal */ + ThreadPriorityHigh = 17, /**< High */ + ThreadPriorityHighest = 18, /**< Highest */ + ThreadPriorityIsr = + (TT_CONFIG_THREAD_MAX_PRIORITIES - 1), /**< Deferred ISR (highest possible) */ +} ThreadPriority; + +/** Thread anonymous structure */ +typedef struct Thread Thread; + +/** ThreadId proxy type to OS low level functions */ +typedef void* ThreadId; + +/** ThreadCallback Your callback to run in new thread + * @warning never use osThreadExit in Thread + */ +typedef int32_t (*ThreadCallback)(void* context); + +/** Write to stdout callback + * @param data pointer to data + * @param size data size @warning your handler must consume everything + */ +typedef void (*ThreadStdoutWriteCallback)(const char* data, size_t size); + +/** Thread state change callback called upon thread state change + * @param state new thread state + * @param context callback context + */ +typedef void (*ThreadStateCallback)(ThreadState state, void* context); + +/** Allocate Thread + * + * @return Thread instance + */ +Thread* tt_thread_alloc(); + +/** Allocate Thread, shortcut version + * + * @param name + * @param stack_size + * @param callback + * @param context + * @return Thread* + */ +Thread* tt_thread_alloc_ex( + const char* name, + uint32_t stack_size, + ThreadCallback callback, + void* context +); + +/** Release Thread + * + * @warning see tt_thread_join + * + * @param thread Thread instance + */ +void tt_thread_free(Thread* thread); + +/** Set Thread name + * + * @param thread Thread instance + * @param name string + */ +void tt_thread_set_name(Thread* thread, const char* name); + +/** + * @brief Set Thread appid + * Technically, it is like a "process id", but it is not a system-wide unique identifier. + * All threads spawned by the same app will have the same appid. + * + * @param thread + * @param appid + */ +void tt_thread_set_appid(Thread* thread, const char* appid); + +/** Mark thread as service + * The service cannot be stopped or removed, and cannot exit from the thread body + * + * @param thread + */ +void tt_thread_mark_as_static(Thread* thread); + +/** Set Thread stack size + * + * @param thread Thread instance + * @param stack_size stack size in bytes + */ +void tt_thread_set_stack_size(Thread* thread, size_t stack_size); + +/** Set Thread callback + * + * @param thread Thread instance + * @param callback ThreadCallback, called upon thread run + */ +void tt_thread_set_callback(Thread* thread, ThreadCallback callback); + +/** Set Thread context + * + * @param thread Thread instance + * @param context pointer to context for thread callback + */ +void tt_thread_set_context(Thread* thread, void* context); + +/** Set Thread priority + * + * @param thread Thread instance + * @param priority ThreadPriority value + */ +void tt_thread_set_priority(Thread* thread, ThreadPriority priority); + +/** Set current thread priority + * + * @param priority ThreadPriority value + */ +void tt_thread_set_current_priority(ThreadPriority priority); + +/** Get current thread priority + * + * @return ThreadPriority value + */ +ThreadPriority tt_thread_get_current_priority(); + +/** Set Thread state change callback + * + * @param thread Thread instance + * @param callback state change callback + */ +void tt_thread_set_state_callback(Thread* thread, ThreadStateCallback callback); + +/** Set Thread state change context + * + * @param thread Thread instance + * @param context pointer to context + */ +void tt_thread_set_state_context(Thread* thread, void* context); + +/** Get Thread state + * + * @param thread Thread instance + * + * @return thread state from ThreadState + */ +ThreadState tt_thread_get_state(Thread* thread); + +/** Start Thread + * + * @param thread Thread instance + */ +void tt_thread_start(Thread* thread); + +/** Join Thread + * + * @warning Use this method only when CPU is not busy(Idle task receives + * control), otherwise it will wait forever. + * + * @param thread Thread instance + * + * @return bool + */ +bool tt_thread_join(Thread* thread); + +/** Get FreeRTOS ThreadId for Thread instance + * + * @param thread Thread instance + * + * @return ThreadId or NULL + */ +ThreadId tt_thread_get_id(Thread* thread); + +/** Enable heap tracing + * + * @param thread Thread instance + */ +void tt_thread_enable_heap_trace(Thread* thread); + +/** Disable heap tracing + * + * @param thread Thread instance + */ +void tt_thread_disable_heap_trace(Thread* thread); + +/** Get thread heap size + * + * @param thread Thread instance + * + * @return size in bytes + */ +size_t tt_thread_get_heap_size(Thread* thread); + +/** Get thread return code + * + * @param thread Thread instance + * + * @return return code + */ +int32_t tt_thread_get_return_code(Thread* thread); + +/** Thread related methods that doesn't involve Thread directly */ + +/** Get FreeRTOS ThreadId for current thread + * + * @param thread Thread instance + * + * @return ThreadId or NULL + */ +ThreadId tt_thread_get_current_id(); + +/** Get Thread instance for current thread + * + * @return pointer to Thread or NULL if this thread doesn't belongs to Tactility + */ +Thread* tt_thread_get_current(); + +/** Return control to scheduler */ +void tt_thread_yield(); + +uint32_t tt_thread_flags_set(ThreadId thread_id, uint32_t flags); + +uint32_t tt_thread_flags_clear(uint32_t flags); + +uint32_t tt_thread_flags_get(void); + +uint32_t tt_thread_flags_wait(uint32_t flags, uint32_t options, uint32_t timeout); + +/** + * @brief Enumerate threads + * + * @param thread_array array of ThreadId, where thread ids will be stored + * @param array_items array size + * @return uint32_t threads count + */ +uint32_t tt_thread_enumerate(ThreadId* thread_array, uint32_t array_items); + +/** + * @brief Get thread name + * + * @param thread_id + * @return const char* name or NULL + */ +const char* tt_thread_get_name(ThreadId thread_id); + +/** + * @brief Get thread appid + * + * @param thread_id + * @return const char* appid + */ +const char* tt_thread_get_appid(ThreadId thread_id); + +/** + * @brief Get thread stack watermark + * + * @param thread_id + * @return uint32_t + */ +uint32_t tt_thread_get_stack_space(ThreadId thread_id); + +/** Get STDOUT callback for thead + * + * @return STDOUT callback + */ +ThreadStdoutWriteCallback tt_thread_get_stdout_callback(); + +/** Set STDOUT callback for thread + * + * @param callback callback or NULL to clear + */ +void tt_thread_set_stdout_callback(ThreadStdoutWriteCallback callback); + +/** Write data to buffered STDOUT + * + * @param data input data + * @param size input data size + * + * @return size_t written data size + */ +size_t tt_thread_stdout_write(const char* data, size_t size); + +/** Flush data to STDOUT + * + * @return int32_t error code + */ +int32_t tt_thread_stdout_flush(); + +/** Suspend thread + * + * @param thread_id thread id + */ +void tt_thread_suspend(ThreadId thread_id); + +/** Resume thread + * + * @param thread_id thread id + */ +void tt_thread_resume(ThreadId thread_id); + +/** Get thread suspended state + * + * @param thread_id thread id + * @return true if thread is suspended + */ +bool tt_thread_is_suspended(ThreadId thread_id); + +bool tt_thread_mark_is_service(ThreadId thread_id); + +#ifdef __cplusplus +} +#endif diff --git a/components/furi/src/timer.c b/components/tactility-core/src/timer.c similarity index 55% rename from components/furi/src/timer.c rename to components/tactility-core/src/timer.c index a18c6062..176316f0 100644 --- a/components/furi/src/timer.c +++ b/components/tactility-core/src/timer.c @@ -6,11 +6,11 @@ #include "freertos/timers.h" typedef struct { - FuriTimerCallback func; + TimerCallback func; void* context; } TimerCallback_t; -static void TimerCallback(TimerHandle_t hTimer) { +static void timer_callback(TimerHandle_t hTimer) { TimerCallback_t* callb; /* Retrieve pointer to callback function and context */ @@ -24,8 +24,8 @@ static void TimerCallback(TimerHandle_t hTimer) { } } -FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* context) { - furi_assert((furi_kernel_is_irq() == 0U) && (func != NULL)); +Timer* tt_timer_alloc(TimerCallback func, TimerType type, void* context) { + tt_assert((tt_kernel_is_irq() == 0U) && (func != NULL)); TimerHandle_t hTimer; TimerCallback_t* callb; @@ -40,7 +40,7 @@ FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* co callb->func = func; callb->context = context; - if (type == FuriTimerTypeOnce) { + if (type == TimerTypeOnce) { reload = pdFALSE; } else { reload = pdTRUE; @@ -50,25 +50,26 @@ FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* co callb = (TimerCallback_t*)((uint32_t)callb | 1U); // TimerCallback function is always provided as a callback and is used to call application // specified function with its context both stored in structure callb. - hTimer = xTimerCreate(NULL, portMAX_DELAY, reload, callb, TimerCallback); - furi_check(hTimer); + // TODO: should we use pointer to function or function directly as-is? + hTimer = xTimerCreate(NULL, portMAX_DELAY, reload, callb, timer_callback); + tt_check(hTimer); /* Return timer ID */ - return ((FuriTimer*)hTimer); + return ((Timer*)hTimer); } -void furi_timer_free(FuriTimer* instance) { - furi_assert(!furi_kernel_is_irq()); - furi_assert(instance); +void tt_timer_free(Timer* instance) { + tt_assert(!tt_kernel_is_irq()); + tt_assert(instance); TimerHandle_t hTimer = (TimerHandle_t)instance; TimerCallback_t* callb; callb = (TimerCallback_t*)pvTimerGetTimerID(hTimer); - furi_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS); + tt_check(xTimerDelete(hTimer, portMAX_DELAY) == pdPASS); - while (furi_timer_is_running(instance)) furi_delay_tick(2); + while (tt_timer_is_running(instance)) tt_delay_tick(2); if ((uint32_t)callb & 1U) { /* Callback memory was allocated from dynamic pool, clear flag */ @@ -79,57 +80,57 @@ void furi_timer_free(FuriTimer* instance) { } } -FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks) { - furi_assert(!furi_kernel_is_irq()); - furi_assert(instance); - furi_assert(ticks < portMAX_DELAY); +TtStatus tt_timer_start(Timer* instance, uint32_t ticks) { + tt_assert(!tt_kernel_is_irq()); + tt_assert(instance); + tt_assert(ticks < portMAX_DELAY); TimerHandle_t hTimer = (TimerHandle_t)instance; - FuriStatus stat; + TtStatus stat; if (xTimerChangePeriod(hTimer, ticks, portMAX_DELAY) == pdPASS) { - stat = FuriStatusOk; + stat = TtStatusOk; } else { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } /* Return execution status */ return (stat); } -FuriStatus furi_timer_restart(FuriTimer* instance, uint32_t ticks) { - furi_assert(!furi_kernel_is_irq()); - furi_assert(instance); - furi_assert(ticks < portMAX_DELAY); +TtStatus tt_timer_restart(Timer* instance, uint32_t ticks) { + tt_assert(!tt_kernel_is_irq()); + tt_assert(instance); + tt_assert(ticks < portMAX_DELAY); TimerHandle_t hTimer = (TimerHandle_t)instance; - FuriStatus stat; + TtStatus stat; if (xTimerChangePeriod(hTimer, ticks, portMAX_DELAY) == pdPASS && xTimerReset(hTimer, portMAX_DELAY) == pdPASS) { - stat = FuriStatusOk; + stat = TtStatusOk; } else { - stat = FuriStatusErrorResource; + stat = TtStatusErrorResource; } /* Return execution status */ return (stat); } -FuriStatus furi_timer_stop(FuriTimer* instance) { - furi_assert(!furi_kernel_is_irq()); - furi_assert(instance); +TtStatus tt_timer_stop(Timer* instance) { + tt_assert(!tt_kernel_is_irq()); + tt_assert(instance); TimerHandle_t hTimer = (TimerHandle_t)instance; - furi_check(xTimerStop(hTimer, portMAX_DELAY) == pdPASS); + tt_check(xTimerStop(hTimer, portMAX_DELAY) == pdPASS); - return FuriStatusOk; + return TtStatusOk; } -uint32_t furi_timer_is_running(FuriTimer* instance) { - furi_assert(!furi_kernel_is_irq()); - furi_assert(instance); +uint32_t tt_timer_is_running(Timer* instance) { + tt_assert(!tt_kernel_is_irq()); + tt_assert(instance); TimerHandle_t hTimer = (TimerHandle_t)instance; @@ -137,36 +138,36 @@ uint32_t furi_timer_is_running(FuriTimer* instance) { return (uint32_t)xTimerIsTimerActive(hTimer); } -uint32_t furi_timer_get_expire_time(FuriTimer* instance) { - furi_assert(!furi_kernel_is_irq()); - furi_assert(instance); +uint32_t tt_timer_get_expire_time(Timer* instance) { + tt_assert(!tt_kernel_is_irq()); + tt_assert(instance); TimerHandle_t hTimer = (TimerHandle_t)instance; return (uint32_t)xTimerGetExpiryTime(hTimer); } -void furi_timer_pending_callback(FuriTimerPendigCallback callback, void* context, uint32_t arg) { +void tt_timer_pending_callback(TimerPendigCallback callback, void* context, uint32_t arg) { BaseType_t ret = pdFAIL; - if (furi_kernel_is_irq()) { + if (tt_kernel_is_irq()) { ret = xTimerPendFunctionCallFromISR(callback, context, arg, NULL); } else { - ret = xTimerPendFunctionCall(callback, context, arg, FuriWaitForever); + ret = xTimerPendFunctionCall(callback, context, arg, TtWaitForever); } - furi_check(ret == pdPASS); + tt_check(ret == pdPASS); } -void furi_timer_set_thread_priority(FuriTimerThreadPriority priority) { - furi_assert(!furi_kernel_is_irq()); +void tt_timer_set_thread_priority(TimerThreadPriority priority) { + tt_assert(!tt_kernel_is_irq()); TaskHandle_t task_handle = xTimerGetTimerDaemonTaskHandle(); - furi_check(task_handle); // Don't call this method before timer task start + tt_check(task_handle); // Don't call this method before timer task start - if (priority == FuriTimerThreadPriorityNormal) { + if (priority == TimerThreadPriorityNormal) { vTaskPrioritySet(task_handle, configTIMER_TASK_PRIORITY); - } else if (priority == FuriTimerThreadPriorityElevated) { + } else if (priority == TimerThreadPriorityElevated) { vTaskPrioritySet(task_handle, configMAX_PRIORITIES - 1); } else { - furi_crash(); + tt_crash(); } } \ No newline at end of file diff --git a/components/tactility-core/src/timer.h b/components/tactility-core/src/timer.h new file mode 100644 index 00000000..9e13e387 --- /dev/null +++ b/components/tactility-core/src/timer.h @@ -0,0 +1,106 @@ +#pragma once + +#include "core_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*TimerCallback)(void* context); + +typedef enum { + TimerTypeOnce = 0, ///< One-shot timer. + TimerTypePeriodic = 1 ///< Repeating timer. +} TimerType; + +typedef void Timer; + +/** Allocate timer + * + * @param[in] func The callback function + * @param[in] type The timer type + * @param context The callback context + * + * @return The pointer to Timer instance + */ +Timer* tt_timer_alloc(TimerCallback func, TimerType type, void* context); + +/** Free timer + * + * @param instance The pointer to Timer instance + */ +void tt_timer_free(Timer* instance); + +/** Start timer + * + * @warning This is asynchronous call, real operation will happen as soon as + * timer service process this request. + * + * @param instance The pointer to Timer instance + * @param[in] ticks The interval in ticks + * + * @return The status. + */ +TtStatus tt_timer_start(Timer* instance, uint32_t ticks); + +/** Restart timer with previous timeout value + * + * @warning This is asynchronous call, real operation will happen as soon as + * timer service process this request. + * + * @param instance The pointer to Timer instance + * @param[in] ticks The interval in ticks + * + * @return The status. + */ +TtStatus tt_timer_restart(Timer* instance, uint32_t ticks); + +/** Stop timer + * + * @warning This is asynchronous call, real operation will happen as soon as + * timer service process this request. + * + * @param instance The pointer to Timer instance + * + * @return The status. + */ +TtStatus tt_timer_stop(Timer* instance); + +/** Is timer running + * + * @warning This cal may and will return obsolete timer state if timer + * commands are still in the queue. Please read FreeRTOS timer + * documentation first. + * + * @param instance The pointer to Timer instance + * + * @return 0: not running, 1: running + */ +uint32_t tt_timer_is_running(Timer* instance); + +/** Get timer expire time + * + * @param instance The Timer instance + * + * @return expire tick + */ +uint32_t tt_timer_get_expire_time(Timer* instance); + +typedef void (*TimerPendigCallback)(void* context, uint32_t arg); + +void tt_timer_pending_callback(TimerPendigCallback callback, void* context, uint32_t arg); + +typedef enum { + TimerThreadPriorityNormal, /**< Lower then other threads */ + TimerThreadPriorityElevated, /**< Same as other threads */ +} TimerThreadPriority; + +/** Set Timer thread priority + * + * @param[in] priority The priority + */ +void tt_timer_set_thread_priority(TimerThreadPriority priority); + +#ifdef __cplusplus +} +#endif diff --git a/components/tactility-core/src/tt_string.c b/components/tactility-core/src/tt_string.c new file mode 100644 index 00000000..7f89427b --- /dev/null +++ b/components/tactility-core/src/tt_string.c @@ -0,0 +1,304 @@ +#include "tt_string.h" +#include + +struct TtString { + string_t string; +}; + +#undef tt_string_alloc_set +#undef tt_string_set +#undef tt_string_cmp +#undef tt_string_cmpi +#undef tt_string_search +#undef tt_string_search_str +#undef tt_string_equal +#undef tt_string_replace +#undef tt_string_replace_str +#undef tt_string_replace_all +#undef tt_string_start_with +#undef tt_string_end_with +#undef tt_string_search_char +#undef tt_string_search_rchar +#undef tt_string_trim +#undef tt_string_cat + +TtString* tt_string_alloc() { + TtString* string = malloc(sizeof(TtString)); + string_init(string->string); + return string; +} + +TtString* tt_string_alloc_set(const TtString* s) { + TtString* string = malloc(sizeof(TtString)); //-V799 + string_init_set(string->string, s->string); + return string; +} //-V773 + +TtString* tt_string_alloc_set_str(const char cstr[]) { + TtString* string = malloc(sizeof(TtString)); //-V799 + string_init_set(string->string, cstr); + return string; +} //-V773 + +TtString* tt_string_alloc_printf(const char format[], ...) { + va_list args; + va_start(args, format); + TtString* string = tt_string_alloc_vprintf(format, args); + va_end(args); + return string; +} + +TtString* tt_string_alloc_vprintf(const char format[], va_list args) { + TtString* string = malloc(sizeof(TtString)); + string_init_vprintf(string->string, format, args); + return string; +} + +TtString* tt_string_alloc_move(TtString* s) { + TtString* string = malloc(sizeof(TtString)); + string_init_move(string->string, s->string); + free(s); + return string; +} + +void tt_string_free(TtString* s) { + string_clear(s->string); + free(s); +} + +void tt_string_reserve(TtString* s, size_t alloc) { + string_reserve(s->string, alloc); +} + +void tt_string_reset(TtString* s) { + string_reset(s->string); +} + +void tt_string_swap(TtString* v1, TtString* v2) { + string_swap(v1->string, v2->string); +} + +void tt_string_move(TtString* v1, TtString* v2) { + string_clear(v1->string); + string_init_move(v1->string, v2->string); + free(v2); +} + +size_t tt_string_hash(const TtString* v) { + return string_hash(v->string); +} + +char tt_string_get_char(const TtString* v, size_t index) { + return string_get_char(v->string, index); +} + +const char* tt_string_get_cstr(const TtString* s) { + return string_get_cstr(s->string); +} + +void tt_string_set(TtString* s, TtString* source) { + string_set(s->string, source->string); +} + +void tt_string_set_str(TtString* s, const char cstr[]) { + string_set(s->string, cstr); +} + +void tt_string_set_strn(TtString* s, const char str[], size_t n) { + string_set_strn(s->string, str, n); +} + +void tt_string_set_char(TtString* s, size_t index, const char c) { + string_set_char(s->string, index, c); +} + +int tt_string_cmp(const TtString* s1, const TtString* s2) { + return string_cmp(s1->string, s2->string); +} + +int tt_string_cmp_str(const TtString* s1, const char str[]) { + return string_cmp(s1->string, str); +} + +int tt_string_cmpi(const TtString* v1, const TtString* v2) { + return string_cmpi(v1->string, v2->string); +} + +int tt_string_cmpi_str(const TtString* v1, const char p2[]) { + return string_cmpi_str(v1->string, p2); +} + +size_t tt_string_search(const TtString* v, const TtString* needle, size_t start) { + return string_search(v->string, needle->string, start); +} + +size_t tt_string_search_str(const TtString* v, const char needle[], size_t start) { + return string_search(v->string, needle, start); +} + +bool tt_string_equal(const TtString* v1, const TtString* v2) { + return string_equal_p(v1->string, v2->string); +} + +bool tt_string_equal_str(const TtString* v1, const char v2[]) { + return string_equal_p(v1->string, v2); +} + +void tt_string_push_back(TtString* v, char c) { + string_push_back(v->string, c); +} + +size_t tt_string_size(const TtString* s) { + return string_size(s->string); +} + +int tt_string_printf(TtString* v, const char format[], ...) { + va_list args; + va_start(args, format); + int result = tt_string_vprintf(v, format, args); + va_end(args); + return result; +} + +int tt_string_vprintf(TtString* v, const char format[], va_list args) { + return string_vprintf(v->string, format, args); +} + +int tt_string_cat_printf(TtString* v, const char format[], ...) { + va_list args; + va_start(args, format); + int result = tt_string_cat_vprintf(v, format, args); + va_end(args); + return result; +} + +int tt_string_cat_vprintf(TtString* v, const char format[], va_list args) { + TtString* string = tt_string_alloc(); + int ret = tt_string_vprintf(string, format, args); + tt_string_cat(v, string); + tt_string_free(string); + return ret; +} + +bool tt_string_empty(const TtString* v) { + return string_empty_p(v->string); +} + +void tt_string_replace_at(TtString* v, size_t pos, size_t len, const char str2[]) { + string_replace_at(v->string, pos, len, str2); +} + +size_t +tt_string_replace(TtString* string, TtString* needle, TtString* replace, size_t start) { + return string_replace(string->string, needle->string, replace->string, start); +} + +size_t tt_string_replace_str(TtString* v, const char str1[], const char str2[], size_t start) { + return string_replace_str(v->string, str1, str2, start); +} + +void tt_string_replace_all_str(TtString* v, const char str1[], const char str2[]) { + string_replace_all_str(v->string, str1, str2); +} + +void tt_string_replace_all(TtString* v, const TtString* str1, const TtString* str2) { + string_replace_all(v->string, str1->string, str2->string); +} + +bool tt_string_start_with(const TtString* v, const TtString* v2) { + return string_start_with_string_p(v->string, v2->string); +} + +bool tt_string_start_with_str(const TtString* v, const char str[]) { + return string_start_with_str_p(v->string, str); +} + +bool tt_string_end_with(const TtString* v, const TtString* v2) { + return string_end_with_string_p(v->string, v2->string); +} + +bool tt_string_end_with_str(const TtString* v, const char str[]) { + return string_end_with_str_p(v->string, str); +} + +size_t tt_string_search_char(const TtString* v, char c, size_t start) { + return string_search_char(v->string, c, start); +} + +size_t tt_string_search_rchar(const TtString* v, char c, size_t start) { + return string_search_rchar(v->string, c, start); +} + +void tt_string_left(TtString* v, size_t index) { + string_left(v->string, index); +} + +void tt_string_right(TtString* v, size_t index) { + string_right(v->string, index); +} + +void tt_string_mid(TtString* v, size_t index, size_t size) { + string_mid(v->string, index, size); +} + +void tt_string_trim(TtString* v, const char charac[]) { + string_strim(v->string, charac); +} + +void tt_string_cat(TtString* v, const TtString* v2) { + string_cat(v->string, v2->string); +} + +void tt_string_cat_str(TtString* v, const char str[]) { + string_cat(v->string, str); +} + +void tt_string_set_n(TtString* v, const TtString* ref, size_t offset, size_t length) { + string_set_n(v->string, ref->string, offset, length); +} + +size_t tt_string_utf8_length(TtString* str) { + return string_length_u(str->string); +} + +void tt_string_utf8_push(TtString* str, TtStringUnicodeValue u) { + string_push_u(str->string, u); +} + +static m_str1ng_utf8_state_e tt_state_to_state(TtStringUTF8State state) { + switch (state) { + case TtStringUTF8StateStarting: + return M_STR1NG_UTF8_STARTING; + case TtStringUTF8StateDecoding1: + return M_STR1NG_UTF8_DECODING_1; + case TtStringUTF8StateDecoding2: + return M_STR1NG_UTF8_DECODING_2; + case TtStringUTF8StateDecoding3: + return M_STR1NG_UTF8_DECODING_3; + default: + return M_STR1NG_UTF8_ERROR; + } +} + +static TtStringUTF8State state_to_tt_state(m_str1ng_utf8_state_e state) { + switch (state) { + case M_STR1NG_UTF8_STARTING: + return TtStringUTF8StateStarting; + case M_STR1NG_UTF8_DECODING_1: + return TtStringUTF8StateDecoding1; + case M_STR1NG_UTF8_DECODING_2: + return TtStringUTF8StateDecoding2; + case M_STR1NG_UTF8_DECODING_3: + return TtStringUTF8StateDecoding3; + default: + return TtStringUTF8StateError; + } +} + +void tt_string_utf8_decode(char c, TtStringUTF8State* state, TtStringUnicodeValue* unicode) { + string_unicode_t m_u = *unicode; + m_str1ng_utf8_state_e m_state = tt_state_to_state(*state); + m_str1ng_utf8_decode(c, &m_state, &m_u); + *state = state_to_tt_state(m_state); + *unicode = m_u; +} diff --git a/components/furi/src/furi_string.h b/components/tactility-core/src/tt_string.h similarity index 62% rename from components/furi/src/furi_string.h rename to components/tactility-core/src/tt_string.h index d63697d8..1cf1b0a2 100644 --- a/components/furi/src/furi_string.h +++ b/components/tactility-core/src/tt_string.h @@ -1,7 +1,3 @@ -/** - * @file string.h - * Furi string primitive - */ #pragma once #include @@ -15,77 +11,77 @@ extern "C" { #endif /** - * @brief Furi string failure constant. + * @brief String failure constant. */ -#define FURI_STRING_FAILURE ((size_t)-1) +#define TT_STRING_FAILURE ((size_t)-1) /** - * @brief Furi string primitive. + * @brief Tactility string primitive. */ -typedef struct FuriString FuriString; +typedef struct TtString TtString; //--------------------------------------------------------------------------- // Constructors //--------------------------------------------------------------------------- /** - * @brief Allocate new FuriString. - * @return FuriString* + * @brief Allocate new TtString. + * @return TtString* */ -FuriString* furi_string_alloc(); +TtString* tt_string_alloc(); /** - * @brief Allocate new FuriString and set it to string. + * @brief Allocate new TtString and set it to string. * Allocate & Set the string a to the string. * @param source - * @return FuriString* + * @return TtString* */ -FuriString* furi_string_alloc_set(const FuriString* source); +TtString* tt_string_alloc_set(const TtString* source); /** - * @brief Allocate new FuriString and set it to C string. + * @brief Allocate new TtString and set it to C string. * Allocate & Set the string a to the C string. * @param cstr_source - * @return FuriString* + * @return TtString* */ -FuriString* furi_string_alloc_set_str(const char cstr_source[]); +TtString* tt_string_alloc_set_str(const char cstr_source[]); /** - * @brief Allocate new FuriString and printf to it. + * @brief Allocate new TtString and printf to it. * Initialize and set a string to the given formatted value. * @param format * @param ... - * @return FuriString* + * @return TtString* */ -FuriString* furi_string_alloc_printf(const char format[], ...) +TtString* tt_string_alloc_printf(const char format[], ...) _ATTRIBUTE((__format__(__printf__, 1, 2))); /** - * @brief Allocate new FuriString and printf to it. + * @brief Allocate new TtString and printf to it. * Initialize and set a string to the given formatted value. * @param format * @param args - * @return FuriString* + * @return TtString* */ -FuriString* furi_string_alloc_vprintf(const char format[], va_list args); +TtString* tt_string_alloc_vprintf(const char format[], va_list args); /** - * @brief Allocate new FuriString and move source string content to it. + * @brief Allocate new TtString and move source string content to it. * Allocate the string, set it to the other one, and destroy the other one. * @param source - * @return FuriString* + * @return TtString* */ -FuriString* furi_string_alloc_move(FuriString* source); +TtString* tt_string_alloc_move(TtString* source); //--------------------------------------------------------------------------- // Destructors //--------------------------------------------------------------------------- /** - * @brief Free FuriString. + * @brief Free TtString. * @param string */ -void furi_string_free(FuriString* string); +void tt_string_free(TtString* string); //--------------------------------------------------------------------------- // String memory management @@ -97,14 +93,14 @@ void furi_string_free(FuriString* string); * @param string * @param size */ -void furi_string_reserve(FuriString* string, size_t size); +void tt_string_reserve(TtString* string, size_t size); /** * @brief Reset string. * Make the string empty. * @param s */ -void furi_string_reset(FuriString* string); +void tt_string_reset(TtString* string); /** * @brief Swap two strings. @@ -112,7 +108,7 @@ void furi_string_reset(FuriString* string); * @param string_1 * @param string_2 */ -void furi_string_swap(FuriString* string_1, FuriString* string_2); +void tt_string_swap(TtString* string_1, TtString* string_2); /** * @brief Move string_2 content to string_1. @@ -120,28 +116,28 @@ void furi_string_swap(FuriString* string_1, FuriString* string_2); * @param string_1 * @param string_2 */ -void furi_string_move(FuriString* string_1, FuriString* string_2); +void tt_string_move(TtString* string_1, TtString* string_2); /** * @brief Compute a hash for the string. * @param string * @return size_t */ -size_t furi_string_hash(const FuriString* string); +size_t tt_string_hash(const TtString* string); /** * @brief Get string size (usually length, but not for UTF-8) * @param string * @return size_t */ -size_t furi_string_size(const FuriString* string); +size_t tt_string_size(const TtString* string); /** * @brief Check that string is empty or not * @param string * @return bool */ -bool furi_string_empty(const FuriString* string); +bool tt_string_empty(const TtString* string); //--------------------------------------------------------------------------- // Getters @@ -154,14 +150,14 @@ bool furi_string_empty(const FuriString* string); * @param index * @return char */ -char furi_string_get_char(const FuriString* string, size_t index); +char tt_string_get_char(const TtString* string, size_t index); /** * @brief Return the string view a classic C string. * @param string * @return const char* */ -const char* furi_string_get_cstr(const FuriString* string); +const char* tt_string_get_cstr(const TtString* string); //--------------------------------------------------------------------------- // Setters @@ -173,7 +169,7 @@ const char* furi_string_get_cstr(const FuriString* string); * @param string * @param source */ -void furi_string_set(FuriString* string, FuriString* source); +void tt_string_set(TtString* string, TtString* source); /** * @brief Set the string to the other C string. @@ -181,7 +177,7 @@ void furi_string_set(FuriString* string, FuriString* source); * @param string * @param source */ -void furi_string_set_str(FuriString* string, const char source[]); +void tt_string_set_str(TtString* string, const char source[]); /** * @brief Set the string to the n first characters of the C string. @@ -189,7 +185,7 @@ void furi_string_set_str(FuriString* string, const char source[]); * @param source * @param length */ -void furi_string_set_strn(FuriString* string, const char source[], size_t length); +void tt_string_set_strn(TtString* string, const char source[], size_t length); /** * @brief Set the character at the given index. @@ -197,7 +193,7 @@ void furi_string_set_strn(FuriString* string, const char source[], size_t length * @param index * @param c */ -void furi_string_set_char(FuriString* string, size_t index, const char c); +void tt_string_set_char(TtString* string, size_t index, const char c); /** * @brief Set the string to the n first characters of other one. @@ -206,7 +202,7 @@ void furi_string_set_char(FuriString* string, size_t index, const char c); * @param offset * @param length */ -void furi_string_set_n(FuriString* string, const FuriString* source, size_t offset, size_t length); +void tt_string_set_n(TtString* string, const TtString* source, size_t offset, size_t length); /** * @brief Format in the string the given printf format @@ -215,7 +211,7 @@ void furi_string_set_n(FuriString* string, const FuriString* source, size_t offs * @param ... * @return int */ -int furi_string_printf(FuriString* string, const char format[], ...) +int tt_string_printf(TtString* string, const char format[], ...) _ATTRIBUTE((__format__(__printf__, 2, 3))); /** @@ -225,7 +221,7 @@ int furi_string_printf(FuriString* string, const char format[], ...) * @param args * @return int */ -int furi_string_vprintf(FuriString* string, const char format[], va_list args); +int tt_string_vprintf(TtString* string, const char format[], va_list args); //--------------------------------------------------------------------------- // Appending @@ -236,7 +232,7 @@ int furi_string_vprintf(FuriString* string, const char format[], va_list args); * @param string * @param c */ -void furi_string_push_back(FuriString* string, char c); +void tt_string_push_back(TtString* string, char c); /** * @brief Append a string to the string. @@ -244,7 +240,7 @@ void furi_string_push_back(FuriString* string, char c); * @param string_1 * @param string_2 */ -void furi_string_cat(FuriString* string_1, const FuriString* string_2); +void tt_string_cat(TtString* string_1, const TtString* string_2); /** * @brief Append a C string to the string. @@ -252,7 +248,7 @@ void furi_string_cat(FuriString* string_1, const FuriString* string_2); * @param string_1 * @param cstring_2 */ -void furi_string_cat_str(FuriString* string_1, const char cstring_2[]); +void tt_string_cat_str(TtString* string_1, const char cstring_2[]); /** * @brief Append to the string the formatted string of the given printf format. @@ -261,7 +257,7 @@ void furi_string_cat_str(FuriString* string_1, const char cstring_2[]); * @param ... * @return int */ -int furi_string_cat_printf(FuriString* string, const char format[], ...) +int tt_string_cat_printf(TtString* string, const char format[], ...) _ATTRIBUTE((__format__(__printf__, 2, 3))); /** @@ -271,7 +267,7 @@ int furi_string_cat_printf(FuriString* string, const char format[], ...) * @param args * @return int */ -int furi_string_cat_vprintf(FuriString* string, const char format[], va_list args); +int tt_string_cat_vprintf(TtString* string, const char format[], va_list args); //--------------------------------------------------------------------------- // Comparators @@ -283,7 +279,7 @@ int furi_string_cat_vprintf(FuriString* string, const char format[], va_list arg * @param string_2 * @return int */ -int furi_string_cmp(const FuriString* string_1, const FuriString* string_2); +int tt_string_cmp(const TtString* string_1, const TtString* string_2); /** * @brief Compare string with C string and return the sort order. @@ -291,7 +287,7 @@ int furi_string_cmp(const FuriString* string_1, const FuriString* string_2); * @param cstring_2 * @return int */ -int furi_string_cmp_str(const FuriString* string_1, const char cstring_2[]); +int tt_string_cmp_str(const TtString* string_1, const char cstring_2[]); /** * @brief Compare two strings (case insensitive according to the current locale) and return the sort order. @@ -300,7 +296,7 @@ int furi_string_cmp_str(const FuriString* string_1, const char cstring_2[]); * @param string_2 * @return int */ -int furi_string_cmpi(const FuriString* string_1, const FuriString* string_2); +int tt_string_cmpi(const TtString* string_1, const TtString* string_2); /** * @brief Compare string with C string (case insensitive according to the current locale) and return the sort order. @@ -309,7 +305,7 @@ int furi_string_cmpi(const FuriString* string_1, const FuriString* string_2); * @param cstring_2 * @return int */ -int furi_string_cmpi_str(const FuriString* string_1, const char cstring_2[]); +int tt_string_cmpi_str(const TtString* string_1, const char cstring_2[]); //--------------------------------------------------------------------------- // Search @@ -324,7 +320,7 @@ int furi_string_cmpi_str(const FuriString* string_1, const char cstring_2[]); * @param start * @return size_t */ -size_t furi_string_search(const FuriString* string, const FuriString* needle, size_t start); +size_t tt_string_search(const TtString* string, const TtString* needle, size_t start); /** * @brief Search the first occurrence of the needle in the string from the position start. @@ -334,7 +330,7 @@ size_t furi_string_search(const FuriString* string, const FuriString* needle, si * @param start * @return size_t */ -size_t furi_string_search_str(const FuriString* string, const char needle[], size_t start); +size_t tt_string_search_str(const TtString* string, const char needle[], size_t start); /** * @brief Search for the position of the character c from the position start (include) in the string. @@ -345,7 +341,7 @@ size_t furi_string_search_str(const FuriString* string, const char needle[], siz * @param start * @return size_t */ -size_t furi_string_search_char(const FuriString* string, char c, size_t start); +size_t tt_string_search_char(const TtString* string, char c, size_t start); /** * @brief Reverse search for the position of the character c from the position start (include) in the string. @@ -356,7 +352,7 @@ size_t furi_string_search_char(const FuriString* string, char c, size_t start); * @param start * @return size_t */ -size_t furi_string_search_rchar(const FuriString* string, char c, size_t start); +size_t tt_string_search_rchar(const TtString* string, char c, size_t start); //--------------------------------------------------------------------------- // Equality @@ -368,7 +364,7 @@ size_t furi_string_search_rchar(const FuriString* string, char c, size_t start); * @param string_2 * @return bool */ -bool furi_string_equal(const FuriString* string_1, const FuriString* string_2); +bool tt_string_equal(const TtString* string_1, const TtString* string_2); /** * @brief Test if the string is equal to the C string. @@ -376,7 +372,7 @@ bool furi_string_equal(const FuriString* string_1, const FuriString* string_2); * @param cstring_2 * @return bool */ -bool furi_string_equal_str(const FuriString* string_1, const char cstring_2[]); +bool tt_string_equal_str(const TtString* string_1, const char cstring_2[]); //--------------------------------------------------------------------------- // Replace @@ -389,7 +385,7 @@ bool furi_string_equal_str(const FuriString* string_1, const char cstring_2[]); * @param len * @param replace */ -void furi_string_replace_at(FuriString* string, size_t pos, size_t len, const char replace[]); +void tt_string_replace_at(TtString* string, size_t pos, size_t len, const char replace[]); /** * @brief Replace a string 'needle' to string 'replace' in a string from 'start' position. @@ -402,7 +398,7 @@ void furi_string_replace_at(FuriString* string, size_t pos, size_t len, const ch * @return size_t */ size_t -furi_string_replace(FuriString* string, FuriString* needle, FuriString* replace, size_t start); +tt_string_replace(TtString* string, TtString* needle, TtString* replace, size_t start); /** * @brief Replace a C string 'needle' to C string 'replace' in a string from 'start' position. @@ -414,8 +410,8 @@ furi_string_replace(FuriString* string, FuriString* needle, FuriString* replace, * @param start * @return size_t */ -size_t furi_string_replace_str( - FuriString* string, +size_t tt_string_replace_str( + TtString* string, const char needle[], const char replace[], size_t start @@ -427,10 +423,10 @@ size_t furi_string_replace_str( * @param needle * @param replace */ -void furi_string_replace_all( - FuriString* string, - const FuriString* needle, - const FuriString* replace +void tt_string_replace_all( + TtString* string, + const TtString* needle, + const TtString* replace ); /** @@ -439,7 +435,7 @@ void furi_string_replace_all( * @param needle * @param replace */ -void furi_string_replace_all_str(FuriString* string, const char needle[], const char replace[]); +void tt_string_replace_all_str(TtString* string, const char needle[], const char replace[]); //--------------------------------------------------------------------------- // Start / End tests @@ -451,7 +447,7 @@ void furi_string_replace_all_str(FuriString* string, const char needle[], const * @param start * @return bool */ -bool furi_string_start_with(const FuriString* string, const FuriString* start); +bool tt_string_start_with(const TtString* string, const TtString* start); /** * @brief Test if the string starts with the given C string. @@ -459,7 +455,7 @@ bool furi_string_start_with(const FuriString* string, const FuriString* start); * @param start * @return bool */ -bool furi_string_start_with_str(const FuriString* string, const char start[]); +bool tt_string_start_with_str(const TtString* string, const char start[]); /** * @brief Test if the string ends with the given string. @@ -467,7 +463,7 @@ bool furi_string_start_with_str(const FuriString* string, const char start[]); * @param end * @return bool */ -bool furi_string_end_with(const FuriString* string, const FuriString* end); +bool tt_string_end_with(const TtString* string, const TtString* end); /** * @brief Test if the string ends with the given C string. @@ -475,7 +471,7 @@ bool furi_string_end_with(const FuriString* string, const FuriString* end); * @param end * @return bool */ -bool furi_string_end_with_str(const FuriString* string, const char end[]); +bool tt_string_end_with_str(const TtString* string, const char end[]); //--------------------------------------------------------------------------- // Trim @@ -486,30 +482,30 @@ bool furi_string_end_with_str(const FuriString* string, const char end[]); * @param string * @param index */ -void furi_string_left(FuriString* string, size_t index); +void tt_string_left(TtString* string, size_t index); /** * @brief Trim the string right from the 'index' position to the last position. * @param string * @param index */ -void furi_string_right(FuriString* string, size_t index); +void tt_string_right(TtString* string, size_t index); /** * @brief Trim the string from position index to size bytes. - * See also furi_string_set_n. + * See also tt_string_set_n. * @param string * @param index * @param size */ -void furi_string_mid(FuriString* string, size_t index, size_t size); +void tt_string_mid(TtString* string, size_t index, size_t size); /** * @brief Trim a string from the given set of characters (default is " \n\r\t"). * @param string * @param chars */ -void furi_string_trim(FuriString* string, const char chars[]); +void tt_string_trim(TtString* string, const char chars[]); //--------------------------------------------------------------------------- // UTF8 @@ -518,43 +514,43 @@ void furi_string_trim(FuriString* string, const char chars[]); /** * @brief An unicode value. */ -typedef unsigned int FuriStringUnicodeValue; +typedef unsigned int TtStringUnicodeValue; /** * @brief Compute the length in UTF8 characters in the string. * @param string * @return size_t */ -size_t furi_string_utf8_length(FuriString* string); +size_t tt_string_utf8_length(TtString* string); /** * @brief Push unicode into string, encoding it in UTF8. * @param string * @param unicode */ -void furi_string_utf8_push(FuriString* string, FuriStringUnicodeValue unicode); +void tt_string_utf8_push(TtString* string, TtStringUnicodeValue unicode); /** * @brief State of the UTF8 decoding machine state. */ typedef enum { - FuriStringUTF8StateStarting, - FuriStringUTF8StateDecoding1, - FuriStringUTF8StateDecoding2, - FuriStringUTF8StateDecoding3, - FuriStringUTF8StateError -} FuriStringUTF8State; + TtStringUTF8StateStarting, + TtStringUTF8StateDecoding1, + TtStringUTF8StateDecoding2, + TtStringUTF8StateDecoding3, + TtStringUTF8StateError +} TtStringUTF8State; /** * @brief Main generic UTF8 decoder. * It takes a character, and the previous state and the previous value of the unicode value. * It updates the state and the decoded unicode value. - * A decoded unicode encoded value is valid only when the state is FuriStringUTF8StateStarting. + * A decoded unicode encoded value is valid only when the state is TtStringUTF8StateStarting. * @param c * @param state * @param unicode */ -void furi_string_utf8_decode(char c, FuriStringUTF8State* state, FuriStringUnicodeValue* unicode); +void tt_string_utf8_decode(char c, TtStringUTF8State* state, TtStringUnicodeValue* unicode); //--------------------------------------------------------------------------- // Lasciate ogne speranza, voi ch’entrate @@ -570,131 +566,131 @@ void furi_string_utf8_decode(char c, FuriStringUTF8State* state, FuriStringUnico /** * @brief Select for 1 argument */ -#define FURI_STRING_SELECT1(func1, func2, a) \ - _Generic((a), char*: func2, const char*: func2, FuriString*: func1, const FuriString*: func1)(a) +#define TT_STRING_SELECT1(func1, func2, a) \ + _Generic((a), char*: func2, const char*: func2, TtString*: func1, const TtString*: func1)(a) /** * @brief Select for 2 arguments */ -#define FURI_STRING_SELECT2(func1, func2, a, b) \ - _Generic((b), char*: func2, const char*: func2, FuriString*: func1, const FuriString*: func1)(a, b) +#define TT_STRING_SELECT2(func1, func2, a, b) \ + _Generic((b), char*: func2, const char*: func2, TtString*: func1, const TtString*: func1)(a, b) /** * @brief Select for 3 arguments */ -#define FURI_STRING_SELECT3(func1, func2, a, b, c) \ - _Generic((b), char*: func2, const char*: func2, FuriString*: func1, const FuriString*: func1)(a, b, c) +#define TT_STRING_SELECT3(func1, func2, a, b, c) \ + _Generic((b), char*: func2, const char*: func2, TtString*: func1, const TtString*: func1)(a, b, c) /** * @brief Select for 4 arguments */ -#define FURI_STRING_SELECT4(func1, func2, a, b, c, d) \ - _Generic((b), char*: func2, const char*: func2, FuriString*: func1, const FuriString*: func1)(a, b, c, d) +#define TT_STRING_SELECT4(func1, func2, a, b, c, d) \ + _Generic((b), char*: func2, const char*: func2, TtString*: func1, const TtString*: func1)(a, b, c, d) /** - * @brief Allocate new FuriString and set it content to string (or C string). + * @brief Allocate new TtString and set it content to string (or C string). * ([c]string) */ -#define furi_string_alloc_set(a) \ - FURI_STRING_SELECT1(furi_string_alloc_set, furi_string_alloc_set_str, a) +#define tt_string_alloc_set(a) \ + TT_STRING_SELECT1(tt_string_alloc_set, tt_string_alloc_set_str, a) /** * @brief Set the string content to string (or C string). * (string, [c]string) */ -#define furi_string_set(a, b) FURI_STRING_SELECT2(furi_string_set, furi_string_set_str, a, b) +#define tt_string_set(a, b) TT_STRING_SELECT2(tt_string_set, tt_string_set_str, a, b) /** * @brief Compare string with string (or C string) and return the sort order. * Note: doesn't work with UTF-8 strings. * (string, [c]string) */ -#define furi_string_cmp(a, b) FURI_STRING_SELECT2(furi_string_cmp, furi_string_cmp_str, a, b) +#define tt_string_cmp(a, b) TT_STRING_SELECT2(tt_string_cmp, tt_string_cmp_str, a, b) /** * @brief Compare string with string (or C string) (case insensitive according to the current locale) and return the sort order. * Note: doesn't work with UTF-8 strings. * (string, [c]string) */ -#define furi_string_cmpi(a, b) FURI_STRING_SELECT2(furi_string_cmpi, furi_string_cmpi_str, a, b) +#define tt_string_cmpi(a, b) TT_STRING_SELECT2(tt_string_cmpi, tt_string_cmpi_str, a, b) /** * @brief Test if the string is equal to the string (or C string). * (string, [c]string) */ -#define furi_string_equal(a, b) FURI_STRING_SELECT2(furi_string_equal, furi_string_equal_str, a, b) +#define tt_string_equal(a, b) TT_STRING_SELECT2(tt_string_equal, tt_string_equal_str, a, b) /** * @brief Replace all occurrences of string into string (or C string to another C string) in a string. * (string, [c]string, [c]string) */ -#define furi_string_replace_all(a, b, c) \ - FURI_STRING_SELECT3(furi_string_replace_all, furi_string_replace_all_str, a, b, c) +#define tt_string_replace_all(a, b, c) \ + TT_STRING_SELECT3(tt_string_replace_all, tt_string_replace_all_str, a, b, c) /** * @brief Search for a string (or C string) in a string * (string, [c]string[, start=0]) */ -#define furi_string_search(...) \ +#define tt_string_search(...) \ M_APPLY( \ - FURI_STRING_SELECT3, \ - furi_string_search, \ - furi_string_search_str, \ + TT_STRING_SELECT3, \ + tt_string_search, \ + tt_string_search_str, \ M_DEFAULT_ARGS(3, (0), __VA_ARGS__) \ ) /** * @brief Search for a C string in a string * (string, cstring[, start=0]) */ -#define furi_string_search_str(...) furi_string_search_str(M_DEFAULT_ARGS(3, (0), __VA_ARGS__)) +#define tt_string_search_str(...) tt_string_search_str(M_DEFAULT_ARGS(3, (0), __VA_ARGS__)) /** * @brief Test if the string starts with the given string (or C string). * (string, [c]string) */ -#define furi_string_start_with(a, b) \ - FURI_STRING_SELECT2(furi_string_start_with, furi_string_start_with_str, a, b) +#define tt_string_start_with(a, b) \ + TT_STRING_SELECT2(tt_string_start_with, tt_string_start_with_str, a, b) /** * @brief Test if the string ends with the given string (or C string). * (string, [c]string) */ -#define furi_string_end_with(a, b) \ - FURI_STRING_SELECT2(furi_string_end_with, furi_string_end_with_str, a, b) +#define tt_string_end_with(a, b) \ + TT_STRING_SELECT2(tt_string_end_with, tt_string_end_with_str, a, b) /** * @brief Append a string (or C string) to the string. * (string, [c]string) */ -#define furi_string_cat(a, b) FURI_STRING_SELECT2(furi_string_cat, furi_string_cat_str, a, b) +#define tt_string_cat(a, b) TT_STRING_SELECT2(tt_string_cat, tt_string_cat_str, a, b) /** * @brief Trim a string from the given set of characters (default is " \n\r\t"). * (string[, set=" \n\r\t"]) */ -#define furi_string_trim(...) furi_string_trim(M_DEFAULT_ARGS(2, (" \n\r\t"), __VA_ARGS__)) +#define tt_string_trim(...) tt_string_trim(M_DEFAULT_ARGS(2, (" \n\r\t"), __VA_ARGS__)) /** * @brief Search for a character in a string. * (string, character[, start=0]) */ -#define furi_string_search_char(...) furi_string_search_char(M_DEFAULT_ARGS(3, (0), __VA_ARGS__)) +#define tt_string_search_char(...) tt_string_search_char(M_DEFAULT_ARGS(3, (0), __VA_ARGS__)) /** * @brief Reverse Search for a character in a string. * (string, character[, start=0]) */ -#define furi_string_search_rchar(...) furi_string_search_rchar(M_DEFAULT_ARGS(3, (0), __VA_ARGS__)) +#define tt_string_search_rchar(...) tt_string_search_rchar(M_DEFAULT_ARGS(3, (0), __VA_ARGS__)) /** * @brief Replace a string to another string (or C string to another C string) in a string. * (string, [c]string, [c]string[, start=0]) */ -#define furi_string_replace(...) \ +#define tt_string_replace(...) \ M_APPLY( \ - FURI_STRING_SELECT4, \ - furi_string_replace, \ - furi_string_replace_str, \ + TT_STRING_SELECT4, \ + tt_string_replace, \ + tt_string_replace_str, \ M_DEFAULT_ARGS(4, (0), __VA_ARGS__) \ ) @@ -702,40 +698,40 @@ void furi_string_utf8_decode(char c, FuriStringUTF8State* state, FuriStringUnico * @brief Replace a C string to another C string in a string. * (string, cstring, cstring[, start=0]) */ -#define furi_string_replace_str(...) furi_string_replace_str(M_DEFAULT_ARGS(4, (0), __VA_ARGS__)) +#define tt_string_replace_str(...) tt_string_replace_str(M_DEFAULT_ARGS(4, (0), __VA_ARGS__)) /** - * @brief INIT OPLIST for FuriString. + * @brief INIT OPLIST for TtString. */ -#define F_STR_INIT(a) ((a) = furi_string_alloc()) +#define F_STR_INIT(a) ((a) = tt_string_alloc()) /** - * @brief INIT SET OPLIST for FuriString. + * @brief INIT SET OPLIST for TtString. */ -#define F_STR_INIT_SET(a, b) ((a) = furi_string_alloc_set(b)) +#define F_STR_INIT_SET(a, b) ((a) = tt_string_alloc_set(b)) /** - * @brief INIT MOVE OPLIST for FuriString. + * @brief INIT MOVE OPLIST for TtString. */ -#define F_STR_INIT_MOVE(a, b) ((a) = furi_string_alloc_move(b)) +#define F_STR_INIT_MOVE(a, b) ((a) = tt_string_alloc_move(b)) /** - * @brief OPLIST for FuriString. + * @brief OPLIST for TtString. */ -#define FURI_STRING_OPLIST \ +#define TT_STRING_OPLIST \ (INIT(F_STR_INIT), \ INIT_SET(F_STR_INIT_SET), \ - SET(furi_string_set), \ + SET(tt_string_set), \ INIT_MOVE(F_STR_INIT_MOVE), \ - MOVE(furi_string_move), \ - SWAP(furi_string_swap), \ - RESET(furi_string_reset), \ - EMPTY_P(furi_string_empty), \ - CLEAR(furi_string_free), \ - HASH(furi_string_hash), \ - EQUAL(furi_string_equal), \ - CMP(furi_string_cmp), \ - TYPE(FuriString*)) + MOVE(tt_string_move), \ + SWAP(tt_string_swap), \ + RESET(tt_string_reset), \ + EMPTY_P(tt_string_empty), \ + CLEAR(tt_string_free), \ + HASH(tt_string_hash), \ + EQUAL(tt_string_equal), \ + CMP(tt_string_cmp), \ + TYPE(TtString*)) #ifdef __cplusplus } diff --git a/components/tactility/CMakeLists.txt b/components/tactility/CMakeLists.txt index 4f2e1f27..f987868b 100644 --- a/components/tactility/CMakeLists.txt +++ b/components/tactility/CMakeLists.txt @@ -19,7 +19,7 @@ idf_component_register( esp_wifi driver fatfs - furi + tactility-core mlib nvs_flash spiffs diff --git a/components/tactility/src/apps/desktop/desktop.c b/components/tactility/src/apps/desktop/desktop.c index 4de5f5bf..2a077d73 100644 --- a/components/tactility/src/apps/desktop/desktop.c +++ b/components/tactility/src/apps/desktop/desktop.c @@ -12,7 +12,7 @@ static void on_app_pressed(lv_event_t* e) { } static void create_app_widget(const AppManifest* manifest, void* _Nullable parent) { - furi_check(parent); + tt_check(parent); lv_obj_t* list = (lv_obj_t*)parent; lv_obj_t* btn = lv_list_add_btn(list, LV_SYMBOL_FILE, manifest->name); lv_obj_add_event_cb(btn, &on_app_pressed, LV_EVENT_CLICKED, (void*)manifest); @@ -26,9 +26,9 @@ static void desktop_show(App app, lv_obj_t* parent) { lv_obj_center(list); lv_list_add_text(list, "System"); - app_manifest_registry_for_each_of_type(AppTypeSystem, list, create_app_widget); + tt_app_manifest_registry_for_each_of_type(AppTypeSystem, list, create_app_widget); lv_list_add_text(list, "User"); - app_manifest_registry_for_each_of_type(AppTypeUser, list, create_app_widget); + tt_app_manifest_registry_for_each_of_type(AppTypeUser, list, create_app_widget); } const AppManifest desktop_app = { diff --git a/components/tactility/src/apps/system/system_info/system_info.c b/components/tactility/src/apps/system/system_info/system_info.c index 4091906d..3d400914 100644 --- a/components/tactility/src/apps/system/system_info/system_info.c +++ b/components/tactility/src/apps/system/system_info/system_info.c @@ -1,8 +1,8 @@ #include "app_manifest.h" -#include "furi_extra_defines.h" -#include "thread.h" -#include "lvgl.h" +#include "core_extra_defines.h" #include "esp_wifi.h" +#include "lvgl.h" +#include "thread.h" static void app_show(App app, lv_obj_t* parent) { UNUSED(app); diff --git a/components/tactility/src/apps/system/wifi_connect/wifi_connect.c b/components/tactility/src/apps/system/wifi_connect/wifi_connect.c index 5d1184fe..9c151889 100644 --- a/components/tactility/src/apps/system/wifi_connect/wifi_connect.c +++ b/components/tactility/src/apps/system/wifi_connect/wifi_connect.c @@ -2,8 +2,8 @@ #include "app.h" #include "esp_lvgl_port.h" -#include "furi_core.h" #include "services/wifi/wifi.h" +#include "tactility_core.h" #include "wifi_connect_state_updating.h" // Forward declarations @@ -17,9 +17,9 @@ static void on_connect(const char* ssid, const char* password, void* parameter) static WifiConnect* wifi_connect_alloc() { WifiConnect* wifi = malloc(sizeof(WifiConnect)); - FuriPubSub* wifi_pubsub = wifi_get_pubsub(); - wifi->wifi_subscription = furi_pubsub_subscribe(wifi_pubsub, &wifi_connect_event_callback, wifi); - wifi->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + PubSub* wifi_pubsub = wifi_get_pubsub(); + wifi->wifi_subscription = tt_pubsub_subscribe(wifi_pubsub, &wifi_connect_event_callback, wifi); + wifi->mutex = tt_mutex_alloc(MutexTypeNormal); wifi->state = (WifiConnectState) { .radio_state = wifi_get_radio_state() }; @@ -33,23 +33,23 @@ static WifiConnect* wifi_connect_alloc() { } static void wifi_connect_free(WifiConnect* wifi) { - FuriPubSub* wifi_pubsub = wifi_get_pubsub(); - furi_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription); - furi_mutex_free(wifi->mutex); + PubSub* wifi_pubsub = wifi_get_pubsub(); + tt_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription); + tt_mutex_free(wifi->mutex); free(wifi); } void wifi_connect_lock(WifiConnect* wifi) { - furi_assert(wifi); - furi_assert(wifi->mutex); - furi_mutex_acquire(wifi->mutex, FuriWaitForever); + tt_assert(wifi); + tt_assert(wifi->mutex); + tt_mutex_acquire(wifi->mutex, TtWaitForever); } void wifi_connect_unlock(WifiConnect* wifi) { - furi_assert(wifi); - furi_assert(wifi->mutex); - furi_mutex_release(wifi->mutex); + tt_assert(wifi); + tt_assert(wifi->mutex); + tt_mutex_release(wifi->mutex); } void wifi_connect_request_view_update(WifiConnect* wifi) { @@ -76,7 +76,7 @@ static void wifi_connect_event_callback(const void* message, void* context) { } static void app_show(App app, lv_obj_t* parent) { - WifiConnect* wifi = (WifiConnect*)app_get_data(app); + WifiConnect* wifi = (WifiConnect*)tt_app_get_data(app); wifi_connect_lock(wifi); wifi->view_enabled = true; @@ -86,7 +86,7 @@ static void app_show(App app, lv_obj_t* parent) { } static void app_hide(App app) { - WifiConnect* wifi = (WifiConnect*)app_get_data(app); + WifiConnect* wifi = (WifiConnect*)tt_app_get_data(app); wifi_connect_lock(wifi); wifi->view_enabled = false; wifi_connect_unlock(wifi); @@ -94,14 +94,14 @@ static void app_hide(App app) { static void app_start(App app) { WifiConnect* wifi_connect = wifi_connect_alloc(app); - app_set_data(app, wifi_connect); + tt_app_set_data(app, wifi_connect); } static void app_stop(App app) { - WifiConnect* wifi = app_get_data(app); - furi_assert(wifi != NULL); + WifiConnect* wifi = tt_app_get_data(app); + tt_assert(wifi != NULL); wifi_connect_free(wifi); - app_set_data(app, NULL); + tt_app_set_data(app, NULL); } AppManifest wifi_connect_app = { diff --git a/components/tactility/src/apps/system/wifi_connect/wifi_connect.h b/components/tactility/src/apps/system/wifi_connect/wifi_connect.h index 4c6a52c4..c7f4da9a 100644 --- a/components/tactility/src/apps/system/wifi_connect/wifi_connect.h +++ b/components/tactility/src/apps/system/wifi_connect/wifi_connect.h @@ -11,8 +11,8 @@ extern "C" { #endif typedef struct { - FuriPubSubSubscription* wifi_subscription; - FuriMutex* mutex; + PubSubSubscription* wifi_subscription; + Mutex* mutex; WifiConnectState state; WifiConnectView view; bool view_enabled; diff --git a/components/tactility/src/apps/system/wifi_connect/wifi_connect_view.c b/components/tactility/src/apps/system/wifi_connect/wifi_connect_view.c index 3f562dca..35e48443 100644 --- a/components/tactility/src/apps/system/wifi_connect/wifi_connect_view.c +++ b/components/tactility/src/apps/system/wifi_connect/wifi_connect_view.c @@ -64,15 +64,15 @@ void wifi_connect_view_create(App app, void* wifi, lv_obj_t* parent) { lv_obj_add_event_cb(view->connect_button, &on_connect, LV_EVENT_CLICKED, wifi); // Init from app parameters - Bundle* _Nullable bundle = app_get_parameters(app); + Bundle* _Nullable bundle = tt_app_get_parameters(app); if (bundle) { char* ssid; - if (bundle_opt_string(bundle, WIFI_CONNECT_PARAM_SSID, &ssid)) { + if (tt_bundle_opt_string(bundle, WIFI_CONNECT_PARAM_SSID, &ssid)) { lv_textarea_set_text(view->ssid_textarea, ssid); } char* password; - if (bundle_opt_string(bundle, WIFI_CONNECT_PARAM_PASSWORD, &password)) { + if (tt_bundle_opt_string(bundle, WIFI_CONNECT_PARAM_PASSWORD, &password)) { lv_textarea_set_text(view->password_textarea, password); } } diff --git a/components/tactility/src/apps/system/wifi_manage/wifi_manage.c b/components/tactility/src/apps/system/wifi_manage/wifi_manage.c index 4eb86509..8948dd07 100644 --- a/components/tactility/src/apps/system/wifi_manage/wifi_manage.c +++ b/components/tactility/src/apps/system/wifi_manage/wifi_manage.c @@ -3,8 +3,8 @@ #include "app.h" #include "apps/system/wifi_connect/wifi_connect_bundle.h" #include "esp_lvgl_port.h" -#include "furi_core.h" #include "services/loader/loader.h" +#include "tactility_core.h" #include "wifi_manage_state_updating.h" #include "wifi_manage_view.h" @@ -12,9 +12,9 @@ static void wifi_manage_event_callback(const void* message, void* context); static void on_connect(const char* ssid) { - Bundle bundle = bundle_alloc(); - bundle_put_string(bundle, WIFI_CONNECT_PARAM_SSID, ssid); - bundle_put_string(bundle, WIFI_CONNECT_PARAM_PASSWORD, ""); // TODO: Implement from cache + Bundle bundle = tt_bundle_alloc(); + tt_bundle_put_string(bundle, WIFI_CONNECT_PARAM_SSID, ssid); + tt_bundle_put_string(bundle, WIFI_CONNECT_PARAM_PASSWORD, ""); // TODO: Implement from cache loader_start_app("wifi_connect", false, bundle); } @@ -29,9 +29,9 @@ static void on_wifi_toggled(bool enabled) { static WifiManage* wifi_manage_alloc() { WifiManage* wifi = malloc(sizeof(WifiManage)); - FuriPubSub* wifi_pubsub = wifi_get_pubsub(); - wifi->wifi_subscription = furi_pubsub_subscribe(wifi_pubsub, &wifi_manage_event_callback, wifi); - wifi->mutex = furi_mutex_alloc(FuriMutexTypeNormal); + PubSub* wifi_pubsub = wifi_get_pubsub(); + wifi->wifi_subscription = tt_pubsub_subscribe(wifi_pubsub, &wifi_manage_event_callback, wifi); + wifi->mutex = tt_mutex_alloc(MutexTypeNormal); wifi->state = (WifiManageState) { .scanning = wifi_is_scanning(), .radio_state = wifi_get_radio_state() @@ -47,23 +47,23 @@ static WifiManage* wifi_manage_alloc() { } static void wifi_manage_free(WifiManage* wifi) { - FuriPubSub* wifi_pubsub = wifi_get_pubsub(); - furi_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription); - furi_mutex_free(wifi->mutex); + PubSub* wifi_pubsub = wifi_get_pubsub(); + tt_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription); + tt_mutex_free(wifi->mutex); free(wifi); } void wifi_manage_lock(WifiManage* wifi) { - furi_assert(wifi); - furi_assert(wifi->mutex); - furi_mutex_acquire(wifi->mutex, FuriWaitForever); + tt_assert(wifi); + tt_assert(wifi->mutex); + tt_mutex_acquire(wifi->mutex, TtWaitForever); } void wifi_manage_unlock(WifiManage* wifi) { - furi_assert(wifi); - furi_assert(wifi->mutex); - furi_mutex_release(wifi->mutex); + tt_assert(wifi); + tt_assert(wifi->mutex); + tt_mutex_release(wifi->mutex); } void wifi_manage_request_view_update(WifiManage* wifi) { @@ -99,7 +99,7 @@ static void wifi_manage_event_callback(const void* message, void* context) { } static void app_show(App app, lv_obj_t* parent) { - WifiManage* wifi = (WifiManage*)app_get_data(app); + WifiManage* wifi = (WifiManage*)tt_app_get_data(app); // State update (it has its own locking) wifi_manage_state_set_radio_state(wifi, wifi_get_radio_state()); @@ -120,7 +120,7 @@ static void app_show(App app, lv_obj_t* parent) { } static void app_hide(App app) { - WifiManage* wifi = (WifiManage*)app_get_data(app); + WifiManage* wifi = (WifiManage*)tt_app_get_data(app); wifi_manage_lock(wifi); wifi->view_enabled = false; wifi_manage_unlock(wifi); @@ -128,14 +128,14 @@ static void app_hide(App app) { static void app_start(App app) { WifiManage* wifi = wifi_manage_alloc(); - app_set_data(app, wifi); + tt_app_set_data(app, wifi); } static void app_stop(App app) { - WifiManage* wifi = (WifiManage*)app_get_data(app); - furi_assert(wifi != NULL); + WifiManage* wifi = (WifiManage*)tt_app_get_data(app); + tt_assert(wifi != NULL); wifi_manage_free(wifi); - app_set_data(app, NULL); + tt_app_set_data(app, NULL); } AppManifest wifi_manage_app = { diff --git a/components/tactility/src/apps/system/wifi_manage/wifi_manage.h b/components/tactility/src/apps/system/wifi_manage/wifi_manage.h index 536953b5..bc7ab626 100644 --- a/components/tactility/src/apps/system/wifi_manage/wifi_manage.h +++ b/components/tactility/src/apps/system/wifi_manage/wifi_manage.h @@ -9,8 +9,8 @@ extern "C" { #endif typedef struct { - FuriPubSubSubscription* wifi_subscription; - FuriMutex* mutex; + PubSubSubscription* wifi_subscription; + Mutex* mutex; WifiManageState state; WifiManageView view; bool view_enabled; diff --git a/components/tactility/src/apps/system/wifi_manage/wifi_manage_view.c b/components/tactility/src/apps/system/wifi_manage/wifi_manage_view.c index 882390d1..7e1380a9 100644 --- a/components/tactility/src/apps/system/wifi_manage/wifi_manage_view.c +++ b/components/tactility/src/apps/system/wifi_manage/wifi_manage_view.c @@ -56,7 +56,7 @@ static void connect(lv_event_t* event) { // We get the SSID from the button label because it's safer than alloc'ing // our own and passing it as the event data const char* ssid = lv_label_get_text(label); - FURI_LOG_I(TAG, "Clicked AP: %s", ssid); + TT_LOG_I(TAG, "Clicked AP: %s", ssid); WifiManageBindings* bindings = (WifiManageBindings*)event->user_data; bindings->on_connect_ssid(ssid); } diff --git a/components/tactility/src/devices.c b/components/tactility/src/devices.c index 151b2cc3..ddc6bcbc 100644 --- a/components/tactility/src/devices.c +++ b/components/tactility/src/devices.c @@ -11,7 +11,7 @@ Hardware tt_hardware_init(const HardwareConfig _Nonnull* config) { config->bootstrap(); } - furi_check(config->display_driver != NULL, "no display driver configured"); + tt_check(config->display_driver != NULL, "no display driver configured"); DisplayDriver display_driver = config->display_driver(); ESP_LOGI(TAG, "display with driver %s", display_driver.name); DisplayDevice* display = tt_display_device_alloc(&display_driver); diff --git a/components/tactility/src/display.c b/components/tactility/src/display.c index 9aa647a3..bed0c5a8 100644 --- a/components/tactility/src/display.c +++ b/components/tactility/src/display.c @@ -4,12 +4,12 @@ DisplayDevice _Nonnull* tt_display_device_alloc(DisplayDriver _Nonnull* driver) { DisplayDevice _Nonnull* display = malloc(sizeof(DisplayDevice)); memset(display, 0, sizeof(DisplayDevice)); - furi_check(driver->create_display_device(display), "failed to create display"); - furi_check(display->io_handle != NULL); - furi_check(display->display_handle != NULL); - furi_check(display->horizontal_resolution != 0); - furi_check(display->vertical_resolution != 0); - furi_check(display->draw_buffer_height > 0); - furi_check(display->bits_per_pixel > 0); + tt_check(driver->create_display_device(display), "failed to create display"); + tt_check(display->io_handle != NULL); + tt_check(display->display_handle != NULL); + tt_check(display->horizontal_resolution != 0); + tt_check(display->vertical_resolution != 0); + tt_check(display->draw_buffer_height > 0); + tt_check(display->bits_per_pixel > 0); return display; } diff --git a/components/tactility/src/graphics.c b/components/tactility/src/graphics.c index 3627ce8e..9b429cca 100644 --- a/components/tactility/src/graphics.c +++ b/components/tactility/src/graphics.c @@ -14,7 +14,7 @@ Lvgl tt_graphics_init(Hardware _Nonnull* hardware) { .timer_period_ms = 5 }; - furi_check(lvgl_port_init(&lvgl_cfg) == ESP_OK, "lvgl port init failed"); + tt_check(lvgl_port_init(&lvgl_cfg) == ESP_OK, "lvgl port init failed"); DisplayDevice _Nonnull* display = hardware->display; // Add display @@ -38,7 +38,7 @@ Lvgl tt_graphics_init(Hardware _Nonnull* hardware) { }; lv_disp_t _Nonnull* disp = lvgl_port_add_disp(&disp_cfg); - furi_check(disp != NULL, "failed to add display"); + tt_check(disp != NULL, "failed to add display"); lv_indev_t _Nullable* touch_indev = NULL; @@ -49,7 +49,7 @@ Lvgl tt_graphics_init(Hardware _Nonnull* hardware) { .handle = hardware->touch->touch_handle, }; touch_indev = lvgl_port_add_touch(&touch_cfg); - furi_check(touch_indev != NULL, "failed to add touch to lvgl"); + tt_check(touch_indev != NULL, "failed to add touch to lvgl"); } return (Lvgl) { diff --git a/components/tactility/src/partitions.c b/components/tactility/src/partitions.c index 2a44f057..ef3ecd2f 100644 --- a/components/tactility/src/partitions.c +++ b/components/tactility/src/partitions.c @@ -18,11 +18,11 @@ static esp_err_t spiffs_init(esp_vfs_spiffs_conf_t* conf) { esp_err_t ret = esp_vfs_spiffs_register(conf); if (ret != ESP_OK) { if (ret == ESP_FAIL) { - FURI_LOG_E(TAG, "Failed to mount or format filesystem %s", conf->base_path); + TT_LOG_E(TAG, "Failed to mount or format filesystem %s", conf->base_path); } else if (ret == ESP_ERR_NOT_FOUND) { - FURI_LOG_E(TAG, "Failed to find SPIFFS partition %s", conf->base_path); + TT_LOG_E(TAG, "Failed to find SPIFFS partition %s", conf->base_path); } else { - FURI_LOG_E(TAG, "Failed to initialize SPIFFS %s (%s)", conf->base_path, esp_err_to_name(ret)); + TT_LOG_E(TAG, "Failed to initialize SPIFFS %s (%s)", conf->base_path, esp_err_to_name(ret)); } return ESP_FAIL; } @@ -30,9 +30,9 @@ static esp_err_t spiffs_init(esp_vfs_spiffs_conf_t* conf) { size_t total = -1, used = 0; ret = esp_spiffs_info(NULL, &total, &used); if (ret != ESP_OK) { - FURI_LOG_E(TAG, "Failed to get SPIFFS partition information for %s (%s)", conf->base_path, esp_err_to_name(ret)); + TT_LOG_E(TAG, "Failed to get SPIFFS partition information for %s (%s)", conf->base_path, esp_err_to_name(ret)); } else { - FURI_LOG_I(TAG, "Partition size for %s: total: %d, used: %d", conf->base_path, total, used); + TT_LOG_I(TAG, "Partition size for %s: total: %d, used: %d", conf->base_path, total, used); } return ESP_OK; } diff --git a/components/tactility/src/services/gui/gui.c b/components/tactility/src/services/gui/gui.c index 51248774..f79766a0 100644 --- a/components/tactility/src/services/gui/gui.c +++ b/components/tactility/src/services/gui/gui.c @@ -1,10 +1,10 @@ #include "gui_i.h" #include "check.h" +#include "core_extra_defines.h" #include "esp_lvgl_port.h" -#include "furi_extra_defines.h" -#include "log.h" #include "kernel.h" +#include "log.h" #define TAG "gui" @@ -17,16 +17,16 @@ static Gui* gui = NULL; Gui* gui_alloc() { Gui* instance = malloc(sizeof(Gui)); memset(instance, 0, sizeof(Gui)); - furi_check(instance != NULL); - instance->thread = furi_thread_alloc_ex( + tt_check(instance != NULL); + instance->thread = tt_thread_alloc_ex( "gui", 4096, // Last known minimum was 2800 for launching desktop &gui_main, NULL ); - instance->mutex = furi_mutex_alloc(FuriMutexTypeRecursive); + instance->mutex = tt_mutex_alloc(MutexTypeRecursive); - furi_check(lvgl_port_lock(100)); + tt_check(lvgl_port_lock(100)); instance->lvgl_parent = lv_scr_act(); lvgl_port_unlock(); @@ -34,33 +34,33 @@ Gui* gui_alloc() { } void gui_free(Gui* instance) { - furi_assert(instance != NULL); - furi_thread_free(instance->thread); - furi_mutex_free(instance->mutex); + tt_assert(instance != NULL); + tt_thread_free(instance->thread); + tt_mutex_free(instance->mutex); free(instance); } void gui_lock() { - furi_assert(gui); - furi_assert(gui->mutex); - furi_check(furi_mutex_acquire(gui->mutex, 1000 / portTICK_PERIOD_MS) == FuriStatusOk); + tt_assert(gui); + tt_assert(gui->mutex); + tt_check(tt_mutex_acquire(gui->mutex, 1000 / portTICK_PERIOD_MS) == TtStatusOk); } void gui_unlock() { - furi_assert(gui); - furi_assert(gui->mutex); - furi_check(furi_mutex_release(gui->mutex) == FuriStatusOk); + tt_assert(gui); + tt_assert(gui->mutex); + tt_check(tt_mutex_release(gui->mutex) == TtStatusOk); } void gui_request_draw() { - furi_assert(gui); - FuriThreadId thread_id = furi_thread_get_id(gui->thread); - furi_thread_flags_set(thread_id, GUI_THREAD_FLAG_DRAW); + tt_assert(gui); + ThreadId thread_id = tt_thread_get_id(gui->thread); + tt_thread_flags_set(thread_id, GUI_THREAD_FLAG_DRAW); } void gui_show_app(App app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide) { gui_lock(); - furi_check(gui->app_view_port == NULL); + tt_check(gui->app_view_port == NULL); gui->app_view_port = view_port_alloc(app, on_show, on_hide); gui_unlock(); gui_request_draw(); @@ -69,7 +69,7 @@ void gui_show_app(App app, ViewPortShowCallback on_show, ViewPortHideCallback on void gui_hide_app() { gui_lock(); ViewPort* view_port = gui->app_view_port; - furi_check(view_port != NULL); + tt_check(view_port != NULL); view_port_hide(view_port); view_port_free(view_port); gui->app_view_port = NULL; @@ -78,23 +78,23 @@ void gui_hide_app() { static int32_t gui_main(void* p) { UNUSED(p); - furi_check(gui); + tt_check(gui); Gui* local_gui = gui; while (1) { - uint32_t flags = furi_thread_flags_wait( + uint32_t flags = tt_thread_flags_wait( GUI_THREAD_FLAG_ALL, - FuriFlagWaitAny, - FuriWaitForever + TtFlagWaitAny, + TtWaitForever ); // Process and dispatch draw call if (flags & GUI_THREAD_FLAG_DRAW) { - furi_thread_flags_clear(GUI_THREAD_FLAG_DRAW); + tt_thread_flags_clear(GUI_THREAD_FLAG_DRAW); gui_redraw(local_gui); } if (flags & GUI_THREAD_FLAG_EXIT) { - furi_thread_flags_clear(GUI_THREAD_FLAG_EXIT); + tt_thread_flags_clear(GUI_THREAD_FLAG_EXIT); break; } } @@ -109,8 +109,8 @@ static void gui_start(Service service) { gui = gui_alloc(); - furi_thread_set_priority(gui->thread, FuriThreadPriorityNormal); - furi_thread_start(gui->thread); + tt_thread_set_priority(gui->thread, ThreadPriorityNormal); + tt_thread_start(gui->thread); } static void gui_stop(Service service) { @@ -118,9 +118,9 @@ static void gui_stop(Service service) { gui_lock(); - FuriThreadId thread_id = furi_thread_get_id(gui->thread); - furi_thread_flags_set(thread_id, GUI_THREAD_FLAG_EXIT); - furi_thread_join(gui->thread); + ThreadId thread_id = tt_thread_get_id(gui->thread); + tt_thread_flags_set(thread_id, GUI_THREAD_FLAG_EXIT); + tt_thread_join(gui->thread); gui_unlock(); diff --git a/components/tactility/src/services/gui/gui_draw.c b/components/tactility/src/services/gui/gui_draw.c index b968457f..29e43358 100644 --- a/components/tactility/src/services/gui/gui_draw.c +++ b/components/tactility/src/services/gui/gui_draw.c @@ -20,13 +20,13 @@ static lv_obj_t* create_app_views(lv_obj_t* parent, App app) { tt_lv_obj_set_style_bg_blacken(vertical_container); // TODO: Move statusbar into separate ViewPort - AppFlags flags = app_get_flags(app); + AppFlags flags = tt_app_get_flags(app); if (flags.show_statusbar) { tt_lv_statusbar_create(vertical_container); } if (flags.show_toolbar) { - const AppManifest* manifest = app_get_manifest(app); + const AppManifest* manifest = tt_app_get_manifest(app); if (manifest != NULL) { // TODO: Keep toolbar on app level so app can update it (app_set_toolbar() etc?) Toolbar toolbar = { @@ -51,22 +51,22 @@ static lv_obj_t* create_app_views(lv_obj_t* parent, App app) { } void gui_redraw(Gui* gui) { - furi_assert(gui); + tt_assert(gui); // Lock GUI and LVGL gui_lock(); - furi_check(lvgl_port_lock(100)); + tt_check(lvgl_port_lock(100)); lv_obj_clean(gui->lvgl_parent); if (gui->app_view_port != NULL) { ViewPort* view_port = gui->app_view_port; - furi_assert(view_port); + tt_assert(view_port); App app = gui->app_view_port->app; lv_obj_t* container = create_app_views(gui->lvgl_parent, app); view_port_show(view_port, container); } else { - FURI_LOG_W(TAG, "nothing to draw"); + TT_LOG_W(TAG, "nothing to draw"); } // Unlock GUI and LVGL diff --git a/components/tactility/src/services/gui/gui_i.h b/components/tactility/src/services/gui/gui_i.h index 6704c3cb..e02018c8 100644 --- a/components/tactility/src/services/gui/gui_i.h +++ b/components/tactility/src/services/gui/gui_i.h @@ -16,8 +16,8 @@ /** Gui structure */ struct Gui { // Thread and lock - FuriThread* thread; - FuriMutex* mutex; + Thread* thread; + Mutex* mutex; // Layers and Canvas lv_obj_t* lvgl_parent; diff --git a/components/tactility/src/services/gui/gui_input.c b/components/tactility/src/services/gui/gui_input.c deleted file mode 100644 index 74707ceb..00000000 --- a/components/tactility/src/services/gui/gui_input.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "gui_i.h" - -/* -void gui_input_events_callback(const void* value, void* ctx) { - furi_assert(value); - furi_assert(ctx); - - Gui* gui = ctx; - - furi_message_queue_put(gui->input_queue, value, FuriWaitForever); - furi_thread_flags_set(gui->thread_id, GUI_THREAD_FLAG_INPUT); -} - -static void gui_input(Gui* gui, InputEvent* input_event) { - furi_assert(gui); - furi_assert(input_event); - - // Check input complementarity - uint8_t key_bit = (1 << input_event->key); - if(input_event->type == InputTypeRelease) { - gui->ongoing_input &= ~key_bit; - } else if(input_event->type == InputTypePress) { - gui->ongoing_input |= key_bit; - } else if(!(gui->ongoing_input & key_bit)) { - FURI_LOG_D( - TAG, - "non-complementary input, discarding key: %s type: %s, sequence: %p", - input_get_key_name(input_event->key), - input_get_type_name(input_event->type), - (void*)input_event->sequence); - return; - } - - gui_lock(gui); - - do { - if(gui->direct_draw && !gui->ongoing_input_view_port) { - break; - } - - ViewPort* view_port = NULL; - - if(gui->lockdown) { - view_port = gui_view_port_find_enabled(gui->layers[GuiLayerDesktop]); - } else { - view_port = gui_view_port_find_enabled(gui->layers[GuiLayerFullscreen]); - if(!view_port) view_port = gui_view_port_find_enabled(gui->layers[GuiLayerWindow]); - if(!view_port) view_port = gui_view_port_find_enabled(gui->layers[GuiLayerDesktop]); - } - - if(!(gui->ongoing_input & ~key_bit) && input_event->type == InputTypePress) { - gui->ongoing_input_view_port = view_port; - } - - if(view_port && view_port == gui->ongoing_input_view_port) { - view_port_input(view_port, input_event); - } else if(gui->ongoing_input_view_port && input_event->type == InputTypeRelease) { - FURI_LOG_D( - TAG, - "ViewPort changed while key press %p -> %p. Sending key: %s, type: %s, sequence: %p to previous view port", - gui->ongoing_input_view_port, - view_port, - input_get_key_name(input_event->key), - input_get_type_name(input_event->type), - (void*)input_event->sequence); - view_port_input(gui->ongoing_input_view_port, input_event); - } else { - FURI_LOG_D( - TAG, - "ViewPort changed while key press %p -> %p. Discarding key: %s, type: %s, sequence: %p", - gui->ongoing_input_view_port, - view_port, - input_get_key_name(input_event->key), - input_get_type_name(input_event->type), - (void*)input_event->sequence); - } - } while(false); - - gui_unlock(gui); -} -*/ diff --git a/components/tactility/src/services/gui/view_port.c b/components/tactility/src/services/gui/view_port.c index 4e337c42..bcd683fe 100644 --- a/components/tactility/src/services/gui/view_port.c +++ b/components/tactility/src/services/gui/view_port.c @@ -19,13 +19,13 @@ ViewPort* view_port_alloc( } void view_port_free(ViewPort* view_port) { - furi_assert(view_port); + tt_assert(view_port); free(view_port); } void view_port_show(ViewPort* view_port, lv_obj_t* parent) { - furi_assert(view_port); - furi_assert(parent); + tt_assert(view_port); + tt_assert(parent); if (view_port->on_show) { tt_lv_obj_set_style_no_padding(parent); view_port->on_show(view_port->app, parent); @@ -33,7 +33,7 @@ void view_port_show(ViewPort* view_port, lv_obj_t* parent) { } void view_port_hide(ViewPort* view_port) { - furi_assert(view_port); + tt_assert(view_port); if (view_port->on_hide) { view_port->on_hide(view_port->app); } diff --git a/components/tactility/src/services/gui/view_port.h b/components/tactility/src/services/gui/view_port.h index 13dd74c1..cc474f98 100644 --- a/components/tactility/src/services/gui/view_port.h +++ b/components/tactility/src/services/gui/view_port.h @@ -6,7 +6,6 @@ extern "C" { #include "app.h" #include "lvgl.h" -#include "context.h" /** ViewPort Draw callback * @warning called from GUI thread diff --git a/components/tactility/src/services/loader/loader.c b/components/tactility/src/services/loader/loader.c index 43fdf10a..d3990015 100644 --- a/components/tactility/src/services/loader/loader.c +++ b/components/tactility/src/services/loader/loader.c @@ -17,11 +17,11 @@ static int32_t loader_main(void* p); static Loader* loader_singleton = NULL; static Loader* loader_alloc() { - furi_check(loader_singleton == NULL); + tt_check(loader_singleton == NULL); loader_singleton = malloc(sizeof(Loader)); - loader_singleton->pubsub = furi_pubsub_alloc(); - loader_singleton->queue = furi_message_queue_alloc(1, sizeof(LoaderMessage)); - loader_singleton->thread = furi_thread_alloc_ex( + loader_singleton->pubsub = tt_pubsub_alloc(); + loader_singleton->queue = tt_message_queue_alloc(1, sizeof(LoaderMessage)); + loader_singleton->thread = tt_thread_alloc_ex( "loader", 4096, // Last known minimum was 2400 for starting Hello World app &loader_main, @@ -34,24 +34,24 @@ static Loader* loader_alloc() { } static void loader_free() { - furi_check(loader_singleton != NULL); - furi_thread_free(loader_singleton->thread); - furi_pubsub_free(loader_singleton->pubsub); - furi_message_queue_free(loader_singleton->queue); - furi_mutex_free(loader_singleton->mutex); + tt_check(loader_singleton != NULL); + tt_thread_free(loader_singleton->thread); + tt_pubsub_free(loader_singleton->pubsub); + tt_message_queue_free(loader_singleton->queue); + tt_mutex_free(loader_singleton->mutex); free(loader_singleton); } void loader_lock() { - furi_assert(loader_singleton); - furi_assert(loader_singleton->mutex); - furi_check(xSemaphoreTakeRecursive(loader_singleton->mutex, portMAX_DELAY) == pdPASS); + tt_assert(loader_singleton); + tt_assert(loader_singleton->mutex); + tt_check(xSemaphoreTakeRecursive(loader_singleton->mutex, portMAX_DELAY) == pdPASS); } void loader_unlock() { - furi_assert(loader_singleton); - furi_assert(loader_singleton->mutex); - furi_check(xSemaphoreGiveRecursive(loader_singleton->mutex) == pdPASS); + tt_assert(loader_singleton); + tt_assert(loader_singleton->mutex); + tt_check(xSemaphoreGiveRecursive(loader_singleton->mutex) == pdPASS); } LoaderStatus loader_start_app(const char* id, bool blocking, Bundle* _Nullable bundle) { @@ -64,13 +64,13 @@ LoaderStatus loader_start_app(const char* id, bool blocking, Bundle* _Nullable b .start.id = id, .start.bundle = bundle, .status_value = &result, - .api_lock = blocking ? api_lock_alloc_locked() : NULL + .api_lock = blocking ? tt_api_lock_alloc_locked() : NULL }; - furi_message_queue_put(loader_singleton->queue, &message, FuriWaitForever); + tt_message_queue_put(loader_singleton->queue, &message, TtWaitForever); if (blocking) { - api_lock_wait_unlock_and_free(message.api_lock); + tt_api_lock_wait_unlock_and_free(message.api_lock); } return result.value; @@ -78,7 +78,7 @@ LoaderStatus loader_start_app(const char* id, bool blocking, Bundle* _Nullable b void loader_stop_app() { LoaderMessage message = {.type = LoaderMessageTypeAppStop}; - furi_message_queue_put(loader_singleton->queue, &message, FuriWaitForever); + tt_message_queue_put(loader_singleton->queue, &message, TtWaitForever); } App _Nullable loader_get_current_app() { @@ -90,8 +90,8 @@ App _Nullable loader_get_current_app() { return app; } -FuriPubSub* loader_get_pubsub() { - furi_assert(loader_singleton); +PubSub* loader_get_pubsub() { + tt_assert(loader_singleton); // it's safe to return pubsub without locking // because it's never freed and loader is never exited // also the loader instance cannot be obtained until the pubsub is created @@ -116,10 +116,10 @@ static const char* app_state_to_string(AppState state) { } static void app_transition_to_state(App app, AppState state) { - const AppManifest* manifest = app_get_manifest(app); - const AppState old_state = app_get_state(app); + const AppManifest* manifest = tt_app_get_manifest(app); + const AppState old_state = tt_app_get_state(app); - FURI_LOG_I( + TT_LOG_I( TAG, "app \"%s\" state: %s -> %s", manifest->id, @@ -129,13 +129,13 @@ static void app_transition_to_state(App app, AppState state) { switch (state) { case APP_STATE_INITIAL: - app_set_state(app, APP_STATE_INITIAL); + tt_app_set_state(app, APP_STATE_INITIAL); break; case APP_STATE_STARTED: if (manifest->on_start != NULL) { manifest->on_start(app); } - app_set_state(app, APP_STATE_STARTED); + tt_app_set_state(app, APP_STATE_STARTED); break; case APP_STATE_SHOWING: gui_show_app( @@ -143,18 +143,18 @@ static void app_transition_to_state(App app, AppState state) { manifest->on_show, manifest->on_hide ); - app_set_state(app, APP_STATE_SHOWING); + tt_app_set_state(app, APP_STATE_SHOWING); break; case APP_STATE_HIDING: gui_hide_app(); - app_set_state(app, APP_STATE_HIDING); + tt_app_set_state(app, APP_STATE_HIDING); break; case APP_STATE_STOPPED: if (manifest->on_stop) { manifest->on_stop(app); } - app_set_data(app, NULL); - app_set_state(app, APP_STATE_STOPPED); + tt_app_set_data(app, NULL); + tt_app_set_state(app, APP_STATE_STOPPED); break; } } @@ -163,20 +163,20 @@ LoaderStatus loader_do_start_app_with_manifest( const AppManifest* _Nonnull manifest, Bundle* _Nullable bundle ) { - FURI_LOG_I(TAG, "start with manifest %s", manifest->id); + TT_LOG_I(TAG, "start with manifest %s", manifest->id); loader_lock(); if (loader_singleton->app_stack_index >= (APP_STACK_SIZE - 1)) { - FURI_LOG_E(TAG, "failed to start app: stack limit of %d reached", APP_STACK_SIZE); + TT_LOG_E(TAG, "failed to start app: stack limit of %d reached", APP_STACK_SIZE); return LoaderStatusErrorInternal; } int8_t previous_index = loader_singleton->app_stack_index; loader_singleton->app_stack_index++; - App app = app_alloc(manifest, bundle); - furi_assert(loader_singleton->app_stack[loader_singleton->app_stack_index] == NULL); + App app = tt_app_alloc(manifest, bundle); + tt_assert(loader_singleton->app_stack[loader_singleton->app_stack_index] == NULL); loader_singleton->app_stack[loader_singleton->app_stack_index] = app; app_transition_to_state(app, APP_STATE_INITIAL); app_transition_to_state(app, APP_STATE_STARTED); @@ -192,7 +192,7 @@ LoaderStatus loader_do_start_app_with_manifest( loader_unlock(); LoaderEvent event = {.type = LoaderEventTypeApplicationStarted}; - furi_pubsub_publish(loader_singleton->pubsub, &event); + tt_pubsub_publish(loader_singleton->pubsub, &event); return LoaderStatusOk; } @@ -201,9 +201,9 @@ static LoaderStatus loader_do_start_by_id( const char* id, Bundle* _Nullable bundle ) { - FURI_LOG_I(TAG, "Start by id %s", id); + TT_LOG_I(TAG, "Start by id %s", id); - const AppManifest* manifest = app_manifest_registry_find_by_id(id); + const AppManifest* manifest = tt_app_manifest_registry_find_by_id(id); if (manifest == NULL) { return LoaderStatusErrorUnknownApp; } else { @@ -219,13 +219,13 @@ static void loader_do_stop_app() { if (current_app_index == -1) { loader_unlock(); - FURI_LOG_E(TAG, "Stop app: no app running"); + TT_LOG_E(TAG, "Stop app: no app running"); return; } if (current_app_index == 0) { loader_unlock(); - FURI_LOG_E(TAG, "Stop app: can't stop root app"); + TT_LOG_E(TAG, "Stop app: can't stop root app"); return; } @@ -234,21 +234,21 @@ static void loader_do_stop_app() { app_transition_to_state(app_to_stop, APP_STATE_HIDING); app_transition_to_state(app_to_stop, APP_STATE_STOPPED); - app_free(app_to_stop); + tt_app_free(app_to_stop); loader_singleton->app_stack[current_app_index] = NULL; loader_singleton->app_stack_index--; - FURI_LOG_I(TAG, "Free heap: %zu", heap_caps_get_free_size(MALLOC_CAP_INTERNAL)); + TT_LOG_I(TAG, "Free heap: %zu", heap_caps_get_free_size(MALLOC_CAP_INTERNAL)); // Resume previous app - furi_assert(loader_singleton->app_stack[loader_singleton->app_stack_index] != NULL); + tt_assert(loader_singleton->app_stack[loader_singleton->app_stack_index] != NULL); App app_to_resume = loader_singleton->app_stack[loader_singleton->app_stack_index]; app_transition_to_state(app_to_resume, APP_STATE_SHOWING); loader_unlock(); LoaderEvent event = {.type = LoaderEventTypeApplicationStopped}; - furi_pubsub_publish(loader_singleton->pubsub, &event); + tt_pubsub_publish(loader_singleton->pubsub, &event); } @@ -258,9 +258,9 @@ static int32_t loader_main(void* p) { LoaderMessage message; bool exit_requested = false; while (!exit_requested) { - furi_check(loader_singleton != NULL); - if (furi_message_queue_get(loader_singleton->queue, &message, FuriWaitForever) == FuriStatusOk) { - FURI_LOG_I(TAG, "Processing message of type %d", message.type); + tt_check(loader_singleton != NULL); + if (tt_message_queue_get(loader_singleton->queue, &message, TtWaitForever) == TtStatusOk) { + TT_LOG_I(TAG, "Processing message of type %d", message.type); switch (message.type) { case LoaderMessageTypeAppStart: // TODO: add bundle @@ -269,7 +269,7 @@ static int32_t loader_main(void* p) { message.start.bundle ); if (message.api_lock) { - api_lock_unlock(message.api_lock); + tt_api_lock_unlock(message.api_lock); } break; case LoaderMessageTypeAppStop: @@ -289,24 +289,24 @@ static int32_t loader_main(void* p) { static void loader_start(Service service) { UNUSED(service); - furi_check(loader_singleton == NULL); + tt_check(loader_singleton == NULL); loader_singleton = loader_alloc(); - furi_thread_set_priority(loader_singleton->thread, FuriThreadPriorityNormal); - furi_thread_start(loader_singleton->thread); + tt_thread_set_priority(loader_singleton->thread, ThreadPriorityNormal); + tt_thread_start(loader_singleton->thread); } static void loader_stop(Service service) { UNUSED(service); - furi_check(loader_singleton != NULL); + tt_check(loader_singleton != NULL); // Send stop signal to thread and wait for thread to finish LoaderMessage message = { .api_lock = NULL, .type = LoaderMessageTypeServiceStop }; - furi_message_queue_put(loader_singleton->queue, &message, FuriWaitForever); - furi_thread_join(loader_singleton->thread); + tt_message_queue_put(loader_singleton->queue, &message, TtWaitForever); + tt_thread_join(loader_singleton->thread); loader_free(); loader_singleton = NULL; diff --git a/components/tactility/src/services/loader/loader.h b/components/tactility/src/services/loader/loader.h index 58adaba5..433acee7 100644 --- a/components/tactility/src/services/loader/loader.h +++ b/components/tactility/src/services/loader/loader.h @@ -2,10 +2,10 @@ #include "app_manifest.h" #include "bundle.h" -#include "furi_core.h" -#include "furi_string.h" #include "pubsub.h" #include "service_manifest.h" +#include "tactility_core.h" +#include "tt_string.h" #ifdef __cplusplus extern "C" { @@ -44,9 +44,9 @@ App _Nullable loader_get_current_app(); /** * @brief Get loader pubsub - * @return FuriPubSub* + * @return PubSub* */ -FuriPubSub* loader_get_pubsub(); +PubSub* loader_get_pubsub(); #ifdef __cplusplus } diff --git a/components/tactility/src/services/loader/loader_i.h b/components/tactility/src/services/loader/loader_i.h index 51b0c791..948c1d0a 100644 --- a/components/tactility/src/services/loader/loader_i.h +++ b/components/tactility/src/services/loader/loader_i.h @@ -13,10 +13,10 @@ #define APP_STACK_SIZE 32 struct Loader { - FuriThread* thread; - FuriPubSub* pubsub; - FuriMessageQueue* queue; - // TODO: replace with FuriMutex + Thread* thread; + PubSub* pubsub; + MessageQueue* queue; + // TODO: replace with Mutex SemaphoreHandle_t mutex; int8_t app_stack_index; App app_stack[APP_STACK_SIZE]; @@ -44,7 +44,7 @@ typedef struct { typedef struct { // This lock blocks anyone from starting an app as long // as an app is already running via loader_start() - FuriApiLock api_lock; + ApiLock api_lock; LoaderMessageType type; union { diff --git a/components/tactility/src/services/wifi/wifi.c b/components/tactility/src/services/wifi/wifi.c index b82cfd7b..6b1ea610 100644 --- a/components/tactility/src/services/wifi/wifi.c +++ b/components/tactility/src/services/wifi/wifi.c @@ -17,11 +17,11 @@ typedef struct { /** @brief Locking mechanism for modifying the Wifi instance */ - FuriMutex* mutex; + Mutex* mutex; /** @brief The public event bus */ - FuriPubSub* pubsub; + PubSub* pubsub; /** @brief The internal message queue */ - FuriMessageQueue* queue; + MessageQueue* queue; /** @brief The network interface when wifi is started */ esp_netif_t* _Nullable netif; /** @brief Scanning results */ @@ -69,12 +69,12 @@ static void wifi_unlock(Wifi* wifi); static Wifi* wifi_alloc() { Wifi* instance = malloc(sizeof(Wifi)); - instance->mutex = furi_mutex_alloc(FuriMutexTypeRecursive); - instance->pubsub = furi_pubsub_alloc(); + instance->mutex = tt_mutex_alloc(MutexTypeRecursive); + instance->pubsub = tt_pubsub_alloc(); // TODO: Deal with messages that come in while an action is ongoing // for example: when scanning and you turn off the radio, the scan should probably stop or turning off // the radio should disable the on/off button in the app as it is pending. - instance->queue = furi_message_queue_alloc(1, sizeof(WifiMessage)); + instance->queue = tt_message_queue_alloc(1, sizeof(WifiMessage)); instance->netif = NULL; instance->scan_active = false; instance->scan_list = NULL; @@ -88,9 +88,9 @@ static Wifi* wifi_alloc() { } static void wifi_free(Wifi* instance) { - furi_mutex_free(instance->mutex); - furi_pubsub_free(instance->pubsub); - furi_message_queue_free(instance->queue); + tt_mutex_free(instance->mutex); + tt_pubsub_free(instance->pubsub); + tt_message_queue_free(instance->queue); free(instance); } @@ -98,8 +98,8 @@ static void wifi_free(Wifi* instance) { // region Public functions -FuriPubSub* wifi_get_pubsub() { - furi_assert(wifi_singleton); +PubSub* wifi_get_pubsub() { + tt_assert(wifi_singleton); return wifi_singleton->pubsub; } @@ -108,21 +108,21 @@ WifiRadioState wifi_get_radio_state() { } void wifi_scan() { - furi_assert(wifi_singleton); + tt_assert(wifi_singleton); WifiMessage message = {.type = WifiMessageTypeScan}; // No need to lock for queue - furi_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); + tt_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); } bool wifi_is_scanning() { - furi_assert(wifi_singleton); + tt_assert(wifi_singleton); return wifi_singleton->scan_active; } void wifi_connect(const char* ssid, const char* _Nullable password) { - furi_assert(wifi_singleton); - furi_check(strlen(ssid) <= 32); - furi_check(password == NULL || strlen(password) <= 64); + tt_assert(wifi_singleton); + tt_check(strlen(ssid) <= 32); + tt_check(password == NULL || strlen(password) <= 64); WifiMessage message = {.type = WifiMessageTypeConnect}; memcpy(message.connect_message.ssid, ssid, 32); if (password != NULL) { @@ -130,17 +130,17 @@ void wifi_connect(const char* ssid, const char* _Nullable password) { } else { message.connect_message.password[0] = 0; } - furi_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); + tt_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); } void wifi_disconnect() { - furi_assert(wifi_singleton); + tt_assert(wifi_singleton); WifiMessage message = {.type = WifiMessageTypeDisconnect}; - furi_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); + tt_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); } void wifi_set_scan_records(uint16_t records) { - furi_assert(wifi_singleton); + tt_assert(wifi_singleton); if (records != wifi_singleton->scan_list_limit) { wifi_scan_list_free_safely(wifi_singleton); wifi_singleton->scan_list_limit = records; @@ -148,14 +148,14 @@ void wifi_set_scan_records(uint16_t records) { } void wifi_get_scan_results(WifiApRecord records[], uint16_t limit, uint16_t* result_count) { - furi_check(wifi_singleton); - furi_check(result_count); + tt_check(wifi_singleton); + tt_check(result_count); if (wifi_singleton->scan_list_count == 0) { *result_count = 0; } else { uint16_t i = 0; - FURI_LOG_I(TAG, "processing up to %d APs", wifi_singleton->scan_list_count); + TT_LOG_I(TAG, "processing up to %d APs", wifi_singleton->scan_list_count); uint16_t last_index = MIN(wifi_singleton->scan_list_count, limit); for (; i < last_index; ++i) { memcpy(records[i].ssid, wifi_singleton->scan_list[i].ssid, 33); @@ -172,31 +172,31 @@ void wifi_set_enabled(bool enabled) { if (enabled) { WifiMessage message = {.type = WifiMessageTypeRadioOn}; // No need to lock for queue - furi_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); + tt_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); } else { WifiMessage message = {.type = WifiMessageTypeRadioOff}; // No need to lock for queue - furi_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); + tt_message_queue_put(wifi_singleton->queue, &message, 100 / portTICK_PERIOD_MS); } } // endregion Public functions static void wifi_lock(Wifi* wifi) { - furi_crash("this fails for now"); - furi_assert(wifi); - furi_assert(wifi->mutex); - furi_check(xSemaphoreTakeRecursive(wifi->mutex, portMAX_DELAY) == pdPASS); + tt_crash("this fails for now"); + tt_assert(wifi); + tt_assert(wifi->mutex); + tt_check(xSemaphoreTakeRecursive(wifi->mutex, portMAX_DELAY) == pdPASS); } static void wifi_unlock(Wifi* wifi) { - furi_assert(wifi); - furi_assert(wifi->mutex); - furi_check(xSemaphoreGiveRecursive(wifi->mutex) == pdPASS); + tt_assert(wifi); + tt_assert(wifi->mutex); + tt_check(xSemaphoreGiveRecursive(wifi->mutex) == pdPASS); } static void wifi_scan_list_alloc(Wifi* wifi) { - furi_check(wifi->scan_list == NULL); + tt_check(wifi->scan_list == NULL); wifi->scan_list = malloc(sizeof(wifi_ap_record_t) * wifi->scan_list_limit); wifi->scan_list_count = 0; } @@ -208,7 +208,7 @@ static void wifi_scan_list_alloc_safely(Wifi* wifi) { } static void wifi_scan_list_free(Wifi* wifi) { - furi_check(wifi->scan_list != NULL); + tt_check(wifi->scan_list != NULL); free(wifi->scan_list); wifi->scan_list = NULL; wifi->scan_list_count = 0; @@ -222,7 +222,7 @@ static void wifi_scan_list_free_safely(Wifi* wifi) { static void wifi_publish_event_simple(Wifi* wifi, WifiEventType type) { WifiEvent turning_on_event = {.type = type}; - furi_pubsub_publish(wifi->pubsub, &turning_on_event); + tt_pubsub_publish(wifi->pubsub, &turning_on_event); } static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { @@ -247,11 +247,11 @@ static void wifi_enable(Wifi* wifi) { state == WIFI_RADIO_ON_PENDING || state == WIFI_RADIO_OFF_PENDING ) { - FURI_LOG_W(TAG, "Can't enable from current state"); + TT_LOG_W(TAG, "Can't enable from current state"); return; } - FURI_LOG_I(TAG, "Enabling"); + TT_LOG_I(TAG, "Enabling"); wifi->radio_state = WIFI_RADIO_ON_PENDING; wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOnPending); @@ -265,9 +265,9 @@ static void wifi_enable(Wifi* wifi) { wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); esp_err_t init_result = esp_wifi_init(&config); if (init_result != ESP_OK) { - FURI_LOG_E(TAG, "Wifi init failed"); + TT_LOG_E(TAG, "Wifi init failed"); if (init_result == ESP_ERR_NO_MEM) { - FURI_LOG_E(TAG, "Insufficient memory"); + TT_LOG_E(TAG, "Insufficient memory"); } wifi->radio_state = WIFI_RADIO_OFF; wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOff); @@ -295,7 +295,7 @@ static void wifi_enable(Wifi* wifi) { )); if (esp_wifi_set_mode(WIFI_MODE_STA) != ESP_OK) { - FURI_LOG_E(TAG, "Wifi mode setting failed"); + TT_LOG_E(TAG, "Wifi mode setting failed"); wifi->radio_state = WIFI_RADIO_OFF; esp_wifi_deinit(); wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOff); @@ -304,9 +304,9 @@ static void wifi_enable(Wifi* wifi) { esp_err_t start_result = esp_wifi_start(); if (start_result != ESP_OK) { - FURI_LOG_E(TAG, "Wifi start failed"); + TT_LOG_E(TAG, "Wifi start failed"); if (start_result == ESP_ERR_NO_MEM) { - FURI_LOG_E(TAG, "Insufficient memory"); + TT_LOG_E(TAG, "Insufficient memory"); } wifi->radio_state = WIFI_RADIO_OFF; esp_wifi_set_mode(WIFI_MODE_NULL); @@ -317,7 +317,7 @@ static void wifi_enable(Wifi* wifi) { wifi->radio_state = WIFI_RADIO_ON; wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOn); - FURI_LOG_I(TAG, "Enabled"); + TT_LOG_I(TAG, "Enabled"); } static void wifi_disable(Wifi* wifi) { @@ -327,11 +327,11 @@ static void wifi_disable(Wifi* wifi) { state == WIFI_RADIO_OFF_PENDING || state == WIFI_RADIO_ON_PENDING ) { - FURI_LOG_W(TAG, "Can't disable from current state"); + TT_LOG_W(TAG, "Can't disable from current state"); return; } - FURI_LOG_I(TAG, "Disabling"); + TT_LOG_I(TAG, "Disabling"); wifi->radio_state = WIFI_RADIO_OFF_PENDING; wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOffPending); @@ -339,14 +339,14 @@ static void wifi_disable(Wifi* wifi) { wifi_scan_list_free_safely(wifi_singleton); if (esp_wifi_stop() != ESP_OK) { - FURI_LOG_E(TAG, "Failed to stop radio"); + TT_LOG_E(TAG, "Failed to stop radio"); wifi->radio_state = WIFI_RADIO_ON; wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOn); return; } if (esp_wifi_set_mode(WIFI_MODE_NULL) != ESP_OK) { - FURI_LOG_E(TAG, "Failed to unset mode"); + TT_LOG_E(TAG, "Failed to unset mode"); } if (esp_event_handler_instance_unregister( @@ -354,7 +354,7 @@ static void wifi_disable(Wifi* wifi) { ESP_EVENT_ANY_ID, wifi->event_handler_any_id ) != ESP_OK) { - FURI_LOG_E(TAG, "Failed to unregister id event handler"); + TT_LOG_E(TAG, "Failed to unregister id event handler"); } if (esp_event_handler_instance_unregister( @@ -362,30 +362,30 @@ static void wifi_disable(Wifi* wifi) { IP_EVENT_STA_GOT_IP, wifi->event_handler_got_ip ) != ESP_OK) { - FURI_LOG_E(TAG, "Failed to unregister ip event handler"); + TT_LOG_E(TAG, "Failed to unregister ip event handler"); } if (esp_wifi_deinit() != ESP_OK) { - FURI_LOG_E(TAG, "Failed to deinit"); + TT_LOG_E(TAG, "Failed to deinit"); } - furi_check(wifi->netif != NULL); + tt_check(wifi->netif != NULL); esp_netif_destroy(wifi->netif); wifi->netif = NULL; wifi->radio_state = WIFI_RADIO_OFF; wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOff); - FURI_LOG_I(TAG, "Disabled"); + TT_LOG_I(TAG, "Disabled"); } static void wifi_scan_internal(Wifi* wifi) { WifiRadioState state = wifi->radio_state; if (state != WIFI_RADIO_ON && state != WIFI_RADIO_CONNECTION_ACTIVE) { - FURI_LOG_W(TAG, "Scan unavailable: wifi not enabled"); + TT_LOG_W(TAG, "Scan unavailable: wifi not enabled"); return; } - FURI_LOG_I(TAG, "Starting scan"); + TT_LOG_I(TAG, "Starting scan"); wifi->scan_active = true; wifi_publish_event_simple(wifi, WifiEventTypeScanStarted); @@ -398,17 +398,17 @@ static void wifi_scan_internal(Wifi* wifi) { ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&record_count, wifi->scan_list)); uint16_t safe_record_count = MIN(wifi->scan_list_limit, record_count); wifi->scan_list_count = safe_record_count; - FURI_LOG_I(TAG, "Scanned %u APs. Showing %u:", record_count, safe_record_count); + TT_LOG_I(TAG, "Scanned %u APs. Showing %u:", record_count, safe_record_count); for (uint16_t i = 0; i < safe_record_count; i++) { wifi_ap_record_t* record = &wifi->scan_list[i]; - FURI_LOG_I(TAG, " - SSID %s (RSSI %d, channel %d)", record->ssid, record->rssi, record->primary); + TT_LOG_I(TAG, " - SSID %s (RSSI %d, channel %d)", record->ssid, record->rssi, record->primary); } esp_wifi_scan_stop(); wifi_publish_event_simple(wifi, WifiEventTypeScanFinished); wifi->scan_active = false; - FURI_LOG_I(TAG, "Finished scan"); + TT_LOG_I(TAG, "Finished scan"); } static void wifi_connect_internal(Wifi* wifi, WifiConnectMessage* connect_message) { @@ -437,7 +437,7 @@ static void wifi_connect_internal(Wifi* wifi, WifiConnectMessage* connect_messag esp_err_t set_config_result = esp_wifi_set_config(WIFI_IF_STA, &wifi_config); if (set_config_result != ESP_OK) { wifi->radio_state = WIFI_RADIO_ON; - FURI_LOG_E(TAG, "failed to set wifi config (%s)", esp_err_to_name(set_config_result)); + TT_LOG_E(TAG, "failed to set wifi config (%s)", esp_err_to_name(set_config_result)); wifi_publish_event_simple(wifi, WifiEventTypeConnectionFailed); return; } @@ -445,7 +445,7 @@ static void wifi_connect_internal(Wifi* wifi, WifiConnectMessage* connect_messag esp_err_t wifi_start_result = esp_wifi_start(); if (wifi_start_result != ESP_OK) { wifi->radio_state = WIFI_RADIO_ON; - FURI_LOG_E(TAG, "failed to start wifi to begin connecting (%s)", esp_err_to_name(wifi_start_result)); + TT_LOG_E(TAG, "failed to start wifi to begin connecting (%s)", esp_err_to_name(wifi_start_result)); wifi_publish_event_simple(wifi, WifiEventTypeConnectionFailed); return; } @@ -479,18 +479,18 @@ static void wifi_connect_internal(Wifi* wifi, WifiConnectMessage* connect_messag static void wifi_disconnect_internal(Wifi* wifi) { esp_err_t stop_result = esp_wifi_stop(); if (stop_result != ESP_OK) { - FURI_LOG_E(TAG, "Failed to disconnect (%s)", esp_err_to_name(stop_result)); + TT_LOG_E(TAG, "Failed to disconnect (%s)", esp_err_to_name(stop_result)); } else { wifi->radio_state = WIFI_RADIO_ON; wifi_publish_event_simple(wifi, WifiEventTypeDisconnected); - FURI_LOG_I(TAG, "Disconnected"); + TT_LOG_I(TAG, "Disconnected"); } } static void wifi_disconnect_internal_but_keep_active(Wifi* wifi) { esp_err_t stop_result = esp_wifi_stop(); if (stop_result != ESP_OK) { - FURI_LOG_E(TAG, "Failed to disconnect (%s)", esp_err_to_name(stop_result)); + TT_LOG_E(TAG, "Failed to disconnect (%s)", esp_err_to_name(stop_result)); return; } @@ -508,7 +508,7 @@ static void wifi_disconnect_internal_but_keep_active(Wifi* wifi) { if (set_config_result != ESP_OK) { // TODO: disable radio, because radio state is in limbo between off and on wifi->radio_state = WIFI_RADIO_OFF; - FURI_LOG_E(TAG, "failed to set wifi config (%s)", esp_err_to_name(set_config_result)); + TT_LOG_E(TAG, "failed to set wifi config (%s)", esp_err_to_name(set_config_result)); wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOff); return; } @@ -517,29 +517,29 @@ static void wifi_disconnect_internal_but_keep_active(Wifi* wifi) { if (wifi_start_result != ESP_OK) { // TODO: disable radio, because radio state is in limbo between off and on wifi->radio_state = WIFI_RADIO_OFF; - FURI_LOG_E(TAG, "failed to start wifi to begin connecting (%s)", esp_err_to_name(wifi_start_result)); + TT_LOG_E(TAG, "failed to start wifi to begin connecting (%s)", esp_err_to_name(wifi_start_result)); wifi_publish_event_simple(wifi, WifiEventTypeRadioStateOff); return; } wifi->radio_state = WIFI_RADIO_ON; wifi_publish_event_simple(wifi, WifiEventTypeDisconnected); - FURI_LOG_I(TAG, "Disconnected"); + TT_LOG_I(TAG, "Disconnected"); } // ESP wifi APIs need to run from the main task, so we can't just spawn a thread _Noreturn int32_t wifi_main(void* p) { UNUSED(p); - FURI_LOG_I(TAG, "Started main loop"); - furi_check(wifi_singleton != NULL); + TT_LOG_I(TAG, "Started main loop"); + tt_check(wifi_singleton != NULL); Wifi* wifi = wifi_singleton; - FuriMessageQueue* queue = wifi->queue; + MessageQueue* queue = wifi->queue; WifiMessage message; while (true) { - if (furi_message_queue_get(queue, &message, 1000 / portTICK_PERIOD_MS) == FuriStatusOk) { - FURI_LOG_I(TAG, "Processing message of type %d", message.type); + if (tt_message_queue_get(queue, &message, 1000 / portTICK_PERIOD_MS) == TtStatusOk) { + TT_LOG_I(TAG, "Processing message of type %d", message.type); switch (message.type) { case WifiMessageTypeRadioOn: wifi_enable(wifi); @@ -563,13 +563,13 @@ _Noreturn int32_t wifi_main(void* p) { static void wifi_service_start(Service service) { UNUSED(service); - furi_check(wifi_singleton == NULL); + tt_check(wifi_singleton == NULL); wifi_singleton = wifi_alloc(); } static void wifi_service_stop(Service service) { UNUSED(service); - furi_check(wifi_singleton != NULL); + tt_check(wifi_singleton != NULL); WifiRadioState state = wifi_singleton->radio_state; if (state != WIFI_RADIO_OFF) { @@ -581,7 +581,7 @@ static void wifi_service_stop(Service service) { // wifi_main() cannot be stopped yet as it runs in the main task. // We could theoretically exit it, but then we wouldn't be able to restart the service. - furi_crash("not fully implemented"); + tt_crash("not fully implemented"); } const ServiceManifest wifi_service = { diff --git a/components/tactility/src/services/wifi/wifi.h b/components/tactility/src/services/wifi/wifi.h index 76de7454..9e2c2d48 100644 --- a/components/tactility/src/services/wifi/wifi.h +++ b/components/tactility/src/services/wifi/wifi.h @@ -49,9 +49,9 @@ typedef struct { /** * @brief Get wifi pubsub - * @return FuriPubSub* + * @return PubSub* */ -FuriPubSub* wifi_get_pubsub(); +PubSub* wifi_get_pubsub(); WifiRadioState wifi_get_radio_state(); /** diff --git a/components/tactility/src/tactility.c b/components/tactility/src/tactility.c index 43c285f5..aa636a2e 100644 --- a/components/tactility/src/tactility.c +++ b/components/tactility/src/tactility.c @@ -1,15 +1,15 @@ #include "tactility.h" -#include #include "app_manifest_registry.h" +#include "core.h" #include "devices_i.h" -#include "furi.h" +#include "esp_wifi.h" #include "graphics_i.h" +#include "nvs_flash.h" #include "partitions.h" #include "service_registry.h" -#include "esp_wifi.h" -#include "nvs_flash.h" #include "services/loader/loader.h" +#include #define TAG "tactility" @@ -27,19 +27,19 @@ extern const AppManifest wifi_manage_app; _Noreturn int32_t wifi_main(void* p); static void register_system_apps() { - FURI_LOG_I(TAG, "Registering default apps"); - app_manifest_registry_add(&desktop_app); - app_manifest_registry_add(&system_info_app); - app_manifest_registry_add(&wifi_connect_app); - app_manifest_registry_add(&wifi_manage_app); + TT_LOG_I(TAG, "Registering default apps"); + tt_app_manifest_registry_add(&desktop_app); + tt_app_manifest_registry_add(&system_info_app); + tt_app_manifest_registry_add(&wifi_connect_app); + tt_app_manifest_registry_add(&wifi_manage_app); } static void register_user_apps(const Config* _Nonnull config) { - FURI_LOG_I(TAG, "Registering user apps"); + TT_LOG_I(TAG, "Registering user apps"); for (size_t i = 0; i < CONFIG_APPS_LIMIT; i++) { const AppManifest* manifest = config->apps[i]; if (manifest != NULL) { - app_manifest_registry_add(manifest); + tt_app_manifest_registry_add(manifest); } else { // reached end of list break; @@ -48,26 +48,26 @@ static void register_user_apps(const Config* _Nonnull config) { } static void register_system_services() { - FURI_LOG_I(TAG, "Registering system services"); - service_registry_add(&gui_service); - service_registry_add(&loader_service); - service_registry_add(&wifi_service); + TT_LOG_I(TAG, "Registering system services"); + tt_service_registry_add(&gui_service); + tt_service_registry_add(&loader_service); + tt_service_registry_add(&wifi_service); } static void start_system_services() { - FURI_LOG_I(TAG, "Starting system services"); - service_registry_start(gui_service.id); - service_registry_start(loader_service.id); - service_registry_start(wifi_service.id); + TT_LOG_I(TAG, "Starting system services"); + tt_service_registry_start(gui_service.id); + tt_service_registry_start(loader_service.id); + tt_service_registry_start(wifi_service.id); } static void register_and_start_user_services(const Config* _Nonnull config) { - FURI_LOG_I(TAG, "Registering and starting user services"); + TT_LOG_I(TAG, "Registering and starting user services"); for (size_t i = 0; i < CONFIG_SERVICES_LIMIT; i++) { const ServiceManifest* manifest = config->services[i]; if (manifest != NULL) { - service_registry_add(manifest); - service_registry_start(manifest->id); + tt_service_registry_add(manifest); + tt_service_registry_start(manifest->id); } else { // reached end of list break; @@ -76,7 +76,7 @@ static void register_and_start_user_services(const Config* _Nonnull config) { } __attribute__((unused)) extern void tactility_start(const Config* _Nonnull config) { - furi_init(); + tt_core_init(); // Initialize NVS esp_err_t ret = nvs_flash_init(); diff --git a/components/tactility/src/tactility.h b/components/tactility/src/tactility.h index 43135fcf..d73e4533 100644 --- a/components/tactility/src/tactility.h +++ b/components/tactility/src/tactility.h @@ -1,9 +1,7 @@ #pragma once -#include "app_manifest.h" #include "devices.h" -#include "furi_extra_defines.h" -#include "service_manifest.h" +#include "tactility_core.h" #ifdef __cplusplus extern "C" { @@ -13,7 +11,7 @@ extern "C" { #define CONFIG_SERVICES_LIMIT 32 // Forward declarations -typedef void* FuriThreadId; +typedef void* ThreadId; typedef void (*Bootstrap)(); typedef TouchDriver (*CreateTouchDriver)(); typedef DisplayDriver (*CreateDisplayDriver)(); diff --git a/components/tactility/src/touch.c b/components/tactility/src/touch.c index 4d7de8c3..78c1aa39 100644 --- a/components/tactility/src/touch.c +++ b/components/tactility/src/touch.c @@ -7,6 +7,6 @@ TouchDevice _Nonnull* tt_touch_alloc(TouchDriver _Nonnull* driver) { &(touch->io_handle), &(touch->touch_handle) ); - furi_check(success, "touch driver failed"); + tt_check(success, "touch driver failed"); return touch; }