diff --git a/components/badge23/include/badge23/scope.h b/components/badge23/include/badge23/scope.h index 302bea447ac39ca1d1ff029f3be08feebfd6b50b..fe21205194e6939af6d740bea809d0e7c05d3799 100644 --- a/components/badge23/include/badge23/scope.h +++ b/components/badge23/include/badge23/scope.h @@ -5,7 +5,8 @@ typedef struct { int16_t * buffer; int16_t buffer_size; int16_t write_head_position; // last written value - volatile uint8_t is_being_read; + // atomic value used to prevent simultaneous reads/writes (not a mutex!). + volatile uint32_t is_being_read; } scope_t; void init_scope(uint16_t size); diff --git a/components/badge23/scope.c b/components/badge23/scope.c index dc92395dd2987625eb0cac9092d3719f25d17fd4..ac78a0f6aa79787c78d3b8d8f21e99bc6370e65b 100644 --- a/components/badge23/scope.c +++ b/components/badge23/scope.c @@ -1,36 +1,59 @@ #include "badge23/scope.h" +#include "esp_log.h" #include <string.h> +#include <freertos/FreeRTOS.h> +#include <freertos/atomic.h> -scope_t * scope; +scope_t * scope = NULL; +static const char* TAG = "scope"; void init_scope(uint16_t size){ + if (scope != NULL) { + return; + } + scope_t * scp = malloc(sizeof(scope_t)); - if(scp == NULL) scope = NULL; + if(scp == NULL) { + ESP_LOGE(TAG, "scope allocation failed, out of memory"); + return; + } scp->buffer_size = size; scp->buffer = malloc(sizeof(int16_t) * scp->buffer_size); if(scp->buffer == NULL){ free(scp); - scope = NULL; - } else { - memset(scp->buffer, 0, sizeof(int16_t) * scp->buffer_size); - scope = scp; + ESP_LOGE(TAG, "scope buffer allocation failed, out of memory"); + return; } + memset(scp->buffer, 0, sizeof(int16_t) * scp->buffer_size); + scope = scp; + ESP_LOGI(TAG, "initialized"); +} + +static inline bool scope_being_read(void) { + return Atomic_CompareAndSwap_u32(&scope->is_being_read, 0, 0) == ATOMIC_COMPARE_AND_SWAP_FAILURE; } void write_to_scope(int16_t value){ - if(scope->is_being_read) return; - if(scope == NULL) return; + if(scope == NULL || scope_being_read()) { + return; + } + scope->write_head_position++; if(scope->write_head_position >= scope->buffer_size) scope->write_head_position = 0; scope->buffer[scope->write_head_position] = value; } -void begin_scope_read(){ - if(scope == NULL) return; - scope->is_being_read = 1; //best mutex +void begin_scope_read(void) { + if (scope == NULL) { + return; + } + Atomic_Increment_u32(&scope->is_being_read); } void read_line_from_scope(uint16_t * line, int16_t point){ + if (scope == NULL) { + return; + } memset(line, 0, 480); int16_t startpoint = scope->write_head_position - point; while(startpoint < 0){ @@ -57,7 +80,9 @@ void read_line_from_scope(uint16_t * line, int16_t point){ } } -void end_scope_read(){ - if(scope == NULL) return; - scope->is_being_read = 0; //best mutex +void end_scope_read(void) { + if (scope == NULL) { + return; + } + Atomic_Decrement_u32(&scope->is_being_read); }