diff --git a/radio/src/os/async_freertos.cpp b/radio/src/os/async_freertos.cpp index 61d99468a..4e88a6351 100644 --- a/radio/src/os/async_freertos.cpp +++ b/radio/src/os/async_freertos.cpp @@ -19,6 +19,7 @@ * GNU General Public License for more details. */ +#include "task.h" #include "async.h" #include @@ -27,7 +28,7 @@ bool async_call(async_func_t func, volatile bool* excl_flag, void* param1, uint32_t param2) { - if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { + if (scheduler_is_running()) { // check exclusive flag first if (excl_flag && *excl_flag) return false; @@ -48,7 +49,7 @@ bool async_call_isr(async_func_t func, volatile bool* excl_flag, void* param1, uint32_t param2) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { + if (scheduler_is_running()) { // check exclusive flag first if (excl_flag && *excl_flag) return false; diff --git a/radio/src/os/task.h b/radio/src/os/task.h index 491f17cd8..e1a62ed93 100644 --- a/radio/src/os/task.h +++ b/radio/src/os/task.h @@ -38,6 +38,8 @@ void task_create(task_handle_t* h, task_func_t func, const char* name, unsigned task_get_stack_usage(task_handle_t* h); unsigned task_get_stack_size(task_handle_t* h); +bool scheduler_is_running(); + void mutex_create(mutex_handle_t* h); bool mutex_lock(mutex_handle_t* h); void mutex_unlock(mutex_handle_t* h); @@ -49,6 +51,7 @@ bool mutex_trylock(mutex_handle_t* h); * * void doWork() * { + * * MutexLock lock = MutexLock::MakeInstance(mutex); * while(!queue.isEmpty) * { @@ -97,9 +100,9 @@ class MutexLock { public: static MutexLock MakeInstance(mutex_handle_t* mtx) {return MutexLock(mtx);} - ~MutexLock() {if(locked) mutex_unlock(mutex);} - void lock() {if(!locked) mutex_lock(mutex); locked=true;} - void unlock() {if(locked) mutex_unlock(mutex); locked=false;} + ~MutexLock() {if(!scheduler_is_running()) return; if(locked) mutex_unlock(mutex);} + void lock() {if(!scheduler_is_running()) return; if(!locked) mutex_lock(mutex); locked=true;} + void unlock() {if(!scheduler_is_running()) return; if(locked) mutex_unlock(mutex); locked=false;} MutexLock(const MutexLock&) = delete; MutexLock(MutexLock&&) = delete; @@ -110,7 +113,7 @@ public: static void operator delete (void*) = delete; static void operator delete[](void*) = delete; private: - MutexLock(mutex_handle_t* mtx):mutex(mtx),locked(false) {mutex_lock(mutex); locked = true;} + MutexLock(mutex_handle_t* mtx):mutex(mtx),locked(false) {if(!scheduler_is_running()) return; mutex_lock(mutex); locked = true;} mutex_handle_t* mutex; bool locked; }; diff --git a/radio/src/os/task_freertos.cpp b/radio/src/os/task_freertos.cpp index 3eedbb0ee..d6745e5c9 100644 --- a/radio/src/os/task_freertos.cpp +++ b/radio/src/os/task_freertos.cpp @@ -47,6 +47,13 @@ unsigned task_get_stack_size(task_handle_t* h) return h->_stack_size * sizeof(StackType_t); } +bool scheduler_is_running() +{ + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) + return true; + return false; +} + void mutex_create(mutex_handle_t* h) { h->_rtos_handle = xSemaphoreCreateMutexStatic(&h->_mutex_struct); diff --git a/radio/src/os/task_native.cpp b/radio/src/os/task_native.cpp index 04a387b67..290c5914c 100644 --- a/radio/src/os/task_native.cpp +++ b/radio/src/os/task_native.cpp @@ -130,6 +130,11 @@ unsigned task_get_stack_size(task_handle_t* h) return h->_stack_size * 4; } +bool scheduler_is_running() +{ + return true; +} + void mutex_create(mutex_handle_t* h) { (void)h; diff --git a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp index eb8570231..ad4f0e16a 100644 --- a/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp +++ b/radio/src/targets/common/arm/stm32/stm32_i2c_driver.cpp @@ -35,8 +35,9 @@ struct stm32_i2c_device { I2C_HandleTypeDef handle; const stm32_i2c_hw_def_t* hw_def; -#if !defined(BOOT) && !defined(RADIO_PA01) +#if !defined(BOOT) mutex_handle_t mutex; + bool mutex_initialized; #endif }; @@ -54,8 +55,16 @@ static I2C_HandleTypeDef* i2c_get_handle(uint8_t bus) return &_i2c_devs[bus].handle; } -#if !defined(BOOT) && !defined(RADIO_PA01) -#define I2CMutex(bus) MutexLock mutexLock = MutexLock::MakeInstance(&i2c_get_device(bus)->mutex) +#if !defined(BOOT) +static void i2c_ensure_mutex(stm32_i2c_device* dev) +{ + if (!dev->mutex_initialized && scheduler_is_running()) { + mutex_create(&dev->mutex); + dev->mutex_initialized = true; + } +} + +#define I2CMutex(bus) i2c_ensure_mutex(i2c_get_device(bus)); MutexLock mutexLock = MutexLock::MakeInstance(&i2c_get_device(bus)->mutex) #else #define I2CMutex(bus) #endif @@ -525,8 +534,8 @@ int stm32_i2c_init(uint8_t bus, uint32_t clock_rate, const stm32_i2c_hw_def_t* h } #endif -#if !defined(BOOT) && !defined(RADIO_PA01) - mutex_create(&dev->mutex); +#if !defined(BOOT) + dev->mutex_initialized = false; #endif return 1; }