Merge develop into main branch (#137)

* SdCard HAL refactored (#135)

- Refactor SdCard HAL
- introduce Lockable

* Screenshot and FatFS improvements (#136)

- Fix screenshots on ESP32
- Improve Screenshot service
- Convert Screenshot app to class-based instead of structs
- Screenshot app now automatically updates when task is finished
- Enable FatFS long filename support

* Re-use common log messages (#138)

For consistency and binary size reduction

* Toolbar spinner should get margin to the right

* More TactilityC features (#139)

* Rewrote Loader

- Simplified Loader by removing custom threa
- Created DispatcherThread
- Move auto-starting apps to Boot app
- Fixed Dispatcher bug where it could get stuck not processing new
messages

* Hide AP settings if the AP is not saved

* Missing from previous commit

* Replace LV_EVENT_CLICKED with LV_EVENT_SHORT_CLICKED

* Refactored files app and created InputDialog (#140)

- Changed Files app so that it has a View and State
- Files app now allows for long-pressing on files to perform actions
- Files app now has rename and delete actions
- Created InputDialog app
- Improved AlertDialog app layout
This commit is contained in:
Ken Van Hoeylandt
2024-12-27 22:12:39 +00:00
committed by GitHub
parent 9033daa6dd
commit 50bd6e8bf6
144 changed files with 3244 additions and 2038 deletions
+19
View File
@@ -0,0 +1,19 @@
#include "tt_app_alertdialog.h"
#include <app/alertdialog/AlertDialog.h>
extern "C" {
void tt_app_alertdialog_start(const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount) {
std::vector<std::string> list;
for (int i = 0; i < buttonLabelCount; i++) {
const char* item = buttonLabels[i];
list.push_back(item);
}
tt::app::alertdialog::start(title, message, list);
}
int32_t tt_app_alertdialog_get_result_index(BundleHandle handle) {
return tt::app::alertdialog::getResultIndex(*(tt::Bundle*)handle);
}
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "tt_bundle.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
void tt_app_alertdialog_start(const char* title, const char* message, const char* buttonLabels[], uint32_t buttonLabelCount);
int32_t tt_app_alertdialog_get_result_index(BundleHandle handle);
#ifdef __cplusplus
}
#endif
+36
View File
@@ -0,0 +1,36 @@
#include "tt_app_context.h"
#include <app/AppContext.h>
struct AppContextDataWrapper {
void* _Nullable data;
};
extern "C" {
#define HANDLE_AS_APP_CONTEXT(handle) ((tt::app::AppContext*)(handle))
void* _Nullable tt_app_context_get_data(AppContextHandle handle) {
auto wrapper = std::reinterpret_pointer_cast<AppContextDataWrapper>(HANDLE_AS_APP_CONTEXT(handle)->getData());
return wrapper ? wrapper->data : nullptr;
}
void tt_app_context_set_data(AppContextHandle handle, void* _Nullable data) {
auto wrapper = std::make_shared<AppContextDataWrapper>();
wrapper->data = data;
HANDLE_AS_APP_CONTEXT(handle)->setData(std::move(wrapper));
}
BundleHandle _Nullable tt_app_context_get_parameters(AppContextHandle handle) {
return (BundleHandle)HANDLE_AS_APP_CONTEXT(handle)->getParameters().get();
}
void tt_app_context_set_result(AppContextHandle handle, Result result, BundleHandle _Nullable bundle) {
auto shared_bundle = std::shared_ptr<tt::Bundle>((tt::Bundle*)bundle);
HANDLE_AS_APP_CONTEXT(handle)->setResult((tt::app::Result)result, std::move(shared_bundle));
}
bool tt_app_context_has_result(AppContextHandle handle) {
return HANDLE_AS_APP_CONTEXT(handle)->hasResult();
}
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "tt_app_manifest.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void* AppContextHandle;
void* _Nullable tt_app_context_get_data(AppContextHandle handle);
void tt_app_context_set_data(AppContextHandle handle, void* _Nullable data);
BundleHandle _Nullable tt_app_context_get_parameters(AppContextHandle handle);
void tt_app_context_set_result(AppContextHandle handle, Result result, BundleHandle _Nullable bundle);
bool tt_app_context_has_result(AppContextHandle handle);
#ifdef __cplusplus
}
#endif
@@ -1,9 +1,10 @@
#include <Check.h>
#include "App.h"
#include "Log.h"
#include "app/ElfApp.h"
#include "tt_app_manifest.h"
#define TAG "tactilityc_app"
#include <Check.h>
#include <Log.h>
#include <app/ElfApp.h>
#define TAG "tt_app"
AppOnStart elfOnStart = nullptr;
AppOnStop elfOnStop = nullptr;
@@ -100,8 +101,8 @@ void tt_set_app_manifest(
elfOnResult = onResult;
tt::app::setElfAppManifest(manifest);
#else
tt_crash("Not intended for PC");
tt_crash("TactilityC is intended for PC/Simulator");
#endif
}
}
}
@@ -1,20 +1,20 @@
#pragma once
#include "lvgl.h"
#include "tt_bundle.h"
#include <lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void* AppContextHandle;
typedef void* BundleHandle;
typedef enum {
AppResultOk,
AppResultCancelled,
AppResultError
} Result;
typedef void* AppContextHandle;
typedef void (*AppOnStart)(AppContextHandle app);
typedef void (*AppOnStop)(AppContextHandle app);
typedef void (*AppOnShow)(AppContextHandle app, lv_obj_t* parent);
@@ -1,4 +1,5 @@
#include "app/selectiondialog/SelectionDialog.h"
#include "tt_app_selectiondialog.h"
#include <app/selectiondialog/SelectionDialog.h>
extern "C" {
@@ -11,4 +12,8 @@ void tt_app_selectiondialog_start(const char* title, int argc, const char* argv[
tt::app::selectiondialog::start(title, list);
}
int32_t tt_app_selectiondialog_get_result_index(BundleHandle handle) {
return tt::app::selectiondialog::getResultIndex(*(tt::Bundle*)handle);
}
}
@@ -1,11 +1,15 @@
#pragma once
#include "tt_bundle.h"
#ifdef __cplusplus
extern "C" {
#endif
void tt_app_selectiondialog_start(const char* title, int argc, const char* argv[]);
int32_t tt_app_selectiondialog_get_result_index(BundleHandle handle);
#ifdef __cplusplus
}
#endif
+51
View File
@@ -0,0 +1,51 @@
#include <cstring>
#include "tt_bundle.h"
#include "Bundle.h"
#define HANDLE_AS_BUNDLE(handle) ((tt::Bundle*)(handle))
extern "C" {
BundleHandle tt_bundle_alloc() {
return new tt::Bundle();
}
void tt_bundle_free(BundleHandle handle) {
delete HANDLE_AS_BUNDLE(handle);
}
bool tt_bundle_opt_bool(BundleHandle handle, const char* key, bool* out) {
return HANDLE_AS_BUNDLE(handle)->optBool(key, *out);
}
bool tt_bundle_opt_int32(BundleHandle handle, const char* key, int32_t* out) {
return HANDLE_AS_BUNDLE(handle)->optInt32(key, *out);
}
bool tt_bundle_opt_string(BundleHandle handle, const char* key, char* out, uint32_t outSize) {
std::string out_string;
if (HANDLE_AS_BUNDLE(handle)->optString(key, out_string)) {
if (out_string.length() < outSize) { // Need 1 byte to add 0 at the end
memcpy(out, out_string.c_str(), out_string.length());
out[out_string.length()] = 0x00;
return true;
} else {
return false;
}
} else {
return false;
}
}
void tt_bundle_put_bool(BundleHandle handle, const char* key, bool value) {
HANDLE_AS_BUNDLE(handle)->putBool(key, value);
}
void tt_bundle_put_int32(BundleHandle handle, const char* key, int32_t value) {
HANDLE_AS_BUNDLE(handle)->putInt32(key, value);
}
void tt_bundle_put_string(BundleHandle handle, const char* key, const char* value) {
HANDLE_AS_BUNDLE(handle)->putString(key, value);
}
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
typedef void* BundleHandle;
BundleHandle tt_bundle_alloc();
void tt_bundle_free(BundleHandle handle);
bool tt_bundle_opt_bool(BundleHandle handle, const char* key, bool* out);
bool tt_bundle_opt_int32(BundleHandle handle, const char* key, int32_t* out);
/**
* Note that outSize must be large enough to include null terminator.
* This means that your string has to be the expected text length + 1 extra character.
*/
bool tt_bundle_opt_string(BundleHandle handle, const char* key, char* out, uint32_t outSize);
void tt_bundle_put_bool(BundleHandle handle, const char* key, bool value);
void tt_bundle_put_int32(BundleHandle handle, const char* key, int32_t value);
void tt_bundle_put_string(BundleHandle handle, const char* key, const char* value);
#ifdef __cplusplus
}
#endif
@@ -2,21 +2,86 @@
#include "elf_symbol.h"
#include "app/App.h"
#include "app/SelectionDialog.h"
#include "lvgl/Toolbar.h"
#include "TactilityC/lvgl/Spinner.h"
#include "tt_app_context.h"
#include "tt_app_manifest.h"
#include "tt_app_alertdialog.h"
#include "tt_app_selectiondialog.h"
#include "tt_bundle.h"
#include "tt_lvgl_spinner.h"
#include "tt_lvgl_toolbar.h"
#include "tt_message_queue.h"
#include "tt_mutex.h"
#include "tt_semaphore.h"
#include "tt_thread.h"
#include "tt_timer.h"
#include "lvgl.h"
#include <lvgl.h>
extern "C" {
const struct esp_elfsym elf_symbols[] {
// Tactility
ESP_ELFSYM_EXPORT(tt_app_context_get_data),
ESP_ELFSYM_EXPORT(tt_app_context_set_data),
ESP_ELFSYM_EXPORT(tt_app_context_get_parameters),
ESP_ELFSYM_EXPORT(tt_app_context_set_result),
ESP_ELFSYM_EXPORT(tt_app_context_has_result),
ESP_ELFSYM_EXPORT(tt_app_selectiondialog_start),
ESP_ELFSYM_EXPORT(tt_app_selectiondialog_get_result_index),
ESP_ELFSYM_EXPORT(tt_app_alertdialog_start),
ESP_ELFSYM_EXPORT(tt_app_alertdialog_get_result_index),
ESP_ELFSYM_EXPORT(tt_bundle_alloc),
ESP_ELFSYM_EXPORT(tt_bundle_free),
ESP_ELFSYM_EXPORT(tt_bundle_opt_bool),
ESP_ELFSYM_EXPORT(tt_bundle_opt_int32),
ESP_ELFSYM_EXPORT(tt_bundle_opt_string),
ESP_ELFSYM_EXPORT(tt_bundle_put_bool),
ESP_ELFSYM_EXPORT(tt_bundle_put_int32),
ESP_ELFSYM_EXPORT(tt_bundle_put_string),
ESP_ELFSYM_EXPORT(tt_set_app_manifest),
ESP_ELFSYM_EXPORT(tt_lvgl_toolbar_create),
ESP_ELFSYM_EXPORT(tt_lvgl_toolbar_create_simple),
ESP_ELFSYM_EXPORT(tt_message_queue_alloc),
ESP_ELFSYM_EXPORT(tt_message_queue_free),
ESP_ELFSYM_EXPORT(tt_message_queue_put),
ESP_ELFSYM_EXPORT(tt_message_queue_get),
ESP_ELFSYM_EXPORT(tt_message_queue_get_capacity),
ESP_ELFSYM_EXPORT(tt_message_queue_get_message_size),
ESP_ELFSYM_EXPORT(tt_message_queue_get_count),
ESP_ELFSYM_EXPORT(tt_message_queue_reset),
ESP_ELFSYM_EXPORT(tt_mutex_alloc),
ESP_ELFSYM_EXPORT(tt_mutex_free),
ESP_ELFSYM_EXPORT(tt_mutex_lock),
ESP_ELFSYM_EXPORT(tt_mutex_unlock),
ESP_ELFSYM_EXPORT(tt_semaphore_alloc),
ESP_ELFSYM_EXPORT(tt_semaphore_free),
ESP_ELFSYM_EXPORT(tt_semaphore_acquire),
ESP_ELFSYM_EXPORT(tt_semaphore_release),
ESP_ELFSYM_EXPORT(tt_semaphore_get_count),
ESP_ELFSYM_EXPORT(tt_thread_alloc),
ESP_ELFSYM_EXPORT(tt_thread_alloc_ext),
ESP_ELFSYM_EXPORT(tt_thread_free),
ESP_ELFSYM_EXPORT(tt_thread_set_name),
ESP_ELFSYM_EXPORT(tt_thread_mark_as_static),
ESP_ELFSYM_EXPORT(tt_thread_is_marked_as_static),
ESP_ELFSYM_EXPORT(tt_thread_set_stack_size),
ESP_ELFSYM_EXPORT(tt_thread_set_callback),
ESP_ELFSYM_EXPORT(tt_thread_set_priority),
ESP_ELFSYM_EXPORT(tt_thread_set_state_callback),
ESP_ELFSYM_EXPORT(tt_thread_get_state),
ESP_ELFSYM_EXPORT(tt_thread_start),
ESP_ELFSYM_EXPORT(tt_thread_join),
ESP_ELFSYM_EXPORT(tt_thread_get_id),
ESP_ELFSYM_EXPORT(tt_thread_get_return_code),
ESP_ELFSYM_EXPORT(tt_timer_alloc),
ESP_ELFSYM_EXPORT(tt_timer_free),
ESP_ELFSYM_EXPORT(tt_timer_start),
ESP_ELFSYM_EXPORT(tt_timer_restart),
ESP_ELFSYM_EXPORT(tt_timer_stop),
ESP_ELFSYM_EXPORT(tt_timer_is_running),
ESP_ELFSYM_EXPORT(tt_timer_get_expire_time),
ESP_ELFSYM_EXPORT(tt_timer_set_pending_callback),
ESP_ELFSYM_EXPORT(tt_timer_set_thread_priority),
// tt::lvgl
ESP_ELFSYM_EXPORT(tt_lvgl_spinner_create),
// lv_obj
@@ -1,4 +1,4 @@
#include "Spinner.h"
#include "tt_lvgl_spinner.h"
#include "lvgl/Spinner.h"
extern "C" {
@@ -1,6 +1,6 @@
#pragma once
#include "lvgl.h"
#include <lvgl.h>
#ifdef __cplusplus
extern "C" {
@@ -1,5 +1,5 @@
#include "Toolbar.h"
#include "lvgl/Toolbar.h"
#include "tt_lvgl_toolbar.h"
#include <lvgl/Toolbar.h>
extern "C" {
@@ -1,7 +1,7 @@
#pragma once
#include "lvgl.h"
#include "TactilityC/app/App.h"
#include <lvgl.h>
#include "tt_app_context.h"
#ifdef __cplusplus
extern "C" {
+40
View File
@@ -0,0 +1,40 @@
#include "tt_message_queue.h"
#include <MessageQueue.h>
#define HANDLE_TO_MESSAGE_QUEUE(handle) ((tt::MessageQueue*)(handle))
extern "C" {
MessageQueueHandle tt_message_queue_alloc(uint32_t capacity, uint32_t messageSize) {
return new tt::MessageQueue(capacity, messageSize);
}
void tt_message_queue_free(MessageQueueHandle handle) {
delete HANDLE_TO_MESSAGE_QUEUE(handle);
}
bool tt_message_queue_put(MessageQueueHandle handle, const void* message, uint32_t timeout) {
return HANDLE_TO_MESSAGE_QUEUE(handle)->put(message, timeout);
}
bool tt_message_queue_get(MessageQueueHandle handle, void* message, uint32_t timeout) {
return HANDLE_TO_MESSAGE_QUEUE(handle)->get(message, timeout);
}
uint32_t tt_message_queue_get_capacity(MessageQueueHandle handle) {
return HANDLE_TO_MESSAGE_QUEUE(handle)->getCapacity();
}
uint32_t tt_message_queue_get_message_size(MessageQueueHandle handle) {
return HANDLE_TO_MESSAGE_QUEUE(handle)->getMessageSize();
}
uint32_t tt_message_queue_get_count(MessageQueueHandle handle) {
return HANDLE_TO_MESSAGE_QUEUE(handle)->getCount();
}
bool tt_message_queue_reset(MessageQueueHandle handle) {
return HANDLE_TO_MESSAGE_QUEUE(handle)->reset();
}
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
typedef void* MessageQueueHandle;
MessageQueueHandle tt_message_queue_alloc(uint32_t capacity, uint32_t messageSize);
void tt_message_queue_free(MessageQueueHandle handle);
bool tt_message_queue_put(MessageQueueHandle handle, const void* message, uint32_t timeout);
bool tt_message_queue_get(MessageQueueHandle handle, void* message, uint32_t timeout);
uint32_t tt_message_queue_get_capacity(MessageQueueHandle handle);
uint32_t tt_message_queue_get_message_size(MessageQueueHandle handle);
uint32_t tt_message_queue_get_count(MessageQueueHandle handle);
bool tt_message_queue_reset(MessageQueueHandle handle);
#ifdef __cplusplus
}
#endif
+31
View File
@@ -0,0 +1,31 @@
#include "tt_mutex.h"
#include "Mutex.h"
extern "C" {
#define HANDLE_AS_MUTEX(handle) ((tt::Mutex*)(handle))
MutexHandle tt_mutex_alloc(enum TtMutexType type) {
switch (type) {
case TtMutexType::MUTEX_TYPE_NORMAL:
return new tt::Mutex(tt::Mutex::TypeNormal);
case TtMutexType::MUTEX_TYPE_RECURSIVE:
return new tt::Mutex(tt::Mutex::TypeRecursive);
default:
tt_crash("Type not supported");
}
}
void tt_mutex_free(MutexHandle handle) {
delete HANDLE_AS_MUTEX(handle);
}
bool tt_mutex_lock(MutexHandle handle, uint32_t timeoutTicks) {
return HANDLE_AS_MUTEX(handle)->lock(timeoutTicks);
}
bool tt_mutex_unlock(MutexHandle handle) {
return HANDLE_AS_MUTEX(handle)->unlock();
}
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
typedef void* MutexHandle;
enum TtMutexType {
MUTEX_TYPE_NORMAL,
MUTEX_TYPE_RECURSIVE
};
MutexHandle tt_mutex_alloc(enum TtMutexType);
void tt_mutex_free(MutexHandle handle);
bool tt_mutex_lock(MutexHandle handle, uint32_t timeoutTicks);
bool tt_mutex_unlock(MutexHandle handle);
#ifdef __cplusplus
}
#endif
+28
View File
@@ -0,0 +1,28 @@
#include "tt_semaphore.h"
#include "Semaphore.h"
extern "C" {
#define HANDLE_AS_SEMAPHORE(handle) ((tt::Semaphore*)(handle))
SemaphoreHandle tt_semaphore_alloc(uint32_t maxCount, uint32_t initialCount) {
return new tt::Semaphore(maxCount, initialCount);
}
void tt_semaphore_free(SemaphoreHandle handle) {
delete HANDLE_AS_SEMAPHORE(handle);
}
bool tt_semaphore_acquire(SemaphoreHandle handle, uint32_t timeoutTicks) {
return HANDLE_AS_SEMAPHORE(handle)->acquire(timeoutTicks);
}
bool tt_semaphore_release(SemaphoreHandle handle) {
return HANDLE_AS_SEMAPHORE(handle)->release();
}
uint32_t tt_semaphore_get_count(SemaphoreHandle handle) {
return HANDLE_AS_SEMAPHORE(handle)->getCount();
}
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
typedef void* SemaphoreHandle;
SemaphoreHandle tt_semaphore_alloc(uint32_t maxCount, uint32_t initialCount);
void tt_semaphore_free(SemaphoreHandle handle);
bool tt_semaphore_acquire(SemaphoreHandle handle, uint32_t timeoutTicks);
bool tt_semaphore_release(SemaphoreHandle handle);
uint32_t tt_semaphore_get_count(SemaphoreHandle handle);
#ifdef __cplusplus
}
#endif
+20
View File
@@ -0,0 +1,20 @@
#include "tt_service_loader.h"
#include <Bundle.h>
#include <service/loader/Loader.h>
extern "C" {
void tt_service_loader_start_app(const char* id, bool blocking, BundleHandle _Nullable bundle) {
auto shared_bundle = std::shared_ptr<tt::Bundle>((tt::Bundle*)bundle);
tt::service::loader::startApp(id, blocking, std::move(shared_bundle));
}
void tt_service_loader_stop_app() {
tt::service::loader::stopApp();
}
AppContextHandle tt_service_loader_get_current_app() {
return tt::service::loader::getCurrentApp();
}
}
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "tt_bundle.h"
#include "tt_app_context.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @param[in] id application manifest id
* @param[in] blocking whether this operation blocks until the application is started
* @param[in] bundle an allocated bundle (or NULL) of which the memory ownership is handed over to this function
*/
void tt_service_loader_start_app(const char* id, bool blocking, BundleHandle _Nullable bundle);
void tt_service_loader_stop_app();
AppContextHandle tt_service_loader_get_current_app();
#ifdef __cplusplus
}
#endif
+78
View File
@@ -0,0 +1,78 @@
#include "tt_thread.h"
#include <Thread.h>
extern "C" {
#define HANDLE_AS_THREAD(handle) ((tt::Thread*)(handle))
ThreadHandle tt_thread_alloc() {
return new tt::Thread();
}
ThreadHandle tt_thread_alloc_ext(
const char* name,
uint32_t stackSize,
ThreadCallback callback,
void* _Nullable callbackContext
) {
return new tt::Thread(
name,
stackSize,
callback,
callbackContext
);
}
void tt_thread_free(ThreadHandle handle) {
delete HANDLE_AS_THREAD(handle);
}
void tt_thread_set_name(ThreadHandle handle, const char* name) {
HANDLE_AS_THREAD(handle)->setName(name);
}
void tt_thread_mark_as_static(ThreadHandle handle) {
HANDLE_AS_THREAD(handle)->markAsStatic();
}
bool tt_thread_is_marked_as_static(ThreadHandle handle) {
return HANDLE_AS_THREAD(handle)->isMarkedAsStatic();
}
void tt_thread_set_stack_size(ThreadHandle handle, size_t size) {
HANDLE_AS_THREAD(handle)->setStackSize(size);
}
void tt_thread_set_callback(ThreadHandle handle, ThreadCallback callback, void* _Nullable callbackContext) {
HANDLE_AS_THREAD(handle)->setCallback(callback, callbackContext);
}
void tt_thread_set_priority(ThreadHandle handle, ThreadPriority priority) {
HANDLE_AS_THREAD(handle)->setPriority((tt::Thread::Priority)priority);
}
void tt_thread_set_state_callback(ThreadHandle handle, ThreadStateCallback callback, void* _Nullable callbackContext) {
HANDLE_AS_THREAD(handle)->setStateCallback((tt::Thread::StateCallback)callback, callbackContext);
}
ThreadState tt_thread_get_state(ThreadHandle handle) {
return (ThreadState)HANDLE_AS_THREAD(handle)->getState();
}
void tt_thread_start(ThreadHandle handle) {
HANDLE_AS_THREAD(handle)->start();
}
bool tt_thread_join(ThreadHandle handle) {
return HANDLE_AS_THREAD(handle)->join();
}
ThreadId tt_thread_get_id(ThreadHandle handle) {
return HANDLE_AS_THREAD(handle)->getId();
}
int32_t tt_thread_get_return_code(ThreadHandle handle) {
return HANDLE_AS_THREAD(handle)->getReturnCode();
}
}
+74
View File
@@ -0,0 +1,74 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#ifdef ESP_PLATFORM
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#else
#include "FreeRTOS.h"
#include "task.h"
#endif
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
typedef void* ThreadHandle;
typedef enum {
ThreadStateStopped,
ThreadStateStarting,
ThreadStateRunning,
} ThreadState;
typedef TaskHandle_t ThreadId;
/** ThreadCallback Your callback to run in new thread
* @warning never use osThreadExit in Thread
*/
typedef int32_t (*ThreadCallback)(void* context);
/** 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);
typedef enum {
ThreadPriorityNone = 0, /**< Uninitialized, choose system default */
ThreadPriorityIdle = 1,
ThreadPriorityLowest = 2,
ThreadPriorityLow = 3,
ThreadPriorityNormal = 4,
ThreadPriorityHigh = 5,
ThreadPriorityHigher = 6,
ThreadPriorityHighest = 7
} ThreadPriority;
ThreadHandle tt_thread_alloc();
ThreadHandle tt_thread_alloc_ext(
const char* name,
uint32_t stackSize,
ThreadCallback callback,
void* _Nullable callbackContext
);
void tt_thread_free(ThreadHandle handle);
void tt_thread_set_name(ThreadHandle handle, const char* name);
void tt_thread_mark_as_static(ThreadHandle handle);
bool tt_thread_is_marked_as_static(ThreadHandle handle);
void tt_thread_set_stack_size(ThreadHandle handle, size_t size);
void tt_thread_set_callback(ThreadHandle handle, ThreadCallback callback, void* _Nullable callbackContext);
void tt_thread_set_priority(ThreadHandle handle, ThreadPriority priority);
void tt_thread_set_state_callback(ThreadHandle handle, ThreadStateCallback callback, void* _Nullable callbackContext);
ThreadState tt_thread_get_state(ThreadHandle handle);
void tt_thread_start(ThreadHandle handle);
bool tt_thread_join(ThreadHandle handle);
ThreadId tt_thread_get_id(ThreadHandle handle);
int32_t tt_thread_get_return_code(ThreadHandle handle);
#ifdef __cplusplus
}
#endif
+65
View File
@@ -0,0 +1,65 @@
#include "tt_timer.h"
#include <Timer.h>
struct TimerWrapper {
std::unique_ptr<tt::Timer> timer;
TimerCallback callback;
void* _Nullable callbackContext;
};
extern "C" {
static void callbackWrapper(std::shared_ptr<void> wrapper) {
auto timer_wrapper = (TimerWrapper*)wrapper.get();
timer_wrapper->callback(timer_wrapper->callbackContext);
}
TimerHandle tt_timer_alloc(TimerType type, TimerCallback callback, void* callbackContext) {
auto wrapper = std::make_shared<TimerWrapper>();
wrapper->callback = callback;
wrapper->callbackContext = callbackContext;
wrapper->timer = std::make_unique<tt::Timer>((tt::Timer::Type)type, callbackWrapper, wrapper);
return wrapper.get();
}
void tt_timer_free(TimerHandle handle) {
auto* wrapper = (TimerWrapper*)handle;
wrapper->timer = nullptr;
delete wrapper;
}
bool tt_timer_start(TimerHandle handle, uint32_t intervalTicks) {
return ((TimerWrapper*)handle)->timer->start(intervalTicks);
}
bool tt_timer_restart(TimerHandle handle, uint32_t intervalTicks) {
return ((TimerWrapper*)handle)->timer->restart(intervalTicks);
}
bool tt_timer_stop(TimerHandle handle) {
return ((TimerWrapper*)handle)->timer->stop();
}
bool tt_timer_is_running(TimerHandle handle) {
return ((TimerWrapper*)handle)->timer->isRunning();
}
uint32_t tt_timer_get_expire_time(TimerHandle handle) {
return ((TimerWrapper*)handle)->timer->getExpireTime();
}
bool tt_timer_set_pending_callback(TimerHandle handle, TimerPendingCallback callback, void* callbackContext, uint32_t arg) {
return ((TimerWrapper*)handle)->timer->setPendingCallback(
callback,
callbackContext,
arg
);
}
void tt_timer_set_thread_priority(TimerHandle handle, TimerThreadPriority priority) {
((TimerWrapper*)handle)->timer->setThreadPriority((tt::Timer::ThreadPriority)priority);
}
}
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
typedef void* TimerHandle;
typedef enum {
TimerTypeOnce = 0, ///< One-shot timer.
TimerTypePeriodic = 1 ///< Repeating timer.
} TimerType;
typedef enum {
TimerThreadPriorityNormal, /**< Lower then other threads */
TimerThreadPriorityElevated, /**< Same as other threads */
} TimerThreadPriority;
typedef void (*TimerCallback)(void* context);
typedef void (*TimerPendingCallback)(void* context, uint32_t arg);
TimerHandle tt_timer_alloc(TimerType type, TimerCallback callback, void* callbackContext);
void tt_timer_free(TimerHandle handle);
bool tt_timer_start(TimerHandle handle, uint32_t intervalTicks);
bool tt_timer_restart(TimerHandle handle, uint32_t intervalTicks);
bool tt_timer_stop(TimerHandle handle);
bool tt_timer_is_running(TimerHandle handle);
uint32_t tt_timer_get_expire_time(TimerHandle handle);
bool tt_timer_set_pending_callback(TimerHandle handle, TimerPendingCallback callback, void* callbackContext, uint32_t arg);
void tt_timer_set_thread_priority(TimerHandle handle, TimerThreadPriority priority);
#ifdef __cplusplus
}
#endif