Hi!
MCU: STM32F411VET6 100 MHz
FreeRTOS 9.0.0 (same thing happens in 10.0.0)
I have a problem using xQueueOverwriteFromISR() with a queue set.
xQueueSelectFromSet() tells that an item is available, but when trying to read out the item, xQueueReceive() returns pdFALSE.
If I instead use xQueueSendToBackFromISR(), everything (seems to) work normally. But this is not quite the functionality I want.
Here is a longer description of the problem area in my system:
I have a “timestamp” queue (length = 1) which I write to every ~20 ms using xQueueOverwriteFromISR() from an interrupt handler.
I have a “command” queue (length = 10) which I occationally write commands to using xQueueSendToBack() from a “command” task (task priority 1).
I have a “receiver” task (task priority 4) that waits on both of these queues using a queue set, and reads out data from the corresponding queue.
After a while of successful operation, the queue set indicates that an item in the “timestamp” queue is available, but when calling xQueueReceive(), it returns failure.
I have tried to isolate the problem in a simple standalone test application (below), but not fully succeeded.
In the below test application, I also get wrong behaviour (I think), after about 6 seconds, but at a different location than in my real system. (See comment in code where it fails.)
Because of the task priorities, and the wait time specified in xQueueSendToBack(), the “command” queue should not get full, but it does!
And also in the test application, if I replace xQueueOverwriteFromISR() with xQueueSendToBackFromISR(), everything works normally.
Anyone else have problems with Queue Sets and xQueueOverwriteFromISR() ?
And yes, the system should be properly set-up with HAL
Init() that calls HALNVIC
SetPriorityGrouping(NVICPRIORITYGROUP_4).
~~~
include “ClockTick.h”
include “HWTimer.h”
include “SystemCore.h”
include “FreeRTOS.h”
include “task.h”
include “timers.h”
include “semphr.h”
QueueHandle
t commandqueue;
QueueHandle
t timestampqueue;
QueueSetHandle
t queueset;
TaskHandle
t commandtask
handle;
TaskHandlet receiver
taskhandle;
void hw
timercallback(unsigned ch, void * user) // IRQ priority 6
{
BaseType
t higherpri
taskwoken = pdFALSE;
int value = 0;
// If I instead use xQueueSendToBackFromISR() here, everything works normally
(void) xQueueOverwriteFromISR(timestamp
queue, &value, &higherpri
taskwoken);
portYIELD
FROMISR(higher
pritask_woken);
}
void command
task(void * param) // task priority 1
{
BaseTypet ret;
int value = 0;
for (;;)
{
vTaskDelay(20);
ret = xQueueSendToBack(command_queue, &value, 5);
// **** This assert fails after a while in this test application *****
configASSERT(ret == pdTRUE);
}
}
void receiver
task(void * param) // task priority 4
{
BaseTypet ret;
int value;
// Start recurring HW-timer (330 us timeout)
StartRecurringHWTimer(0, ClockTicksFrom
us(330), hwtimer_callback, NULL);
for (;;)
{
// Wait for command or timestamp
QueueSetMemberHandle
t handle = xQueueSelectFromSet(queueset, 200);
if (handle == (QueueSetMemberHandle_t) timestamp_queue)
{
ret = xQueueReceive(timestamp_queue, &value, 0);
// **** This assert fails after a while in my real system *****
configASSERT(ret == pdTRUE);
}
else if (handle == (QueueSetMemberHandle_t) command_queue)
{
ret = xQueueReceive(command_queue, &value, 0);
configASSERT(ret == pdTRUE);
}
else
{
configASSERT(handle == NULL);
}
}
}
int main(void)
{
// Init system: HAL, clocks, etc.
ErrorHandler
Init();
SystemCoreInit();
ClockTick
Init();
HWTimerInit();
// Create queues
command
queue = xQueueCreate(10, sizeof(int));
timestampqueue = xQueueCreate(1, sizeof(int));
// Create queue sets
queue
set = xQueueCreateSet(10 + 1);
xQueueAddToSet((QueueSetMemberHandlet)command
queue, queueset);
xQueueAddToSet((QueueSetMemberHandle
t)timestampqueue, queue_set);
// Create command and receiver tasks
xTaskCreate(command
task, “CMD”, 3 * configMINIMALSTACK
SIZE, NULL, 1, &commandtask
handle);
xTaskCreate(receivertask, “RCV”, 3 * configMINIMAL
STACKSIZE, NULL, 4, &receiver
taskhandle);
vTaskStartScheduler();
return 0;
}
/*
define configUSE_PREEMPTION 1
define configUSEPORTOPTIMISEDTASKSELECTION 1
define configUSETICKLESSIDLE 0
define configCPUCLOCKHZ ( SystemCoreClock )
define configTICKRATEHZ ( ( TickTypet ) 1000 ) /* Note! 1000 Hz is MAX, as HAL tick & FreeRTOS shares SysTickHandler() */
define configUSE16BIT_TICKS 0
define configMAX_PRIORITIES 5
define configUSETIMESLICING 1
define configIDLESHOULDYIELD 1
define configMINIMALSTACKSIZE ( ( unsigned short ) 130 )
define configMAXTASKNAME_LEN 10
define configUSETASKNOTIFICATIONS 0
define configUSE_MUTEXES 1
define configUSERECURSIVEMUTEXES 1
define configUSECOUNTINGSEMAPHORES 0
define configUSEQUEUESETS 1
define configUSEALTERNATIVEAPI 0
define configQUEUEREGISTRYSIZE 8
define configUSENEWLIBREENTRANT 1 /* Integrating with Newlib & Newlib-Nano */
define configENABLEBACKWARDCOMPATIBILITY 0
define configNUMTHREADLOCALSTORAGEPOINTERS 0
define configUSEAPPLICATIONTASK_TAG 0
define configLIBRARYMAXSYSCALLINTERRUPTPRIORITY 5
*/
~~~