Unverified Commit 652f9f9e authored by Earle F. Philhower, III's avatar Earle F. Philhower, III Committed by GitHub

Fix FreeRTOS CoreMutex shim to handle ISRs (#1442)

* Fix FreeRTOS CoreMutex shim to handle ISRs

Automatically check, when in FreeRTOS, if we're in an ISR and
if so call the correct mutex grab.

Thanks to @caveman99 for finding and proposing a solution!

Fixes #1441

* Fix the CoreMutex destructor, too
parent cac9eb0c
...@@ -30,7 +30,7 @@ CoreMutex::CoreMutex(mutex_t *mutex, uint8_t option) { ...@@ -30,7 +30,7 @@ CoreMutex::CoreMutex(mutex_t *mutex, uint8_t option) {
_option = option; _option = option;
if (__isFreeRTOS) { if (__isFreeRTOS) {
auto m = __get_freertos_mutex_for_ptr(mutex); auto m = __get_freertos_mutex_for_ptr(mutex);
if (_option & FromISR) { if (__freertos_check_if_in_isr()) {
__freertos_mutex_take_from_isr(m); __freertos_mutex_take_from_isr(m);
} else { } else {
if (!__freertos_mutex_try_take(m)) { if (!__freertos_mutex_try_take(m)) {
...@@ -56,7 +56,7 @@ CoreMutex::~CoreMutex() { ...@@ -56,7 +56,7 @@ CoreMutex::~CoreMutex() {
if (_acquired) { if (_acquired) {
if (__isFreeRTOS) { if (__isFreeRTOS) {
auto m = __get_freertos_mutex_for_ptr(_mutex); auto m = __get_freertos_mutex_for_ptr(_mutex);
if (_option & FromISR) { if (__freertos_check_if_in_isr()) {
__freertos_mutex_give_from_isr(m); __freertos_mutex_give_from_isr(m);
} else { } else {
__freertos_mutex_give(m); __freertos_mutex_give(m);
......
...@@ -27,8 +27,7 @@ ...@@ -27,8 +27,7 @@
#include "_freertos.h" #include "_freertos.h"
enum { enum {
DebugEnable = 1, DebugEnable = 1
FromISR = 1 << 1,
}; };
class CoreMutex { class CoreMutex {
......
...@@ -37,6 +37,8 @@ extern "C" { ...@@ -37,6 +37,8 @@ extern "C" {
typedef QueueHandle_t SemaphoreHandle_t; typedef QueueHandle_t SemaphoreHandle_t;
#endif #endif
extern bool __freertos_check_if_in_isr() __attribute__((weak));
extern SemaphoreHandle_t __freertos_mutex_create() __attribute__((weak)); extern SemaphoreHandle_t __freertos_mutex_create() __attribute__((weak));
extern SemaphoreHandle_t _freertos_recursive_mutex_create() __attribute__((weak)); extern SemaphoreHandle_t _freertos_recursive_mutex_create() __attribute__((weak));
......
...@@ -77,7 +77,7 @@ static std::map<pin_size_t, CBInfo> _map; ...@@ -77,7 +77,7 @@ static std::map<pin_size_t, CBInfo> _map;
void _gpioInterruptDispatcher(uint gpio, uint32_t events) { void _gpioInterruptDispatcher(uint gpio, uint32_t events) {
(void) events; (void) events;
// Only need to lock around the std::map check, not the whole IRQ callback // Only need to lock around the std::map check, not the whole IRQ callback
CoreMutex m(&_irqMutex, (FromISR | DebugEnable)); CoreMutex m(&_irqMutex);
if (m) { if (m) {
auto irq = _map.find(gpio); auto irq = _map.find(gpio);
if (irq != _map.end()) { if (irq != _map.end()) {
......
...@@ -85,6 +85,10 @@ extern "C" { ...@@ -85,6 +85,10 @@ extern "C" {
void __freertos_recursive_mutex_give(SemaphoreHandle_t mtx) { void __freertos_recursive_mutex_give(SemaphoreHandle_t mtx) {
xSemaphoreGiveRecursive(mtx); xSemaphoreGiveRecursive(mtx);
} }
bool __freertos_check_if_in_isr() {
return portCHECK_IF_IN_ISR();
}
} }
...@@ -488,5 +492,3 @@ void __USBStart() { ...@@ -488,5 +492,3 @@ void __USBStart() {
xTaskCreate(__usb, "USB", 256, 0, configMAX_PRIORITIES - 2, &__usbTask); xTaskCreate(__usb, "USB", 256, 0, configMAX_PRIORITIES - 2, &__usbTask);
vTaskCoreAffinitySet(__usbTask, 1 << 0); vTaskCoreAffinitySet(__usbTask, 1 << 0);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment