1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 06:23:53 +01:00

cpu/esp_common/freertos: add timeout handling to xQueue

This commit is contained in:
Gunar Schorcht 2022-06-17 07:17:40 +02:00
parent 99fa182fb4
commit 780fd9a815
4 changed files with 91 additions and 3 deletions

View File

@ -60,7 +60,6 @@ endif
ifneq (,$(filter periph_i2c,$(USEMODULE)))
ifneq (,$(filter esp_i2c_hw,$(USEMODULE)))
USEMODULE += core_thread_flags
USEMODULE += ztimer_msec
USEMODULE += periph_i2c_hw
else

View File

@ -81,6 +81,7 @@ config MODULE_ESP_COMMON
select MODULE_LOG # override default log implementation by default
select MODULE_PERIPH
select MODULE_ESP_IDF
select MODULE_CORE_THREAD_FLAGS if MODULE_ZTIMER_MSEC
help
Common code module for ESP SoCs.

View File

@ -93,3 +93,9 @@ ifneq (,$(filter esp_wifi_any,$(USEMODULE)))
USEMODULE += netopt
USEMODULE += ztimer_msec
endif
ifneq (,$(filter esp_freertos_common,$(USEMODULE)))
ifneq (,$(filter ztimer_msec,$(USEMODULE)))
USEMODULE += core_thread_flags
endif
endif

View File

@ -24,6 +24,9 @@
#include "rmutex.h"
#include "syscalls.h"
#include "thread.h"
#if IS_USED(MODULE_ZTIMER_MSEC)
#include "ztimer.h"
#endif
#include "rom/ets_sys.h"
@ -154,6 +157,40 @@ BaseType_t IRAM_ATTR xQueueReset( QueueHandle_t xQueue )
return pdPASS;
}
#if IS_USED(MODULE_ZTIMER_MSEC)
/* descriptor for timeout handling for a thread that is waiting in a queue */
typedef struct {
thread_t *thread; /* the thread */
list_node_t *queue; /* the queue in which it is waiting */
bool timeout; /* timeout occurred */
} _queue_waiting_thread_t;
static void _queue_timeout(void *arg)
{
_queue_waiting_thread_t *wtd = arg;
assert(wtd != NULL);
assert(wtd->queue != NULL);
assert(wtd->thread != NULL);
vTaskEnterCritical(0);
/* remove the thread from the waiting queue */
list_node_t *node = (list_node_t *)&(wtd->thread->rq_entry);
list_remove(wtd->queue, node);
/* unblock the waintg thread */
sched_set_status(wtd->thread, STATUS_PENDING);
sched_context_switch_request =
wtd->thread->priority < thread_get_priority(thread_get_active());
wtd->timeout = true;
vTaskExitCritical(0);
}
#endif
BaseType_t IRAM_ATTR _queue_generic_send(QueueHandle_t xQueue,
const void * const pvItemToQueue,
const BaseType_t xCopyPosition,
@ -248,10 +285,33 @@ BaseType_t IRAM_ATTR _queue_generic_send(QueueHandle_t xQueue,
DEBUG("%s pid=%d queue=%p suspended calling thread\n", __func__,
thread_getpid(), xQueue);
#if IS_USED(MODULE_ZTIMER_MSEC)
_queue_waiting_thread_t wdt = { .queue = &queue->sending,
.thread = me,
.timeout = false };
ztimer_t tm = { .callback = _queue_timeout,
.arg = &wdt };
if (xTicksToWait < portMAX_DELAY) {
ztimer_set(ZTIMER_MSEC, &tm, xTicksToWait * portTICK_PERIOD_MS);
}
#else
assert((xTicksToWait == 0) || (xTicksToWait == portMAX_DELAY));
#endif
vTaskExitCritical(0);
thread_yield_higher();
/* TODO timeout handling with xTicksToWait */
#if IS_USED(MODULE_ZTIMER_MSEC)
vTaskEnterCritical(0);
if (xTicksToWait < portMAX_DELAY) {
ztimer_remove(ZTIMER_MSEC, &tm);
if (wdt.timeout) {
vTaskExitCritical(0);
return errQUEUE_FULL;
}
}
vTaskExitCritical(0);
#endif
DEBUG("%s pid=%d queue=%p continue calling thread\n", __func__,
thread_getpid(), xQueue);
}
@ -354,10 +414,32 @@ BaseType_t IRAM_ATTR _queue_generic_recv (QueueHandle_t xQueue,
DEBUG("%s pid=%d queue=%p suspended calling thread\n", __func__,
thread_getpid(), xQueue);
#if IS_USED(MODULE_ZTIMER_MSEC)
_queue_waiting_thread_t wdt = { .queue = &queue->receiving,
.thread = me,
.timeout = false };
ztimer_t tm = { .callback = _queue_timeout,
.arg = &wdt };
if (xTicksToWait < portMAX_DELAY) {
ztimer_set(ZTIMER_MSEC, &tm, xTicksToWait * portTICK_PERIOD_MS);
}
#else
assert((xTicksToWait == 0) || (xTicksToWait == portMAX_DELAY));
#endif
vTaskExitCritical(0);
thread_yield_higher();
/* TODO timeout handling with xTicksToWait */
#if IS_USED(MODULE_ZTIMER_MSEC)
vTaskEnterCritical(0);
if (xTicksToWait < portMAX_DELAY) {
ztimer_remove(ZTIMER_MSEC, &tm);
if (wdt.timeout) {
vTaskExitCritical(0);
return errQUEUE_FULL;
}
}
vTaskExitCritical(0);
#endif
DEBUG("%s pid=%d queue=%p continue calling thread\n", __func__,
thread_getpid(), xQueue);
}