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
+3
View File
@@ -5,10 +5,12 @@
namespace tt {
[[deprecated("Using this is poor software design in most scenarios")]]
typedef enum {
TtWaitForever = 0xFFFFFFFFU,
} TtWait;
[[deprecated("Define flags as needed")]]
typedef enum {
TtFlagWaitAny = 0x00000000U, ///< Wait for any flag (default).
TtFlagWaitAll = 0x00000001U, ///< Wait for all flags.
@@ -22,6 +24,7 @@ typedef enum {
TtFlagErrorISR = 0xFFFFFFFAU, ///< TtStatusErrorISR (-6).
} TtFlag;
[[deprecated("Use bool or specific type")]]
typedef enum {
TtStatusOk = 0, ///< Operation completed successfully.
TtStatusError =
+47 -19
View File
@@ -1,3 +1,4 @@
#include <kernel/Kernel.h>
#include "Dispatcher.h"
#include "Check.h"
@@ -19,32 +20,59 @@ Dispatcher::~Dispatcher() {
void Dispatcher::dispatch(Callback callback, std::shared_ptr<void> context) {
auto message = std::make_shared<DispatcherMessage>(callback, std::move(context));
// Mutate
mutex.acquire(TtWaitForever);
queue.push(std::move(message));
if (queue.size() == BACKPRESSURE_WARNING_COUNT) {
TT_LOG_W(TAG, "Backpressure: You're not consuming fast enough (100 queued)");
if (mutex.lock(1000 / portTICK_PERIOD_MS)) {
queue.push(std::move(message));
TT_LOG_I(TAG, "dispatch");
if (queue.size() == BACKPRESSURE_WARNING_COUNT) {
TT_LOG_W(TAG, "Backpressure: You're not consuming fast enough (100 queued)");
}
mutex.unlock();
// Signal
eventFlag.set(1);
} else {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
}
mutex.release();
// Signal
eventFlag.set(1);
}
uint32_t Dispatcher::consume(uint32_t timeout_ticks) {
// Wait for signal and clear
eventFlag.wait(1, TtFlagWaitAny, timeout_ticks);
eventFlag.clear(1);
// Mutate
if (mutex.acquire(1 / portTICK_PERIOD_MS) == TtStatusOk) {
auto item = queue.front();
queue.pop();
// Don't keep lock as callback might be slow
tt_check(mutex.release() == TtStatusOk);
item->callback(item->context);
TickType_t start_ticks = kernel::getTicks();
if (eventFlag.wait(1, TtFlagWaitAny, timeout_ticks) == TtStatusErrorTimeout) {
return 0;
}
return true;
TickType_t ticks_remaining = TT_MAX(timeout_ticks - (kernel::getTicks() - start_ticks), 0);
eventFlag.clear(1);
TT_LOG_I(TAG, "Dispatcher continuing");
// Mutate
bool processing = true;
uint32_t consumed = 0;
do {
if (mutex.lock(ticks_remaining / portTICK_PERIOD_MS)) {
if (!queue.empty()) {
TT_LOG_I(TAG, "Dispatcher popping from queue");
auto item = queue.front();
queue.pop();
consumed++;
processing = !queue.empty();
// Don't keep lock as callback might be slow
tt_check(mutex.unlock());
item->callback(item->context);
} else {
tt_check(mutex.unlock());
}
} else {
TT_LOG_E(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
}
} while (processing);
return consumed;
}
} // namespace
+46
View File
@@ -0,0 +1,46 @@
#include "DispatcherThread.h"
namespace tt {
int32_t dispatcherThreadMain(void* context) {
auto* dispatcherThread = (DispatcherThread*)context;
dispatcherThread->_threadMain();
return 0;
}
DispatcherThread::DispatcherThread(const std::string& threadName, size_t threadStackSize) {
thread = std::make_unique<Thread>(
threadName,
threadStackSize,
dispatcherThreadMain,
this
);
}
DispatcherThread::~DispatcherThread() {
if (thread->getState() != Thread::StateStopped) {
stop();
}
}
void DispatcherThread::_threadMain() {
do {
dispatcher.consume(1000);
} while (!interruptThread);
}
void DispatcherThread::dispatch(Callback callback, std::shared_ptr<void> context) {
dispatcher.dispatch(callback, std::move(context));
}
void DispatcherThread::start() {
interruptThread = false;
thread->start();
}
void DispatcherThread::stop() {
interruptThread = true;
thread->join();
}
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include "Dispatcher.h"
namespace tt {
/** Starts a Thread to process dispatched messages */
class DispatcherThread {
Dispatcher dispatcher;
std::unique_ptr<Thread> thread;
bool interruptThread = false;
public:
explicit DispatcherThread(const std::string& threadName, size_t threadStackSize = 4096);
~DispatcherThread();
/**
* Dispatch a message.
*/
void dispatch(Callback callback, std::shared_ptr<void> context);
/** Start the thread (blocking). */
void start();
/** Stop the thread (blocking). */
void stop();
/** Internal method */
void _threadMain();
};
}
+10
View File
@@ -0,0 +1,10 @@
#include "Lockable.h"
namespace tt {
std::unique_ptr<ScopedLockableUsage> Lockable::scoped() const {
auto* scoped = new ScopedLockableUsage(*this);
return std::unique_ptr<ScopedLockableUsage>(scoped);
}
}
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#include "Check.h"
#include <memory>
namespace tt {
class ScopedLockableUsage;
class Lockable {
public:
virtual ~Lockable() = default;
virtual bool lock(uint32_t timeoutTicks) const = 0;
virtual bool unlock() const = 0;
std::unique_ptr<ScopedLockableUsage> scoped() const;
};
class ScopedLockableUsage final : public Lockable {
const Lockable& lockable;
public:
explicit ScopedLockableUsage(const Lockable& lockable) : lockable(lockable) {}
~ScopedLockableUsage() final {
lockable.unlock(); // We don't care whether it succeeded or not
}
bool lock(uint32_t timeout) const override {
return lockable.lock(timeout);
}
bool unlock() const override {
return lockable.unlock();
}
};
}
+2
View File
@@ -1,5 +1,7 @@
#pragma once
#include "LogMessages.h"
#ifdef ESP_TARGET
#include "esp_log.h"
#else
+22
View File
@@ -0,0 +1,22 @@
/**
* Contains common log messages.
* This helps to keep the binary smaller.
*/
#pragma once
// Mutex
#define LOG_MESSAGE_MUTEX_LOCK_FAILED "Mutex acquisition timeout"
#define LOG_MESSAGE_MUTEX_LOCK_FAILED_FMT "Mutex acquisition timeout (%s)"
// SPI
#define LOG_MESSAGE_SPI_INIT_START_FMT "SPI %d init"
#define LOG_MESSAGE_SPI_INIT_FAILED_FMT "SPI %d init failed"
// I2C
#define LOG_MESSAGE_I2C_INIT_START "I2C init"
#define LOG_MESSAGE_I2C_INIT_CONFIG_FAILED "I2C config failed"
#define LOG_MESSAGE_I2C_INIT_DRIVER_INSTALL_FAILED "I2C driver install failed"
// Power on
#define LOG_MESSAGE_POWER_ON_START "Power on"
#define LOG_MESSAGE_POWER_ON_FAILED "Power on failed"
+35 -73
View File
@@ -4,9 +4,9 @@
namespace tt {
MessageQueue::MessageQueue(uint32_t msg_count, uint32_t msg_size) {
tt_assert((kernel::isIrq() == 0U) && (msg_count > 0U) && (msg_size > 0U));
queue_handle = xQueueCreate(msg_count, msg_size);
MessageQueue::MessageQueue(uint32_t capacity, uint32_t msg_size) {
tt_assert((kernel::isIrq() == 0U) && (capacity > 0U) && (msg_size > 0U));
queue_handle = xQueueCreate(capacity, msg_size);
tt_check(queue_handle);
}
@@ -15,106 +15,75 @@ MessageQueue::~MessageQueue() {
vQueueDelete(queue_handle);
}
TtStatus MessageQueue::put(const void* msg_ptr, uint32_t timeout) {
TtStatus stat;
bool MessageQueue::put(const void* message, uint32_t timeout) {
bool result = true;
BaseType_t yield;
stat = TtStatusOk;
if (kernel::isIrq() != 0U) {
if ((queue_handle == nullptr) || (msg_ptr == nullptr) || (timeout != 0U)) {
stat = TtStatusErrorParameter;
if ((queue_handle == nullptr) || (message == nullptr) || (timeout != 0U)) {
result = false;
} else {
yield = pdFALSE;
if (xQueueSendToBackFromISR(queue_handle, msg_ptr, &yield) != pdTRUE) {
stat = TtStatusErrorResource;
if (xQueueSendToBackFromISR(queue_handle, message, &yield) != pdTRUE) {
result = false;
} else {
portYIELD_FROM_ISR(yield);
}
}
} else {
if ((queue_handle == nullptr) || (msg_ptr == nullptr)) {
stat = TtStatusErrorParameter;
} else {
if (xQueueSendToBack(queue_handle, msg_ptr, (TickType_t)timeout) != pdPASS) {
if (timeout != 0U) {
stat = TtStatusErrorTimeout;
} else {
stat = TtStatusErrorResource;
}
}
}
} else if ((queue_handle == nullptr) || (message == nullptr)) {
result = false;
} else if (xQueueSendToBack(queue_handle, message, (TickType_t)timeout) != pdPASS) {
result = false;
}
/* Return execution status */
return (stat);
return result;
}
TtStatus MessageQueue::get(void* msg_ptr, uint32_t timeout_ticks) {
TtStatus stat;
bool MessageQueue::get(void* msg_ptr, uint32_t timeout_ticks) {
bool result = true;
BaseType_t yield;
stat = TtStatusOk;
if (kernel::isIrq() != 0U) {
if (kernel::isIrq()) {
if ((queue_handle == nullptr) || (msg_ptr == nullptr) || (timeout_ticks != 0U)) {
stat = TtStatusErrorParameter;
result = false;
} else {
yield = pdFALSE;
if (xQueueReceiveFromISR(queue_handle, msg_ptr, &yield) != pdPASS) {
stat = TtStatusErrorResource;
result = false;
} else {
portYIELD_FROM_ISR(yield);
}
}
} else {
if ((queue_handle == nullptr) || (msg_ptr == nullptr)) {
stat = TtStatusErrorParameter;
} else {
if (xQueueReceive(queue_handle, msg_ptr, (TickType_t)timeout_ticks) != pdPASS) {
if (timeout_ticks != 0U) {
stat = TtStatusErrorTimeout;
} else {
stat = TtStatusErrorResource;
}
}
result = false;
} else if (xQueueReceive(queue_handle, msg_ptr, (TickType_t)timeout_ticks) != pdPASS) {
result = false;
}
}
/* Return execution status */
return (stat);
return result;
}
uint32_t MessageQueue::getCapacity() const {
auto* mq = (StaticQueue_t*)(queue_handle);
uint32_t capacity;
if (mq == nullptr) {
capacity = 0U;
return 0U;
} else {
/* capacity = pxQueue->uxLength */
capacity = mq->uxDummy4[1];
return mq->uxDummy4[1];
}
/* Return maximum number of messages */
return (capacity);
}
uint32_t MessageQueue::getMessageSize() const {
auto* mq = (StaticQueue_t*)(queue_handle);
uint32_t size;
if (mq == nullptr) {
size = 0U;
return 0U;
} else {
/* size = pxQueue->uxItemSize */
size = mq->uxDummy4[2];
return mq->uxDummy4[2];
}
/* Return maximum message size */
return (size);
}
uint32_t MessageQueue::getCount() const {
@@ -129,7 +98,7 @@ uint32_t MessageQueue::getCount() const {
}
/* Return number of queued messages */
return ((uint32_t)count);
return (uint32_t)count;
}
uint32_t MessageQueue::getSpace() const {
@@ -150,24 +119,17 @@ uint32_t MessageQueue::getSpace() const {
space = (uint32_t)uxQueueSpacesAvailable((QueueHandle_t)mq);
}
/* Return number of available slots */
return (space);
return space;
}
TtStatus MessageQueue::reset() {
TtStatus stat;
if (kernel::isIrq() != 0U) {
stat = TtStatusErrorISR;
} else if (queue_handle == nullptr) {
stat = TtStatusErrorParameter;
bool MessageQueue::reset() {
tt_check(!kernel::isIrq());
if (queue_handle == nullptr) {
return false;
} else {
stat = TtStatusOk;
(void)xQueueReset(queue_handle);
xQueueReset(queue_handle);
return true;
}
/* Return execution status */
return (stat);
}
} // namespace
+26 -46
View File
@@ -19,81 +19,61 @@
namespace tt {
/**
* Message Queue implementation.
* Calls can be done from ISR/IRQ mode unless otherwise specified.
*/
class MessageQueue {
private:
QueueHandle_t queue_handle;
public:
/** Allocate message queue
*
* @param[in] msg_count The message count
* @param[in] msg_size The message size
* @param[in] capacity Maximum messages in queue
* @param[in] messageSize The size in bytes of a single message
*/
MessageQueue(uint32_t msg_count, uint32_t msg_size);
MessageQueue(uint32_t capacity, uint32_t messageSize);
~MessageQueue();
/** 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.
* @param[in] message A pointer to a message. The message will be copied into a buffer.
* @param[in] timeoutTicks
* @return success result
*/
TtStatus put(const void* msg_ptr, uint32_t timeout);
bool put(const void* message, uint32_t timeoutTicks);
/** 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.
* @param message A pointer to an already allocated message object
* @param[in] timeoutTicks
* @return success result
*/
TtStatus get(void* msg_ptr, uint32_t timeout_ticks);
bool get(void* message, uint32_t timeoutTicks);
/** Get queue capacity
*
* @param instance pointer to MessageQueue instance
*
* @return capacity in object count
/**
* @return The maximum amount of messages that can be in the queue at any given time.
*/
uint32_t getCapacity() const;
/** Get message size
*
* @param instance pointer to MessageQueue instance
*
* @return Message size in bytes
/**
* @return The size of a single message in bytes
*/
uint32_t getMessageSize() const;
/** Get message count in queue
*
* @param instance pointer to MessageQueue instance
*
* @return Message count
/**
* @return How many messages are currently in the queue.
*/
uint32_t getCount() const;
/** Get queue available space
*
* @param instance pointer to MessageQueue instance
*
* @return Message count
/**
* @return How many messages can be added to the queue before the put() method starts blocking.
*/
uint32_t getSpace() const;
/** Reset queue
*
* @param instance pointer to MessageQueue instance
*
* @return The status.
/** Reset queue (cannot be called in ISR/IRQ mode)
* @return success result
*/
TtStatus reset();
bool reset();
};
} // namespace
-5
View File
@@ -110,11 +110,6 @@ ThreadId Mutex::getOwner() const {
return (ThreadId)xSemaphoreGetMutexHolder(semaphore);
}
std::unique_ptr<ScopedMutexUsage> Mutex::scoped() const {
return std::make_unique<ScopedMutexUsage>(*this);
}
Mutex* tt_mutex_alloc(Mutex::Type type) {
return new Mutex(type);
}
+8 -27
View File
@@ -8,6 +8,7 @@
#include "Thread.h"
#include "RtosCompatSemaphore.h"
#include "Check.h"
#include "Lockable.h"
#include <memory>
namespace tt {
@@ -18,7 +19,7 @@ class ScopedMutexUsage;
* Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex
* Can be used in IRQ mode (within ISR context)
*/
class Mutex {
class Mutex : public Lockable {
public:
@@ -35,35 +36,15 @@ private:
public:
explicit Mutex(Type type = TypeNormal);
~Mutex();
~Mutex() override;
TtStatus acquire(uint32_t timeout) const;
TtStatus acquire(uint32_t timeoutTicks) const;
TtStatus release() const;
bool lock(uint32_t timeoutTicks) const override { return acquire(timeoutTicks) == TtStatusOk; }
bool unlock() const override { return release() == TtStatusOk; }
ThreadId getOwner() const;
std::unique_ptr<ScopedMutexUsage> scoped() const;
};
class ScopedMutexUsage {
const Mutex& mutex;
bool acquired = false;
public:
ScopedMutexUsage(const Mutex& mutex) : mutex(mutex) {}
~ScopedMutexUsage() {
if (acquired) {
tt_check(mutex.release() == TtStatusOk);
}
}
bool acquire(uint32_t timeout) {
TtStatus result = mutex.acquire(timeout);
acquired = (result == TtStatusOk);
return acquired;
}
};
/** Allocate Mutex
+9 -22
View File
@@ -28,49 +28,36 @@ Semaphore::~Semaphore() {
vSemaphoreDelete(handle);
}
TtStatus Semaphore::acquire(uint32_t timeout) const {
bool Semaphore::acquire(uint32_t timeout) const {
if (TT_IS_IRQ_MODE()) {
if (timeout != 0U) {
return TtStatusErrorParameter;
return false;
} else {
BaseType_t yield = pdFALSE;
if (xSemaphoreTakeFromISR(handle, &yield) != pdPASS) {
return TtStatusErrorResource;
return false;
} else {
portYIELD_FROM_ISR(yield);
return TtStatusOk;
return true;
}
}
} else {
if (xSemaphoreTake(handle, (TickType_t)timeout) != pdPASS) {
if (timeout != 0U) {
return TtStatusErrorTimeout;
} else {
return TtStatusErrorResource;
}
} else {
return TtStatusOk;
}
return xSemaphoreTake(handle, (TickType_t)timeout) == pdPASS;
}
}
TtStatus Semaphore::release() const {
bool Semaphore::release() const {
if (TT_IS_IRQ_MODE()) {
BaseType_t yield = pdFALSE;
if (xSemaphoreGiveFromISR(handle, &yield) != pdTRUE) {
return TtStatusErrorResource;
return false;
} else {
portYIELD_FROM_ISR(yield);
return TtStatusOk;
return true;
}
} else {
if (xSemaphoreGive(handle) != pdPASS) {
return TtStatusErrorResource;
} else {
return TtStatusOk;
}
return xSemaphoreGive(handle) == pdPASS;
}
}
+8 -16
View File
@@ -15,37 +15,29 @@ namespace tt {
/**
* Wrapper for xSemaphoreCreateBinary (max count == 1) and xSemaphoreCreateCounting (max count > 1)
* Can be used in IRQ mode (within ISR context)
* Can be used from IRQ/ISR mode, but cannot be created/destroyed from such a context.
*/
class Semaphore {
private:
SemaphoreHandle_t handle;
public:
/**
* Cannot be called from IRQ/ISR mode.
* @param[in] maxCount The maximum count
* @param[in] initialCount The initial count
*/
Semaphore(uint32_t maxCount, uint32_t initialCount);
/**
* @param instance The pointer to Semaphore instance
*/
/** Cannot be called from IRQ/ISR mode. */
~Semaphore();
/** Acquire semaphore
* @param[in] timeout The timeout
* @return the status
*/
TtStatus acquire(uint32_t timeout) const;
/** Acquire semaphore */
bool acquire(uint32_t timeoutTicks) const;
/** Release semaphore
* @return the status
*/
TtStatus release() const;
/** Release semaphore */
bool release() const;
/** Get semaphore count
* @return semaphore count
*/
/** @return semaphore count */
uint32_t getCount() const;
};
+2 -6
View File
@@ -66,12 +66,8 @@ bool StreamBuffer::isEmpty() const {
return xStreamBufferIsEmpty(handle) == pdTRUE;
};
TtStatus StreamBuffer::reset() const {
if (xStreamBufferReset(handle) == pdPASS) {
return TtStatusOk;
} else {
return TtStatusError;
}
bool StreamBuffer::reset() const {
return xStreamBufferReset(handle) == pdPASS;
}
} // namespace
+1 -1
View File
@@ -141,7 +141,7 @@ public:
* @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.
*/
TtStatus reset() const;
bool reset() const;
};
+4 -6
View File
@@ -13,17 +13,15 @@ int findLastIndex(const char* text, size_t from_index, char find) {
return -1;
}
bool getPathParent(const char* path, char* output) {
int index = findLastIndex(path, strlen(path) - 1, '/');
bool getPathParent(const std::string& path, std::string& output) {
int index = findLastIndex(path.c_str(), path.length() - 1, '/');
if (index == -1) {
return false;
} else if (index == 0) {
output[0] = '/';
output[1] = 0x00;
output = "/";
return true;
} else {
memcpy(output, path, index);
output[index] = 0x00;
output = path.substr(0, index);
return true;
}
}
+1 -1
View File
@@ -21,7 +21,7 @@ int findLastIndex(const char* text, size_t from_index, char find);
* @param[out] output an output buffer that is allocated to at least the size of "current"
* @return true when successful
*/
bool getPathParent(const char* path, char* output);
bool getPathParent(const std::string& path, std::string& output);
/**
* Given a filesystem path as input, get the last segment of a path
+13 -26
View File
@@ -37,33 +37,22 @@ Timer::~Timer() {
tt_check(xTimerDelete(timerHandle, portMAX_DELAY) == pdPASS);
}
TtStatus Timer::start(uint32_t ticks) {
bool Timer::start(uint32_t intervalTicks) {
tt_assert(!kernel::isIrq());
tt_assert(ticks < portMAX_DELAY);
if (xTimerChangePeriod(timerHandle, ticks, portMAX_DELAY) == pdPASS) {
return TtStatusOk;
} else {
return TtStatusErrorResource;
}
tt_assert(intervalTicks < portMAX_DELAY);
return xTimerChangePeriod(timerHandle, intervalTicks, portMAX_DELAY) == pdPASS;
}
TtStatus Timer::restart(uint32_t ticks) {
bool Timer::restart(uint32_t intervalTicks) {
tt_assert(!kernel::isIrq());
tt_assert(ticks < portMAX_DELAY);
if (xTimerChangePeriod(timerHandle, ticks, portMAX_DELAY) == pdPASS &&
xTimerReset(timerHandle, portMAX_DELAY) == pdPASS) {
return TtStatusOk;
} else {
return TtStatusErrorResource;
}
tt_assert(intervalTicks < portMAX_DELAY);
return xTimerChangePeriod(timerHandle, intervalTicks, portMAX_DELAY) == pdPASS &&
xTimerReset(timerHandle, portMAX_DELAY) == pdPASS;
}
TtStatus Timer::stop() {
bool Timer::stop() {
tt_assert(!kernel::isIrq());
tt_check(xTimerStop(timerHandle, portMAX_DELAY) == pdPASS);
return TtStatusOk;
return xTimerStop(timerHandle, portMAX_DELAY) == pdPASS;
}
bool Timer::isRunning() {
@@ -76,17 +65,15 @@ uint32_t Timer::getExpireTime() {
return (uint32_t)xTimerGetExpiryTime(timerHandle);
}
void Timer::pendingCallback(PendingCallback callback, void* callbackContext, uint32_t arg) {
BaseType_t ret = pdFAIL;
bool Timer::setPendingCallback(PendingCallback callback, void* callbackContext, uint32_t arg) {
if (kernel::isIrq()) {
ret = xTimerPendFunctionCallFromISR(callback, callbackContext, arg, nullptr);
return xTimerPendFunctionCallFromISR(callback, callbackContext, arg, nullptr) == pdPASS;
} else {
ret = xTimerPendFunctionCall(callback, callbackContext, arg, TtWaitForever);
return xTimerPendFunctionCall(callback, callbackContext, arg, TtWaitForever) == pdPASS;
}
tt_assert(ret == pdPASS);
}
void Timer::setThreadPriority(TimerThreadPriority priority) {
void Timer::setThreadPriority(ThreadPriority priority) {
tt_assert(!kernel::isIrq());
TaskHandle_t task_handle = xTimerGetTimerDaemonTaskHandle();
+9 -10
View File
@@ -15,7 +15,6 @@ public:
typedef void (*Callback)(std::shared_ptr<void> context);
typedef void (*PendingCallback)(void* context, uint32_t arg);
Callback callback;
std::shared_ptr<void> callbackContext;
@@ -39,9 +38,9 @@ public:
* timer service process this request.
*
* @param[in] ticks The interval in ticks
* @return The status.
* @return success result
*/
TtStatus start(uint32_t ticks);
bool start(uint32_t intervalTicks);
/** Restart timer with previous timeout value
*
@@ -50,9 +49,9 @@ public:
*
* @param[in] ticks The interval in ticks
*
* @return The status.
* @return success result
*/
TtStatus restart(uint32_t ticks);
bool restart(uint32_t intervalTicks);
/** Stop timer
@@ -60,9 +59,9 @@ public:
* @warning This is asynchronous call, real operation will happen as soon as
* timer service process this request.
*
* @return The status.
* @return success result
*/
TtStatus stop();
bool stop();
/** Is timer running
*
@@ -82,18 +81,18 @@ public:
*/
uint32_t getExpireTime();
void pendingCallback(PendingCallback callback, void* callbackContext, uint32_t arg);
bool setPendingCallback(PendingCallback callback, void* callbackContext, uint32_t arg);
typedef enum {
TimerThreadPriorityNormal, /**< Lower then other threads */
TimerThreadPriorityElevated, /**< Same as other threads */
} TimerThreadPriority;
} ThreadPriority;
/** Set Timer thread priority
*
* @param[in] priority The priority
*/
void setThreadPriority(TimerThreadPriority priority);
void setThreadPriority(ThreadPriority priority);
};
} // namespace
+6 -6
View File
@@ -26,17 +26,17 @@ long getSize(FILE* file) {
return file_size;
}
static std::unique_ptr<uint8_t[]> readBinaryInternal(const char* filepath, size_t& outSize, size_t sizePadding = 0) {
FILE* file = fopen(filepath, "rb");
static std::unique_ptr<uint8_t[]> readBinaryInternal(const std::string& filepath, size_t& outSize, size_t sizePadding = 0) {
FILE* file = fopen(filepath.c_str(), "rb");
if (file == nullptr) {
TT_LOG_E(TAG, "Failed to open %s", filepath);
TT_LOG_E(TAG, "Failed to open %s", filepath.c_str());
return nullptr;
}
long content_length = getSize(file);
if (content_length == -1) {
TT_LOG_E(TAG, "Failed to determine content length for %s", filepath);
TT_LOG_E(TAG, "Failed to determine content length for %s", filepath.c_str());
return nullptr;
}
@@ -64,11 +64,11 @@ static std::unique_ptr<uint8_t[]> readBinaryInternal(const char* filepath, size_
return data;
}
std::unique_ptr<uint8_t[]> readBinary(const char* filepath, size_t& outSize) {
std::unique_ptr<uint8_t[]> readBinary(const std::string& filepath, size_t& outSize) {
return readBinaryInternal(filepath, outSize);
}
std::unique_ptr<uint8_t[]> readString(const char* filepath) {
std::unique_ptr<uint8_t[]> readString(const std::string& filepath) {
size_t size = 0;
auto data = readBinaryInternal(filepath, size, 1);
if (size > 0) {
+2 -2
View File
@@ -7,7 +7,7 @@ namespace tt::file {
long getSize(FILE* file);
std::unique_ptr<uint8_t[]> readBinary(const char* filepath, size_t& outSize);
std::unique_ptr<uint8_t[]> readString(const char* filepath);
std::unique_ptr<uint8_t[]> readBinary(const std::string& filepath, size_t& outSize);
std::unique_ptr<uint8_t[]> readString(const std::string& filepath);
}