USART RTOS Driver

The universal synchronous and asynchronous receiver and transmitter (USART) is normally used to transfer data from one device to the other.

The transfer functions of the USART RTOS driver are optimized for RTOS support. That is, the transfer functions will not work without RTOS, the transfer functions should be called only in an RTOS task or thread.

The USART RTOS driver use a ring buffer to store received data. When the USART raise the data received interrupt, the data will be stored in the ring buffer at the next free location. When the ring buffer is full, the next reception will overwrite the oldest data stored in the ring buffer. When initialize the driver, the ring buffer must be allocated and passed to driver for use. The size of the buffer must be the power of two, e.g., 32 or 64. When reading data through the USART RTOS API, and if the number of bytes asked for are more than currently available in the ring buffer or more than the ringbuf size, the task/thread will be blocked until read is done. If the number of bytes asked for is less than the available bytes in the ring buffer, the remaining bytes will be kept until a new call.

On the other hand, when sending data over USART, the data is not copied to an internal buffer. The data buffer supplied by the user is used. Then the task/thread will be blocked to wait until all data is sent.

During data transfer, the USART TX/RX process is not protected, so that a more flexible way can be chosen in the application.

The user can set an action for the flow control pins by the driver API if the flow control is enabled. All the available states are defined in the usart_os_flow_control_status union.

Note that the user can set the state of the flow control pins only if the automatic support of the flow control is not supported by the hardware.

Summary of the API's Functional Features

The API provides functions to:
  • Initialize and deinitialize the driver and associated hardware

  • Register I/O descriptor

  • Enable or disable USART

  • Hookup callback handlers on transfer complete, or error events

  • Data transfer: transmission, reception

Summary of Configuration Options

Below is a list of the main USART parameters that can be configured in START. Many of these parameters are used by the usart_os_init function when initializing the driver and underlying hardware. Most of the initial values can be overridden and changed runtime by calling the appropriate API functions.
  • Set USART baudrate

  • Select UART or USART communication mode

  • Select character size

  • Set Data order

  • Flow control

  • Which clock source is used

Driver Implementation Description

After USART hardware initialization, the usart_os_get_io_descriptor() function is needed to register an I/O descriptor. Then start the read/write operation.

Concurrency

  • The write buffer should not be changed while data is being sent

Limitations

  • The driver does not support 9-bit character size

Example of Usage

The following shows a simple example of using the USART. The USART must have been initialized by usart_os_init. This initialization will configure the operation of the USART.

The example registers an I/O descriptor and then starts a reading operation.
/** * Example task of using USART_0 to echo using the I/O abstraction. */static void USART_0_example_task(void *p){    struct io_descriptor *io;    uint16_t              data;    (void)p;    usart_os_get_io(&USART_0, &io);    for (;;) {        if (io_read(io, (uint8_t *)&data, 2) == 2) {            io_write(io, (uint8_t *)&data, 2);        }    }}#define TASK_TRANSFER_STACK_SIZE            ( 256/sizeof( portSTACK_TYPE ))#define TASK_TRANSFER_STACK_PRIORITY        ( tskIDLE_PRIORITY + 0 )static TaskHandle_t xCreatedTransferTask;static void task_transfer_create(void){    /* Create the task that handles the CLI. */    if (xTaskCreate(USART_0_example_task, "transfer", TASK_TRANSFER_STACK_SIZE, NULL,    TASK_TRANSFER_STACK_PRIORITY, &xCreatedTransferTask) != pdPASS) {        while(1) {;        }    }}static void tasks_run(void){    vTaskStartScheduler();}int main(void){    /* Initializes MCU, drivers and middleware */    atmel_start_init();    task_transfer_create();    tasks_run();    /* Replace with your application code */    while (1) {    }}

Dependencies

  • The USART peripheral and its related I/O lines and clocks

  • The NVIC must be configured so that USART interrupt requests are periodically serviced

  • RTOS