Skip to content

Commit

Permalink
Protect screen refresh from switch_view() with a mutex.
Browse files Browse the repository at this point in the history
  • Loading branch information
antirez committed Jan 24, 2023
1 parent 05899c2 commit 2a791b1
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 2 deletions.
7 changes: 7 additions & 0 deletions app.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extern const SubGhzProtocolRegistry protoview_protocol_registry;
* and setting color to black. */
static void render_callback(Canvas *const canvas, void *ctx) {
ProtoViewApp *app = ctx;
furi_mutex_acquire(app->view_updating_mutex,FuriWaitForever);

/* Clear screen. */
canvas_set_color(canvas, ColorWhite);
Expand All @@ -37,6 +38,7 @@ static void render_callback(Canvas *const canvas, void *ctx) {

/* Draw the alert box if set. */
ui_draw_alert_if_needed(canvas, app);
furi_mutex_release(app->view_updating_mutex);
}

/* Here all we do is putting the events into the queue that will be handled
Expand All @@ -55,6 +57,8 @@ static void input_callback(InputEvent* input_event, void* ctx)
* special views ViewGoNext and ViewGoPrev in order to move to
* the logical next/prev view. */
static void app_switch_view(ProtoViewApp *app, ProtoViewCurrentView switchto) {
furi_mutex_acquire(app->view_updating_mutex,FuriWaitForever);

/* Switch to the specified view. */
ProtoViewCurrentView old = app->current_view;
if (switchto == ViewGoNext) {
Expand Down Expand Up @@ -98,6 +102,7 @@ static void app_switch_view(ProtoViewApp *app, ProtoViewCurrentView switchto) {
/* If there is an alert on screen, dismiss it: if the user is
* switching view she already read it. */
ui_dismiss_alert(app);
furi_mutex_release(app->view_updating_mutex);
}

/* Allocate the application state and initialize a number of stuff.
Expand Down Expand Up @@ -126,6 +131,7 @@ ProtoViewApp* protoview_app_alloc() {
app->show_text_input = false;
app->alert_dismiss_time = 0;
app->current_view = ViewRawPulses;
app->view_updating_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
for (int j = 0; j < ViewLast; j++) app->current_subview[j] = 0;
app->direct_sampling_enabled = false;
app->view_privdata = malloc(PROTOVIEW_VIEW_PRIVDATA_LEN);
Expand Down Expand Up @@ -173,6 +179,7 @@ void protoview_app_free(ProtoViewApp *app) {
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_NOTIFICATION);
furi_message_queue_free(app->event_queue);
furi_mutex_free(app->view_updating_mutex);
app->gui = NULL;

// Frequency setting.
Expand Down
4 changes: 4 additions & 0 deletions app.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ struct ProtoViewApp {
ViewPort *view_port; /* We just use a raw viewport and we render
everything into the low level canvas. */
ProtoViewCurrentView current_view; /* Active left-right view ID. */
FuriMutex *view_updating_mutex; /* The Flipper GUI calls the screen redraw
callback in a different thread. We
use this mutex to protect the redraw
from changes in app->view_privdata. */
int current_subview[ViewLast]; /* Active up-down subview ID. */
FuriMessageQueue *event_queue; /* Keypress events go here. */

Expand Down
5 changes: 3 additions & 2 deletions view_direct_sampling.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) {
privdata->captured = malloc(CAPTURED_BITMAP_SIZE);

/* Read from data from GPIO */
if (privdata->captured == NULL)
FURI_LOG_E(TAG, "captured is NULL reading GPIO.");
for (int j = 0; j < CAPTURED_BITMAP_SIZE*8; j++) {
uint32_t start_time = DWT->CYCCNT;
bool level = furi_hal_gpio_read(&gpio_cc1101_g0);
Expand Down Expand Up @@ -91,8 +93,7 @@ void view_enter_direct_sampling(ProtoViewApp *app) {
/* Exit view. Restore the subghz thread. */
void view_exit_direct_sampling(ProtoViewApp *app) {
DirectSamplingViewPrivData *privdata = app->view_privdata;
free(privdata->captured);
privdata->captured = NULL;
if (privdata->captured) free(privdata->captured);
app->direct_sampling_enabled = false;

/* Restart normal data feeding. */
Expand Down

0 comments on commit 2a791b1

Please sign in to comment.