[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 : >
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);
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
xQueueMidiMessages = xQueueCreate(20, sizeof(uint32t)); xQueueScreenMessages = xQueueCreate(20, sizeof(uint32t)); >
 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(vCheckSlowly, (signed char *)"SlowLoop", 1024, NULL, 1, NULL);
     uint16_t prio = configKERNEL_INTERRUPT_PRIORITY;

     vTaskStartScheduler();
 }

 for(;;);

 while(1);
} From Core_loop, the Sender : extern xQueueHandle xQueueScreenMessages; void SendToScreen(uint8t messagetype, 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 look look OK to me. What happend if you don't call ReadAndDecodeFromCore ?
regards Jonathan
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 : >
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