Quality RTOS & Embedded Software

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




Loading

Need help with queue and task priority

Posted by ephobb on December 31, 2015

Hi, I am using three task. two task are sending data to queue(both having priority as 1) and one task is reading that data(priority as 2 and periodic 1000ms). but i m observing bit different output. Initially both task queueing data. but after some time only one task in queueing data. here is my code.

~~~~

include "stm32f1xx_hal.h"
include "cmsis_os.h"
include "task.h" /* RTOS task related API prototypes. */

UARTHandleTypeDef huart1; xQueueHandle uartqueue=0;

void SystemClockConfig(void); static void MXGPIOInit(void); static void MXUSART1UARTInit(void); void StartDefaultTask(void const * argument); void sendstr1(void const * argument); void send2(void const * argument); void Sduart(void const * argument);

int main(void) { HALInit(); SystemClockConfig(); MXGPIOInit(); MXUSART1UART_Init();

uart_queue	= xQueueCreate(11,sizeof(uint8_t *));	
xTaskCreate((TaskFunction_t)send_str1,"string1",128,NULL,1,NULL);
xTaskCreate((TaskFunction_t)send2,"string2",64,NULL,1,NULL);
xTaskCreate((TaskFunction_t)Sd_uart,"Suart",64,NULL,2,NULL);

vTaskStartScheduler();

while (1) {

}

}

void StartDefaultTask(void const * argument) { for(;;) { osDelay(1); } }

void sendstr1(void const * argument) { uint8t *dat="Task1"; for(;;) { xQueueSend(uart_queue,&dat,500); GPIOA->ODR = 0x00000000; taskYIELD(); } }

void send2(void const * argument) { uint8t *dat=" Task2"; for(;;) { xQueueSendToBack(uartqueue,&dat,500); GPIOA->ODR = 0x00000020; taskYIELD(); } }

void Sduart(void const * argument) { TickTypet xLastWakeTime; // Initialise the xLastWakeTime variable with the current time. xLastWakeTime = xTaskGetTickCount(); uint8t *data; for(;;) { if(xQueueReceive(uartqueue,&data,100)) { HALUARTTransmit(&huart1,data,11,1000); } else { HALUARTTransmit(&huart1,"--",2,1000); } vTaskDelayUntil(&xLastWakeTime,1000/portTICKRATEMS);

}

} ~~~~

and output is

~~~~ Task1 Task2 Task2Task1 Task2Task1 Task2Task1 Task2Task1 Task2Task1 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 Task2 ~~~~

plz help me with this.


Need help with queue and task priority

Posted by rtel on December 31, 2015

It would be very hard to predict how the code would execute. sendstr1() and send2() are writing to the queue continuously (or at least, attempting to), but Sduart() is only removing data from the queue every 1000ms, therefore, other than for the first few milliseconds, the queue will always be full.

Once the queue is full, sendstr1() and send2() will block attempting to write to the queue, but time out before Sduart() times out.

I think what you are seeing is task1 and task2 being written to the queue while the queue is being filled - then once the queue is full, which task happens to get unblocked, if any, when Sd_uart() removes and item from the queue is unpredictable.


Need help with queue and task priority

Posted by ephobb on January 1, 2016

Thanks. Yeah, two task's are writting to queue continously. but we can see output is, flow of task is as follow: task1 - > Sduart -> Task2->SdUart->Task1->....

But instead, i was trying to use following sequeunce as , Task1->Task2->SdUart->Task1->Task2->SdUart->.....

i m just wondering that, in Task1 and Task2 i m calling taskYIELD(). If i m calling taskYIELD from Task1 then control should go to Task2 and then again Task1.and Sduart will get call after 1000 ms. So till the time queue will be fulled and Task1 and task2 will be in block state. Sduart will remove item from queue and again Task1 and Task2 will be in ready and runnning state.

but it is not working as expected. Plz suggest me on this.


Need help with queue and task priority

Posted by rtel on January 1, 2016

But instead, i was trying to use following sequeunce as , Task1->Task2->SdUart->Task1->Task2->SdUart->.....

In which case you can have Sd_Uart use a long block time, and control the flow with the Task1 and Task2.

Task1 and Task2 can do something like:

~~~~~ for( ;; ) { xQueueSend(...); vTaskDelay( [whatever rate you want to send at] ); } ~~~~~

Then one task will unblock, write to the queue, and go back into the Blocked state for however long you like. While that task is in the Blocked state the other sending task will run and do the same. That way they will write to the queue in turn. In the mean time the receiving task just unblocks when there is data in the queue. If you want both senders to post to the queue before the receiver executes then the receiver must have the lower priority.

There are more elaborate ways you could control the sequencing, but if the two senders are the same priority and use the same block time then the above should work. You could even give one sender a higher priority than the other to ensure the order never changes even when tick interrupts occur while one of them is running.


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




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

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

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