Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem


Loading

[STM32F4] Creating a queue between two tasks corrupts data sent to vTaskDelayUntil

Posted by benoitdes on April 15, 2014

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

Posted by dumarjo on April 15, 2014

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

Posted by rtel on April 15, 2014

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

Posted by benoitdes on April 15, 2014

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

Posted by dumarjo on April 15, 2014

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)); > > GPIOConfig(); // Config des E/S et des RCC > > Resetallhighluminositystep(); > Updateledsregisters(0,0,0); > DisplayLedStartup(); > > InterruptConfig(); // BPM & Encoders 1, 2, 4, 5, 6 interrupt config > > SPI2Config(); // Config SPI pour l'ecran > > DACConfig(); > USARTConfig(); // Config du midi in, midi out et de l'interruption sur midi in > > InterruptConfig(); // BPM & Encoders 1, 2, 4, 5, 6 interrupt config > > i2CConfig(); // Config i2C pour le touchpad > ADCConfig(); // Config des 4 entrees analogiques > > screeninit(); > tabscreeninit(); > setzonewhite(0,0,127,63); > > //USBStop(); > USBConfig(); > > // Force analog outputs at 0V > GPIOResetBits(GPIOB, GPIOPin11); //GATE > SetDACCh1Voltage(0); // CV > SetDACCh2Voltage(0); // ANALOG > > // All note off (MIDI + USB) > SendAllNoteOff(); > > if (xBinarySemaphoreCoreLoop != NULL && xQueueMidiMessages != NULL && xQueueScreenMessages != NULL) { > > // Allumage de la led de debug SWD > SwitchLeds(LEDSWDOFF); > > // This is the timer for the core loop (accuracy => us) TIM2 > TIMConfig(); > // Interrupt triggered by the timer TIM2 > EnableTimerInterrupt(); > > //vTrackLoop needs a stack size in bytes after the task name > xTaskCreate(vTrackLoop, (signed char *)"CoreLoop", 512, NULL, 4, NULL); > > // vIHMChecker is launched every 5 ms, can you believe it ? > xTaskCreate(vIHMChecker, (signed char )"IHMLoop", 128, NULL, 3, NULL); > > // vDisplayLed is launched every 1 ms > xTaskCreate(vDisplayLed, (signed char *)"LedLoop", 128, NULL, 2, NULL); > > // vUpdateScreen is launched every 30 ms > xTaskCreate(vUpdateScreen, (signed char *)"ScreenLoop", 128, NULL, 1, NULL); > > // vCheckSlowly is launched every 2 seconds > // xTaskCreate(vCheckSlowly, (signed char *)"SlowLoop", 1024, NULL, 1, NULL); > > uint16t prio = configKERNELINTERRUPTPRIORITY; > > vTaskStartScheduler(); > } > > for(;;); > > while(1); > } > > From Coreloop, the Sender : > > extern xQueueHandle xQueueScreenMessages; > > void SendToScreen(uint8t messagetype, uint16t content){ > > uint32t messtosend = (messagetype << 16) | content; > > xQueueGenericSend(xQueueScreenMessages, &messtosend, 0, pdFALSE); > } > > In ScreenLoop, the receiver : > > / > * The purpose of this task is to update the screen > / > void vUpdateScreen( void *pvParameters ) > { > uint32t 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/(portTICKRATEMS); > portBASETYPE xStatus = pdFALSE; > const uint32t messagefromcore; > > / Variables / > static uint8t Count = 0; > static uint8t Logo_OFF = FALSE; > > / Start of the task vSystemTimer */ > TASKLOOP > { > // DEBUG > if (uxHighWaterMark < 10){while(1);} > > xStatus = xQueueReceive(xQueueScreenMessages, &messagefromcore, 0); > if (xStatus == pdPASS) {ReadAndDecodeFromCore(messagefromcore);} > > /* 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

Posted by rtel on April 15, 2014

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

Posted by dumarjo on April 15, 2014

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

Posted by benoitdes on April 15, 2014

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

Posted by dumarjo on April 15, 2014

Hi,

it's only a chance that you don't have seen the bug.

Jonathan


[ Back to the top ]    [ About FreeRTOS ]    [ Privacy ]    [ Sitemap ]    [ ]


Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

OpenRTOS and SafeRTOS

Xilinx Microblaze and Zynq partner