created ServiceManifest (#5)

based on AppManifest
This commit is contained in:
Ken Van Hoeylandt
2024-01-05 19:38:39 +01:00
committed by GitHub
parent 3b9986fcef
commit e842e30ab3
39 changed files with 134 additions and 352 deletions
+1 -10
View File
@@ -10,20 +10,11 @@ extern "C" {
typedef struct _lv_obj_t lv_obj_t;
typedef enum {
AppTypeService,
AppTypeSystem,
AppTypeDesktop,
AppTypeSettings,
AppTypeUser
} AppType;
typedef enum {
AppStackSizeTiny = 512,
AppStackSizeSmall = 1024,
AppStackSizeNormal = 2048,
AppStackSizeLarge = 4096,
AppStackSizeHuge = 8192,
} AppStackSize;
typedef void (*AppOnStart)(void _Nonnull* parameter);
typedef void (*AppOnStop)();
typedef void (*AppOnShow)(lv_obj_t* parent, void* context);
+1 -5
View File
@@ -6,10 +6,6 @@
#define TAG "app_registry"
typedef struct {
const AppManifest* manifest;
} AppEntry;
DICT_DEF2(AppManifestDict, const char*, M_CSTR_DUP_OPLIST, const AppManifest*, M_PTR_OPLIST)
#define APP_REGISTRY_FOR_EACH(manifest_var_name, code_to_execute) \
@@ -17,7 +13,7 @@ DICT_DEF2(AppManifestDict, const char*, M_CSTR_DUP_OPLIST, const AppManifest*, M
app_registry_lock(); \
AppManifestDict_it_t it; \
for (AppManifestDict_it(it, app_manifest_dict); !AppManifestDict_end_p(it); AppManifestDict_next(it)) { \
const AppManifest* (manifest_var_name) = AppManifestDict_cref(it)->value; \
const AppManifest*(manifest_var_name) = AppManifestDict_cref(it)->value; \
code_to_execute; \
} \
app_registry_unlock(); \
+2 -2
View File
@@ -37,7 +37,7 @@ FURI_NORETURN void __furi_halt_implementation();
/** Crash system with message. */
#define __furi_crash(message) \
do { \
ESP_LOGE("crash", "%s\n\tat %s:%d", ((message) ? ((const char*)message) : ""), __FILE__, __LINE__); \
ESP_LOGE("crash", "%s\n\tat %s:%d", ((message) ? (message) : ""), __FILE__, __LINE__); \
__furi_crash_implementation(); \
} while (0)
@@ -50,7 +50,7 @@ FURI_NORETURN void __furi_halt_implementation();
/** Halt system with message. */
#define __furi_halt(message) \
do { \
ESP_LOGE("halt", "%s\n\tat %s:%d", ((message) ? ((const char*)message) : ""), __FILE__, __LINE__); \
ESP_LOGE("halt", "%s\n\tat %s:%d", ((message) ? (message) : ""), __FILE__, __LINE__); \
__furi_halt_implementation(); \
} while (0)
+4 -4
View File
@@ -1,19 +1,18 @@
#include "furi.h"
#include "app_manifest_registry.h"
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#define TAG "furi"
void furi_init() {
FURI_LOG_I(TAG, "init start");
furi_assert(!furi_kernel_is_irq());
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
vTaskSuspendAll();
}
furi_record_init();
xTaskResumeAll();
#if defined(__ARM_ARCH_7A__) && (__ARM_ARCH_7A__ == 0U)
@@ -24,4 +23,5 @@ void furi_init() {
#endif
app_manifest_registry_init();
FURI_LOG_I(TAG, "init complete");
}
-1
View File
@@ -10,7 +10,6 @@
#include "message_queue.h"
#include "mutex.h"
#include "pubsub.h"
#include "record.h"
#include "semaphore.h"
#include "stream_buffer.h"
#include "string.h"
-151
View File
@@ -1,151 +0,0 @@
#include "record.h"
#include "check.h"
#include "event_flag.h"
#include "mutex.h"
#include "m-dict.h"
#include "m_cstr_dup.h"
#include "log.h"
#define TAG "record"
#define FURI_RECORD_FLAG_READY (0x1)
typedef struct {
FuriEventFlag* flags;
void* data;
size_t holders_count;
} FuriRecordData;
DICT_DEF2(FuriRecordDataDict, const char*, M_CSTR_DUP_OPLIST, FuriRecordData, M_POD_OPLIST)
typedef struct {
FuriMutex* mutex;
FuriRecordDataDict_t records;
} FuriRecord;
static FuriRecord* furi_record = NULL;
static FuriRecordData* furi_record_get(const char* name) {
return FuriRecordDataDict_get(furi_record->records, name);
}
static void furi_record_put(const char* name, FuriRecordData* record_data) {
FuriRecordDataDict_set_at(furi_record->records, name, *record_data);
}
static void furi_record_erase(const char* name, FuriRecordData* record_data) {
furi_event_flag_free(record_data->flags);
FuriRecordDataDict_erase(furi_record->records, name);
}
void furi_record_init() {
furi_record = malloc(sizeof(FuriRecord));
furi_record->mutex = furi_mutex_alloc(FuriMutexTypeRecursive);
furi_check(furi_record->mutex);
FuriRecordDataDict_init(furi_record->records);
}
static FuriRecordData* furi_record_data_get_or_create(const char* name) {
furi_assert(furi_record);
FuriRecordData* record_data = furi_record_get(name);
if (!record_data) {
FuriRecordData new_record;
new_record.flags = furi_event_flag_alloc();
new_record.data = NULL;
new_record.holders_count = 0;
furi_record_put(name, &new_record);
record_data = furi_record_get(name);
}
return record_data;
}
static void furi_record_lock() {
furi_check(furi_mutex_acquire(furi_record->mutex, FuriWaitForever) == FuriStatusOk);
}
static void furi_record_unlock() {
furi_check(furi_mutex_release(furi_record->mutex) == FuriStatusOk);
}
bool furi_record_exists(const char* name) {
furi_assert(furi_record);
furi_assert(name);
bool ret = false;
furi_record_lock();
ret = (furi_record_get(name) != NULL);
furi_record_unlock();
return ret;
}
void furi_record_create(const char* name, void* data) {
furi_assert(furi_record);
furi_record_lock();
// Get record data and fill it
FuriRecordData* record_data = furi_record_data_get_or_create(name);
furi_assert(record_data->data == NULL);
record_data->data = data;
furi_event_flag_set(record_data->flags, FURI_RECORD_FLAG_READY);
furi_record_unlock();
}
bool furi_record_destroy(const char* name) {
furi_assert(furi_record);
bool ret = false;
furi_record_lock();
FuriRecordData* record_data = furi_record_get(name);
furi_assert(record_data);
if (record_data->holders_count == 0) {
furi_record_erase(name, record_data);
ret = true;
}
furi_record_unlock();
return ret;
}
void* furi_record_open(const char* name) {
furi_assert(name);
furi_assert(furi_record);
furi_record_lock();
FuriRecordData* record_data = furi_record_data_get_or_create(name);
record_data->holders_count++;
furi_record_unlock();
// Wait for record to become ready
furi_check(
furi_event_flag_wait(
record_data->flags,
FURI_RECORD_FLAG_READY,
FuriFlagWaitAny | FuriFlagNoClear,
FuriWaitForever
) == FURI_RECORD_FLAG_READY
);
return record_data->data;
}
void furi_record_close(const char* name) {
furi_assert(name);
furi_assert(furi_record);
furi_record_lock();
FuriRecordData* record_data = furi_record_get(name);
furi_assert(record_data);
record_data->holders_count--;
furi_record_unlock();
}
-80
View File
@@ -1,80 +0,0 @@
/**
* @file record.h
* Furi: record API
*/
#pragma once
#include "furi_extra_defines.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Opens a record, calls the code and then closes the record.
* @param record_name const char* that contains the name of the record
* @param variable_name the name of the variable that is used in the `code`
* @param code the code to execute: consider putting it between {}
*/
#define FURI_RECORD_TRANSACTION(record_name, variable_type, variable_name, code) \
{ \
variable_type (variable_name) = (variable_type)furi_record_open(record_name); \
code; \
furi_record_close(record_name); \
}
/** Initialize record storage For internal use only.
*/
void furi_record_init();
/** Check if record exists
*
* @param name record name
* @note Thread safe. Create and destroy must be executed from the same
* thread.
*/
bool furi_record_exists(const char* name);
/** Create record
*
* @param name record name
* @param data data pointer
* @note Thread safe. Create and destroy must be executed from the same
* thread.
*/
void furi_record_create(const char* name, void* data);
/** Destroy record
*
* @param name record name
*
* @return true if successful, false if still have holders or thread is not
* owner.
* @note Thread safe. Create and destroy must be executed from the same
* thread.
*/
bool furi_record_destroy(const char* name);
/** Open record
*
* @param name record name
*
* @return pointer to the record
* @note Thread safe. Open and close must be executed from the same
* thread. Suspends caller thread till record is available
*/
FURI_RETURNS_NONNULL void* furi_record_open(const char* name);
/** Close record
*
* @param name record name
* @note Thread safe. Open and close must be executed from the same
* thread.
*/
void furi_record_close(const char* name);
#ifdef __cplusplus
}
#endif
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*ServiceOnStart)(void _Nonnull* parameter);
typedef void (*ServiceOnStop)();
typedef struct {
/**
* The identifier by which the app is launched by the system and other apps.
*/
const char* _Nonnull id;
/**
* Non-blocking method to call when service is started.
*/
const ServiceOnStart _Nullable on_start;
/**
* Non-blocking method to call when service is stopped.
*/
const ServiceOnStop _Nullable on_stop;
} ServiceManifest;
#ifdef __cplusplus
}
#endif