Update docs and fix bugs (#149)

Improved the docs for the 3 main Tactility projects. I also fixed some inaccuracies and bugs in certain APIs as I went through the code.
This commit is contained in:
Ken Van Hoeylandt
2025-01-07 20:45:23 +01:00
committed by GitHub
parent ff4287e2ce
commit 415096c3b2
62 changed files with 503 additions and 517 deletions
+13 -7
View File
@@ -7,17 +7,23 @@
namespace tt {
typedef struct {
/** @brief The configuration for the operating system
* It contains the hardware configuration, apps and services
*/
struct Configuration {
/** HAL configuration (drivers) */
const hal::Configuration* hardware;
// List of user applications
const app::AppManifest* const apps[TT_CONFIG_APPS_LIMIT];
const service::ServiceManifest* const services[TT_CONFIG_SERVICES_LIMIT];
const char* autoStartAppId;
} Configuration;
/** List of user applications */
const app::AppManifest* const apps[TT_CONFIG_APPS_LIMIT] = {};
/** List of user services */
const service::ServiceManifest* const services[TT_CONFIG_SERVICES_LIMIT] = {};
/** Optional app to start automatically after the splash screen. */
const char* _Nullable autoStartAppId = nullptr;
};
/**
* Attempts to initialize Tactility and all configured hardware.
* @param config
* @param[in] config
*/
void run(const Configuration& config);
+2 -2
View File
@@ -16,8 +16,8 @@ typedef union {
} Flags;
/**
* A limited representation of the application instance.
* Do not store references or pointers to these!
* The public representation of an application instance.
* @warning Do not store references or pointers to these! You can retrieve them via the service registry.
*/
class AppContext {
+13 -29
View File
@@ -11,7 +11,8 @@ namespace tt::app {
class AppContext;
typedef enum {
/** Application types */
enum Type {
/** Boot screen, shown before desktop is launched. */
TypeBoot,
/** A desktop app sits at the root of the app stack managed by the Loader service */
@@ -24,8 +25,9 @@ typedef enum {
TypeSettings,
/** User-provided apps. */
TypeUser
} Type;
};
/** Result status code for application result callback. */
typedef enum {
ResultOk,
ResultCancelled,
@@ -39,49 +41,31 @@ typedef void (*AppOnHide)(AppContext& app);
typedef void (*AppOnResult)(AppContext& app, Result result, const Bundle& resultData);
struct AppManifest {
/**
* The identifier by which the app is launched by the system and other apps.
*/
/** The identifier by which the app is launched by the system and other apps. */
std::string id;
/**
* The user-readable name of the app. Used in UI.
*/
/** The user-readable name of the app. Used in UI. */
std::string name;
/**
* Optional icon.
*/
/** Optional icon. */
std::string icon = {};
/**
* App type affects launch behaviour.
*/
/** App type affects launch behaviour. */
Type type = TypeUser;
/**
* Non-blocking method to call when app is started.
*/
/** Non-blocking method to call when app is started. */
AppOnStart onStart = nullptr;
/**
* Non-blocking method to call when app is stopped.
*/
/** Non-blocking method to call when app is stopped. */
AppOnStop _Nullable onStop = nullptr;
/**
* Non-blocking method to create the GUI
*/
/** Non-blocking method to create the GUI. */
AppOnShow _Nullable onShow = nullptr;
/**
* Non-blocking method, called before gui is destroyed
*/
/** Non-blocking method, called before gui is destroyed. */
AppOnHide _Nullable onHide = nullptr;
/**
* Handle the result for apps that are launched
*/
/** Handle the result for apps that are launched. */
AppOnResult _Nullable onResult = nullptr;
};
+1 -1
View File
@@ -22,7 +22,7 @@ bool startElfApp(const std::string& filePath) {
assert(elfFileData == nullptr);
size_t size = 0;
elfFileData = file::readBinary(filePath.c_str(), size);
elfFileData = file::readBinary(filePath, size);
if (elfFileData == nullptr) {
return false;
}
+8
View File
@@ -6,8 +6,16 @@
namespace tt::app {
/** Register an application with its manifest */
void addApp(const AppManifest* manifest);
/** Find an application manifest by its id
* @param[in] id the manifest id
* @return the application manifest if it was found
*/
const AppManifest _Nullable* findAppById(const std::string& id);
/** @return a list of all registered apps. This includes user and system apps. */
std::vector<const AppManifest*> getApps();
} // namespace
@@ -9,10 +9,10 @@
#include <esp_cpu_utils.h>
std::string getUrlFromCrashData() {
auto* crash_data = getRtcCrashData();
auto* stack_buffer = (uint32_t*) malloc(crash_data->callstackLength * 2 * sizeof(uint32_t));
for (int i = 0; i < crash_data->callstackLength; ++i) {
const CallstackFrame&frame = crash_data->callstack[i];
auto crash_data = getRtcCrashData();
auto* stack_buffer = (uint32_t*) malloc(crash_data.callstackLength * 2 * sizeof(uint32_t));
for (int i = 0; i < crash_data.callstackLength; ++i) {
const CallstackFrame&frame = crash_data.callstack[i];
uint32_t pc = esp_cpu_process_stack_pc(frame.pc);
#if CRASH_DATA_INCLUDES_SP
uint32_t sp = frame.sp;
@@ -30,7 +30,7 @@ std::string getUrlFromCrashData() {
stream << "&a=" << CONFIG_IDF_TARGET; // Architecture
stream << "&s="; // Stacktrace
for (int i = crash_data->callstackLength - 1; i >= 0; --i) {
for (int i = crash_data.callstackLength - 1; i >= 0; --i) {
uint32_t pc = stack_buffer[(i * 2)];
stream << std::hex << pc;
#if CRASH_DATA_INCLUDES_SP
+6 -6
View File
@@ -3,10 +3,10 @@
namespace tt::lvgl {
Mutex lockMutex;
static Mutex lockMutex;
static bool defaultLock(uint32_t timeoutTicks) {
return lockMutex.acquire(timeoutTicks) == TtStatusOk;
static bool defaultLock(uint32_t timeoutMillis) {
return lockMutex.acquire(timeoutMillis) == TtStatusOk;
}
static void defaultUnlock() {
@@ -21,8 +21,8 @@ void syncSet(LvglLock lock, LvglUnlock unlock) {
unlock_singleton = unlock;
}
bool lock(uint32_t timeout_ticks) {
return lock_singleton(timeout_ticks);
bool lock(TickType_t timeout) {
return lock_singleton(pdMS_TO_TICKS(timeout == 0 ? portMAX_DELAY : timeout));
}
void unlock() {
@@ -33,7 +33,7 @@ class LvglSync : public Lockable {
public:
~LvglSync() override = default;
bool lock(uint32_t timeoutTicks) const override {
bool lock(TickType_t timeoutTicks) const override {
return tt::lvgl::lock(timeoutTicks);
}
+14 -3
View File
@@ -6,12 +6,23 @@
namespace tt::lvgl {
typedef bool (*LvglLock)(uint32_t timeout_ticks);
/**
* LVGL locking function
* @param[in] timeoutMillis timeout in milliseconds. waits forever when 0 is passed.
* @warning this works with milliseconds, as opposed to every other FreeRTOS function that works in ticks!
* @warning when passing zero, we wait forever, as this is the default behaviour for esp_lvgl_port, and we want it to remain consistent
*/
typedef bool (*LvglLock)(uint32_t timeoutMillis);
typedef void (*LvglUnlock)();
void syncSet(LvglLock lock, LvglUnlock unlock);
bool isSyncSet();
bool lock(uint32_t timeout_ticks);
/**
* LVGL locking function
* @param[in] timeout as ticks
* @warning when passing zero, we wait forever, as this is the default behaviour for esp_lvgl_port, and we want it to remain consistent
*/
bool lock(TickType_t timeout);
void unlock();
std::shared_ptr<Lockable> getLvglSyncLockable();
+6 -7
View File
@@ -9,12 +9,11 @@ typedef struct Gui Gui;
/**
* Set the app viewport in the gui state and request the gui to draw it.
*
* @param app
* @param on_show
* @param on_hide
* @param[in] app
* @param[in] onShow
* @param[in] onHide
*/
void showApp(app::AppContext& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide);
void showApp(app::AppContext& app, ViewPortShowCallback onShow, ViewPortHideCallback onHide);
/**
* Hide the current app's viewport.
@@ -25,7 +24,7 @@ void hideApp();
/**
* Show the on-screen keyboard.
* @param textarea the textarea to focus the input for
* @param[in] textarea the textarea to focus the input for
*/
void keyboardShow(lv_obj_t* textarea);
@@ -47,7 +46,7 @@ bool keyboardIsEnabled();
* Glue code for the on-screen keyboard and the hardware keyboard:
* - Attach automatic hide/show parameters for the on-screen keyboard.
* - Registers the textarea to the default lv_group_t for hardware keyboards.
* @param textarea
* @param[in] textarea
*/
void keyboardAddTextArea(lv_obj_t* textarea);
+8 -12
View File
@@ -26,26 +26,22 @@ typedef struct ViewPort {
} ViewPort;
/** ViewPort allocator
*
* always returns view_port or stops system if not enough memory.
* @param app
* @param on_show Called to create LVGL widgets
* @param on_hide Called before clearing the LVGL widget parent
*
* @return ViewPort instance
* @param onShow Called to create LVGL widgets
* @param onHide Called before clearing the LVGL widget parent
* @return ViewPort instance
*/
ViewPort* view_port_alloc(
app::AppContext& app,
ViewPortShowCallback on_show,
ViewPortHideCallback on_hide
ViewPortShowCallback onShow,
ViewPortHideCallback onHide
);
/** ViewPort deallocator
*
/** ViewPort destruction
* Ensure that view_port was unregistered in GUI system before use.
*
* @param view_port ViewPort instance
* @param viewPort ViewPort instance
*/
void view_port_free(ViewPort* view_port);
void view_port_free(ViewPort* viewPort);
} // namespace
+2 -3
View File
@@ -26,11 +26,10 @@ typedef enum {
*/
void startApp(const std::string& id, bool blocking = false, std::shared_ptr<const Bundle> _Nullable parameters = nullptr);
/**
* @brief Stop the currently showing app. Show the previous app if any app was still running.
*/
/** @brief Stop the currently showing app. Show the previous app if any app was still running. */
void stopApp();
/** @return the currently running app (it is only ever null before the splash screen is shown) */
app::AppContext* _Nullable getCurrentApp();
/**
@@ -39,7 +39,7 @@ void ScreenshotService::startApps(const char* path) {
}
}
void ScreenshotService::startTimed(const char* path, uint8_t delay_in_seconds, uint8_t amount) {
void ScreenshotService::startTimed(const char* path, uint8_t delayInSeconds, uint8_t amount) {
auto scoped_lockable = mutex.scoped();
if (!scoped_lockable->lock(50 / portTICK_PERIOD_MS)) {
TT_LOG_W(TAG, LOG_MESSAGE_MUTEX_LOCK_FAILED);
@@ -49,7 +49,7 @@ void ScreenshotService::startTimed(const char* path, uint8_t delay_in_seconds, u
if (task == nullptr || task->isFinished()) {
task = std::make_unique<ScreenshotTask>();
mode = ScreenshotModeTimed;
task->startTimed(path, delay_in_seconds, amount);
task->startTimed(path, delayInSeconds, amount);
} else {
TT_LOG_W(TAG, "Screenshot task already running");
}
@@ -16,8 +16,10 @@ typedef enum {
ScreenshotModeApps
} Mode;
class ScreenshotService {
private:
Mutex mutex;
std::unique_ptr<ScreenshotTask> task;
Mode mode = ScreenshotModeNone;
@@ -25,9 +27,23 @@ class ScreenshotService {
public:
bool isTaskStarted();
/** The state of the service. */
Mode getMode();
/** @brief Start taking screenshot whenever an app is started
* @param[in] path the path to store the screenshots at
*/
void startApps(const char* path);
void startTimed(const char* path, uint8_t delay_in_seconds, uint8_t amount);
/** @brief Start taking screenshots after a certain delay
* @param[in] path the path to store the screenshots at
* @param[in] delayInSeconds the delay before starting (and between successive screenshots)
* @param[in] amount 0 = indefinite, >0 for a specific
*/
void startTimed(const char* path, uint8_t delayInSeconds, uint8_t amount);
/** @brief Stop taking screenshots */
void stop();
};
@@ -35,22 +35,18 @@ public:
~ScreenshotTask();
/** @brief Start taking screenshots after a certain delay
* @param task the screenshot task
* @param path the path to store the screenshots at
* @param delay_in_seconds the delay before starting (and between successive screenshots)
* @param amount 0 = indefinite, >0 for a specific
* @param[in] path the path to store the screenshots at
* @param[in] delayInSeconds the delay before starting (and between successive screenshots)
* @param[in] amount 0 = indefinite, >0 for a specific
*/
void startTimed(const char* path, uint8_t delay_in_seconds, uint8_t amount);
void startTimed(const char* path, uint8_t delayInSeconds, uint8_t amount);
/** @brief Start taking screenshot whenever an app is started
* @param task the screenshot task
* @param path the path to store the screenshots at
* @param[in] path the path to store the screenshots at
*/
void startApps(const char* path);
/** @brief Stop taking screenshots
* @param task the screenshot task
*/
/** @brief Stop taking screenshots */
void stop();
void taskMain();