[Fl-3147] Remove ValueMutex (#2467)
* Move keypad_test to furi_mutex * Move text_box_test to furi_mutex * Move snake_game to furi_mutex * Remove ValueMutex completely * Snake Game: simplify code and fix PVS warning * F18: sync API symbols Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
eefca9f498
commit
9819306731
@ -11,6 +11,7 @@ typedef struct {
|
|||||||
uint16_t left;
|
uint16_t left;
|
||||||
uint16_t right;
|
uint16_t right;
|
||||||
uint16_t ok;
|
uint16_t ok;
|
||||||
|
FuriMutex* mutex;
|
||||||
} KeypadTestState;
|
} KeypadTestState;
|
||||||
|
|
||||||
static void keypad_test_reset_state(KeypadTestState* state) {
|
static void keypad_test_reset_state(KeypadTestState* state) {
|
||||||
@ -22,7 +23,8 @@ static void keypad_test_reset_state(KeypadTestState* state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void keypad_test_render_callback(Canvas* canvas, void* ctx) {
|
static void keypad_test_render_callback(Canvas* canvas, void* ctx) {
|
||||||
KeypadTestState* state = (KeypadTestState*)acquire_mutex((ValueMutex*)ctx, 25);
|
KeypadTestState* state = ctx;
|
||||||
|
furi_mutex_acquire(state->mutex, FuriWaitForever);
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
char strings[5][20];
|
char strings[5][20];
|
||||||
|
|
||||||
@ -51,7 +53,7 @@ static void keypad_test_render_callback(Canvas* canvas, void* ctx) {
|
|||||||
|
|
||||||
canvas_draw_str(canvas, 10, 63, "[back] - reset, hold to exit");
|
canvas_draw_str(canvas, 10, 63, "[back] - reset, hold to exit");
|
||||||
|
|
||||||
release_mutex((ValueMutex*)ctx, state);
|
furi_mutex_release(state->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keypad_test_input_callback(InputEvent* input_event, void* ctx) {
|
static void keypad_test_input_callback(InputEvent* input_event, void* ctx) {
|
||||||
@ -64,17 +66,17 @@ int32_t keypad_test_app(void* p) {
|
|||||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
||||||
furi_check(event_queue);
|
furi_check(event_queue);
|
||||||
|
|
||||||
KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0};
|
KeypadTestState state = {{false, false, false, false, false}, 0, 0, 0, 0, 0, NULL};
|
||||||
|
state.mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
|
|
||||||
ValueMutex state_mutex;
|
if(!state.mutex) {
|
||||||
if(!init_mutex(&state_mutex, &_state, sizeof(KeypadTestState))) {
|
|
||||||
FURI_LOG_E(TAG, "cannot create mutex");
|
FURI_LOG_E(TAG, "cannot create mutex");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewPort* view_port = view_port_alloc();
|
ViewPort* view_port = view_port_alloc();
|
||||||
|
|
||||||
view_port_draw_callback_set(view_port, keypad_test_render_callback, &state_mutex);
|
view_port_draw_callback_set(view_port, keypad_test_render_callback, &state);
|
||||||
view_port_input_callback_set(view_port, keypad_test_input_callback, event_queue);
|
view_port_input_callback_set(view_port, keypad_test_input_callback, event_queue);
|
||||||
|
|
||||||
// Open GUI and register view_port
|
// Open GUI and register view_port
|
||||||
@ -83,7 +85,7 @@ int32_t keypad_test_app(void* p) {
|
|||||||
|
|
||||||
InputEvent event;
|
InputEvent event;
|
||||||
while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||||
KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex);
|
furi_mutex_acquire(state.mutex, FuriWaitForever);
|
||||||
FURI_LOG_I(
|
FURI_LOG_I(
|
||||||
TAG,
|
TAG,
|
||||||
"key: %s type: %s",
|
"key: %s type: %s",
|
||||||
@ -92,54 +94,54 @@ int32_t keypad_test_app(void* p) {
|
|||||||
|
|
||||||
if(event.key == InputKeyRight) {
|
if(event.key == InputKeyRight) {
|
||||||
if(event.type == InputTypePress) {
|
if(event.type == InputTypePress) {
|
||||||
state->press[0] = true;
|
state.press[0] = true;
|
||||||
} else if(event.type == InputTypeRelease) {
|
} else if(event.type == InputTypeRelease) {
|
||||||
state->press[0] = false;
|
state.press[0] = false;
|
||||||
} else if(event.type == InputTypeShort) {
|
} else if(event.type == InputTypeShort) {
|
||||||
++state->right;
|
++state.right;
|
||||||
}
|
}
|
||||||
} else if(event.key == InputKeyLeft) {
|
} else if(event.key == InputKeyLeft) {
|
||||||
if(event.type == InputTypePress) {
|
if(event.type == InputTypePress) {
|
||||||
state->press[1] = true;
|
state.press[1] = true;
|
||||||
} else if(event.type == InputTypeRelease) {
|
} else if(event.type == InputTypeRelease) {
|
||||||
state->press[1] = false;
|
state.press[1] = false;
|
||||||
} else if(event.type == InputTypeShort) {
|
} else if(event.type == InputTypeShort) {
|
||||||
++state->left;
|
++state.left;
|
||||||
}
|
}
|
||||||
} else if(event.key == InputKeyUp) {
|
} else if(event.key == InputKeyUp) {
|
||||||
if(event.type == InputTypePress) {
|
if(event.type == InputTypePress) {
|
||||||
state->press[2] = true;
|
state.press[2] = true;
|
||||||
} else if(event.type == InputTypeRelease) {
|
} else if(event.type == InputTypeRelease) {
|
||||||
state->press[2] = false;
|
state.press[2] = false;
|
||||||
} else if(event.type == InputTypeShort) {
|
} else if(event.type == InputTypeShort) {
|
||||||
++state->up;
|
++state.up;
|
||||||
}
|
}
|
||||||
} else if(event.key == InputKeyDown) {
|
} else if(event.key == InputKeyDown) {
|
||||||
if(event.type == InputTypePress) {
|
if(event.type == InputTypePress) {
|
||||||
state->press[3] = true;
|
state.press[3] = true;
|
||||||
} else if(event.type == InputTypeRelease) {
|
} else if(event.type == InputTypeRelease) {
|
||||||
state->press[3] = false;
|
state.press[3] = false;
|
||||||
} else if(event.type == InputTypeShort) {
|
} else if(event.type == InputTypeShort) {
|
||||||
++state->down;
|
++state.down;
|
||||||
}
|
}
|
||||||
} else if(event.key == InputKeyOk) {
|
} else if(event.key == InputKeyOk) {
|
||||||
if(event.type == InputTypePress) {
|
if(event.type == InputTypePress) {
|
||||||
state->press[4] = true;
|
state.press[4] = true;
|
||||||
} else if(event.type == InputTypeRelease) {
|
} else if(event.type == InputTypeRelease) {
|
||||||
state->press[4] = false;
|
state.press[4] = false;
|
||||||
} else if(event.type == InputTypeShort) {
|
} else if(event.type == InputTypeShort) {
|
||||||
++state->ok;
|
++state.ok;
|
||||||
}
|
}
|
||||||
} else if(event.key == InputKeyBack) {
|
} else if(event.key == InputKeyBack) {
|
||||||
if(event.type == InputTypeLong) {
|
if(event.type == InputTypeLong) {
|
||||||
release_mutex(&state_mutex, state);
|
furi_mutex_release(state.mutex);
|
||||||
break;
|
break;
|
||||||
} else if(event.type == InputTypeShort) {
|
} else if(event.type == InputTypeShort) {
|
||||||
keypad_test_reset_state(state);
|
keypad_test_reset_state(&state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release_mutex(&state_mutex, state);
|
furi_mutex_release(state.mutex);
|
||||||
view_port_update(view_port);
|
view_port_update(view_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +149,7 @@ int32_t keypad_test_app(void* p) {
|
|||||||
gui_remove_view_port(gui, view_port);
|
gui_remove_view_port(gui, view_port);
|
||||||
view_port_free(view_port);
|
view_port_free(view_port);
|
||||||
furi_message_queue_free(event_queue);
|
furi_message_queue_free(event_queue);
|
||||||
delete_mutex(&state_mutex);
|
furi_mutex_free(state.mutex);
|
||||||
|
|
||||||
furi_record_close(RECORD_GUI);
|
furi_record_close(RECORD_GUI);
|
||||||
|
|
||||||
|
@ -53,15 +53,17 @@ static void (*text_box_test_render[])(Canvas* canvas) = {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
|
FuriMutex* mutex;
|
||||||
} TextBoxTestState;
|
} TextBoxTestState;
|
||||||
|
|
||||||
static void text_box_test_render_callback(Canvas* canvas, void* ctx) {
|
static void text_box_test_render_callback(Canvas* canvas, void* ctx) {
|
||||||
TextBoxTestState* state = acquire_mutex((ValueMutex*)ctx, 25);
|
TextBoxTestState* state = ctx;
|
||||||
|
furi_mutex_acquire(state->mutex, FuriWaitForever);
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
|
|
||||||
text_box_test_render[state->idx](canvas);
|
text_box_test_render[state->idx](canvas);
|
||||||
|
|
||||||
release_mutex((ValueMutex*)ctx, state);
|
furi_mutex_release(state->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void text_box_test_input_callback(InputEvent* input_event, void* ctx) {
|
static void text_box_test_input_callback(InputEvent* input_event, void* ctx) {
|
||||||
@ -74,17 +76,17 @@ int32_t text_box_test_app(void* p) {
|
|||||||
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent));
|
||||||
furi_check(event_queue);
|
furi_check(event_queue);
|
||||||
|
|
||||||
TextBoxTestState _state = {.idx = 0};
|
TextBoxTestState state = {.idx = 0, .mutex = NULL};
|
||||||
|
state.mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
|
|
||||||
ValueMutex state_mutex;
|
if(!state.mutex) {
|
||||||
if(!init_mutex(&state_mutex, &_state, sizeof(TextBoxTestState))) {
|
|
||||||
FURI_LOG_E(TAG, "Cannot create mutex");
|
FURI_LOG_E(TAG, "Cannot create mutex");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewPort* view_port = view_port_alloc();
|
ViewPort* view_port = view_port_alloc();
|
||||||
|
|
||||||
view_port_draw_callback_set(view_port, text_box_test_render_callback, &state_mutex);
|
view_port_draw_callback_set(view_port, text_box_test_render_callback, &state);
|
||||||
view_port_input_callback_set(view_port, text_box_test_input_callback, event_queue);
|
view_port_input_callback_set(view_port, text_box_test_input_callback, event_queue);
|
||||||
|
|
||||||
// Open GUI and register view_port
|
// Open GUI and register view_port
|
||||||
@ -94,24 +96,24 @@ int32_t text_box_test_app(void* p) {
|
|||||||
uint32_t test_renders_num = COUNT_OF(text_box_test_render);
|
uint32_t test_renders_num = COUNT_OF(text_box_test_render);
|
||||||
InputEvent event;
|
InputEvent event;
|
||||||
while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) {
|
||||||
TextBoxTestState* state = acquire_mutex_block(&state_mutex);
|
furi_mutex_acquire(state.mutex, FuriWaitForever);
|
||||||
|
|
||||||
if(event.type == InputTypeShort) {
|
if(event.type == InputTypeShort) {
|
||||||
if(event.key == InputKeyRight) {
|
if(event.key == InputKeyRight) {
|
||||||
if(state->idx < test_renders_num - 1) {
|
if(state.idx < test_renders_num - 1) {
|
||||||
state->idx++;
|
state.idx++;
|
||||||
}
|
}
|
||||||
} else if(event.key == InputKeyLeft) {
|
} else if(event.key == InputKeyLeft) {
|
||||||
if(state->idx > 0) {
|
if(state.idx > 0) {
|
||||||
state->idx--;
|
state.idx--;
|
||||||
}
|
}
|
||||||
} else if(event.key == InputKeyBack) {
|
} else if(event.key == InputKeyBack) {
|
||||||
release_mutex(&state_mutex, state);
|
furi_mutex_release(state.mutex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release_mutex(&state_mutex, state);
|
furi_mutex_release(state.mutex);
|
||||||
view_port_update(view_port);
|
view_port_update(view_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +121,7 @@ int32_t text_box_test_app(void* p) {
|
|||||||
gui_remove_view_port(gui, view_port);
|
gui_remove_view_port(gui, view_port);
|
||||||
view_port_free(view_port);
|
view_port_free(view_port);
|
||||||
furi_message_queue_free(event_queue);
|
furi_message_queue_free(event_queue);
|
||||||
delete_mutex(&state_mutex);
|
furi_mutex_free(state.mutex);
|
||||||
|
|
||||||
furi_record_close(RECORD_GUI);
|
furi_record_close(RECORD_GUI);
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
// v2 tests
|
// v2 tests
|
||||||
void test_furi_create_open();
|
void test_furi_create_open();
|
||||||
void test_furi_valuemutex();
|
|
||||||
void test_furi_concurrent_access();
|
void test_furi_concurrent_access();
|
||||||
void test_furi_pubsub();
|
void test_furi_pubsub();
|
||||||
|
|
||||||
@ -30,10 +29,6 @@ MU_TEST(mu_test_furi_create_open) {
|
|||||||
test_furi_create_open();
|
test_furi_create_open();
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(mu_test_furi_valuemutex) {
|
|
||||||
test_furi_valuemutex();
|
|
||||||
}
|
|
||||||
|
|
||||||
MU_TEST(mu_test_furi_pubsub) {
|
MU_TEST(mu_test_furi_pubsub) {
|
||||||
test_furi_pubsub();
|
test_furi_pubsub();
|
||||||
}
|
}
|
||||||
@ -51,7 +46,6 @@ MU_TEST_SUITE(test_suite) {
|
|||||||
|
|
||||||
// v2 tests
|
// v2 tests
|
||||||
MU_RUN_TEST(mu_test_furi_create_open);
|
MU_RUN_TEST(mu_test_furi_create_open);
|
||||||
MU_RUN_TEST(mu_test_furi_valuemutex);
|
|
||||||
MU_RUN_TEST(mu_test_furi_pubsub);
|
MU_RUN_TEST(mu_test_furi_pubsub);
|
||||||
MU_RUN_TEST(mu_test_furi_memmgr);
|
MU_RUN_TEST(mu_test_furi_memmgr);
|
||||||
}
|
}
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <furi.h>
|
|
||||||
|
|
||||||
#include "../minunit.h"
|
|
||||||
|
|
||||||
void test_furi_valuemutex() {
|
|
||||||
const int init_value = 0xdeadbeef;
|
|
||||||
const int changed_value = 0x12345678;
|
|
||||||
|
|
||||||
int value = init_value;
|
|
||||||
bool result;
|
|
||||||
ValueMutex valuemutex;
|
|
||||||
|
|
||||||
// init mutex case
|
|
||||||
result = init_mutex(&valuemutex, &value, sizeof(value));
|
|
||||||
mu_assert(result, "init mutex failed");
|
|
||||||
|
|
||||||
// acquire mutex case
|
|
||||||
int* value_pointer = acquire_mutex(&valuemutex, 100);
|
|
||||||
mu_assert_pointers_eq(value_pointer, &value);
|
|
||||||
|
|
||||||
// second acquire mutex case
|
|
||||||
int* value_pointer_second = acquire_mutex(&valuemutex, 100);
|
|
||||||
mu_assert_pointers_eq(value_pointer_second, NULL);
|
|
||||||
|
|
||||||
// change value case
|
|
||||||
*value_pointer = changed_value;
|
|
||||||
mu_assert_int_eq(value, changed_value);
|
|
||||||
|
|
||||||
// release mutex case
|
|
||||||
result = release_mutex(&valuemutex, &value);
|
|
||||||
mu_assert(result, "release mutex failed");
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
//acquire mutex blocking case
|
|
||||||
//write mutex blocking case
|
|
||||||
//read mutex blocking case
|
|
||||||
|
|
||||||
mu_check(delete_mutex(&valuemutex));
|
|
||||||
}
|
|
@ -50,6 +50,7 @@ typedef struct {
|
|||||||
Direction nextMovement; // if backward of currentMovement, ignore
|
Direction nextMovement; // if backward of currentMovement, ignore
|
||||||
Point fruit;
|
Point fruit;
|
||||||
GameState state;
|
GameState state;
|
||||||
|
FuriMutex* mutex;
|
||||||
} SnakeState;
|
} SnakeState;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -92,12 +93,10 @@ const NotificationSequence sequence_eat = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void snake_game_render_callback(Canvas* const canvas, void* ctx) {
|
static void snake_game_render_callback(Canvas* const canvas, void* ctx) {
|
||||||
const SnakeState* snake_state = acquire_mutex((ValueMutex*)ctx, 25);
|
furi_assert(ctx);
|
||||||
if(snake_state == NULL) {
|
const SnakeState* snake_state = ctx;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Before the function is called, the state is set with the canvas_reset(canvas)
|
furi_mutex_acquire(snake_state->mutex, FuriWaitForever);
|
||||||
|
|
||||||
// Frame
|
// Frame
|
||||||
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
canvas_draw_frame(canvas, 0, 0, 128, 64);
|
||||||
@ -134,7 +133,7 @@ static void snake_game_render_callback(Canvas* const canvas, void* ctx) {
|
|||||||
canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, buffer);
|
canvas_draw_str_aligned(canvas, 64, 41, AlignCenter, AlignBottom, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
release_mutex((ValueMutex*)ctx, snake_state);
|
furi_mutex_release(snake_state->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void snake_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
static void snake_game_input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) {
|
||||||
@ -324,15 +323,16 @@ int32_t snake_game_app(void* p) {
|
|||||||
SnakeState* snake_state = malloc(sizeof(SnakeState));
|
SnakeState* snake_state = malloc(sizeof(SnakeState));
|
||||||
snake_game_init_game(snake_state);
|
snake_game_init_game(snake_state);
|
||||||
|
|
||||||
ValueMutex state_mutex;
|
snake_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
if(!init_mutex(&state_mutex, snake_state, sizeof(SnakeState))) {
|
|
||||||
|
if(!snake_state->mutex) {
|
||||||
FURI_LOG_E("SnakeGame", "cannot create mutex\r\n");
|
FURI_LOG_E("SnakeGame", "cannot create mutex\r\n");
|
||||||
free(snake_state);
|
free(snake_state);
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewPort* view_port = view_port_alloc();
|
ViewPort* view_port = view_port_alloc();
|
||||||
view_port_draw_callback_set(view_port, snake_game_render_callback, &state_mutex);
|
view_port_draw_callback_set(view_port, snake_game_render_callback, snake_state);
|
||||||
view_port_input_callback_set(view_port, snake_game_input_callback, event_queue);
|
view_port_input_callback_set(view_port, snake_game_input_callback, event_queue);
|
||||||
|
|
||||||
FuriTimer* timer =
|
FuriTimer* timer =
|
||||||
@ -352,7 +352,7 @@ int32_t snake_game_app(void* p) {
|
|||||||
for(bool processing = true; processing;) {
|
for(bool processing = true; processing;) {
|
||||||
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
|
||||||
|
|
||||||
SnakeState* snake_state = (SnakeState*)acquire_mutex_block(&state_mutex);
|
furi_mutex_acquire(snake_state->mutex, FuriWaitForever);
|
||||||
|
|
||||||
if(event_status == FuriStatusOk) {
|
if(event_status == FuriStatusOk) {
|
||||||
// press events
|
// press events
|
||||||
@ -391,7 +391,7 @@ int32_t snake_game_app(void* p) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
view_port_update(view_port);
|
view_port_update(view_port);
|
||||||
release_mutex(&state_mutex, snake_state);
|
furi_mutex_release(snake_state->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return backlight to normal state
|
// Return backlight to normal state
|
||||||
@ -404,7 +404,7 @@ int32_t snake_game_app(void* p) {
|
|||||||
furi_record_close(RECORD_NOTIFICATION);
|
furi_record_close(RECORD_NOTIFICATION);
|
||||||
view_port_free(view_port);
|
view_port_free(view_port);
|
||||||
furi_message_queue_free(event_queue);
|
furi_message_queue_free(event_queue);
|
||||||
delete_mutex(&state_mutex);
|
furi_mutex_free(snake_state->mutex);
|
||||||
free(snake_state);
|
free(snake_state);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,17.0,,
|
Version,+,18.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.h,,
|
Header,+,applications/services/cli/cli_vcp.h,,
|
||||||
@ -156,6 +156,7 @@ Header,+,lib/toolbox/manchester_decoder.h,,
|
|||||||
Header,+,lib/toolbox/manchester_encoder.h,,
|
Header,+,lib/toolbox/manchester_encoder.h,,
|
||||||
Header,+,lib/toolbox/md5.h,,
|
Header,+,lib/toolbox/md5.h,,
|
||||||
Header,+,lib/toolbox/path.h,,
|
Header,+,lib/toolbox/path.h,,
|
||||||
|
Header,+,lib/toolbox/pretty_format.h,,
|
||||||
Header,+,lib/toolbox/protocols/protocol_dict.h,,
|
Header,+,lib/toolbox/protocols/protocol_dict.h,,
|
||||||
Header,+,lib/toolbox/random_name.h,,
|
Header,+,lib/toolbox/random_name.h,,
|
||||||
Header,+,lib/toolbox/saved_struct.h,,
|
Header,+,lib/toolbox/saved_struct.h,,
|
||||||
@ -439,7 +440,6 @@ Function,-,_wctomb_r,int,"_reent*, char*, wchar_t, _mbstate_t*"
|
|||||||
Function,-,a64l,long,const char*
|
Function,-,a64l,long,const char*
|
||||||
Function,+,abort,void,
|
Function,+,abort,void,
|
||||||
Function,-,abs,int,int
|
Function,-,abs,int,int
|
||||||
Function,+,acquire_mutex,void*,"ValueMutex*, uint32_t"
|
|
||||||
Function,-,aligned_alloc,void*,"size_t, size_t"
|
Function,-,aligned_alloc,void*,"size_t, size_t"
|
||||||
Function,+,aligned_free,void,void*
|
Function,+,aligned_free,void,void*
|
||||||
Function,+,aligned_malloc,void*,"size_t, size_t"
|
Function,+,aligned_malloc,void*,"size_t, size_t"
|
||||||
@ -573,7 +573,6 @@ Function,-,ctermid,char*,char*
|
|||||||
Function,-,ctime,char*,const time_t*
|
Function,-,ctime,char*,const time_t*
|
||||||
Function,-,ctime_r,char*,"const time_t*, char*"
|
Function,-,ctime_r,char*,"const time_t*, char*"
|
||||||
Function,-,cuserid,char*,char*
|
Function,-,cuserid,char*,char*
|
||||||
Function,+,delete_mutex,_Bool,ValueMutex*
|
|
||||||
Function,+,dialog_ex_alloc,DialogEx*,
|
Function,+,dialog_ex_alloc,DialogEx*,
|
||||||
Function,+,dialog_ex_disable_extended_events,void,DialogEx*
|
Function,+,dialog_ex_disable_extended_events,void,DialogEx*
|
||||||
Function,+,dialog_ex_enable_extended_events,void,DialogEx*
|
Function,+,dialog_ex_enable_extended_events,void,DialogEx*
|
||||||
@ -684,6 +683,7 @@ Function,+,file_browser_worker_set_folder_callback,void,"BrowserWorker*, Browser
|
|||||||
Function,+,file_browser_worker_set_item_callback,void,"BrowserWorker*, BrowserWorkerListItemCallback"
|
Function,+,file_browser_worker_set_item_callback,void,"BrowserWorker*, BrowserWorkerListItemCallback"
|
||||||
Function,+,file_browser_worker_set_list_callback,void,"BrowserWorker*, BrowserWorkerListLoadCallback"
|
Function,+,file_browser_worker_set_list_callback,void,"BrowserWorker*, BrowserWorkerListLoadCallback"
|
||||||
Function,+,file_browser_worker_set_long_load_callback,void,"BrowserWorker*, BrowserWorkerLongLoadCallback"
|
Function,+,file_browser_worker_set_long_load_callback,void,"BrowserWorker*, BrowserWorkerLongLoadCallback"
|
||||||
|
Function,+,file_info_is_dir,_Bool,const FileInfo*
|
||||||
Function,+,file_stream_alloc,Stream*,Storage*
|
Function,+,file_stream_alloc,Stream*,Storage*
|
||||||
Function,+,file_stream_close,_Bool,Stream*
|
Function,+,file_stream_close,_Bool,Stream*
|
||||||
Function,+,file_stream_get_error,FS_Error,Stream*
|
Function,+,file_stream_get_error,FS_Error,Stream*
|
||||||
@ -707,6 +707,7 @@ Function,-,flipper_application_preload_status_to_string,const char*,FlipperAppli
|
|||||||
Function,+,flipper_application_spawn,FuriThread*,"FlipperApplication*, void*"
|
Function,+,flipper_application_spawn,FuriThread*,"FlipperApplication*, void*"
|
||||||
Function,+,flipper_format_buffered_file_alloc,FlipperFormat*,Storage*
|
Function,+,flipper_format_buffered_file_alloc,FlipperFormat*,Storage*
|
||||||
Function,+,flipper_format_buffered_file_close,_Bool,FlipperFormat*
|
Function,+,flipper_format_buffered_file_close,_Bool,FlipperFormat*
|
||||||
|
Function,+,flipper_format_buffered_file_open_always,_Bool,"FlipperFormat*, const char*"
|
||||||
Function,+,flipper_format_buffered_file_open_existing,_Bool,"FlipperFormat*, const char*"
|
Function,+,flipper_format_buffered_file_open_existing,_Bool,"FlipperFormat*, const char*"
|
||||||
Function,+,flipper_format_delete_key,_Bool,"FlipperFormat*, const char*"
|
Function,+,flipper_format_delete_key,_Bool,"FlipperFormat*, const char*"
|
||||||
Function,+,flipper_format_file_alloc,FlipperFormat*,Storage*
|
Function,+,flipper_format_file_alloc,FlipperFormat*,Storage*
|
||||||
@ -1234,6 +1235,7 @@ Function,+,furi_thread_flags_get,uint32_t,
|
|||||||
Function,+,furi_thread_flags_set,uint32_t,"FuriThreadId, uint32_t"
|
Function,+,furi_thread_flags_set,uint32_t,"FuriThreadId, uint32_t"
|
||||||
Function,+,furi_thread_flags_wait,uint32_t,"uint32_t, uint32_t, uint32_t"
|
Function,+,furi_thread_flags_wait,uint32_t,"uint32_t, uint32_t, uint32_t"
|
||||||
Function,+,furi_thread_free,void,FuriThread*
|
Function,+,furi_thread_free,void,FuriThread*
|
||||||
|
Function,+,furi_thread_get_appid,const char*,FuriThreadId
|
||||||
Function,+,furi_thread_get_current,FuriThread*,
|
Function,+,furi_thread_get_current,FuriThread*,
|
||||||
Function,+,furi_thread_get_current_id,FuriThreadId,
|
Function,+,furi_thread_get_current_id,FuriThreadId,
|
||||||
Function,+,furi_thread_get_current_priority,FuriThreadPriority,
|
Function,+,furi_thread_get_current_priority,FuriThreadPriority,
|
||||||
@ -1248,6 +1250,7 @@ Function,+,furi_thread_is_suspended,_Bool,FuriThreadId
|
|||||||
Function,+,furi_thread_join,_Bool,FuriThread*
|
Function,+,furi_thread_join,_Bool,FuriThread*
|
||||||
Function,+,furi_thread_mark_as_service,void,FuriThread*
|
Function,+,furi_thread_mark_as_service,void,FuriThread*
|
||||||
Function,+,furi_thread_resume,void,FuriThreadId
|
Function,+,furi_thread_resume,void,FuriThreadId
|
||||||
|
Function,+,furi_thread_set_appid,void,"FuriThread*, const char*"
|
||||||
Function,+,furi_thread_set_callback,void,"FuriThread*, FuriThreadCallback"
|
Function,+,furi_thread_set_callback,void,"FuriThread*, FuriThreadCallback"
|
||||||
Function,+,furi_thread_set_context,void,"FuriThread*, void*"
|
Function,+,furi_thread_set_context,void,"FuriThread*, void*"
|
||||||
Function,+,furi_thread_set_current_priority,void,FuriThreadPriority
|
Function,+,furi_thread_set_current_priority,void,FuriThreadPriority
|
||||||
@ -1312,7 +1315,6 @@ Function,+,icon_get_data,const uint8_t*,const Icon*
|
|||||||
Function,+,icon_get_height,uint8_t,const Icon*
|
Function,+,icon_get_height,uint8_t,const Icon*
|
||||||
Function,+,icon_get_width,uint8_t,const Icon*
|
Function,+,icon_get_width,uint8_t,const Icon*
|
||||||
Function,-,index,char*,"const char*, int"
|
Function,-,index,char*,"const char*, int"
|
||||||
Function,+,init_mutex,_Bool,"ValueMutex*, void*, size_t"
|
|
||||||
Function,-,initstate,char*,"unsigned, char*, size_t"
|
Function,-,initstate,char*,"unsigned, char*, size_t"
|
||||||
Function,+,input_get_key_name,const char*,InputKey
|
Function,+,input_get_key_name,const char*,InputKey
|
||||||
Function,+,input_get_type_name,const char*,InputType
|
Function,+,input_get_type_name,const char*,InputType
|
||||||
@ -1491,6 +1493,7 @@ Function,+,power_get_pubsub,FuriPubSub*,Power*
|
|||||||
Function,+,power_is_battery_healthy,_Bool,Power*
|
Function,+,power_is_battery_healthy,_Bool,Power*
|
||||||
Function,+,power_off,void,Power*
|
Function,+,power_off,void,Power*
|
||||||
Function,+,power_reboot,void,PowerBootMode
|
Function,+,power_reboot,void,PowerBootMode
|
||||||
|
Function,+,pretty_format_bytes_hex_canonical,void,"FuriString*, size_t, const char*, const uint8_t*, size_t"
|
||||||
Function,-,printf,int,"const char*, ..."
|
Function,-,printf,int,"const char*, ..."
|
||||||
Function,+,property_value_out,void,"PropertyValueContext*, const char*, unsigned int, ..."
|
Function,+,property_value_out,void,"PropertyValueContext*, const char*, unsigned int, ..."
|
||||||
Function,+,protocol_dict_alloc,ProtocolDict*,"const ProtocolBase**, size_t"
|
Function,+,protocol_dict_alloc,ProtocolDict*,"const ProtocolBase**, size_t"
|
||||||
@ -1534,12 +1537,10 @@ Function,+,rand,int,
|
|||||||
Function,-,rand_r,int,unsigned*
|
Function,-,rand_r,int,unsigned*
|
||||||
Function,+,random,long,
|
Function,+,random,long,
|
||||||
Function,-,rawmemchr,void*,"const void*, int"
|
Function,-,rawmemchr,void*,"const void*, int"
|
||||||
Function,-,read_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
|
|
||||||
Function,+,realloc,void*,"void*, size_t"
|
Function,+,realloc,void*,"void*, size_t"
|
||||||
Function,-,reallocarray,void*,"void*, size_t, size_t"
|
Function,-,reallocarray,void*,"void*, size_t, size_t"
|
||||||
Function,-,reallocf,void*,"void*, size_t"
|
Function,-,reallocf,void*,"void*, size_t"
|
||||||
Function,-,realpath,char*,"const char*, char*"
|
Function,-,realpath,char*,"const char*, char*"
|
||||||
Function,+,release_mutex,_Bool,"ValueMutex*, const void*"
|
|
||||||
Function,-,remove,int,const char*
|
Function,-,remove,int,const char*
|
||||||
Function,-,rename,int,"const char*, const char*"
|
Function,-,rename,int,"const char*, const char*"
|
||||||
Function,-,renameat,int,"int, const char*, int, const char*"
|
Function,-,renameat,int,"int, const char*, int, const char*"
|
||||||
@ -1617,14 +1618,18 @@ Function,-,srand48,void,long
|
|||||||
Function,-,srandom,void,unsigned
|
Function,-,srandom,void,unsigned
|
||||||
Function,+,sscanf,int,"const char*, const char*, ..."
|
Function,+,sscanf,int,"const char*, const char*, ..."
|
||||||
Function,+,storage_common_copy,FS_Error,"Storage*, const char*, const char*"
|
Function,+,storage_common_copy,FS_Error,"Storage*, const char*, const char*"
|
||||||
|
Function,+,storage_common_exists,_Bool,"Storage*, const char*"
|
||||||
Function,+,storage_common_fs_info,FS_Error,"Storage*, const char*, uint64_t*, uint64_t*"
|
Function,+,storage_common_fs_info,FS_Error,"Storage*, const char*, uint64_t*, uint64_t*"
|
||||||
Function,+,storage_common_merge,FS_Error,"Storage*, const char*, const char*"
|
Function,+,storage_common_merge,FS_Error,"Storage*, const char*, const char*"
|
||||||
|
Function,+,storage_common_migrate,FS_Error,"Storage*, const char*, const char*"
|
||||||
Function,+,storage_common_mkdir,FS_Error,"Storage*, const char*"
|
Function,+,storage_common_mkdir,FS_Error,"Storage*, const char*"
|
||||||
Function,+,storage_common_remove,FS_Error,"Storage*, const char*"
|
Function,+,storage_common_remove,FS_Error,"Storage*, const char*"
|
||||||
Function,+,storage_common_rename,FS_Error,"Storage*, const char*, const char*"
|
Function,+,storage_common_rename,FS_Error,"Storage*, const char*, const char*"
|
||||||
|
Function,+,storage_common_resolve_path_and_ensure_app_directory,void,"Storage*, FuriString*"
|
||||||
Function,+,storage_common_stat,FS_Error,"Storage*, const char*, FileInfo*"
|
Function,+,storage_common_stat,FS_Error,"Storage*, const char*, FileInfo*"
|
||||||
Function,+,storage_common_timestamp,FS_Error,"Storage*, const char*, uint32_t*"
|
Function,+,storage_common_timestamp,FS_Error,"Storage*, const char*, uint32_t*"
|
||||||
Function,+,storage_dir_close,_Bool,File*
|
Function,+,storage_dir_close,_Bool,File*
|
||||||
|
Function,+,storage_dir_exists,_Bool,"Storage*, const char*"
|
||||||
Function,+,storage_dir_open,_Bool,"File*, const char*"
|
Function,+,storage_dir_open,_Bool,"File*, const char*"
|
||||||
Function,+,storage_dir_read,_Bool,"File*, FileInfo*, char*, uint16_t"
|
Function,+,storage_dir_read,_Bool,"File*, FileInfo*, char*, uint16_t"
|
||||||
Function,-,storage_dir_rewind,_Bool,File*
|
Function,-,storage_dir_rewind,_Bool,File*
|
||||||
@ -1995,7 +2000,6 @@ Function,+,widget_alloc,Widget*,
|
|||||||
Function,+,widget_free,void,Widget*
|
Function,+,widget_free,void,Widget*
|
||||||
Function,+,widget_get_view,View*,Widget*
|
Function,+,widget_get_view,View*,Widget*
|
||||||
Function,+,widget_reset,void,Widget*
|
Function,+,widget_reset,void,Widget*
|
||||||
Function,-,write_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
|
|
||||||
Function,-,xPortGetFreeHeapSize,size_t,
|
Function,-,xPortGetFreeHeapSize,size_t,
|
||||||
Function,-,xPortGetMinimumEverFreeHeapSize,size_t,
|
Function,-,xPortGetMinimumEverFreeHeapSize,size_t,
|
||||||
Function,-,xPortStartScheduler,BaseType_t,
|
Function,-,xPortStartScheduler,BaseType_t,
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,17.0,,
|
Version,+,18.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.h,,
|
Header,+,applications/services/cli/cli_vcp.h,,
|
||||||
@ -491,7 +491,6 @@ Function,-,acosh,double,double
|
|||||||
Function,-,acoshf,float,float
|
Function,-,acoshf,float,float
|
||||||
Function,-,acoshl,long double,long double
|
Function,-,acoshl,long double,long double
|
||||||
Function,-,acosl,long double,long double
|
Function,-,acosl,long double,long double
|
||||||
Function,+,acquire_mutex,void*,"ValueMutex*, uint32_t"
|
|
||||||
Function,-,aligned_alloc,void*,"size_t, size_t"
|
Function,-,aligned_alloc,void*,"size_t, size_t"
|
||||||
Function,+,aligned_free,void,void*
|
Function,+,aligned_free,void,void*
|
||||||
Function,+,aligned_malloc,void*,"size_t, size_t"
|
Function,+,aligned_malloc,void*,"size_t, size_t"
|
||||||
@ -703,7 +702,6 @@ Function,-,ctermid,char*,char*
|
|||||||
Function,-,ctime,char*,const time_t*
|
Function,-,ctime,char*,const time_t*
|
||||||
Function,-,ctime_r,char*,"const time_t*, char*"
|
Function,-,ctime_r,char*,"const time_t*, char*"
|
||||||
Function,-,cuserid,char*,char*
|
Function,-,cuserid,char*,char*
|
||||||
Function,+,delete_mutex,_Bool,ValueMutex*
|
|
||||||
Function,+,dialog_ex_alloc,DialogEx*,
|
Function,+,dialog_ex_alloc,DialogEx*,
|
||||||
Function,+,dialog_ex_disable_extended_events,void,DialogEx*
|
Function,+,dialog_ex_disable_extended_events,void,DialogEx*
|
||||||
Function,+,dialog_ex_enable_extended_events,void,DialogEx*
|
Function,+,dialog_ex_enable_extended_events,void,DialogEx*
|
||||||
@ -1692,7 +1690,6 @@ Function,+,infrared_worker_tx_set_get_signal_callback,void,"InfraredWorker*, Inf
|
|||||||
Function,+,infrared_worker_tx_set_signal_sent_callback,void,"InfraredWorker*, InfraredWorkerMessageSentCallback, void*"
|
Function,+,infrared_worker_tx_set_signal_sent_callback,void,"InfraredWorker*, InfraredWorkerMessageSentCallback, void*"
|
||||||
Function,+,infrared_worker_tx_start,void,InfraredWorker*
|
Function,+,infrared_worker_tx_start,void,InfraredWorker*
|
||||||
Function,+,infrared_worker_tx_stop,void,InfraredWorker*
|
Function,+,infrared_worker_tx_stop,void,InfraredWorker*
|
||||||
Function,+,init_mutex,_Bool,"ValueMutex*, void*, size_t"
|
|
||||||
Function,-,initstate,char*,"unsigned, char*, size_t"
|
Function,-,initstate,char*,"unsigned, char*, size_t"
|
||||||
Function,+,input_get_key_name,const char*,InputKey
|
Function,+,input_get_key_name,const char*,InputKey
|
||||||
Function,+,input_get_type_name,const char*,InputType
|
Function,+,input_get_type_name,const char*,InputType
|
||||||
@ -2164,12 +2161,10 @@ Function,+,rand,int,
|
|||||||
Function,-,rand_r,int,unsigned*
|
Function,-,rand_r,int,unsigned*
|
||||||
Function,+,random,long,
|
Function,+,random,long,
|
||||||
Function,-,rawmemchr,void*,"const void*, int"
|
Function,-,rawmemchr,void*,"const void*, int"
|
||||||
Function,-,read_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
|
|
||||||
Function,+,realloc,void*,"void*, size_t"
|
Function,+,realloc,void*,"void*, size_t"
|
||||||
Function,-,reallocarray,void*,"void*, size_t, size_t"
|
Function,-,reallocarray,void*,"void*, size_t, size_t"
|
||||||
Function,-,reallocf,void*,"void*, size_t"
|
Function,-,reallocf,void*,"void*, size_t"
|
||||||
Function,-,realpath,char*,"const char*, char*"
|
Function,-,realpath,char*,"const char*, char*"
|
||||||
Function,+,release_mutex,_Bool,"ValueMutex*, const void*"
|
|
||||||
Function,-,remainder,double,"double, double"
|
Function,-,remainder,double,"double, double"
|
||||||
Function,-,remainderf,float,"float, float"
|
Function,-,remainderf,float,"float, float"
|
||||||
Function,-,remainderl,long double,"long double, long double"
|
Function,-,remainderl,long double,"long double, long double"
|
||||||
@ -2967,7 +2962,6 @@ Function,+,widget_alloc,Widget*,
|
|||||||
Function,+,widget_free,void,Widget*
|
Function,+,widget_free,void,Widget*
|
||||||
Function,+,widget_get_view,View*,Widget*
|
Function,+,widget_get_view,View*,Widget*
|
||||||
Function,+,widget_reset,void,Widget*
|
Function,+,widget_reset,void,Widget*
|
||||||
Function,-,write_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
|
|
||||||
Function,-,xPortGetFreeHeapSize,size_t,
|
Function,-,xPortGetFreeHeapSize,size_t,
|
||||||
Function,-,xPortGetMinimumEverFreeHeapSize,size_t,
|
Function,-,xPortGetMinimumEverFreeHeapSize,size_t,
|
||||||
Function,-,xPortStartScheduler,BaseType_t,
|
Function,-,xPortStartScheduler,BaseType_t,
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
#include "valuemutex.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
bool init_mutex(ValueMutex* valuemutex, void* value, size_t size) {
|
|
||||||
// mutex without name,
|
|
||||||
// no attributes (unfortunately robust mutex is not supported by FreeRTOS),
|
|
||||||
// with dynamic memory allocation
|
|
||||||
valuemutex->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
|
||||||
if(valuemutex->mutex == NULL) return false;
|
|
||||||
|
|
||||||
valuemutex->value = value;
|
|
||||||
valuemutex->size = size;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool delete_mutex(ValueMutex* valuemutex) {
|
|
||||||
if(furi_mutex_acquire(valuemutex->mutex, FuriWaitForever) == FuriStatusOk) {
|
|
||||||
furi_mutex_free(valuemutex->mutex);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void* acquire_mutex(ValueMutex* valuemutex, uint32_t timeout) {
|
|
||||||
if(furi_mutex_acquire(valuemutex->mutex, timeout) == FuriStatusOk) {
|
|
||||||
return valuemutex->value;
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool release_mutex(ValueMutex* valuemutex, const void* value) {
|
|
||||||
if(value != valuemutex->value) return false;
|
|
||||||
|
|
||||||
if(furi_mutex_release(valuemutex->mutex) != FuriStatusOk) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool read_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout) {
|
|
||||||
void* value = acquire_mutex(valuemutex, timeout);
|
|
||||||
if(value == NULL || len > valuemutex->size) return false;
|
|
||||||
memcpy(data, value, len > 0 ? len : valuemutex->size);
|
|
||||||
if(!release_mutex(valuemutex, value)) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool write_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout) {
|
|
||||||
void* value = acquire_mutex(valuemutex, timeout);
|
|
||||||
if(value == NULL || len > valuemutex->size) return false;
|
|
||||||
memcpy(value, data, len > 0 ? len : valuemutex->size);
|
|
||||||
if(!release_mutex(valuemutex, value)) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,149 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "mutex.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* == ValueMutex ==
|
|
||||||
|
|
||||||
* The most simple concept is ValueMutex.
|
|
||||||
* It is wrapper around mutex and value pointer.
|
|
||||||
* You can take and give mutex to work with value and read and write value.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void* value;
|
|
||||||
size_t size;
|
|
||||||
FuriMutex* mutex;
|
|
||||||
} ValueMutex;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates ValueMutex.
|
|
||||||
*/
|
|
||||||
bool init_mutex(ValueMutex* valuemutex, void* value, size_t size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Free resources allocated by `init_mutex`.
|
|
||||||
* This function doesn't free the memory occupied by `ValueMutex` itself.
|
|
||||||
*/
|
|
||||||
bool delete_mutex(ValueMutex* valuemutex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call for work with data stored in mutex.
|
|
||||||
* @return pointer to data if success, NULL otherwise.
|
|
||||||
*/
|
|
||||||
void* acquire_mutex(ValueMutex* valuemutex, uint32_t timeout);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper: infinitely wait for mutex
|
|
||||||
*/
|
|
||||||
static inline void* acquire_mutex_block(ValueMutex* valuemutex) {
|
|
||||||
return acquire_mutex(valuemutex, FuriWaitForever);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* With statement for value mutex, acts as lambda
|
|
||||||
* @param name a resource name, const char*
|
|
||||||
* @param function_body a (){} lambda declaration,
|
|
||||||
* executed within you parent function context.
|
|
||||||
*/
|
|
||||||
#define with_value_mutex(value_mutex, function_body) \
|
|
||||||
{ \
|
|
||||||
void* p = acquire_mutex_block(value_mutex); \
|
|
||||||
furi_check(p); \
|
|
||||||
({ void __fn__ function_body __fn__; })(p); \
|
|
||||||
release_mutex(value_mutex, p); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Release mutex after end of work with data.
|
|
||||||
* Call `release_mutex` and pass ValueData instance and pointer to data.
|
|
||||||
*/
|
|
||||||
bool release_mutex(ValueMutex* valuemutex, const void* value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instead of take-access-give sequence you can use `read_mutex` and `write_mutex` functions.
|
|
||||||
* Both functions return true in case of success, false otherwise.
|
|
||||||
*/
|
|
||||||
bool read_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout);
|
|
||||||
|
|
||||||
bool write_mutex(ValueMutex* valuemutex, void* data, size_t len, uint32_t timeout);
|
|
||||||
|
|
||||||
inline static bool write_mutex_block(ValueMutex* valuemutex, void* data, size_t len) {
|
|
||||||
return write_mutex(valuemutex, data, len, FuriWaitForever);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static bool read_mutex_block(ValueMutex* valuemutex, void* data, size_t len) {
|
|
||||||
return read_mutex(valuemutex, data, len, FuriWaitForever);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Usage example
|
|
||||||
|
|
||||||
```C
|
|
||||||
// MANIFEST
|
|
||||||
// name="example-provider-app"
|
|
||||||
// stack=128
|
|
||||||
|
|
||||||
void provider_app(void* _p) {
|
|
||||||
// create record with mutex
|
|
||||||
uint32_t example_value = 0;
|
|
||||||
ValueMutex example_mutex;
|
|
||||||
// call `init_mutex`.
|
|
||||||
if(!init_mutex(&example_mutex, (void*)&example_value, sizeof(uint32_t))) {
|
|
||||||
printf("critical error\n");
|
|
||||||
flapp_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_record_create("provider/example", (void*)&example_mutex);
|
|
||||||
|
|
||||||
// we are ready to provide record to other apps
|
|
||||||
flapp_ready();
|
|
||||||
|
|
||||||
// get value and increment it
|
|
||||||
while(1) {
|
|
||||||
uint32_t* value = acquire_mutex(&example_mutex, OsWaitForever);
|
|
||||||
if(value != NULL) {
|
|
||||||
value++;
|
|
||||||
}
|
|
||||||
release_mutex(&example_mutex, value);
|
|
||||||
|
|
||||||
furi_delay_ms(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MANIFEST
|
|
||||||
// name="example-consumer-app"
|
|
||||||
// stack=128
|
|
||||||
// require="example-provider-app"
|
|
||||||
void consumer_app(void* _p) {
|
|
||||||
// this app run after flapp_ready call in all requirements app
|
|
||||||
|
|
||||||
// open mutex value
|
|
||||||
ValueMutex* counter_mutex = furi_record_open("provider/example");
|
|
||||||
if(counter_mutex == NULL) {
|
|
||||||
printf("critical error\n");
|
|
||||||
flapp_exit(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// continuously read value every 1s
|
|
||||||
uint32_t counter;
|
|
||||||
while(1) {
|
|
||||||
if(read_mutex(counter_mutex, &counter, sizeof(counter), OsWaitForever)) {
|
|
||||||
printf("counter value: %d\n", counter);
|
|
||||||
}
|
|
||||||
|
|
||||||
furi_delay_ms(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
*/
|
|
@ -16,7 +16,6 @@
|
|||||||
#include "core/semaphore.h"
|
#include "core/semaphore.h"
|
||||||
#include "core/thread.h"
|
#include "core/thread.h"
|
||||||
#include "core/timer.h"
|
#include "core/timer.h"
|
||||||
#include "core/valuemutex.h"
|
|
||||||
#include "core/string.h"
|
#include "core/string.h"
|
||||||
#include "core/stream_buffer.h"
|
#include "core/stream_buffer.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user