[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
Hi everyone,
I’m using coocox and yagarto on a STM32F427 with FreeRTOS 7.5.2. I have 5 tasks running simultaneously with several priorities. All interrupts are set to NVICPriorityGroup4 and until now preemption priorities were right.
TASK 1 : Higher priority (4). Synchronized with a timer interrupt and a binary semaphore. Receive messages through a queue from task 2 (buttons task). OK
TASK 2 : Priority (3). Check buttons of user interface periodically. Task delayed with a vTaskDelayUntil(). OK
TASK 3 : Priority (2). Show leds periodically. Task delayed with a vTaskDelayUntil(). OK
TASK 4 : Priority (1). Screen task. Cyclic task delayed with a vTaskDelayUntil(). Until now, OK
TASK 5 : Priority (1). Low priority and frequency task. Doesn’t do anything.
All of this worked well. I tried to add a queue filled by TASK 1 and read by TASK 4 (when it’s possible). Since this change, when i receive a message in the TASK 4 the values of pxPreviousWakeTime and xTimeIncrement seemed to be corrupted (become a random very large number).
And this TASK no longer executes periodically. Before receiving a message from this queue everything works fine.
I precise that i have enough heap configured, i use heap_4 and HighWaterMark of each task is sufficient.
Do you know what it could be ?
And do you know if there is a way to Block TASK 4 until a message arrive in the queue whereas this TASK has a lower priority than the sender ?
Thanks !
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
Hi,
Without showing the code that is use to fill the queue is hard to help.
Jonathan
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
In addition to Jonathan’s reply, are you using a recent version of FreeRTOS with configASSERT() defined? The most recent versions include additional assert() calls to help track down common configuration errors.
Regards.
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
Thanks for your answers,
Well, my code is like this.
In the main :
xQueueHandle xQueueMidiMessages; xQueueHandle xQueueScreenMessages; /* Declare a variable of type xSemaphoreHandle. This is used to reference the semaphore that is used to synchronize a task with an interrupt. */ xSemaphoreHandle xBinarySemaphoreCoreLoop; int main(void) { /* System Initialization. */ SystemInit(); SystemCoreClockUpdate(); /* Before a semaphore is used it must be explicitly created */ xBinarySemaphoreCoreLoop = xSemaphoreCreateCounting(3,0); // We need to know the size of an internal midi message ! 20 messages of uint32_t they said. xQueueMidiMessages = xQueueGenericCreate(20, 32, (unsigned char)0); xQueueScreenMessages = xQueueGenericCreate(5, 32, (unsigned char)0); GPIO_Config(); // Config des E/S et des RCC Reset_all_high_luminosity_step(); Update_leds_registers(0,0,0); Display_Led_Startup(); Interrupt_Config(); // BPM & Encoders 1, 2, 4, 5, 6 interrupt config SPI2_Config(); // Config SPI pour l'ecran DAC_Config(); USART_Config(); // Config du midi in, midi out et de l'interruption sur midi in Interrupt_Config(); // BPM & Encoders 1, 2, 4, 5, 6 interrupt config i2C_Config(); // Config i2C pour le touchpad ADC_Config(); // Config des 4 entrees analogiques screen_init(); tab_screen_init(); set_zone_white(0,0,127,63); //USB_Stop(); USB_Config(); // Force analog outputs at 0V GPIO_ResetBits(GPIOB, GPIO_Pin_11); //GATE Set_DAC_Ch1_Voltage(0); // CV Set_DAC_Ch2_Voltage(0); // ANALOG // All note off (MIDI + USB) Send_All_Note_Off(); if (xBinarySemaphoreCoreLoop != NULL && xQueueMidiMessages != NULL && xQueueScreenMessages != NULL) { // Allumage de la led de debug SWD Switch_Leds(LED_SWD_OFF); // This is the timer for the core loop (accuracy => us) TIM2 TIM_Config(); // Interrupt triggered by the timer TIM2 EnableTimerInterrupt(); //vTrack_Loop needs a stack size in bytes after the task name xTaskCreate(vTrack_Loop, (signed char *)"Core_Loop", 512, NULL, 4, NULL); // vIHM_Checker is launched every 5 ms, can you believe it ? xTaskCreate(vIHM_Checker, (signed char *)"IHM_Loop", 128, NULL, 3, NULL); // vDisplay_Led is launched every 1 ms xTaskCreate(vDisplay_Led, (signed char *)"Led_Loop", 128, NULL, 2, NULL); // vUpdate_Screen is launched every 30 ms xTaskCreate(vUpdate_Screen, (signed char *)"Screen_Loop", 128, NULL, 1, NULL); // vCheck_Slowly is launched every 2 seconds // xTaskCreate(vCheck_Slowly, (signed char *)"Slow_Loop", 1024, NULL, 1, NULL); uint16_t prio = configKERNEL_INTERRUPT_PRIORITY; vTaskStartScheduler(); } for(;;); while(1); }From Core_loop, the Sender :
extern xQueueHandle xQueueScreenMessages; void Send_To_Screen(uint8_t message_type, uint16_t content){ uint32_t mess_to_send = (message_type << 16) | content; xQueueGenericSend(xQueueScreenMessages, &mess_to_send, 0, pdFALSE); }In Screen_Loop, the receiver :
/* * The purpose of this task is to update the screen */ void vUpdate_Screen( void *pvParameters ) { uint32_t uxHighWaterMark; /* Inspect our own high water mark on entering the task. */ uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL ); portTickType xLastWakeTime; xLastWakeTime = xTaskGetTickCount(); /* This task is launched every 30ms */ portTickType currentPortTick = 30/(portTICK_RATE_MS); portBASE_TYPE xStatus = pdFALSE; const uint32_t message_from_core; /* Variables */ static uint8_t Count = 0; static uint8_t Logo_OFF = FALSE; /* Start of the task vSystem_Timer */ TASK_LOOP { // DEBUG if (uxHighWaterMark < 10){while(1);} xStatus = xQueueReceive(xQueueScreenMessages, &message_from_core, 0); if (xStatus == pdPASS) {ReadAndDecodeFromCore(message_from_core);} /* Delay */ vTaskDelayUntil( &xLastWakeTime, currentPortTick); } }The first time i receive something through the queue, when returning from xQueueReceive, xLastWakeTime and currentPortTick seemed corrupted. I have this kind of assert defined :
define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }The new types of assert are in version 8.0.0 of FreeRTOS ? Regards, Benoit
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
Hi,
Le 2014-04-15 09:31, BenoitDes a écrit :
>
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active. http://www.avast.com
Thanks for your answers, Well, my code is like this. In the main : xQueueHandle xQueueMidiMessages; xQueueHandle xQueueScreenMessages; /* Declare a variable of type xSemaphoreHandle. This is used to reference the semaphore that is used to synchronize a task with an interrupt. */ xSemaphoreHandle xBinarySemaphoreCoreLoop; int main(void) { /* System Initialization. */ SystemInit(); SystemCoreClockUpdate();xQueueMidiMessages = xQueueCreate(20, sizeof(uint32t)); xQueueScreenMessages = xQueueCreate(20, sizeof(uint32t)); >why not using the macro to create your queue directly ? Also from the comment above the creation of the Midi queue this should look like this/* Before a semaphore is used it must be explicitly created */ xBinarySemaphoreCoreLoop = xSemaphoreCreateCounting(3,0); // We need to know the size of an internal midi message ! 20 messages of uint32_t they said. xQueueMidiMessages = xQueueGenericCreate(20, 32, (unsigned char)0); xQueueScreenMessages = xQueueGenericCreate(5, 32, (unsigned char)0);
regards Jonathan// xTaskCreate(vCheckSlowly, (signed char *)"SlowLoop", 1024, NULL, 1, NULL);GPIO_Config(); // Config des E/S et des RCC Reset_all_high_luminosity_step(); Update_leds_registers(0,0,0); Display_Led_Startup(); Interrupt_Config(); // BPM & Encoders 1, 2, 4, 5, 6 interrupt config SPI2_Config(); // Config SPI pour l'ecran DAC_Config(); USART_Config(); // Config du midi in, midi out et de l'interruption sur midi in Interrupt_Config(); // BPM & Encoders 1, 2, 4, 5, 6 interrupt config i2C_Config(); // Config i2C pour le touchpad ADC_Config(); // Config des 4 entrees analogiques screen_init(); tab_screen_init(); set_zone_white(0,0,127,63); //USB_Stop(); USB_Config(); // Force analog outputs at 0V GPIO_ResetBits(GPIOB, GPIO_Pin_11); //GATE Set_DAC_Ch1_Voltage(0); // CV Set_DAC_Ch2_Voltage(0); // ANALOG // All note off (MIDI + USB) Send_All_Note_Off(); if (xBinarySemaphoreCoreLoop != NULL && xQueueMidiMessages != NULL && xQueueScreenMessages != NULL) { // Allumage de la led de debug SWD Switch_Leds(LED_SWD_OFF); // This is the timer for the core loop (accuracy => us) TIM2 TIM_Config(); // Interrupt triggered by the timer TIM2 EnableTimerInterrupt(); //vTrack_Loop needs a stack size in bytes after the task name xTaskCreate(vTrack_Loop, (signed char *)"Core_Loop", 512, NULL, 4, NULL); // vIHM_Checker is launched every 5 ms, can you believe it ? xTaskCreate(vIHM_Checker, (signed char *)"IHM_Loop", 128, NULL, 3, NULL); // vDisplay_Led is launched every 1 ms xTaskCreate(vDisplay_Led, (signed char *)"Led_Loop", 128, NULL, 2, NULL); // vUpdate_Screen is launched every 30 ms xTaskCreate(vUpdate_Screen, (signed char *)"Screen_Loop", 128, NULL, 1, NULL); // vCheck_Slowly is launched every 2 seconds
} From Core_loop, the Sender : extern xQueueHandle xQueueScreenMessages; void SendToScreen(uint8t messagetype, uint16_t content){uint16_t prio = configKERNEL_INTERRUPT_PRIORITY; vTaskStartScheduler(); } for(;;); while(1);
} In Screen_Loop, the receiver : /* * The purpose of this task is to update the screen / void vUpdate_Screen( void *pvParameters ) { uint32_t uxHighWaterMark; / Inspect our own high water mark on entering the task. */ uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );uint32_t mess_to_send = (message_type << 16) | content; xQueueGenericSend(xQueueScreenMessages, &mess_to_send, 0, pdFALSE);
} the first look look OK to me. What happend if you don't call ReadAndDecodeFromCore ?portTickType xLastWakeTime; xLastWakeTime = xTaskGetTickCount(); /* This task is launched every 30ms */ portTickType currentPortTick = 30/(portTICK_RATE_MS); portBASE_TYPE xStatus = pdFALSE; const uint32_t message_from_core; /* Variables */ static uint8_t Count = 0; static uint8_t Logo_OFF = FALSE; /* Start of the task vSystem_Timer */ TASK_LOOP { // DEBUG if (uxHighWaterMark < 10){while(1);} xStatus = xQueueReceive(xQueueScreenMessages, &message_from_core, 0); if (xStatus == pdPASS) {ReadAndDecodeFromCore(message_from_core);} /* Delay */ vTaskDelayUntil( &xLastWakeTime, currentPortTick); }
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active. http://www.avast.com
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
A couple of points:
uxHighWaterMark only ever seems to be set on entry into the task - which is before the task has really used much stack. Try updating it on every loop. Do you have a stack overflow hook defined? If not I would definitely recommend defining one: http://www.freertos.org/Stacks-and-stack-overflow-checking.html
messagefromcore is defined as a const but its value is not being set at definition (as would need to be the case for a const), and then you are trying to update it by passing it into xQueueReceive() despite it being declared const. I'm not sure what the compiler will make of that, probably nothing at low optimisation levesl, but a lot at high optimisation levels. I would expect this to generate multiple compiler warnings.
You are calling xQueueGenericSend() which is not part of the documented API. You should be calling xQueueSend(), xQueueSendToBack() (which is the same as xQueueSend()), or xQueueSendToFront().
Likewise you are calling xQueueGenericCreate() which is not a part of the documented API. You should be calling xQueueCreate(). When you do create xQueueScreenMessages (using the wrong API function) you are setting the item size to 32, but when you send and receive from the queue you are using a variable that has a size of 4 -> this will definitely cause corruption and is no doubt the root cause of your problem.
Regards.
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
Hi.
Le 2014-04-15 09:58, Real Time Engineers ltd. a écrit :
>
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active. http://www.avast.com
A couple of points: uxHighWaterMark only ever seems to be set on entry into the task - which is before the task has really used much stack. Try updating it on every loop. Do you have a stack overflow hook defined? If not I would definitely recommend defining one: http://www.freertos.org/Stacks-and-stack-overflow-checking.html messagefromcore is defined as a const but its value is not being set at definition (as would need to be the case for a const), and then you are trying to update it by passing it into xQueueReceive() despite it being declared const. I'm not sure what the compiler will make of that, probably nothing at low optimisation levesl, but a lot at high optimisation levels. I would expect this to generate multiple compiler warnings. You are calling xQueueGenericSend() which is not part of the documented API. You should be calling xQueueSend(), xQueueSendToBack() (which is the same as xQueueSend()), or xQueueSendToFront(). Likewise you are calling xQueueGenericCreate() which is not a part of the documented API. You should be calling xQueueCreate(). When you do create xQueueScreenMessages (using the wrong API function) you are setting the item size to 32, but when you send and receive from the queue you are using a variable that has a size of 4 -> this will definitely cause corruption and is no doubt the root cause of your problem. i' missed that one 🙂Regards.
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil https://sourceforge.net/p/freertos/discussion/382005/thread/91ecf944/?limit=25#012e
Sent from sourceforge.net because you indicated interest in https://sourceforge.net/p/freertos/discussion/382005/ To unsubscribe from further messages, please visit https://sourceforge.net/auth/subscriptions/ -- This message has been scanned for viruses and dangerous content by MailScanner http://www.mailscanner.info/, and is believed to be clean.
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active. http://www.avast.com
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
I was sure it was a dumb cause...
I tried several things that's why generic functions where used. All the points are corrected. And of course now it works well. Strange i didn't see this memory issue before with xQueueMidiMessages which i use for two month now...
Thanks a lot !
Benoit
[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil
Hi,
it's only a chance that you don't have seen the bug.
Jonathan