Quality RTOS & Embedded Software

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




Loading

Can't get simple queue to work using sender task and receiver task

Posted by rafaeladel on January 22, 2016

I'm trying to run a simple example with queues using Atmega32. I have 1. Two sending tasks 2. One receiving task 3. Buzzer 4. 3 LEDS (for errors detection)

The first sending task turns on the buzzer. The second sending task turns off the buzzer. The receiver task receive execution code from either one of the sending tasks and act according to that code (0x01 to turn on buzzer , 0x02 to turn off buzzer).

The 3 leds are for error detection. 1. Pin 5 led -> queue empty (Receiver side) 2. Pin 6 led -> queue not empty (when it should be) (Receiver side) 3. Pin 7 led -> queue is full (Sender side)

The receiver task has higher priority than the two sender tasks. And it waits for 100ms in block state till any data arrives in queue.

The problem is, I always get pin (5) led on !! meaning the queue is empty. Where I thing the buzzer should go on and off without toggeling any leds for errors.

My assumption that the two sender tasks never run and the schedular always run the receiver (having the highest priority), but again there's (100ms) for the receiver in block state where the two sender should operate.

Here's my code:

~~~~

define F_CPU 8000000UL
include
include "freertos/FreeRTOS.h"
include "freertos/task.h"
include "freertos/queue.h"
include "freertos/FreeRTOSConfig.h"

void tasksender(void *pvParameters); void taskreceiver(void *pvParameters);

QueueHandlet myqueue;

int main(void) { myqueue = xQueueCreate(1, sizeof(char)); if(myqueue != NULL) { DDRD = 0xf0; char senderone = 0x01; char sendertwo = 0x02;

	xTaskCreate(task_sender, NULL, 50, &sender_one, 1, NULL);
	xTaskCreate(task_sender, NULL, 50, &sender_two, 1, NULL);
	xTaskCreate(task_receiver, NULL, 50, NULL, 2, NULL);

	vTaskStartScheduler();	
}
return 0;

}

void tasksender(void *pvParameters) { char msg = '0'; portBASETYPE status = '0'; while(1) { PORTD = 1 << PD7; msg = (char) pvParameters; status = xQueueSendToBack(myqueue, &msg, 0); if(status == errQUEUEFULL) { PORTD = 1 << PD7; } taskYIELD(); } }

void taskreceiver(void *pvParameters) { char recievedmsg = '0'; portTickType timeToWait = 100 / portTICKRATEMS; portBASETYPE status = '0'; while(1) { if(uxQueueMessagesWaiting(myqueue) != 0) { PORTD = 1 << PD6; } status = xQueueReceive(myqueue, &recievedmsg, timeToWait); if(status == pdPASS) { if(recievedmsg == 0x01) { PORTD = 1 << PD4; } else if(recievedmsg == 0x02) { PORTD &= ~(1 << PD4); } } else if(status == errQUEUE_EMPTY){ PORTD = 1 << PD5;

	}
}

} ~~~~

My FreeRTOSConfig.h:

~~~~

define configUSE_PREEMPTION 1
define configUSEIDLEHOOK 0
define configUSETICKHOOK 0
define configCPUCLOCKHZ ( ( unsigned long ) 8000000 )
define configTICKRATEHZ ( ( portTickType ) 1 )
define configMAXPRIORITIES ( ( unsigned portBASETYPE ) 3)
define configMINIMALSTACKSIZE ( ( unsigned short ) 85 )
define configTOTALHEAPSIZE ( (size_t ) ( 600 ) )
define configMAXTASKNAME_LEN ( 8 )
define configUSETRACEFACILITY 0
define configUSE16BIT_TICKS 1
define configIDLESHOULDYIELD 0
define configQUEUEREGISTRYSIZE 0

/* Co-routine definitions. */

define configUSECOROUTINES 0
define configMAXCOROUTINE_PRIORITIES ( 2 )

/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */

define INCLUDE_vTaskPrioritySet 0
define INCLUDE_uxTaskPriorityGet 0
define INCLUDE_vTaskDelete 1
define INCLUDE_vTaskCleanUpResources 0
define INCLUDE_vTaskSuspend 0
define INCLUDE_vTaskDelayUntil 1
define INCLUDE_vTaskDelay 1

~~~~


Can't get simple queue to work using sender task and receiver task

Posted by rtel on January 23, 2016

It is not clear what you are asking. If I were to rephrase it as the following, would I be correct?

"I have two low priority tasks that constantly write to a queue without blocking, and a high priority task that blocks reading from the queue with a 100 tick time out. As the low priority tasks are running continuously without blocking I would never expect the 100 tick time out to expire, but it does, what could be the reason for this"?

A brief look at your code shows two potential issues.

First you are declaring a block scope variable senderone (same goes for sendertwo), then passing the address of this variable into the task. The task then uses the address of a block scope variable - so the address of a variable that doesn't really exist any more. On the AVR that may be ok, as I don't think the memory used by main() is then re-used, but on something like a Cortex-M this will definitely cause you a problem as the memory used by main() is then re-used by interrupts.

The other potential issue is more subtle, and that is how you are using pointers. This can can get quite confusing, but really is a C issue, rather than a FreeRTOS issue. In the task you have a local varaible msg, and you pass the address of msg into the queue send function. That means the queue will copy 1 byte (as the queue item size is one) from the address of the variable (which is an address on the task stack) rather than from the address msg is pointing to. msg is pointing to the variable that you have set with your buzzer on/off code.

It might be easier then to copy the buzzer on/off value into the task using the task parameter, rather than the address of a variable that is set to the value. For example:

In main: ~~~~ char sender_one = 1;

/* Cast the value 1 to a void , so it can get passed into the xTaskCreate() function, rather than passing in the address of the variable. */ xTaskCreate(task_sender, NULL, 50, (void)sender_one, 1, NULL); ~~~~

In your task: ~~~~ void task_receiver(void pvParameters) { / Cast the value back from a void * to an integer (char). */ char msg = (char) pvParameter;

/* This time, msg holds the value 1, not the address of 
another variable, so now it IS valid to pass the address of
msg into the xQueueSendToBack() function. */
xQueueSendToBack(my_queue, &msg, 0);

~~~~

This should fix both the potential issues highlighted above, and simplify the code.


Can't get simple queue to work using sender task and receiver task

Posted by rafaeladel on January 23, 2016

Yes, that's quite what I meant. I mean when a sender sends in the queue, the receiver should receive the data and never get errQueue_FULL error. I've made the changes you've suggested. But unfortunately the issue still exists. Here's how my code is after the modifications:

~~~~

define F_CPU 8000000UL
include
include "freertos/FreeRTOS.h"
include "freertos/task.h"
include "freertos/queue.h"
include "freertos/FreeRTOSConfig.h"

void tasksender(void *pvParameters); void taskreceiver(void *pvParameters);

QueueHandlet myqueue; char senderone = 0x01; char sendertwo = 0x02;

int main(void) { myqueue = xQueueCreate(1, sizeof(char)); if(myqueue != NULL) { DDRD = 0xf0;

	xTaskCreate(task_sender, NULL, 300, (void *) sender_one, 1, NULL);
	xTaskCreate(task_sender, NULL, 300, (void *) sender_two, 1, NULL);
	xTaskCreate(task_receiver, NULL, 300, NULL, 2, NULL);

	vTaskStartScheduler();	
}
return 0;

}

void tasksender(void *pvParameters) { char msg = (char) pvParameters; portBASETYPE status = '0'; while(1) { status = xQueueSendToBack(myqueue, &msg, 0); if(status == errQUEUEFULL) { PORTD = 1 << PD7; } taskYIELD(); } }

void taskreceiver(void *pvParameters) { char recievedmsg = '0'; portTickType timeToWait = 100 / portTICKRATEMS; portBASETYPE status = '0'; while(1) { if(uxQueueMessagesWaiting(myqueue) != 0) { PORTD = 1 << PD6; } status = xQueueReceive(myqueue, &recievedmsg, timeToWait); if(status == pdPASS) { if(recievedmsg == 0x01) { PORTD = 1 << PD4; } else if(recievedmsg == 0x02) { PORTD &= ~(1 << PD4); } } else if(status == errQUEUE_EMPTY){ PORTD = 1 << PD5;

	}
}

}

~~~~


Can't get simple queue to work using sender task and receiver task

Posted by rtel on January 23, 2016

A couple of notes, although I'm not sure which FreeRTOS version you are using. Note after fixing the first point below, I was able to run your code (using a different FreeRTOS port) without any problems - it behaved as expected and the queue was never empty:

  • You can't use NULL as the text name for the tasks being created (second parameter to xTaskCreate()). That will cause a NULL pointer to be dereferenced.

  • Did you check the return values of xTaskCreate() to check the tasks are being created, or step through the code to check the tasks are being created as expected?

  • Do you have configASSERT() defined, the stack overflow checks turned on, the malloc failed hook defined, etc?

  • portTickType was deprecated some time ago, it is recommended to use TickType_t instead.

  • portBASETYPE was deprecated some time ago, it is recommended to use BaseTypet instead.


Can't get simple queue to work using sender task and receiver task

Posted by rafaeladel on January 23, 2016

I made the adjustement you've suggested but still the issue exists. However, I've tried making receiver task priority to be the same as the sender (instead of 2, changed it to 1). And it worked.

I wonder having the receiver task with priority higher than the sender is correct or just making it equal to the sender tasks.


Can't get simple queue to work using sender task and receiver task

Posted by rtel on January 23, 2016

I could not see anything wrong with your original code, and for me at least it executed as expected, although I was using a different RTOS port.

Which version of FreeRTOS are you using?


Can't get simple queue to work using sender task and receiver task

Posted by rafaeladel on January 23, 2016

Using FreeRTOS V8.2.3


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




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

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

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

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

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists