Hi all,
I made a simple program with 2 tasks and 2 queues and I’ve been able to make it work.
Both tasks modify the variable passed through the queus.
I have just a question regarding the creation of the queue handler.
If I create them at compile-time there are no issues, but if I do it run-time the program crashes.
Both queues handle are contained in a structure.
If I create the handle’s structure before the main() as:
UBaseType_t uxQueueLength = 1;
UBaseType_t uxItemSize = sizeof(uint32_t);
...
...
typedef struct{
QueueHandle_t hQueueTx;
QueueHandle_t hQueueRx;
}queues_t;
// queues structure created as COMPILE-TIME
queues_t queues;
Everything works as expected.
But if I move the structure creation in the main function the program doesn’t work anymore.
int main(void) {
...
...
// queues structure created as RUN-TIME
queues_t queues;
// queues creation
queues.hQueueTx = xQueueCreate(uxQueueLength, uxItemSize);
queues.hQueueRx = xQueueCreate(uxQueueLength, uxItemSize);
...
...
/* TASK A CREATION */
if(pdPASS == xTaskCreate(
vTaskA, "Task_A", usStackDepth, (void*)&queues, uxPriority, &hTask_A)){
// task successfully created
}
/* TASK B CREATION */
if(pdPASS == xTaskCreate(
vTaskB, "Task_B", usStackDepth, (void*)&queues, uxPriority, &hTask_B)){
// task successfully created
}
...
...
Precisely, when the task executes the xQueueSendToBack() the PC jumps to the HardFault_Handler.
void vTaskA(void *pvStruct){
uint32_t variable = 0;
queues_t *queues = (queues_t*)pvStruct;
for(;;){
// send the variable value to the Task_B through the Tx queue
if(xQueueSendToBack(
queues->hQueueTx,
(void*)&variable,
portMAX_DELAY) == pdFAIL){
// buffer not available
}
...
...
In fact in this last case I can see that the handles don’t contain the correct values set at the queues creation (see images below).
Why? That’s suprise me… I spent few debug hours about this…
Here the queues structure inside the running task when is created run-time:
While here the same queues structure created compile-time (when the program works):
In the Reference Manual (V10.0.0) page 201 the example code creates the queue handle in run-time and uses the code as I did it:
int main( void )
{
QueueHandle_t xQueue;
/* Create the queue, storing the returned handle in the xQueue variable. */
xQueue = xQueueCreate( QUEUE_LENGTH, QUEUE_ITEM_SIZE );
if( xQueue == NULL )
{
/* The queue could not be created – do something. */
}
/* Create a task, passing in the queue handle as the task parameter. */
xTaskCreate( vAnotherTask,
“Task”,
STACK_SIZE,
( void * ) xQueue, /* xQueue is used as the task parameter. */
TASK_PRIORITY,
NULL );
/* Start the task executing. */
vTaskStartScheduler();
Can someone help me to understand this?
Many thanks!
AGA