freeRTOS tasks with queue not working - Page 1
Forum section: electronics / general

author: diyaudio
author_rank: Frequent Contributor
timestamp: November 22, 2018, 08:33:45 pm
content: Using FreeRTOS 9.0CMSIS-RTOS API 1.2Chip STM32L162RETProblem: I have two tasks and one message queue, one task sends a data struct the other task receives it, everything works as expected, but whenI add a uint8_t data and increase the DATA_SIZE from 5-Bytes upwards (4-Bytes works) the program hangs! I set the task stack size to 512 Bytes (nothing!),I have no idea where else to look? I stepped through the code and the code hangs during osPoolFree (block < pool_id->pool) a HardFault_Handler is generated.Is there a bug with CMSIS RTOS 1.0 ?Code:osThreadId tid_thread1; // ID for thread 1osThreadId tid_thread2; // for thread 2typedef struct { // Message object structurefloat voltage; // AD result of measured voltagefloat current; // AD result of measured currentint counter; // A counter valueuint8_t data;} T_MEAS;osPoolDef(mpool, 16, T_MEAS); // Define memory poolosPoolId mpool;osMessageQDef(MsgBox, 16, T_MEAS); // Define message queueosMessageQId MsgBox;void send_thread (void const *argument); // forward referencevoid recv_thread (void const *argument); // forward reference//// Thread 1: Send thread//void send_thread (void const *argument) {for(;;){HAL_GPIO_TogglePin(GPIOC, LED_1_Pin);T_MEAS *mptr;mptr = osPoolAlloc(mpool); // Allocate memory for the messagemptr->voltage = 223.72; // Set the message contentmptr->current = 17.54;mptr->counter = 120786;memcpy(mptr->data, data_arr, sizeof(mptr->data));osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever); // Send MessageosDelay(100);mptr = osPoolAlloc(mpool); // Allocate memory for the messagemptr->voltage = 227.23; // Prepare a 2nd messagemptr->current = 12.41;mptr->counter = 170823;osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever); // Send MessageosThreadYield(); // Cooperative multitasking// We are done here, exit this thread}}//// Thread 2: Receive thread//void recv_thread (void const *argument) {T_MEAS *rptr;osEvent evt;for (;;) {evt = osMessageGet(MsgBox, osWaitForever); // wait for messageif (evt.status == osEventMessage) {HAL_GPIO_TogglePin(GPIOC, LED_3_Pin);rptr = evt.value.p;printf ("\nVoltage: %.2f V\n", rptr->voltage);printf ("Current: %.2f A\n", rptr->current);// printf ("Number of cycles: %d\n", rptr->counter);osPoolFree(mpool, evt.value); // free memory allocated for message}}}void StartApplication (void) {mpool = osPoolCreate(osPool(mpool)); // create memory poolMsgBox = osMessageCreate(osMessageQ(MsgBox), NULL); // create msg queueosThreadDef( send_threadTask, send_thread, osPriorityNormal, NULL, 512 );osThreadDef( recv_threadTask, recv_thread, osPriorityNormal, NULL, 512 );tid_thread1 = osThreadCreate(osThread(send_threadTask), NULL);tid_thread2 = osThreadCreate(osThread(recv_threadTask), NULL);}

author: diyaudio
author_rank: Frequent Contributor
timestamp: November 23, 2018, 07:59:06 am
content: Looks like I'm alone on this one, I will probably have to re-create and carefully check the overall heap sizes and get back on my progress.

author: ogden
author_rank: Super Contributor
timestamp: November 23, 2018, 08:17:47 am
content: Quote from: diyaudio on November 23, 2018, 07:59:06 amIf you are moving (big) data usingmessagingsystem of the RTOS, you are doing it wrong. Save data globally and transmit state of the data (or pointer or ID) between threads, not actual data itself. Most likely that's why you are not getting answers - because hardly anybody is messaging so many bytes as you.

author: diyaudio
author_rank: Frequent Contributor
timestamp: November 23, 2018, 09:49:55 am
content: Quote from: ogden on November 23, 2018, 08:17:47 amFirstly thanks, you are right your answer tells me I need to re think my design. I will post another solution using a osPoolAlloc() I'm not sure if osPoolAlloc is the way to go to store global data, as its free osPoolFree(mpool, evt.value); is causing it to hang.

author: tsman
author_rank: Frequent Contributor
timestamp: November 23, 2018, 10:53:01 am
content: The queues are allocated from the heap. Not the per task stack. You sure you've got enough space in there? Check the return value for osMessagePut.What ogden said about not trying to pass large chunks of data around.

author: newbrain
author_rank: Super Contributor
timestamp: November 23, 2018, 11:52:34 am
content: Quote from: diyaudio on November 23, 2018, 09:49:55 amShould that rather be osPoolFree(mpool, evt.value.p)?If osPoolFree is expecting a void*, I wonder how it is able to even compile without error.

author: diyaudio
author_rank: Frequent Contributor
timestamp: November 23, 2018, 09:12:21 pm
content: it works now, but strange see the variation in osMessageQDefCode:// ARM sample that doesn't work. !!!osMessageQDef(MsgBox, 16, T_MEAS);// audto generated using the latest cubemx 5.0... settings 256 queue size, 5 item size. works!! (see the parameters generated compared to above)osMessageQDef(myQueue01, 256, 5);// modified ARM sample using sizeof works!!!osMessageQDef(MsgBox, 16, sizeof(T_MEAS) );// yet macro osMessageQDef parameter type, already performs a sizeof()#define osMessageQDef(name, queue_sz, type) \const osMessageQDef_t os_messageQ_def_##name = \{ (queue_sz), sizeof (type) }

author: diyaudio
author_rank: Frequent Contributor
timestamp: November 23, 2018, 09:41:26 pm
content: Quote from: ogden on November 23, 2018, 08:17:47 amIf we look at the sample a pool allocates memory on the heap that is shared globally, the queue holds a pointer to the pool allocation see osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever);Code:T_MEAS *mptr;mptr = osPoolAlloc(mpool); // Allocate memory for the messagemptr->voltage = 223.72; // Set the message contentmptr->current = 17.54;mptr->counter = 120786;memcpy(mptr->data, data_arr, sizeof(mptr->data));osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever); // Send MessageosDelay(100);mptr = osPoolAlloc(mpool); // Allocate memory for the messagemptr->voltage = 227.23; // Prepare a 2nd messagemptr->current = 12.41;mptr->counter = 170823;osMessagePut(MsgBox, (uint32_t)mptr, osWaitForever); // Send MessageCode:T_MEAS *rptr;osEvent evt;for (;;) {evt = osMessageGet(MsgBox, osWaitForever); // wait for messageif (evt.status == osEventMessage) {rptr = evt.value.p;printf ("\nVoltage: %.2f V\n", rptr->voltage);printf ("Current: %.2f A\n", rptr->current);printf ("Number of cycles: %d\n", rptr->counter);osPoolFree(mpool, evt.value.p); // free memory allocated for message}}