The interrupt driven character queue transfer mode can be used with both FreeRTOS_read() and FreeRTOS_write().
ioconfigUSE_TX_CHAR_QUEUE and/or ioconfigUSE_RX_CHAR_QUEUE must be set to 1 in
for the character queue transfer mode to be available for writes and reads respectively. It
must also be explicitly enabled for the peripheral being used within the
same configuration file.
When the character queue transfer mode is selected for writes, FreeRTOS_write()
does not write directly to the peripheral. Instead the bytes are sent to
a transmit queue. The
peripheral's interrupt service routine removes the bytes from the queue and
sends them to the peripheral.
When the character queue transfer mode is selected for reads, FreeRTOS_read()
does not read bytes directly from the peripheral, but from a receive queue
that is filled by the FreeRTOS+IO interrupt service routine as data is received.
The interrupt service routines, and the FreeRTOS queues, are implemented
by the FreeRTOS+IO code, and do not need to be provided by the application
Interrupt Driven Character Queue Transfer Mode
Simple usage model
Automatically places the calling task into the
Blocked state to wait for the read or write operation
to complete - if it cannot complete immediately. This
ensures the task calling FreeRTOS_read() or FreeRTOS_write()
only uses CPU time when there is actually processing
that can be performed.
A read and/or write timeout can be set to ensure
FreeRTOS_read() and FreeRTOS_write() calls do not
Bytes received by the peripheral are automatically
buffered, and not lost, even if a FreeRTOS_read()
operation is not in progress when the bytes are received.
Calls to FreeRTOS_write() can occur at any time. There
is no need to wait for a previous transmission to complete,
or for the peripheral to be free.
The FreeRTOS+IO driver requires RAM for the queues.
The queue length is configured by the third parameter
of the FreeRTOS_ioctl() call used to select the
Character queues are inefficient, so their use should
be limited to applications that do not
require large amounts of data to be read or written.
For example, character queues provide a very convenient
transfer mode for command line interfaces, where
characters are only received as quickly as somebody
FreeRTOS queues have an in-built mutual exclusion
mechanism, but only at the single character level.
Therefore, it is guaranteed that the queue data structures
will not become corrupt if two tasks attempting to
perform a FreeRTOS_write() (or a FreeRTOS_read()) at
the same time, but there is no guarantee that the
data will not become interleaved if that happens.
The application writer can guard against that eventuality
using task priorities, or external mutual exclusion
(using a mutex for example) if it is necessary.
The ioctlUSE_CHARACTER_QUEUE_TX and ioctlUSE_CHARACTER_QUEUE_RX request codes are used in calls to FreeRTOS_ioctl()
to configure a peripheral
to use interrupt driven character queue writes and reads respectively.
Note these request codes will result in the peripheral's
interrupt being enabled, and the peripheral's interrupt priority being set to the
lowest possible. The ioctlSET_INTERRUPT_PRIORITY request code can be used
to raise the peripheral's priority if necessary.
void vAFunction( void )
const uint32_t ulMaxBlock100ms = ( 100UL / portTICK_PERIOD_MS );
xOpenedPort = FreeRTOS_open( "/SPI2/", NULL );
if( xOpenedPort != NULL )
FreeRTOS_ioctl( xOpenedPort, ioctlUSE_CHARACTER_QUEUE_RX, ( void * ) 20 );
FreeRTOS_ioctl( xOpenedPort, ioctlUSE_CHARACTER_QUEUE_TX, ( void * ) 20 );
FreeRTOS_ioctl( xOpenedPort, ioctlSET_RX_TIMEOUT, ( void * ) ulMaxBlock100ms );
FreeRTOS_ioctl( xOpenedPort, ioctlSET_TX_TIMEOUT, ( void * ) ulMaxBlock100ms );
for( ;; )
xBytesTransferred = FreeRTOS_write( xOpenedPort, ucBuffer, 10 );
configASSERT( xBytesTransferred == 10 );
xBytesTransferred = FreeRTOS_read( xOpenedPort, ucBuffer, 10 );
if( xBytesTransferred == 10 )