furi_check - a new way to asserting (#204)

* hal-related task_is_isr_context function
* furi_check implementation
* change application to use furi_check
* add second level of assertion
* add TODO about ISR context
* Applications: refactor furi_check and furi_assert.
* Apploader: propwer widget usage. Menu: check on furi resource request.
* refactor furi_check

Co-authored-by: Aleksandr Kutuzov <aku@plooks.com>
Co-authored-by: coreglitch <mail@s3f.ru>
This commit is contained in:
DrZlo13 2020-10-29 09:27:17 +03:00 committed by GitHub
parent c9b921f6ce
commit 8aeafd8179
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 292 additions and 136 deletions

View File

@ -51,13 +51,12 @@ static void handle_menu(void* _ctx) {
void app_loader(void* p) { void app_loader(void* p) {
osThreadId_t self_id = osThreadGetId(); osThreadId_t self_id = osThreadGetId();
assert(self_id); furi_check(self_id);
AppLoaderState state; AppLoaderState state;
state.handler = NULL; state.handler = NULL;
state.widget = widget_alloc(); state.widget = widget_alloc();
assert(state.widget);
widget_enabled_set(state.widget, false); widget_enabled_set(state.widget, false);
widget_draw_callback_set(state.widget, render_callback, &state); widget_draw_callback_set(state.widget, render_callback, &state);
widget_input_callback_set(state.widget, input_callback, &state); widget_input_callback_set(state.widget, input_callback, &state);

View File

@ -15,7 +15,7 @@ void backlight_control(void* p) {
// open record // open record
PubSub* event_record = furi_open("input_events"); PubSub* event_record = furi_open("input_events");
assert(event_record != NULL); furi_check(event_record);
subscribe_pubsub(event_record, event_cb, (void*)update); subscribe_pubsub(event_record, event_cb, (void*)update);
// we ready to work // we ready to work

View File

@ -203,7 +203,7 @@ static void input_callback(InputEvent* input_event, void* ctx) {
extern "C" void cc1101_workaround(void* p) { extern "C" void cc1101_workaround(void* p) {
osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(AppEvent), NULL); osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(AppEvent), NULL);
assert(event_queue); furi_check(event_queue);
State _state; State _state;
_state.mode = ModeRx; _state.mode = ModeRx;

View File

@ -16,11 +16,11 @@ static void event_cb(const void* value, void* ctx) {
void application_input_dump(void* p) { void application_input_dump(void* p) {
// open record // open record
ValueManager* state_record = furi_open("input_state"); ValueManager* state_record = furi_open("input_state");
assert(state_record != NULL); furi_check(state_record);
subscribe_pubsub(&state_record->pubsub, state_cb, NULL); subscribe_pubsub(&state_record->pubsub, state_cb, NULL);
PubSub* event_record = furi_open("input_events"); PubSub* event_record = furi_open("input_events");
assert(event_record != NULL); furi_check(event_record);
subscribe_pubsub(event_record, event_cb, NULL); subscribe_pubsub(event_record, event_cb, NULL);
for(;;) { for(;;) {

View File

@ -3,8 +3,8 @@
#include "icon.h" #include "icon.h"
#include "icon_i.h" #include "icon_i.h"
#include <assert.h>
#include <flipper.h> #include <flipper.h>
#include <flipper_v2.h>
typedef struct { typedef struct {
CanvasApi api; CanvasApi api;
@ -60,12 +60,12 @@ CanvasApi* canvas_api_init() {
} }
void canvas_api_free(CanvasApi* api) { void canvas_api_free(CanvasApi* api) {
assert(api); furi_assert(api);
free(api); free(api);
} }
void canvas_commit(CanvasApi* api) { void canvas_commit(CanvasApi* api) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
u8g2_SetPowerSave(&canvas->fb, 0); // wake up display u8g2_SetPowerSave(&canvas->fb, 0); // wake up display
u8g2_SendBuffer(&canvas->fb); u8g2_SendBuffer(&canvas->fb);
@ -77,7 +77,7 @@ void canvas_frame_set(
uint8_t offset_y, uint8_t offset_y,
uint8_t width, uint8_t width,
uint8_t height) { uint8_t height) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
canvas->offset_x = offset_x; canvas->offset_x = offset_x;
canvas->offset_y = offset_y; canvas->offset_y = offset_y;
@ -86,31 +86,31 @@ void canvas_frame_set(
} }
uint8_t canvas_width(CanvasApi* api) { uint8_t canvas_width(CanvasApi* api) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
return canvas->width; return canvas->width;
} }
uint8_t canvas_height(CanvasApi* api) { uint8_t canvas_height(CanvasApi* api) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
return canvas->height; return canvas->height;
} }
void canvas_clear(CanvasApi* api) { void canvas_clear(CanvasApi* api) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
u8g2_ClearBuffer(&canvas->fb); u8g2_ClearBuffer(&canvas->fb);
} }
void canvas_color_set(CanvasApi* api, Color color) { void canvas_color_set(CanvasApi* api, Color color) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
u8g2_SetDrawColor(&canvas->fb, color); u8g2_SetDrawColor(&canvas->fb, color);
} }
void canvas_font_set(CanvasApi* api, Font font) { void canvas_font_set(CanvasApi* api, Font font) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
u8g2_SetFontMode(&canvas->fb, 1); u8g2_SetFontMode(&canvas->fb, 1);
if(font == FontPrimary) { if(font == FontPrimary) {
@ -118,12 +118,12 @@ void canvas_font_set(CanvasApi* api, Font font) {
} else if(font == FontSecondary) { } else if(font == FontSecondary) {
u8g2_SetFont(&canvas->fb, u8g2_font_HelvetiPixel_tr); u8g2_SetFont(&canvas->fb, u8g2_font_HelvetiPixel_tr);
} else { } else {
assert(0); furi_check(0);
} }
} }
void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str) { void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str) {
assert(api); furi_assert(api);
if(!str) return; if(!str) return;
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
@ -132,7 +132,7 @@ void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str) {
} }
void canvas_icon_draw(CanvasApi* api, uint8_t x, uint8_t y, Icon* icon) { void canvas_icon_draw(CanvasApi* api, uint8_t x, uint8_t y, Icon* icon) {
assert(api); furi_assert(api);
if(!icon) return; if(!icon) return;
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
x += canvas->offset_x; x += canvas->offset_x;
@ -142,25 +142,25 @@ void canvas_icon_draw(CanvasApi* api, uint8_t x, uint8_t y, Icon* icon) {
} }
void canvas_dot_draw(CanvasApi* api, uint8_t x, uint8_t y) { void canvas_dot_draw(CanvasApi* api, uint8_t x, uint8_t y) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
u8g2_DrawPixel(&canvas->fb, x, y); u8g2_DrawPixel(&canvas->fb, x, y);
} }
void canvas_box_draw(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height) { void canvas_box_draw(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
u8g2_DrawBox(&canvas->fb, x, y, width, height); u8g2_DrawBox(&canvas->fb, x, y, width, height);
} }
void canvas_draw_frame(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height) { void canvas_draw_frame(CanvasApi* api, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
u8g2_DrawFrame(&canvas->fb, x, y, width, height); u8g2_DrawFrame(&canvas->fb, x, y, width, height);
} }
void canvas_draw_line(CanvasApi* api, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) { void canvas_draw_line(CanvasApi* api, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
assert(api); furi_assert(api);
Canvas* canvas = (Canvas*)api; Canvas* canvas = (Canvas*)api;
u8g2_DrawLine(&canvas->fb, x1, y1, x2, y2); u8g2_DrawLine(&canvas->fb, x1, y1, x2, y2);
} }

View File

@ -34,7 +34,7 @@ Widget* gui_widget_find_enabled(WidgetArray_t array) {
} }
void gui_update(Gui* gui) { void gui_update(Gui* gui) {
assert(gui); furi_assert(gui);
GuiMessage message; GuiMessage message;
message.type = GuiMessageTypeRedraw; message.type = GuiMessageTypeRedraw;
gui_event_messsage_send(gui->event, &message); gui_event_messsage_send(gui->event, &message);
@ -83,7 +83,7 @@ bool gui_redraw_none(Gui* gui) {
} }
void gui_redraw(Gui* gui) { void gui_redraw(Gui* gui) {
assert(gui); furi_assert(gui);
gui_lock(gui); gui_lock(gui);
if(!gui_redraw_fs(gui)) { if(!gui_redraw_fs(gui)) {
@ -98,7 +98,9 @@ void gui_redraw(Gui* gui) {
} }
void gui_input(Gui* gui, InputEvent* input_event) { void gui_input(Gui* gui, InputEvent* input_event) {
assert(gui); furi_assert(gui);
furi_assert(input_event);
gui_lock(gui); gui_lock(gui);
Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerFullscreen]); Widget* widget = gui_widget_find_enabled(gui->layers[GuiLayerFullscreen]);
@ -113,19 +115,19 @@ void gui_input(Gui* gui, InputEvent* input_event) {
} }
void gui_lock(Gui* gui) { void gui_lock(Gui* gui) {
assert(gui); furi_assert(gui);
assert(osMutexAcquire(gui->mutex, osWaitForever) == osOK); furi_check(osMutexAcquire(gui->mutex, osWaitForever) == osOK);
} }
void gui_unlock(Gui* gui) { void gui_unlock(Gui* gui) {
assert(gui); furi_assert(gui);
assert(osMutexRelease(gui->mutex) == osOK); furi_check(osMutexRelease(gui->mutex) == osOK);
} }
void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) { void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) {
assert(gui_api); furi_assert(gui_api);
assert(widget); furi_assert(widget);
assert(layer < GuiLayerMAX); furi_check(layer < GuiLayerMAX);
Gui* gui = (Gui*)gui_api; Gui* gui = (Gui*)gui_api;
gui_lock(gui); gui_lock(gui);
@ -136,8 +138,8 @@ void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) {
} }
void gui_remove_widget(GuiApi* gui_api, Widget* widget) { void gui_remove_widget(GuiApi* gui_api, Widget* widget) {
assert(gui_api); furi_assert(gui_api);
assert(widget); furi_assert(widget);
Gui* gui = (Gui*)gui_api; Gui* gui = (Gui*)gui_api;
gui_lock(gui); gui_lock(gui);
@ -164,7 +166,7 @@ Gui* gui_alloc() {
gui->api.remove_widget = gui_remove_widget; gui->api.remove_widget = gui_remove_widget;
// Allocate mutex // Allocate mutex
gui->mutex = osMutexNew(NULL); gui->mutex = osMutexNew(NULL);
assert(gui->mutex); furi_check(gui->mutex);
// Event dispatcher // Event dispatcher
gui->event = gui_event_alloc(); gui->event = gui_event_alloc();
// Drawing canvas api // Drawing canvas api

View File

@ -1,7 +1,6 @@
#include "gui_event.h" #include "gui_event.h"
#include <flipper_v2.h> #include <flipper_v2.h>
#include <assert.h>
#define GUI_EVENT_MQUEUE_SIZE 8 #define GUI_EVENT_MQUEUE_SIZE 8
@ -11,7 +10,9 @@ struct GuiEvent {
}; };
void gui_event_input_events_callback(const void* value, void* ctx) { void gui_event_input_events_callback(const void* value, void* ctx) {
assert(ctx); furi_assert(value);
furi_assert(ctx);
GuiEvent* gui_event = ctx; GuiEvent* gui_event = ctx;
GuiMessage message; GuiMessage message;
@ -23,35 +24,36 @@ void gui_event_input_events_callback(const void* value, void* ctx) {
GuiEvent* gui_event_alloc() { GuiEvent* gui_event_alloc() {
GuiEvent* gui_event = furi_alloc(sizeof(GuiEvent)); GuiEvent* gui_event = furi_alloc(sizeof(GuiEvent));
// Allocate message que
// Allocate message queue
gui_event->mqueue = osMessageQueueNew(GUI_EVENT_MQUEUE_SIZE, sizeof(GuiMessage), NULL); gui_event->mqueue = osMessageQueueNew(GUI_EVENT_MQUEUE_SIZE, sizeof(GuiMessage), NULL);
assert(gui_event->mqueue); furi_check(gui_event->mqueue);
// Input // Input
gui_event->input_event_record = furi_open("input_events"); gui_event->input_event_record = furi_open("input_events");
assert(gui_event->input_event_record != NULL); furi_check(gui_event->input_event_record != NULL);
subscribe_pubsub(gui_event->input_event_record, gui_event_input_events_callback, gui_event); subscribe_pubsub(gui_event->input_event_record, gui_event_input_events_callback, gui_event);
return gui_event; return gui_event;
} }
void gui_event_free(GuiEvent* gui_event) { void gui_event_free(GuiEvent* gui_event) {
assert(gui_event); furi_assert(gui_event);
assert(osMessageQueueDelete(gui_event->mqueue) == osOK); furi_check(osMessageQueueDelete(gui_event->mqueue) == osOK);
free(gui_event); free(gui_event);
} }
void gui_event_messsage_send(GuiEvent* gui_event, GuiMessage* message) { void gui_event_messsage_send(GuiEvent* gui_event, GuiMessage* message) {
assert(gui_event); furi_assert(gui_event);
assert(message); furi_assert(message);
osMessageQueuePut(gui_event->mqueue, message, 0, 0); osMessageQueuePut(gui_event->mqueue, message, 0, 0);
} }
GuiMessage gui_event_message_next(GuiEvent* gui_event) { GuiMessage gui_event_message_next(GuiEvent* gui_event) {
assert(gui_event); furi_assert(gui_event);
GuiMessage message; GuiMessage message;
assert(osMessageQueueGet(gui_event->mqueue, &message, NULL, osWaitForever) == osOK); furi_check(osMessageQueueGet(gui_event->mqueue, &message, NULL, osWaitForever) == osOK);
return message; return message;
} }

View File

@ -3,7 +3,7 @@
#include <cmsis_os2.h> #include <cmsis_os2.h>
#include <flipper.h> #include <flipper.h>
#include <assert.h> #include <flipper_v2.h>
Icon* icon_alloc(const IconData* data) { Icon* icon_alloc(const IconData* data) {
Icon* icon = furi_alloc(sizeof(Icon)); Icon* icon = furi_alloc(sizeof(Icon));
@ -12,12 +12,12 @@ Icon* icon_alloc(const IconData* data) {
} }
void icon_free(Icon* icon) { void icon_free(Icon* icon) {
assert(icon); furi_assert(icon);
free(icon); free(icon);
} }
const uint8_t* icon_get_data(Icon* icon) { const uint8_t* icon_get_data(Icon* icon) {
assert(icon); furi_assert(icon);
if(icon->tick) { if(icon->tick) {
uint32_t now = osKernelGetTickCount(); uint32_t now = osKernelGetTickCount();
if(now < icon->tick) { if(now < icon->tick) {
@ -32,32 +32,32 @@ const uint8_t* icon_get_data(Icon* icon) {
} }
void icon_next_frame(Icon* icon) { void icon_next_frame(Icon* icon) {
assert(icon); furi_assert(icon);
icon->frame = (icon->frame + 1) % icon->data->frame_count; icon->frame = (icon->frame + 1) % icon->data->frame_count;
} }
uint8_t icon_get_width(Icon* icon) { uint8_t icon_get_width(Icon* icon) {
assert(icon); furi_assert(icon);
return icon->data->width; return icon->data->width;
} }
uint8_t icon_get_height(Icon* icon) { uint8_t icon_get_height(Icon* icon) {
assert(icon); furi_assert(icon);
return icon->data->height; return icon->data->height;
} }
bool icon_is_animated(Icon* icon) { bool icon_is_animated(Icon* icon) {
assert(icon); furi_assert(icon);
return icon->data->frame_count > 1; return icon->data->frame_count > 1;
} }
void icon_start_animation(Icon* icon) { void icon_start_animation(Icon* icon) {
assert(icon); furi_assert(icon);
icon->tick = osKernelGetTickCount(); icon->tick = osKernelGetTickCount();
} }
void icon_stop_animation(Icon* icon) { void icon_stop_animation(Icon* icon) {
assert(icon); furi_assert(icon);
icon->tick = 0; icon->tick = 0;
icon->frame = 0; icon->frame = 0;
} }

View File

@ -3,6 +3,7 @@
#include <cmsis_os.h> #include <cmsis_os.h>
#include <flipper.h> #include <flipper.h>
#include <flipper_v2.h>
#include "gui.h" #include "gui.h"
#include "gui_i.h" #include "gui_i.h"
@ -25,13 +26,13 @@ Widget* widget_alloc(WidgetDrawCallback callback, void* callback_context) {
} }
void widget_free(Widget* widget) { void widget_free(Widget* widget) {
assert(widget); furi_assert(widget);
assert(widget->gui == NULL); furi_check(widget->gui == NULL);
free(widget); free(widget);
} }
void widget_enabled_set(Widget* widget, bool enabled) { void widget_enabled_set(Widget* widget, bool enabled) {
assert(widget); furi_assert(widget);
if(widget->is_enabled != enabled) { if(widget->is_enabled != enabled) {
widget->is_enabled = enabled; widget->is_enabled = enabled;
widget_update(widget); widget_update(widget);
@ -39,47 +40,47 @@ void widget_enabled_set(Widget* widget, bool enabled) {
} }
bool widget_is_enabled(Widget* widget) { bool widget_is_enabled(Widget* widget) {
assert(widget); furi_assert(widget);
return widget->is_enabled; return widget->is_enabled;
} }
void widget_draw_callback_set(Widget* widget, WidgetDrawCallback callback, void* context) { void widget_draw_callback_set(Widget* widget, WidgetDrawCallback callback, void* context) {
assert(widget); furi_assert(widget);
widget->draw_callback = callback; widget->draw_callback = callback;
widget->draw_callback_context = context; widget->draw_callback_context = context;
} }
void widget_input_callback_set(Widget* widget, WidgetInputCallback callback, void* context) { void widget_input_callback_set(Widget* widget, WidgetInputCallback callback, void* context) {
assert(widget); furi_assert(widget);
widget->input_callback = callback; widget->input_callback = callback;
widget->input_callback_context = context; widget->input_callback_context = context;
} }
void widget_update(Widget* widget) { void widget_update(Widget* widget) {
assert(widget); furi_assert(widget);
if(widget->gui) gui_update(widget->gui); if(widget->gui) gui_update(widget->gui);
} }
void widget_gui_set(Widget* widget, Gui* gui) { void widget_gui_set(Widget* widget, Gui* gui) {
assert(widget); furi_assert(widget);
assert(gui); furi_assert(gui);
widget->gui = gui; widget->gui = gui;
} }
void widget_draw(Widget* widget, CanvasApi* canvas_api) { void widget_draw(Widget* widget, CanvasApi* canvas_api) {
assert(widget); furi_assert(widget);
assert(canvas_api); furi_assert(canvas_api);
assert(widget->gui);
furi_check(widget->gui);
if(widget->draw_callback) { if(widget->draw_callback) {
widget->draw_callback(canvas_api, widget->draw_callback_context); widget->draw_callback(canvas_api, widget->draw_callback_context);
} }
} }
void widget_input(Widget* widget, InputEvent* event) { void widget_input(Widget* widget, InputEvent* event) {
assert(widget); furi_assert(widget);
assert(event); furi_assert(event);
assert(widget->gui);
furi_check(widget->gui);
if(widget->input_callback) widget->input_callback(event, widget->input_callback_context); if(widget->input_callback) widget->input_callback(event, widget->input_callback_context);
} }

View File

@ -1,6 +1,5 @@
#include "irukagotchi.h" #include "irukagotchi.h"
#include <assert.h>
#include <flipper_v2.h> #include <flipper_v2.h>
#include <gui/gui.h> #include <gui/gui.h>
@ -46,7 +45,7 @@ Irukagotchi* irukagotchi_alloc() {
widget_input_callback_set(irukagotchi->widget, irukagotchi_input_callback, irukagotchi); widget_input_callback_set(irukagotchi->widget, irukagotchi_input_callback, irukagotchi);
irukagotchi->menu_vm = furi_open("menu"); irukagotchi->menu_vm = furi_open("menu");
assert(irukagotchi->menu_vm); furi_check(irukagotchi->menu_vm);
return irukagotchi; return irukagotchi;
} }
@ -55,9 +54,9 @@ void irukagotchi_task() {
Irukagotchi* irukagotchi = irukagotchi_alloc(); Irukagotchi* irukagotchi = irukagotchi_alloc();
FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL);
assert(gui_record); furi_check(gui_record);
GuiApi* gui = furi_take(gui_record); GuiApi* gui = furi_take(gui_record);
assert(gui); furi_check(gui);
gui->add_widget(gui, irukagotchi->widget, GuiLayerNone); gui->add_widget(gui, irukagotchi->widget, GuiLayerNone);
furi_commit(gui_record); furi_commit(gui_record);

View File

@ -41,7 +41,7 @@ ValueMutex* menu_init() {
// Open GUI and register fullscreen widget // Open GUI and register fullscreen widget
GuiApi* gui = furi_open("gui"); GuiApi* gui = furi_open("gui");
assert(gui); furi_check(gui);
gui->add_widget(gui, menu->widget, GuiLayerFullscreen); gui->add_widget(gui, menu->widget, GuiLayerFullscreen);
widget_enabled_set(menu->widget, false); widget_enabled_set(menu->widget, false);
@ -52,7 +52,7 @@ ValueMutex* menu_init() {
} }
void menu_build_main(Menu* menu) { void menu_build_main(Menu* menu) {
assert(menu); furi_assert(menu);
// Root point // Root point
menu->root = menu_item_alloc_menu(NULL, NULL); menu->root = menu_item_alloc_menu(NULL, NULL);
@ -76,13 +76,13 @@ void menu_draw_secondary(Menu* menu, CanvasApi* canvas) {
} }
void menu_widget_callback(CanvasApi* canvas, void* context) { void menu_widget_callback(CanvasApi* canvas, void* context) {
assert(canvas); furi_assert(canvas);
assert(context); furi_assert(context);
Menu* menu = acquire_mutex((ValueMutex*)context, 100); // wait 10 ms to get mutex Menu* menu = acquire_mutex((ValueMutex*)context, 100); // wait 10 ms to get mutex
if(menu == NULL) return; // redraw fail if(menu == NULL) return; // redraw fail
assert(menu->current); furi_assert(menu->current);
canvas->clear(canvas); canvas->clear(canvas);
canvas->set_color(canvas, ColorBlack); canvas->set_color(canvas, ColorBlack);
@ -123,14 +123,14 @@ void menu_widget_callback(CanvasApi* canvas, void* context) {
} }
void menu_update(Menu* menu) { void menu_update(Menu* menu) {
assert(menu); furi_assert(menu);
menu_event_activity_notify(menu->event); menu_event_activity_notify(menu->event);
widget_update(menu->widget); widget_update(menu->widget);
} }
void menu_up(Menu* menu) { void menu_up(Menu* menu) {
assert(menu); furi_assert(menu);
size_t position = menu_item_get_position(menu->current); size_t position = menu_item_get_position(menu->current);
MenuItemArray_t* items = menu_item_get_subitems(menu->current); MenuItemArray_t* items = menu_item_get_subitems(menu->current);
@ -141,7 +141,7 @@ void menu_up(Menu* menu) {
} }
void menu_down(Menu* menu) { void menu_down(Menu* menu) {
assert(menu); furi_assert(menu);
size_t position = menu_item_get_position(menu->current); size_t position = menu_item_get_position(menu->current);
MenuItemArray_t* items = menu_item_get_subitems(menu->current); MenuItemArray_t* items = menu_item_get_subitems(menu->current);
position++; position++;
@ -151,7 +151,7 @@ void menu_down(Menu* menu) {
} }
void menu_ok(Menu* menu) { void menu_ok(Menu* menu) {
assert(menu); furi_assert(menu);
if(!menu->current) { if(!menu->current) {
widget_enabled_set(menu->widget, true); widget_enabled_set(menu->widget, true);
@ -180,7 +180,7 @@ void menu_ok(Menu* menu) {
} }
void menu_back(Menu* menu) { void menu_back(Menu* menu) {
assert(menu); furi_assert(menu);
MenuItem* parent = menu_item_get_parent(menu->current); MenuItem* parent = menu_item_get_parent(menu->current);
if(parent) { if(parent) {
menu->current = parent; menu->current = parent;
@ -191,7 +191,7 @@ void menu_back(Menu* menu) {
} }
void menu_exit(Menu* menu) { void menu_exit(Menu* menu) {
assert(menu); furi_assert(menu);
widget_enabled_set(menu->widget, false); widget_enabled_set(menu->widget, false);
menu->current = NULL; menu->current = NULL;
menu_update(menu); menu_update(menu);
@ -203,7 +203,7 @@ void menu_task(void* p) {
MenuEvent* menu_event = NULL; MenuEvent* menu_event = NULL;
{ {
Menu* menu = acquire_mutex_block(menu_mutex); Menu* menu = acquire_mutex_block(menu_mutex);
assert(menu); furi_check(menu);
menu_build_main(menu); menu_build_main(menu);

View File

@ -1,11 +1,11 @@
#include "menu_event.h" #include "menu_event.h"
#include <cmsis_os.h> #include <cmsis_os.h>
#include <assert.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <flipper.h> #include <flipper.h>
#include <flipper_v2.h>
#define MENU_MESSAGE_MQUEUE_SIZE 8 #define MENU_MESSAGE_MQUEUE_SIZE 8
@ -25,30 +25,28 @@ MenuEvent* menu_event_alloc() {
MenuEvent* menu_event = furi_alloc(sizeof(MenuEvent)); MenuEvent* menu_event = furi_alloc(sizeof(MenuEvent));
menu_event->mqueue = osMessageQueueNew(MENU_MESSAGE_MQUEUE_SIZE, sizeof(MenuMessage), NULL); menu_event->mqueue = osMessageQueueNew(MENU_MESSAGE_MQUEUE_SIZE, sizeof(MenuMessage), NULL);
assert(menu_event->mqueue); furi_check(menu_event->mqueue);
menu_event->timeout_timer = menu_event->timeout_timer =
osTimerNew(MenuEventimeout_callback, osTimerOnce, menu_event, NULL); osTimerNew(MenuEventimeout_callback, osTimerOnce, menu_event, NULL);
assert(menu_event->timeout_timer); furi_check(menu_event->timeout_timer);
return menu_event; return menu_event;
} }
void menu_event_free(MenuEvent* menu_event) { void menu_event_free(MenuEvent* menu_event) {
osStatus_t status; furi_assert(menu_event);
assert(menu_event); furi_check(osMessageQueueDelete(menu_event->mqueue) == osOK);
status = osMessageQueueDelete(menu_event->mqueue);
assert(status == osOK);
free(menu_event); free(menu_event);
} }
void menu_event_activity_notify(MenuEvent* menu_event) { void menu_event_activity_notify(MenuEvent* menu_event) {
assert(menu_event); furi_assert(menu_event);
osTimerStart(menu_event->timeout_timer, 60000U); // 1m timeout, return to main osTimerStart(menu_event->timeout_timer, 60000U); // 1m timeout, return to main
} }
MenuMessage menu_event_next(MenuEvent* menu_event) { MenuMessage menu_event_next(MenuEvent* menu_event) {
assert(menu_event); furi_assert(menu_event);
MenuMessage message; MenuMessage message;
while(osMessageQueueGet(menu_event->mqueue, &message, NULL, osWaitForever) != osOK) { while(osMessageQueueGet(menu_event->mqueue, &message, NULL, osWaitForever) != osOK) {
}; };

View File

@ -1,8 +1,8 @@
#include "menu_item.h" #include "menu_item.h"
#include <stdlib.h> #include <stdlib.h>
#include <assert.h>
#include <string.h> #include <string.h>
#include <flipper.h> #include <flipper.h>
#include <flipper_v2.h>
struct MenuItem { struct MenuItem {
MenuItemType type; MenuItemType type;
@ -52,7 +52,7 @@ menu_item_alloc_function(const char* label, Icon* icon, MenuItemCallback callbac
} }
void menu_item_release(MenuItem* menu_item) { void menu_item_release(MenuItem* menu_item) {
assert(menu_item); furi_assert(menu_item);
if(menu_item->type == MenuItemTypeMenu) { if(menu_item->type == MenuItemTypeMenu) {
//TODO: iterate and release //TODO: iterate and release
free(menu_item->data); free(menu_item->data);
@ -61,62 +61,61 @@ void menu_item_release(MenuItem* menu_item) {
} }
MenuItem* menu_item_get_parent(MenuItem* menu_item) { MenuItem* menu_item_get_parent(MenuItem* menu_item) {
assert(menu_item); furi_assert(menu_item);
return menu_item->parent; return menu_item->parent;
} }
void menu_item_subitem_add(MenuItem* menu_item, MenuItem* sub_item) { void menu_item_subitem_add(MenuItem* menu_item, MenuItem* sub_item) {
assert(menu_item); furi_assert(menu_item);
assert(menu_item->type == MenuItemTypeMenu); furi_check(menu_item->type == MenuItemTypeMenu);
MenuItemArray_t* items = menu_item->data; MenuItemArray_t* items = menu_item->data;
sub_item->parent = menu_item; sub_item->parent = menu_item;
MenuItemArray_push_back(*items, sub_item); MenuItemArray_push_back(*items, sub_item);
} }
uint8_t menu_item_get_type(MenuItem* menu_item) { uint8_t menu_item_get_type(MenuItem* menu_item) {
assert(menu_item); furi_assert(menu_item);
return menu_item->type; return menu_item->type;
} }
void menu_item_set_position(MenuItem* menu_item, size_t position) { void menu_item_set_position(MenuItem* menu_item, size_t position) {
assert(menu_item); furi_assert(menu_item);
menu_item->position = position; menu_item->position = position;
} }
size_t menu_item_get_position(MenuItem* menu_item) { size_t menu_item_get_position(MenuItem* menu_item) {
assert(menu_item); furi_assert(menu_item);
return menu_item->position; return menu_item->position;
} }
void menu_item_set_label(MenuItem* menu_item, const char* label) { void menu_item_set_label(MenuItem* menu_item, const char* label) {
assert(menu_item); furi_assert(menu_item);
menu_item->label = label; menu_item->label = label;
} }
const char* menu_item_get_label(MenuItem* menu_item) { const char* menu_item_get_label(MenuItem* menu_item) {
assert(menu_item); furi_assert(menu_item);
return menu_item->label; return menu_item->label;
} }
void menu_item_set_icon(MenuItem* menu_item, Icon* icon) { void menu_item_set_icon(MenuItem* menu_item, Icon* icon) {
assert(menu_item); furi_assert(menu_item);
menu_item->icon = icon; menu_item->icon = icon;
} }
Icon* menu_item_get_icon(MenuItem* menu_item) { Icon* menu_item_get_icon(MenuItem* menu_item) {
assert(menu_item); furi_assert(menu_item);
return menu_item->icon; return menu_item->icon;
} }
MenuItemArray_t* menu_item_get_subitems(MenuItem* menu_item) { MenuItemArray_t* menu_item_get_subitems(MenuItem* menu_item) {
assert(menu_item); furi_assert(menu_item);
assert(menu_item->type == MenuItemTypeMenu); furi_check(menu_item->type == MenuItemTypeMenu);
return menu_item->data; return menu_item->data;
} }
void menu_item_function_call(MenuItem* menu_item) { void menu_item_function_call(MenuItem* menu_item) {
assert(menu_item); furi_assert(menu_item);
assert(menu_item->type == MenuItemTypeFunction); furi_check(menu_item->type == MenuItemTypeFunction);
if(menu_item->callback) menu_item->callback(menu_item->callback_context); if(menu_item->callback) menu_item->callback(menu_item->callback_context);
} }

View File

@ -1,6 +1,7 @@
#include "dispatcher.h" #include "dispatcher.h"
#include <flipper.h> #include <flipper.h>
#include <flipper_v2.h>
struct Dispatcher { struct Dispatcher {
void* message; void* message;
@ -16,41 +17,41 @@ Dispatcher* dispatcher_alloc(size_t queue_size, size_t message_size) {
dispatcher->message_size = message_size; dispatcher->message_size = message_size;
dispatcher->mqueue = osMessageQueueNew(queue_size, message_size, NULL); dispatcher->mqueue = osMessageQueueNew(queue_size, message_size, NULL);
assert(dispatcher->mqueue); furi_check(dispatcher->mqueue);
dispatcher->lock_mutex = osMutexNew(NULL); dispatcher->lock_mutex = osMutexNew(NULL);
assert(dispatcher->lock_mutex); furi_check(dispatcher->lock_mutex);
dispatcher_lock(dispatcher); dispatcher_lock(dispatcher);
return dispatcher; return dispatcher;
} }
void dispatcher_free(Dispatcher* dispatcher) { void dispatcher_free(Dispatcher* dispatcher) {
assert(dispatcher); furi_assert(dispatcher);
free(dispatcher); free(dispatcher);
} }
void dispatcher_send(Dispatcher* dispatcher, Message* message) { void dispatcher_send(Dispatcher* dispatcher, Message* message) {
assert(dispatcher); furi_assert(dispatcher);
assert(message); furi_assert(message);
assert(osMessageQueuePut(dispatcher->mqueue, message, 0, osWaitForever) == osOK); furi_check(osMessageQueuePut(dispatcher->mqueue, message, 0, osWaitForever) == osOK);
} }
// TODO: bad side-effect // TODO: bad side-effect
void dispatcher_recieve(Dispatcher* dispatcher, Message* message) { void dispatcher_recieve(Dispatcher* dispatcher, Message* message) {
assert(dispatcher); furi_assert(dispatcher);
assert(message); furi_assert(message);
dispatcher_unlock(dispatcher); dispatcher_unlock(dispatcher);
assert(osMessageQueueGet(dispatcher->mqueue, message, NULL, osWaitForever) == osOK); furi_check(osMessageQueueGet(dispatcher->mqueue, message, NULL, osWaitForever) == osOK);
dispatcher_lock(dispatcher); dispatcher_lock(dispatcher);
} }
void dispatcher_lock(Dispatcher* dispatcher) { void dispatcher_lock(Dispatcher* dispatcher) {
assert(dispatcher); furi_assert(dispatcher);
assert(osMutexAcquire(dispatcher->lock_mutex, osWaitForever) == osOK); furi_check(osMutexAcquire(dispatcher->lock_mutex, osWaitForever) == osOK);
} }
void dispatcher_unlock(Dispatcher* dispatcher) { void dispatcher_unlock(Dispatcher* dispatcher) {
assert(dispatcher); furi_assert(dispatcher);
assert(osMutexRelease(dispatcher->lock_mutex) == osOK); furi_check(osMutexRelease(dispatcher->lock_mutex) == osOK);
} }

View File

@ -1,6 +1,5 @@
#include "nfc.h" #include "nfc.h"
#include <assert.h>
#include <flipper_v2.h> #include <flipper_v2.h>
#include <gui/gui.h> #include <gui/gui.h>
@ -152,7 +151,9 @@ void nfc_worker_task(void* context) {
} }
void nfc_draw_callback(CanvasApi* canvas, void* context) { void nfc_draw_callback(CanvasApi* canvas, void* context) {
assert(context); furi_assert(canvas);
furi_assert(context);
Nfc* nfc = context; Nfc* nfc = context;
dispatcher_lock(nfc->dispatcher); dispatcher_lock(nfc->dispatcher);
@ -187,7 +188,8 @@ void nfc_draw_callback(CanvasApi* canvas, void* context) {
} }
void nfc_input_callback(InputEvent* event, void* context) { void nfc_input_callback(InputEvent* event, void* context) {
assert(context); furi_assert(event);
furi_assert(context);
Nfc* nfc = context; Nfc* nfc = context;
if(!event->state) return; if(!event->state) return;
@ -196,7 +198,7 @@ void nfc_input_callback(InputEvent* event, void* context) {
} }
void nfc_test_callback(void* context) { void nfc_test_callback(void* context) {
assert(context); furi_assert(context);
Nfc* nfc = context; Nfc* nfc = context;
dispatcher_lock(nfc->dispatcher); dispatcher_lock(nfc->dispatcher);
@ -213,21 +215,21 @@ void nfc_test_callback(void* context) {
} }
void nfc_read_callback(void* context) { void nfc_read_callback(void* context) {
assert(context); furi_assert(context);
Nfc* nfc = context; Nfc* nfc = context;
nfc->screen = 1; nfc->screen = 1;
widget_enabled_set(nfc->widget, true); widget_enabled_set(nfc->widget, true);
} }
void nfc_write_callback(void* context) { void nfc_write_callback(void* context) {
assert(context); furi_assert(context);
Nfc* nfc = context; Nfc* nfc = context;
nfc->screen = 1; nfc->screen = 1;
widget_enabled_set(nfc->widget, true); widget_enabled_set(nfc->widget, true);
} }
void nfc_bridge_callback(void* context) { void nfc_bridge_callback(void* context) {
assert(context); furi_assert(context);
Nfc* nfc = context; Nfc* nfc = context;
nfc->screen = 1; nfc->screen = 1;
widget_enabled_set(nfc->widget, true); widget_enabled_set(nfc->widget, true);
@ -244,7 +246,7 @@ Nfc* nfc_alloc() {
widget_input_callback_set(nfc->widget, nfc_input_callback, nfc); widget_input_callback_set(nfc->widget, nfc_input_callback, nfc);
nfc->menu_vm = furi_open("menu"); nfc->menu_vm = furi_open("menu");
assert(nfc->menu_vm); furi_check(nfc->menu_vm);
nfc->menu = menu_item_alloc_menu("NFC", nfc->icon); nfc->menu = menu_item_alloc_menu("NFC", nfc->icon);
menu_item_subitem_add( menu_item_subitem_add(
@ -266,9 +268,9 @@ void nfc_task(void* p) {
Nfc* nfc = nfc_alloc(); Nfc* nfc = nfc_alloc();
FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL); FuriRecordSubscriber* gui_record = furi_open_deprecated("gui", false, false, NULL, NULL, NULL);
assert(gui_record); furi_check(gui_record);
GuiApi* gui = furi_take(gui_record); GuiApi* gui = furi_take(gui_record);
assert(gui); furi_check(gui);
widget_enabled_set(nfc->widget, false); widget_enabled_set(nfc->widget, false);
gui->add_widget(gui, nfc->widget, GuiLayerFullscreen); gui->add_widget(gui, nfc->widget, GuiLayerFullscreen);
furi_commit(gui_record); furi_commit(gui_record);

41
core/api-basic/check.c Normal file
View File

@ -0,0 +1,41 @@
#include "check.h"
#include "api-hal-task.h"
void __furi_abort(void);
// TODO printf doesnt work in ISR context
void __furi_check(void) {
printf("assertion failed in release mode, switch to debug mode to see full assert info");
__furi_abort();
}
// TODO printf doesnt work in ISR context
void __furi_check_debug(const char* file, int line, const char* function, const char* condition) {
printf(
"assertion \"%s\" failed: file \"%s\", line %d%s%s",
condition,
file,
line,
function ? ", function: " : "",
function ? function : "");
if(task_is_isr_context()) {
printf(" in [ISR] context");
} else {
FuriApp* app = find_task(xTaskGetCurrentTaskHandle());
if(app == NULL) {
printf(", in [main] context");
} else {
printf(", in [%s] app context", app->name);
}
}
__furi_abort();
}
void __furi_abort(void) {
taskDISABLE_INTERRUPTS();
while(1) {
}
}

41
core/api-basic/check.h Normal file
View File

@ -0,0 +1,41 @@
#pragma once
#include "flipper.h"
// Find how to how get function's pretty name
#ifndef __FURI_CHECK_FUNC
// Use g++'s demangled names in C++
#if defined __cplusplus && defined __GNUC__
#define __FURI_CHECK_FUNC __PRETTY_FUNCTION__
// C99 requires the use of __func__
#elif __STDC_VERSION__ >= 199901L
#define __FURI_CHECK_FUNC __func__
// Older versions of gcc don't have __func__ but can use __FUNCTION__
#elif __GNUC__ >= 2
#define __FURI_CHECK_FUNC __FUNCTION__
// failed to detect __func__ support
#else
#define __FURI_CHECK_FUNC ((char*)0)
#endif
#endif
// !__FURI_CHECK_FUNC
// We have two levels of assertion
// One - furi_check, which always runs, the only difference is in the level of debug information
// The second is furi_assert, which doesn't compile in release mode
#ifdef NDEBUG
#define furi_check(__e) ((__e) ? (void)0 : __furi_check())
#define furi_assert(__e) ((void)0)
#else
#define furi_check(__e) \
((__e) ? (void)0 : __furi_check_debug(__FILE__, __LINE__, __FURI_CHECK_FUNC, #__e))
#define furi_assert(__e) \
((__e) ? (void)0 : __furi_check_debug(__FILE__, __LINE__, __FURI_CHECK_FUNC, #__e))
#endif
// !NDEBUG
void __furi_check(void);
void __furi_check_debug(const char* file, int line, const char* function, const char* condition);

View File

@ -49,7 +49,7 @@ static inline void* acquire_mutex_block(ValueMutex* valuemutex) {
#define with_value_mutex(value_mutex, function_body) \ #define with_value_mutex(value_mutex, function_body) \
{ \ { \
void* p = acquire_mutex_block(value_mutex); \ void* p = acquire_mutex_block(value_mutex); \
assert(p); \ furi_check(p); \
({ void __fn__ function_body __fn__; })(p); \ ({ void __fn__ function_body __fn__; })(p); \
release_mutex(value_mutex, p); \ release_mutex(value_mutex, p); \
} }

View File

@ -15,6 +15,7 @@ extern "C" {
#include "api-basic/event.h" #include "api-basic/event.h"
#include "api-basic/memmgr.h" #include "api-basic/memmgr.h"
#include "api-basic/check.h"
#include "api-hal/api-gpio.h" #include "api-hal/api-gpio.h"

View File

@ -0,0 +1,54 @@
#include "api-hal-task.h"
#include "cmsis_os.h"
//-----------------------------cmsis_os2.c-------------------------------
// helpers to get isr context
// get arch
#ifndef __ARM_ARCH_6M__
#define __ARM_ARCH_6M__ 0
#endif
#ifndef __ARM_ARCH_7M__
#define __ARM_ARCH_7M__ 0
#endif
#ifndef __ARM_ARCH_7EM__
#define __ARM_ARCH_7EM__ 0
#endif
#ifndef __ARM_ARCH_8M_MAIN__
#define __ARM_ARCH_8M_MAIN__ 0
#endif
#ifndef __ARM_ARCH_7A__
#define __ARM_ARCH_7A__ 0
#endif
// get masks
#if((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M_MAIN__ == 1U))
#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U))
#elif(__ARM_ARCH_6M__ == 1U)
#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
#elif(__ARM_ARCH_7A__ == 1U)
/* CPSR mask bits */
#define CPSR_MASKBIT_I 0x80U
#define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U)
#else
#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
#endif
// get is irq mode
#if(__ARM_ARCH_7A__ == 1U)
/* CPSR mode bitmasks */
#define CPSR_MODE_USER 0x10U
#define CPSR_MODE_SYSTEM 0x1FU
#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
#else
#define IS_IRQ_MODE() (__get_IPSR() != 0U)
#endif
// added osKernelGetState(), because KernelState is a static var
#define IS_IRQ() (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (osKernelGetState() == osKernelRunning)))
//-------------------------end of cmsis_os2.c----------------------------
bool task_is_isr_context(void) {
return IS_IRQ();
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "main.h"
#include <stdbool.h>
bool task_is_isr_context(void);

View File

@ -3,3 +3,4 @@
#include "api-hal-gpio.h" #include "api-hal-gpio.h"
#include "api-hal-delay.h" #include "api-hal-delay.h"
#include "api-hal-pwm.h" #include "api-hal-pwm.h"
#include "api-hal-task.h"

View File

@ -0,0 +1,5 @@
#include "api-hal-task.h"
bool task_is_isr_context(void) {
return false;
}

View File

@ -0,0 +1,5 @@
#pragma once
#include "main.h"
#include <stdbool.h>
bool task_is_isr_context(void);