refactor(radio): async call handling to prevent GX12 switch lockups (#5949)
This commit is contained in:
+15
-3
@@ -250,19 +250,31 @@ void timer_10ms()
|
||||
#include <FreeRTOS/include/FreeRTOS.h>
|
||||
#include <FreeRTOS/include/timers.h>
|
||||
|
||||
static volatile bool _timer_10ms_cb_in_queue = false;
|
||||
|
||||
static void _timer_10ms_cb(void *pvParameter1, uint32_t ulParameter2)
|
||||
{
|
||||
(void)pvParameter1;
|
||||
(void)ulParameter2;
|
||||
_timer_10ms_cb_in_queue = false;
|
||||
timer_10ms();
|
||||
}
|
||||
|
||||
void per10ms()
|
||||
{
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
|
||||
if (!_timer_10ms_cb_in_queue && xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTimerPendFunctionCallFromISR(_timer_10ms_cb, nullptr, 0, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
xReturn = xTimerPendFunctionCallFromISR(_timer_10ms_cb, nullptr, 0, &xHigherPriorityTaskWoken);
|
||||
|
||||
if (xReturn == pdPASS) {
|
||||
_timer_10ms_cb_in_queue = true;
|
||||
} else {
|
||||
TRACE("xTimerPendFunctionCallFromISR() queue full");
|
||||
}
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ struct bsp_io_expander {
|
||||
uint32_t state;
|
||||
};
|
||||
|
||||
static volatile bool _poll_switches_in_queue = false;
|
||||
static bsp_io_expander _io_switches;
|
||||
static bsp_io_expander _io_fs_switches;
|
||||
|
||||
@@ -60,25 +61,27 @@ static uint32_t _read_io_expander(bsp_io_expander* io)
|
||||
static void _poll_switches(void *pvParameter1, uint32_t ulParameter2)
|
||||
{
|
||||
(void)ulParameter2;
|
||||
bsp_io_expander* io = (bsp_io_expander*)pvParameter1;
|
||||
_read_io_expander(io);
|
||||
_poll_switches_in_queue = false;
|
||||
bsp_io_read_switches();
|
||||
bsp_io_read_fs_switches();
|
||||
}
|
||||
|
||||
static void _io_int_handler(bsp_io_expander* io)
|
||||
static void _io_int_handler()
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
xTimerPendFunctionCallFromISR(_poll_switches, (void*)io, 0,
|
||||
&xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
} else {
|
||||
_read_io_expander(io);
|
||||
}
|
||||
}
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
static void _io_int_handler() {
|
||||
_io_int_handler(&_io_switches);
|
||||
_io_int_handler(&_io_fs_switches);
|
||||
if (!_poll_switches_in_queue && xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
xReturn = xTimerPendFunctionCallFromISR(_poll_switches, nullptr, 0,
|
||||
&xHigherPriorityTaskWoken);
|
||||
|
||||
if (xReturn == pdPASS) {
|
||||
_poll_switches_in_queue = true;
|
||||
} else {
|
||||
TRACE("xTimerPendFunctionCallFromISR() queue full");
|
||||
}
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
}
|
||||
|
||||
int bsp_io_init()
|
||||
|
||||
@@ -205,12 +205,15 @@ void telemetryStop()
|
||||
}
|
||||
}
|
||||
|
||||
static volatile bool _poll_frame_queued[NUM_MODULES] = {false};
|
||||
|
||||
static void _poll_frame(void *pvParameter1, uint32_t ulParameter2)
|
||||
{
|
||||
_telemetryIsPolling = true;
|
||||
|
||||
auto drv = (const etx_proto_driver_t*)pvParameter1;
|
||||
auto module = (uint8_t)ulParameter2;
|
||||
_poll_frame_queued[module] = false;
|
||||
|
||||
auto mod = pulsesGetModuleDriver(module);
|
||||
if (!mod || !mod->drv || !mod->ctx || (drv != mod->drv))
|
||||
@@ -246,8 +249,18 @@ static void _poll_frame(void *pvParameter1, uint32_t ulParameter2)
|
||||
void telemetryFrameTrigger_ISR(uint8_t module, const etx_proto_driver_t* drv)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
xTimerPendFunctionCallFromISR(_poll_frame, (void*)drv, module, &xHigherPriorityTaskWoken);
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
BaseType_t xReturn = pdFALSE;
|
||||
|
||||
if (!_poll_frame_queued[module] && xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
xReturn = xTimerPendFunctionCallFromISR(_poll_frame, (void*)drv, module, &xHigherPriorityTaskWoken);
|
||||
|
||||
if (xReturn == pdPASS) {
|
||||
_poll_frame_queued[module] = true;
|
||||
} else {
|
||||
TRACE("xTimerPendFunctionCallFromISR() queue full");
|
||||
}
|
||||
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user