| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- #pragma once
- #include "cmsis_os.h"
- #ifdef HAVE_FREERTOS
- #include <semphr.h>
- #endif
- #include <stdbool.h>
- #include <stdlib.h>
- #include <stdint.h>
- #include <string.h>
- #include <assert.h>
- #include "assets_icons.h"
- #define MAX_TASK_RECORDS 8
- #define MAX_RECORD_SUBSCRIBERS 8
- inline static void* furi_alloc(size_t size) {
- void* p = malloc(size);
- assert(p);
- return memset(p, 0, size);
- }
- /// application is just a function
- typedef void (*FlipperApplication)(void*);
- /// pointer to value callback function
- typedef void (*FlipperRecordCallback)(const void*, size_t, void*);
- typedef enum {
- FlipperRecordStateMute, ///< record open and mute this handler
- FlipperRecordStateUnmute, ///< record unmuted
- FlipperRecordStateDeleted ///< record owner halt
- } FlipperRecordState;
- /// pointer to state callback function
- typedef void (*FlipperRecordStateCallback)(FlipperRecordState, void*);
- struct _FuriRecord;
- typedef struct {
- bool allocated;
- FlipperRecordCallback cb; ///< value cb
- FlipperRecordStateCallback state_cb; ///< state cb
- uint8_t mute_counter; ///< see "wiki/FURI#mute-algorithm"
- bool no_mute;
- struct _FuriRecord* record; ///< parent record
- void* ctx;
- } FuriRecordSubscriber;
- /// FURI record handler
- struct _FuriRecord {
- const char* name;
- void* value;
- size_t size;
- StaticSemaphore_t mutex_buffer;
- SemaphoreHandle_t mutex;
- uint8_t mute_counter;
- FuriRecordSubscriber subscribers[MAX_RECORD_SUBSCRIBERS];
- };
- typedef struct _FuriRecord FuriRecord;
- /// store info about active task
- typedef struct {
- const char* name;
- FlipperApplication application;
- const char* prev_name;
- FlipperApplication prev;
- TaskHandle_t handler;
- uint8_t records_count; ///< count of records which task open
- FuriRecord* records[MAX_TASK_RECORDS]; ///< list of records which task open
- bool ready;
- } FuriApp;
- // application dependency info
- typedef struct {
- uint8_t count;
- const char** name;
- } FlipperAppLibrary;
- // application startup info
- typedef struct {
- FlipperApplication app;
- const char* name;
- FlipperAppLibrary libs;
- IconName icon;
- } FlipperStartupApp;
- // Init core
- bool furi_init(void);
- /*!
- Simply starts application.
- It call app entrypoint with param passed as argument.
- Useful for daemon applications and pop-up.
- */
- FuriApp* furiac_start(FlipperApplication app, const char* name, void* param);
- /*!
- Swtich to other application.
- FURI stop current app, call app entrypoint with param passed as
- argument and save current application entrypoint to prev field
- in current application registry.
- Useful for UI or "active" application.
- */
- void furiac_switch(FlipperApplication app, char* name, void* param);
- /*!
- Stop current application
- (stop thread and clear application's stack), start application
- from prev entry in current application registry, cleanup current
- application registry.
- */
- void furiac_exit(void* param);
- /*!
- Mark application as prepared and ready to perform actions
- */
- void furiac_ready();
- /*
- Wait for the libraries we depend on
- */
- void furiac_wait_libs(const FlipperAppLibrary* libs);
- /*!
- Stop specified app without returning to prev application.
- */
- bool furiac_kill(FuriApp* app);
- // find task pointer by handle
- FuriApp* find_task(TaskHandle_t handler);
- /*!
- Creates named FURI record.
- \param[in] name you can open this record anywhere
- \param[in] value pointer to data.
- \param[in] size size of data.
- If NULL, create FURI Pipe (only callbacks management, no data/mutex)
- Returns false if registry have not enough memory for creating.
- */
- bool furi_create_deprecated(const char* name, void* value, size_t size);
- /*!
- Opens existing FURI record by name.
- Returns NULL if record does not exist.
- \param[in] solo if true another applications handlers set into "muted" state.
- When appication has exited or record has closed, all handlers is unmuted.
- It may be useful for concurrently acces to resources like framebuffer or beeper.
- \param[in] no_mute if true, another applications cannot mute this handler.
- */
- FuriRecordSubscriber* furi_open_deprecated(
- const char* name,
- bool solo,
- bool no_mute,
- FlipperRecordCallback value_callback,
- FlipperRecordStateCallback state_callback,
- void* ctx);
- /*!
- */
- void furi_close(FuriRecordSubscriber* handler);
- /*!
- read message from record.
- Returns true if success, false otherwise (closed/non-existent record)
- Also return false if you try to read from FURI pipe
- TODO: enum return value with execution status
- */
- bool furi_read(FuriRecordSubscriber* record, void* data, size_t size);
- /*!
- write message to record.
- Returns true if success, false otherwise (closed/non-existent record or muted).
- TODO: enum return value with execution status
- */
- bool furi_write(FuriRecordSubscriber* record, const void* data, size_t size);
- /*!
- lock value mutex.
- It can be useful if records contain pointer to buffer which you want to change.
- You must call furi_give after operation on data and
- you shouldn't block executing between take and give calls
- Returns pointer to data, NULL if closed/non-existent record or muted
- TODO: enum return value with execution status
- */
- void* furi_take(FuriRecordSubscriber* record);
- /*!
- unlock value mutex.
- */
- void furi_give(FuriRecordSubscriber* record);
- /*!
- unlock value mutex and notify subscribers that data is chaned.
- */
- void furi_commit(FuriRecordSubscriber* handler);
|