From 8aeafd8179f74e360222d24230e386c13e174e7d Mon Sep 17 00:00:00 2001 From: DrZlo13 Date: Thu, 29 Oct 2020 09:27:17 +0300 Subject: [PATCH] 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 Co-authored-by: coreglitch --- applications/app-loader/app-loader.c | 3 +- .../backlight-control/backlight-control.c | 2 +- .../cc1101-workaround/cc1101-workaround.cpp | 2 +- applications/examples/input_dump.c | 4 +- applications/gui/canvas.c | 32 +++++------ applications/gui/gui.c | 28 +++++----- applications/gui/gui_event.c | 24 +++++---- applications/gui/icon.c | 18 +++---- applications/gui/widget.c | 31 +++++------ applications/irukagotchi/irukagotchi.c | 7 ++- applications/menu/menu.c | 24 ++++----- applications/menu/menu_event.c | 16 +++--- applications/menu/menu_item.c | 33 ++++++------ applications/nfc/dispatcher.c | 27 +++++----- applications/nfc/nfc.c | 22 ++++---- core/api-basic/check.c | 41 ++++++++++++++ core/api-basic/check.h | 41 ++++++++++++++ core/api-basic/valuemutex.h | 2 +- core/flipper_v2.h | 1 + firmware/targets/f2/api-hal/api-hal-task.c | 54 +++++++++++++++++++ firmware/targets/f2/api-hal/api-hal-task.h | 5 ++ firmware/targets/f2/api-hal/api-hal.h | 1 + firmware/targets/local/api-hal/api-hal-task.c | 5 ++ firmware/targets/local/api-hal/api-hal-task.h | 5 ++ 24 files changed, 292 insertions(+), 136 deletions(-) create mode 100644 core/api-basic/check.c create mode 100644 core/api-basic/check.h create mode 100644 firmware/targets/f2/api-hal/api-hal-task.c create mode 100644 firmware/targets/f2/api-hal/api-hal-task.h create mode 100644 firmware/targets/local/api-hal/api-hal-task.c create mode 100644 firmware/targets/local/api-hal/api-hal-task.h diff --git a/applications/app-loader/app-loader.c b/applications/app-loader/app-loader.c index b9d0fb3a..bd0419d2 100644 --- a/applications/app-loader/app-loader.c +++ b/applications/app-loader/app-loader.c @@ -51,13 +51,12 @@ static void handle_menu(void* _ctx) { void app_loader(void* p) { osThreadId_t self_id = osThreadGetId(); - assert(self_id); + furi_check(self_id); AppLoaderState state; state.handler = NULL; state.widget = widget_alloc(); - assert(state.widget); widget_enabled_set(state.widget, false); widget_draw_callback_set(state.widget, render_callback, &state); widget_input_callback_set(state.widget, input_callback, &state); diff --git a/applications/backlight-control/backlight-control.c b/applications/backlight-control/backlight-control.c index 014f2f13..3ef42a90 100644 --- a/applications/backlight-control/backlight-control.c +++ b/applications/backlight-control/backlight-control.c @@ -15,7 +15,7 @@ void backlight_control(void* p) { // open record PubSub* event_record = furi_open("input_events"); - assert(event_record != NULL); + furi_check(event_record); subscribe_pubsub(event_record, event_cb, (void*)update); // we ready to work diff --git a/applications/cc1101-workaround/cc1101-workaround.cpp b/applications/cc1101-workaround/cc1101-workaround.cpp index ac66e629..b794bd23 100644 --- a/applications/cc1101-workaround/cc1101-workaround.cpp +++ b/applications/cc1101-workaround/cc1101-workaround.cpp @@ -203,7 +203,7 @@ static void input_callback(InputEvent* input_event, void* ctx) { extern "C" void cc1101_workaround(void* p) { osMessageQueueId_t event_queue = osMessageQueueNew(1, sizeof(AppEvent), NULL); - assert(event_queue); + furi_check(event_queue); State _state; _state.mode = ModeRx; diff --git a/applications/examples/input_dump.c b/applications/examples/input_dump.c index 1ab70c32..ce740d9c 100644 --- a/applications/examples/input_dump.c +++ b/applications/examples/input_dump.c @@ -16,11 +16,11 @@ static void event_cb(const void* value, void* ctx) { void application_input_dump(void* p) { // open record ValueManager* state_record = furi_open("input_state"); - assert(state_record != NULL); + furi_check(state_record); subscribe_pubsub(&state_record->pubsub, state_cb, NULL); PubSub* event_record = furi_open("input_events"); - assert(event_record != NULL); + furi_check(event_record); subscribe_pubsub(event_record, event_cb, NULL); for(;;) { diff --git a/applications/gui/canvas.c b/applications/gui/canvas.c index 4f5af999..77ef2075 100644 --- a/applications/gui/canvas.c +++ b/applications/gui/canvas.c @@ -3,8 +3,8 @@ #include "icon.h" #include "icon_i.h" -#include #include +#include typedef struct { CanvasApi api; @@ -60,12 +60,12 @@ CanvasApi* canvas_api_init() { } void canvas_api_free(CanvasApi* api) { - assert(api); + furi_assert(api); free(api); } void canvas_commit(CanvasApi* api) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; u8g2_SetPowerSave(&canvas->fb, 0); // wake up display u8g2_SendBuffer(&canvas->fb); @@ -77,7 +77,7 @@ void canvas_frame_set( uint8_t offset_y, uint8_t width, uint8_t height) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; canvas->offset_x = offset_x; canvas->offset_y = offset_y; @@ -86,31 +86,31 @@ void canvas_frame_set( } uint8_t canvas_width(CanvasApi* api) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; return canvas->width; } uint8_t canvas_height(CanvasApi* api) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; return canvas->height; } void canvas_clear(CanvasApi* api) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; u8g2_ClearBuffer(&canvas->fb); } void canvas_color_set(CanvasApi* api, Color color) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; u8g2_SetDrawColor(&canvas->fb, color); } void canvas_font_set(CanvasApi* api, Font font) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; u8g2_SetFontMode(&canvas->fb, 1); if(font == FontPrimary) { @@ -118,12 +118,12 @@ void canvas_font_set(CanvasApi* api, Font font) { } else if(font == FontSecondary) { u8g2_SetFont(&canvas->fb, u8g2_font_HelvetiPixel_tr); } else { - assert(0); + furi_check(0); } } void canvas_str_draw(CanvasApi* api, uint8_t x, uint8_t y, const char* str) { - assert(api); + furi_assert(api); if(!str) return; Canvas* canvas = (Canvas*)api; 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) { - assert(api); + furi_assert(api); if(!icon) return; Canvas* canvas = (Canvas*)api; 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) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; u8g2_DrawPixel(&canvas->fb, x, y); } 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; 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) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; 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) { - assert(api); + furi_assert(api); Canvas* canvas = (Canvas*)api; u8g2_DrawLine(&canvas->fb, x1, y1, x2, y2); } diff --git a/applications/gui/gui.c b/applications/gui/gui.c index cdfa3f7e..78b14932 100644 --- a/applications/gui/gui.c +++ b/applications/gui/gui.c @@ -34,7 +34,7 @@ Widget* gui_widget_find_enabled(WidgetArray_t array) { } void gui_update(Gui* gui) { - assert(gui); + furi_assert(gui); GuiMessage message; message.type = GuiMessageTypeRedraw; gui_event_messsage_send(gui->event, &message); @@ -83,7 +83,7 @@ bool gui_redraw_none(Gui* gui) { } void gui_redraw(Gui* gui) { - assert(gui); + furi_assert(gui); gui_lock(gui); if(!gui_redraw_fs(gui)) { @@ -98,7 +98,9 @@ void gui_redraw(Gui* gui) { } void gui_input(Gui* gui, InputEvent* input_event) { - assert(gui); + furi_assert(gui); + furi_assert(input_event); + gui_lock(gui); 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) { - assert(gui); - assert(osMutexAcquire(gui->mutex, osWaitForever) == osOK); + furi_assert(gui); + furi_check(osMutexAcquire(gui->mutex, osWaitForever) == osOK); } void gui_unlock(Gui* gui) { - assert(gui); - assert(osMutexRelease(gui->mutex) == osOK); + furi_assert(gui); + furi_check(osMutexRelease(gui->mutex) == osOK); } void gui_add_widget(GuiApi* gui_api, Widget* widget, GuiLayer layer) { - assert(gui_api); - assert(widget); - assert(layer < GuiLayerMAX); + furi_assert(gui_api); + furi_assert(widget); + furi_check(layer < GuiLayerMAX); Gui* gui = (Gui*)gui_api; 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) { - assert(gui_api); - assert(widget); + furi_assert(gui_api); + furi_assert(widget); Gui* gui = (Gui*)gui_api; gui_lock(gui); @@ -164,7 +166,7 @@ Gui* gui_alloc() { gui->api.remove_widget = gui_remove_widget; // Allocate mutex gui->mutex = osMutexNew(NULL); - assert(gui->mutex); + furi_check(gui->mutex); // Event dispatcher gui->event = gui_event_alloc(); // Drawing canvas api diff --git a/applications/gui/gui_event.c b/applications/gui/gui_event.c index c178b6e4..bc532a26 100644 --- a/applications/gui/gui_event.c +++ b/applications/gui/gui_event.c @@ -1,7 +1,6 @@ #include "gui_event.h" #include -#include #define GUI_EVENT_MQUEUE_SIZE 8 @@ -11,7 +10,9 @@ struct GuiEvent { }; void gui_event_input_events_callback(const void* value, void* ctx) { - assert(ctx); + furi_assert(value); + furi_assert(ctx); + GuiEvent* gui_event = ctx; GuiMessage message; @@ -23,35 +24,36 @@ void gui_event_input_events_callback(const void* value, void* ctx) { GuiEvent* gui_event_alloc() { GuiEvent* gui_event = furi_alloc(sizeof(GuiEvent)); - // Allocate message que + + // Allocate message queue gui_event->mqueue = osMessageQueueNew(GUI_EVENT_MQUEUE_SIZE, sizeof(GuiMessage), NULL); - assert(gui_event->mqueue); + furi_check(gui_event->mqueue); // Input 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); return gui_event; } void gui_event_free(GuiEvent* gui_event) { - assert(gui_event); - assert(osMessageQueueDelete(gui_event->mqueue) == osOK); + furi_assert(gui_event); + furi_check(osMessageQueueDelete(gui_event->mqueue) == osOK); free(gui_event); } void gui_event_messsage_send(GuiEvent* gui_event, GuiMessage* message) { - assert(gui_event); - assert(message); + furi_assert(gui_event); + furi_assert(message); osMessageQueuePut(gui_event->mqueue, message, 0, 0); } GuiMessage gui_event_message_next(GuiEvent* gui_event) { - assert(gui_event); + furi_assert(gui_event); GuiMessage message; - assert(osMessageQueueGet(gui_event->mqueue, &message, NULL, osWaitForever) == osOK); + furi_check(osMessageQueueGet(gui_event->mqueue, &message, NULL, osWaitForever) == osOK); return message; } diff --git a/applications/gui/icon.c b/applications/gui/icon.c index 97d4639c..dabff14f 100644 --- a/applications/gui/icon.c +++ b/applications/gui/icon.c @@ -3,7 +3,7 @@ #include #include -#include +#include Icon* icon_alloc(const IconData* data) { Icon* icon = furi_alloc(sizeof(Icon)); @@ -12,12 +12,12 @@ Icon* icon_alloc(const IconData* data) { } void icon_free(Icon* icon) { - assert(icon); + furi_assert(icon); free(icon); } const uint8_t* icon_get_data(Icon* icon) { - assert(icon); + furi_assert(icon); if(icon->tick) { uint32_t now = osKernelGetTickCount(); if(now < icon->tick) { @@ -32,32 +32,32 @@ const uint8_t* icon_get_data(Icon* icon) { } void icon_next_frame(Icon* icon) { - assert(icon); + furi_assert(icon); icon->frame = (icon->frame + 1) % icon->data->frame_count; } uint8_t icon_get_width(Icon* icon) { - assert(icon); + furi_assert(icon); return icon->data->width; } uint8_t icon_get_height(Icon* icon) { - assert(icon); + furi_assert(icon); return icon->data->height; } bool icon_is_animated(Icon* icon) { - assert(icon); + furi_assert(icon); return icon->data->frame_count > 1; } void icon_start_animation(Icon* icon) { - assert(icon); + furi_assert(icon); icon->tick = osKernelGetTickCount(); } void icon_stop_animation(Icon* icon) { - assert(icon); + furi_assert(icon); icon->tick = 0; icon->frame = 0; } diff --git a/applications/gui/widget.c b/applications/gui/widget.c index 2a97a593..2b231efe 100644 --- a/applications/gui/widget.c +++ b/applications/gui/widget.c @@ -3,6 +3,7 @@ #include #include +#include #include "gui.h" #include "gui_i.h" @@ -25,13 +26,13 @@ Widget* widget_alloc(WidgetDrawCallback callback, void* callback_context) { } void widget_free(Widget* widget) { - assert(widget); - assert(widget->gui == NULL); + furi_assert(widget); + furi_check(widget->gui == NULL); free(widget); } void widget_enabled_set(Widget* widget, bool enabled) { - assert(widget); + furi_assert(widget); if(widget->is_enabled != enabled) { widget->is_enabled = enabled; widget_update(widget); @@ -39,47 +40,47 @@ void widget_enabled_set(Widget* widget, bool enabled) { } bool widget_is_enabled(Widget* widget) { - assert(widget); + furi_assert(widget); return widget->is_enabled; } void widget_draw_callback_set(Widget* widget, WidgetDrawCallback callback, void* context) { - assert(widget); + furi_assert(widget); widget->draw_callback = callback; widget->draw_callback_context = context; } void widget_input_callback_set(Widget* widget, WidgetInputCallback callback, void* context) { - assert(widget); + furi_assert(widget); widget->input_callback = callback; widget->input_callback_context = context; } void widget_update(Widget* widget) { - assert(widget); + furi_assert(widget); if(widget->gui) gui_update(widget->gui); } void widget_gui_set(Widget* widget, Gui* gui) { - assert(widget); - assert(gui); + furi_assert(widget); + furi_assert(gui); widget->gui = gui; } void widget_draw(Widget* widget, CanvasApi* canvas_api) { - assert(widget); - assert(canvas_api); - assert(widget->gui); + furi_assert(widget); + furi_assert(canvas_api); + furi_check(widget->gui); if(widget->draw_callback) { widget->draw_callback(canvas_api, widget->draw_callback_context); } } void widget_input(Widget* widget, InputEvent* event) { - assert(widget); - assert(event); - assert(widget->gui); + furi_assert(widget); + furi_assert(event); + furi_check(widget->gui); if(widget->input_callback) widget->input_callback(event, widget->input_callback_context); } diff --git a/applications/irukagotchi/irukagotchi.c b/applications/irukagotchi/irukagotchi.c index 2e317d9e..7698a3f6 100644 --- a/applications/irukagotchi/irukagotchi.c +++ b/applications/irukagotchi/irukagotchi.c @@ -1,6 +1,5 @@ #include "irukagotchi.h" -#include #include #include @@ -46,7 +45,7 @@ Irukagotchi* irukagotchi_alloc() { widget_input_callback_set(irukagotchi->widget, irukagotchi_input_callback, irukagotchi); irukagotchi->menu_vm = furi_open("menu"); - assert(irukagotchi->menu_vm); + furi_check(irukagotchi->menu_vm); return irukagotchi; } @@ -55,9 +54,9 @@ void irukagotchi_task() { Irukagotchi* irukagotchi = irukagotchi_alloc(); 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); - assert(gui); + furi_check(gui); gui->add_widget(gui, irukagotchi->widget, GuiLayerNone); furi_commit(gui_record); diff --git a/applications/menu/menu.c b/applications/menu/menu.c index 77bb28aa..cd110c42 100644 --- a/applications/menu/menu.c +++ b/applications/menu/menu.c @@ -41,7 +41,7 @@ ValueMutex* menu_init() { // Open GUI and register fullscreen widget GuiApi* gui = furi_open("gui"); - assert(gui); + furi_check(gui); gui->add_widget(gui, menu->widget, GuiLayerFullscreen); widget_enabled_set(menu->widget, false); @@ -52,7 +52,7 @@ ValueMutex* menu_init() { } void menu_build_main(Menu* menu) { - assert(menu); + furi_assert(menu); // Root point 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) { - assert(canvas); - assert(context); + furi_assert(canvas); + furi_assert(context); Menu* menu = acquire_mutex((ValueMutex*)context, 100); // wait 10 ms to get mutex if(menu == NULL) return; // redraw fail - assert(menu->current); + furi_assert(menu->current); canvas->clear(canvas); canvas->set_color(canvas, ColorBlack); @@ -123,14 +123,14 @@ void menu_widget_callback(CanvasApi* canvas, void* context) { } void menu_update(Menu* menu) { - assert(menu); + furi_assert(menu); menu_event_activity_notify(menu->event); widget_update(menu->widget); } void menu_up(Menu* menu) { - assert(menu); + furi_assert(menu); size_t position = menu_item_get_position(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) { - assert(menu); + furi_assert(menu); size_t position = menu_item_get_position(menu->current); MenuItemArray_t* items = menu_item_get_subitems(menu->current); position++; @@ -151,7 +151,7 @@ void menu_down(Menu* menu) { } void menu_ok(Menu* menu) { - assert(menu); + furi_assert(menu); if(!menu->current) { widget_enabled_set(menu->widget, true); @@ -180,7 +180,7 @@ void menu_ok(Menu* menu) { } void menu_back(Menu* menu) { - assert(menu); + furi_assert(menu); MenuItem* parent = menu_item_get_parent(menu->current); if(parent) { menu->current = parent; @@ -191,7 +191,7 @@ void menu_back(Menu* menu) { } void menu_exit(Menu* menu) { - assert(menu); + furi_assert(menu); widget_enabled_set(menu->widget, false); menu->current = NULL; menu_update(menu); @@ -203,7 +203,7 @@ void menu_task(void* p) { MenuEvent* menu_event = NULL; { Menu* menu = acquire_mutex_block(menu_mutex); - assert(menu); + furi_check(menu); menu_build_main(menu); diff --git a/applications/menu/menu_event.c b/applications/menu/menu_event.c index af0f1227..e5053af2 100644 --- a/applications/menu/menu_event.c +++ b/applications/menu/menu_event.c @@ -1,11 +1,11 @@ #include "menu_event.h" #include -#include #include #include #include +#include #define MENU_MESSAGE_MQUEUE_SIZE 8 @@ -25,30 +25,28 @@ MenuEvent* menu_event_alloc() { MenuEvent* menu_event = furi_alloc(sizeof(MenuEvent)); menu_event->mqueue = osMessageQueueNew(MENU_MESSAGE_MQUEUE_SIZE, sizeof(MenuMessage), NULL); - assert(menu_event->mqueue); + furi_check(menu_event->mqueue); menu_event->timeout_timer = osTimerNew(MenuEventimeout_callback, osTimerOnce, menu_event, NULL); - assert(menu_event->timeout_timer); + furi_check(menu_event->timeout_timer); return menu_event; } void menu_event_free(MenuEvent* menu_event) { - osStatus_t status; - assert(menu_event); - status = osMessageQueueDelete(menu_event->mqueue); - assert(status == osOK); + furi_assert(menu_event); + furi_check(osMessageQueueDelete(menu_event->mqueue) == osOK); free(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 } MenuMessage menu_event_next(MenuEvent* menu_event) { - assert(menu_event); + furi_assert(menu_event); MenuMessage message; while(osMessageQueueGet(menu_event->mqueue, &message, NULL, osWaitForever) != osOK) { }; diff --git a/applications/menu/menu_item.c b/applications/menu/menu_item.c index 8e1e790e..8c8cb273 100644 --- a/applications/menu/menu_item.c +++ b/applications/menu/menu_item.c @@ -1,8 +1,8 @@ #include "menu_item.h" #include -#include #include #include +#include struct MenuItem { MenuItemType type; @@ -52,7 +52,7 @@ menu_item_alloc_function(const char* label, Icon* icon, MenuItemCallback callbac } void menu_item_release(MenuItem* menu_item) { - assert(menu_item); + furi_assert(menu_item); if(menu_item->type == MenuItemTypeMenu) { //TODO: iterate and release free(menu_item->data); @@ -61,62 +61,61 @@ void menu_item_release(MenuItem* menu_item) { } MenuItem* menu_item_get_parent(MenuItem* menu_item) { - assert(menu_item); + furi_assert(menu_item); return menu_item->parent; } void menu_item_subitem_add(MenuItem* menu_item, MenuItem* sub_item) { - assert(menu_item); - assert(menu_item->type == MenuItemTypeMenu); + furi_assert(menu_item); + furi_check(menu_item->type == MenuItemTypeMenu); MenuItemArray_t* items = menu_item->data; sub_item->parent = menu_item; MenuItemArray_push_back(*items, sub_item); } uint8_t menu_item_get_type(MenuItem* menu_item) { - assert(menu_item); + furi_assert(menu_item); return menu_item->type; } void menu_item_set_position(MenuItem* menu_item, size_t position) { - assert(menu_item); + furi_assert(menu_item); menu_item->position = position; } size_t menu_item_get_position(MenuItem* menu_item) { - assert(menu_item); + furi_assert(menu_item); return menu_item->position; } void menu_item_set_label(MenuItem* menu_item, const char* label) { - assert(menu_item); + furi_assert(menu_item); menu_item->label = label; } const char* menu_item_get_label(MenuItem* menu_item) { - assert(menu_item); + furi_assert(menu_item); return menu_item->label; } void menu_item_set_icon(MenuItem* menu_item, Icon* icon) { - assert(menu_item); + furi_assert(menu_item); menu_item->icon = icon; } Icon* menu_item_get_icon(MenuItem* menu_item) { - assert(menu_item); + furi_assert(menu_item); return menu_item->icon; } MenuItemArray_t* menu_item_get_subitems(MenuItem* menu_item) { - assert(menu_item); - assert(menu_item->type == MenuItemTypeMenu); + furi_assert(menu_item); + furi_check(menu_item->type == MenuItemTypeMenu); return menu_item->data; } void menu_item_function_call(MenuItem* menu_item) { - assert(menu_item); - assert(menu_item->type == MenuItemTypeFunction); - + furi_assert(menu_item); + furi_check(menu_item->type == MenuItemTypeFunction); if(menu_item->callback) menu_item->callback(menu_item->callback_context); } diff --git a/applications/nfc/dispatcher.c b/applications/nfc/dispatcher.c index 0d106a6b..8e2a9c83 100644 --- a/applications/nfc/dispatcher.c +++ b/applications/nfc/dispatcher.c @@ -1,6 +1,7 @@ #include "dispatcher.h" #include +#include struct Dispatcher { void* message; @@ -16,41 +17,41 @@ Dispatcher* dispatcher_alloc(size_t queue_size, size_t message_size) { dispatcher->message_size = message_size; dispatcher->mqueue = osMessageQueueNew(queue_size, message_size, NULL); - assert(dispatcher->mqueue); + furi_check(dispatcher->mqueue); dispatcher->lock_mutex = osMutexNew(NULL); - assert(dispatcher->lock_mutex); + furi_check(dispatcher->lock_mutex); dispatcher_lock(dispatcher); return dispatcher; } void dispatcher_free(Dispatcher* dispatcher) { - assert(dispatcher); + furi_assert(dispatcher); free(dispatcher); } void dispatcher_send(Dispatcher* dispatcher, Message* message) { - assert(dispatcher); - assert(message); - assert(osMessageQueuePut(dispatcher->mqueue, message, 0, osWaitForever) == osOK); + furi_assert(dispatcher); + furi_assert(message); + furi_check(osMessageQueuePut(dispatcher->mqueue, message, 0, osWaitForever) == osOK); } // TODO: bad side-effect void dispatcher_recieve(Dispatcher* dispatcher, Message* message) { - assert(dispatcher); - assert(message); + furi_assert(dispatcher); + furi_assert(message); dispatcher_unlock(dispatcher); - assert(osMessageQueueGet(dispatcher->mqueue, message, NULL, osWaitForever) == osOK); + furi_check(osMessageQueueGet(dispatcher->mqueue, message, NULL, osWaitForever) == osOK); dispatcher_lock(dispatcher); } void dispatcher_lock(Dispatcher* dispatcher) { - assert(dispatcher); - assert(osMutexAcquire(dispatcher->lock_mutex, osWaitForever) == osOK); + furi_assert(dispatcher); + furi_check(osMutexAcquire(dispatcher->lock_mutex, osWaitForever) == osOK); } void dispatcher_unlock(Dispatcher* dispatcher) { - assert(dispatcher); - assert(osMutexRelease(dispatcher->lock_mutex) == osOK); + furi_assert(dispatcher); + furi_check(osMutexRelease(dispatcher->lock_mutex) == osOK); } diff --git a/applications/nfc/nfc.c b/applications/nfc/nfc.c index 3b57319b..a87bf240 100644 --- a/applications/nfc/nfc.c +++ b/applications/nfc/nfc.c @@ -1,6 +1,5 @@ #include "nfc.h" -#include #include #include @@ -152,7 +151,9 @@ void nfc_worker_task(void* context) { } void nfc_draw_callback(CanvasApi* canvas, void* context) { - assert(context); + furi_assert(canvas); + furi_assert(context); + Nfc* nfc = context; dispatcher_lock(nfc->dispatcher); @@ -187,7 +188,8 @@ void nfc_draw_callback(CanvasApi* canvas, void* context) { } void nfc_input_callback(InputEvent* event, void* context) { - assert(context); + furi_assert(event); + furi_assert(context); Nfc* nfc = context; if(!event->state) return; @@ -196,7 +198,7 @@ void nfc_input_callback(InputEvent* event, void* context) { } void nfc_test_callback(void* context) { - assert(context); + furi_assert(context); Nfc* nfc = context; dispatcher_lock(nfc->dispatcher); @@ -213,21 +215,21 @@ void nfc_test_callback(void* context) { } void nfc_read_callback(void* context) { - assert(context); + furi_assert(context); Nfc* nfc = context; nfc->screen = 1; widget_enabled_set(nfc->widget, true); } void nfc_write_callback(void* context) { - assert(context); + furi_assert(context); Nfc* nfc = context; nfc->screen = 1; widget_enabled_set(nfc->widget, true); } void nfc_bridge_callback(void* context) { - assert(context); + furi_assert(context); Nfc* nfc = context; nfc->screen = 1; widget_enabled_set(nfc->widget, true); @@ -244,7 +246,7 @@ Nfc* nfc_alloc() { widget_input_callback_set(nfc->widget, nfc_input_callback, nfc); nfc->menu_vm = furi_open("menu"); - assert(nfc->menu_vm); + furi_check(nfc->menu_vm); nfc->menu = menu_item_alloc_menu("NFC", nfc->icon); menu_item_subitem_add( @@ -266,9 +268,9 @@ void nfc_task(void* p) { Nfc* nfc = nfc_alloc(); 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); - assert(gui); + furi_check(gui); widget_enabled_set(nfc->widget, false); gui->add_widget(gui, nfc->widget, GuiLayerFullscreen); furi_commit(gui_record); diff --git a/core/api-basic/check.c b/core/api-basic/check.c new file mode 100644 index 00000000..edd50a7d --- /dev/null +++ b/core/api-basic/check.c @@ -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) { + } +} \ No newline at end of file diff --git a/core/api-basic/check.h b/core/api-basic/check.h new file mode 100644 index 00000000..60758792 --- /dev/null +++ b/core/api-basic/check.h @@ -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); \ No newline at end of file diff --git a/core/api-basic/valuemutex.h b/core/api-basic/valuemutex.h index aff5ffe4..986e936a 100644 --- a/core/api-basic/valuemutex.h +++ b/core/api-basic/valuemutex.h @@ -49,7 +49,7 @@ static inline void* acquire_mutex_block(ValueMutex* valuemutex) { #define with_value_mutex(value_mutex, function_body) \ { \ void* p = acquire_mutex_block(value_mutex); \ - assert(p); \ + furi_check(p); \ ({ void __fn__ function_body __fn__; })(p); \ release_mutex(value_mutex, p); \ } diff --git a/core/flipper_v2.h b/core/flipper_v2.h index 7e72f9d9..e0de77b4 100644 --- a/core/flipper_v2.h +++ b/core/flipper_v2.h @@ -15,6 +15,7 @@ extern "C" { #include "api-basic/event.h" #include "api-basic/memmgr.h" +#include "api-basic/check.h" #include "api-hal/api-gpio.h" diff --git a/firmware/targets/f2/api-hal/api-hal-task.c b/firmware/targets/f2/api-hal/api-hal-task.c new file mode 100644 index 00000000..c6127d65 --- /dev/null +++ b/firmware/targets/f2/api-hal/api-hal-task.c @@ -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(); +} \ No newline at end of file diff --git a/firmware/targets/f2/api-hal/api-hal-task.h b/firmware/targets/f2/api-hal/api-hal-task.h new file mode 100644 index 00000000..87ee5ae7 --- /dev/null +++ b/firmware/targets/f2/api-hal/api-hal-task.h @@ -0,0 +1,5 @@ +#pragma once +#include "main.h" +#include + +bool task_is_isr_context(void); \ No newline at end of file diff --git a/firmware/targets/f2/api-hal/api-hal.h b/firmware/targets/f2/api-hal/api-hal.h index b5dd7707..68fb0bfb 100644 --- a/firmware/targets/f2/api-hal/api-hal.h +++ b/firmware/targets/f2/api-hal/api-hal.h @@ -3,3 +3,4 @@ #include "api-hal-gpio.h" #include "api-hal-delay.h" #include "api-hal-pwm.h" +#include "api-hal-task.h" diff --git a/firmware/targets/local/api-hal/api-hal-task.c b/firmware/targets/local/api-hal/api-hal-task.c new file mode 100644 index 00000000..9729cedd --- /dev/null +++ b/firmware/targets/local/api-hal/api-hal-task.c @@ -0,0 +1,5 @@ +#include "api-hal-task.h" + +bool task_is_isr_context(void) { + return false; +} \ No newline at end of file diff --git a/firmware/targets/local/api-hal/api-hal-task.h b/firmware/targets/local/api-hal/api-hal-task.h new file mode 100644 index 00000000..87ee5ae7 --- /dev/null +++ b/firmware/targets/local/api-hal/api-hal-task.h @@ -0,0 +1,5 @@ +#pragma once +#include "main.h" +#include + +bool task_is_isr_context(void); \ No newline at end of file