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

Serial driver - what is a good approach?

Posted by Marcel van Lieshout on February 14, 2005
I am about to start writing a general-use serial port driver for the port (wizC) I'm working on. I would like to ask you all what approach would be the most appropiate.

Receiving is simple: to avoid race-conditions, only a single task should be receiving at any time.

Xmitting is more interesting. Several tasks should be able to transmit data through a single uart. The output of these tasks might (will!) be mixed up. Of course, this is not desirable. These are the scenarios I came up with:

=================================
ResourceReservation
Before a task can start sending data to the xmit-queue, a semaphore has to be taken. After a not-to-be-interrupted chunk has been queued, the semaphore is released. At this point another task can take it's turn by taking the semaphore.

Pro's:
- small datasize on queue
- small ram-overhead on sending task
- simple

Con's:
- possibly many messages to queue
- It may take long for a task to generate it's chunk
=================================
Messagepreparing
The xmitqueue contains a pointer to the data a task wants to xmit. An entry in the queue will be processed in it's entirety before the next queue-entry is retrieved. A method must be found so a task knows it's message has been processed and the buffer can be re-used.

Pro's
- small datasize on queue
- few messages on the queue
- tasks may write to the queue any time

Con's
- (much) more ram needed
- buffer-free mechanism
=================================

How would you do this?

Marcel

RE: Serial driver - what is a good approach?

Posted by Richard on February 14, 2005
> Receiving is simple: to avoid race-conditions, only a single task should be
> receiving at any time.
>
> Xmitting is more interesting. Several tasks should be able to transmit data
> through a single uart. The output of these tasks might (will!) be mixed up.
> Of course, this is not desirable. These are the scenarios I came up with:


Really this is an application design issue - and also very dependent on your available resources. On very resource restrained systems is may be best to design so only one task transmits and one receives (can be the same task of coarse).

If this is not possible then an alternative might be to have a 'Tx task'. The Tx task has sole control over the COM port and no other task can access it directly. With this scheme tasks that want to send data send the data to the Tx task (this can just be a pointer to a buffer of coarse) via a queue. The Tx task removed data from the queue one message at a time and sends it to the COM port. The queue mechanism ensures mutual exclusion as data is posted to the queue. Having one task move data between the queue and the COM port ensure mutual exclusion of the hardware and ensure one message does not start to be transmitted before the last has finished.


> =================================
> ResourceReservation
> Before a task can start sending data to the xmit-queue, a semaphore has to be
> taken. After a not-to-be-interrupted chunk has been queued, the semaphore is
> released. At this point another task can take it's turn by taking the semaphore.
>
> Pro's:
> - small datasize on queue
> - small ram-overhead on sending task
> - simple
>
> Con's:
> - possibly many messages to queue
> - It may take long for a task to generate it's chunk
> =================================

This is a good solution for the reasons you say. It can result in difficult application design - priority inversion and the like.



> Messagepreparing
> The xmitqueue contains a pointer to the data a task wants to xmit. An entry
> in the queue will be processed in it's entirety before the next queue-entry
> is retrieved. A method must be found so a task knows it's message has been processed
> and the buffer can be re-used.
>
> Pro's
> - small datasize on queue
> - few messages on the queue
> - tasks may write to the queue any time
>
> Con's
> - (much) more ram needed
> - buffer-free mechanism
> =================================

I think this is similar to the mechanism I suggest with the Tx task? This is good in that you don't have to copy too much data around as well. I think this is how I did the I2C driver for the WizNET demo (I would have to refresh my memory).

>
> How would you do this?


Not the answer you wanted...because its not really an answer...but it really does depend on the particular application needs. My approach with the demo applications is to provide a sample driver, and then note that it is not necessarily the best solution because one solution will never fit all. I would suggest you do the same. Have a driver using either of the mechanisms as a sample, but then you can say in the comments that there are obviously other solutions.

Regards.

RE: Serial driver - what is a good approach?

Posted by Marcel van Lieshout on February 14, 2005
Thanks. Not the answer I wanted, but I must admit it is the answer I expected.

Another question:
Suppose I would like to write a task that should "listen" on multiple queues. As far as I can see, I would have to check the number of messages in each queue and yield(), delay() or ... and then test again.

Is there a smarter way? Perhaps a new "wait on multiple queues" api-call that returns the handle of a queue that has at least 1 msg or NULL if the wait-timeout expires?

RE: Serial driver - what is a good approach?

Posted by Richard on February 15, 2005
As you point out, there is no way to wait on multiple queues at present. This could be introduced as a new API call, ... but ..., the reason it was left out was to do with code size. The kernel is written with size in mind and allowing a task to wait on multiple queues would require some major changes with a large efficiency impact.

An alternative: Have the task wait on a single queue with an identifier in the queued message to say what the message is or where it came from. For example, if you want to receive messages from queueA and queueB you could replace the following code:

void vATask( void *pvParameters )
{
for(;;)
{
if( something on queueA )
{
receive item from queueA;
}
if( something on queueB )
{
receive item from queueB;
}
}
}



with

#define QueueA 0
#define QueueB 1

typedef struct Q_ITEM
{
int Q;
void *PointerToData;
} xQData;

void vATask( void *pvParameters )
{
xQData Data;

for(;;)
{
if( cQueueReceive( Queue, &Data, 0xffff ) )
{
switch( Data.Q )
{
case QueueA : Process data;
break;
case QueueB : Process data;
break;
}
}
}
}


[ 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