UART (Universal Asynchronous Receiver-Transmitter)

  1. General Introduction
  2. API Overview
  3. Initializing and configuring UART
  4. Transmitting data over UART
  5. Transmitting Data Full Code Example
  6. Receiving data over UART
  7. Receiving Data Full Code Example

General Introduction

UART stands short for Universal Asynchronous Receiver Transmitter and it is a physical circuit in a micro controller or a stand-alone IC. A UART’s main purpose is to transmit and receive serial data over two wires. In UART communication, two UARTs communicate directly with each other.

UARTs transmit data asynchronously, which means there is no clock signal to synchronize the output of bits from the transmitting UART to the sampling of bits by the receiving UART. Instead of a clock signal, the transmitting UART adds start and stop bits to the data packet being transferred. These bits define the beginning and end of the data packet so the receiving UART knows when to start reading the bits.

Data transmitted via UART is organized into packets. Each packet contains 1 start bit, 5 to 9 data bits (depending on the UART hardware interface), an optional parity bit, and 1 or 2 stop bits:

Image

The data rate for UART range from 230.4kbps to 16Mbps.

The configurable parameters for UART are:

  • Baud Rate: The Baud rate is a measure of the speed of data transfer at which data can be transferred and incoming data is read. It is expressed in bits per second (bps).
  • Start Bit: The first bit of an ongoing UART data packet transmission. It indicates that the data line is leaving its idle state, typically from logic high to logic low. It simplifies communication between transmitter and receiver, but does not deliver meaningful data.
  • Stop Bit: The last bit of an ongoing UART data packet transmission represents the end of the data transmission. It raises the logic level back into the idle state, typically to logic high.
  • Parity Bit: Parity describes the evenness or oddness of a number. The parity bit is a way for the receiving UART to tell if any data has changed during transmission. After the receiving UART reads the data frame, it counts the number of bits with a value of 1 and checks if the total is an even or odd number. If the parity bit is a 0 (even parity), the bits in the data frame should total to an even number. If the parity bit is a 1 (odd parity), the 1 bits in the data frame should total to an odd number. When the parity bit matches the data, the UART knows that the transmission was free of error. But if the parity bit is a 0, and the total is odd or the parity bit is a 1, and the total is even, the UART knows that bits in the data frame have changed.

Please note that for a working UART communication it is necessary that both UART endpoints operate at the same baud rate. Furthermore, the same configuration about the start, stop and parity bits need to be applied to both endpoints.

API Overview

It is generally recommended to develop an application based on the highest API level the XDK framework supports, although it is possible to access deeper API levels if the highest level does not provide the functionality required for a specific purpose.

As with most XDK functionalities, there is an API allowing simple access to necessary functions for developing applications that use the serial bus protocols on the Extension Bus. For that the BSP and Utils API provided by the Platform layer will be used.

The picture below illustrates the interfaces for UART, SPI and I2C from the corresponding API.

Image

Initializing and configuring UART

This section describes how to initialize UART either to receive or transmit data. It also covers the necessary configuration for the baud rate, the start bit, stop bit and parity bit. For that, the following interfaces will be used.

#include "BSP_ExtensionPort.h"
#include "BCDS_MCU_UART.h"
#include "BCDS_UARTTransceiver.h"

The BSP_ExtensionPort.h is used to connect and configure the UART interface on the Extension Bus. With it, the configuration of the Baud rate, the start, stop and parity bits will be implemented.

The following Table shows an excerpt of the functions used to implement a working UART connection.

FunctionDescription
BSP_ExtensionPort_Connect()This function is called to enable the power control for the extension bus and disables all GPIO pins to conserve power
BSP_ExtensionPort_ConnectUart()This function is called to configure the corresponding UART receive (RX) and transmit (TX) pins on the extension bus
BSP_ExtensionPort_SetUartConfig()This function is called to configure UART settings, such as Baud rate, start bit, stop bit and parity bit
BSP_ExtensionPort_GetUartHandle()This function returns the handle for the UART communication holding all relevant configuration data
BSP_ExtensionPort_EnableUart()This function is called to enable the UART module for transmitting and reading data

The interface BCDS_MCU_UART.h is used to initialize UART on the driver level to handle the events when data is received or transmitted via UART over the function MCU_UART_Initialize().

Furthermore, the interface BCDS_UARTTransceiver.h is used to extend UART to add functionality such as a ring buffer to store the incoming data and to send out data streams greater than one UART data packet.

The following table shows an excerpt of the used functions from the UART Transceiver interface.

FunctionDescription
UARTTransceiver_Initialize()This function is used to initialize the UART transceiver module
UARTTransceiver_StartInAsyncMode()This function is used to start the UART transceiver for asynchronous data transmission
UARTTransceiver_ReadData()This function is used to read stored UART data from the UART transceiver
UARTTransceiver_WriteData()This function is used to send multiple UART data packets via the UART transceiver

The code below shows an outline of the first configurations to the UART module.

// Place this code snippet inside AppInitSystem() after BCDS_UNUSED(param2);
BSP_ExtensionPort_Connect();
BSP_ExtensionPort_ConnectUart();
BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_PARITY, BSP_EXTENSIONPORT_UART_NO_PARITY, NULL);
BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_BAUDRATE, UINT32_C(9600), NULL);
BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_STOPBITS, BSP_EXTENSIONPORT_UART_STOPBITS_ONE, NULL);

First, the function BSP_ExtensionPort_Connect() is called to enable the power control on the Extension Bus and to disable all pins on the Extension Bus. The function BSP_ExtensionPort_ConnectUart() configures the UART pins PB9 and PB10 on the Extension Bus to be used as TX and RX pins.

Afterwards, BSP_ExtensionPort_SetUartConfig() is called to configure the baud rate, the number of stop bits and the parity bits. As for this outline, a baud rate of 9600, one stop bit and no parity bit is configured.

Now the initialization of the UART module on the driver level can begin. For that, a global variable of the type UARTTranceiver_T, as shown in the following code, needs to be declared.

static UARTTransceiver_T UartTransceiverInstance;

This variable will hold all relevant information in regards to the UART data transmission as well as the UART module itself. The specific information will be for example the amount of received data stored in an internal ring buffer.

The MCU_UART_Initialize() requires a callback function with the type and parameter signature as shown in the code below needs to be declared.

void UartDriverCallBack(UART_T uart, struct MCU_UART_Event_S event){
  if (UartTransceiverInstance.handle == uart){
    UARTTransceiver_LoopCallback(&UartTransceiverInstance, event);
  }
}

This function invokes the UART receive and transmit event by passing it to the UARTTransceiver_LoopCallback() function. UARTTransceiver_LoopCallback() takes the triggered events and reads for example data from the UART module or sends the next UART data packet over it.

Afterwards, the UART driver API can be initialized using the following code.

HWHandle_T UartHandle = BSP_ExtensionPort_GetUartHandle();

MCU_UART_Initialize(UartHandle, UartDriverCallBack);

Before the initialization function MCU_UART_Initialize() can be called, the hardware handle with the configurations made in one of the previous code snippets needs to be obtained by calling the function BSP_ExtensionPort_GetUartHandle() and assigned to a variable of type HWHandle_T. Then the function MCU_UART_Initialize() can be called by passing the previously declared callback function as a parameter.

Now that the configuration on the UART hardware level is completed and the driver API is initialized, the utility API for the UARTTransceiver can be initialized.

As preparation, the following code defines a Ring Buffer, which will be used later.

#define MAX_UART_RING_BUFFERSIZE UINT32_C(45)

static uint8_t UartRingBuffer[MAX_UART_RING_BUFFERSIZE];

For using the UARTTransceiver a static buffer needs to be declared. This buffer called UartRingBuffer will be used as a ring buffer for the UART module and temporarily store the received UART data packets. After it is created, it is recommended to leave it as it is and to do no further operation with it in other code snippets, other than the proposed ones.

Now, the UARTTransceiver can be initialized using the following code.

enum UARTTransceiver_UartType_E type = UART_TRANSCEIVER_UART_TYPE_UART;
uint8_t rxBuffSize = (MAX_UART_RING_BUFFERSIZE-1);
UARTTransceiver_Initialize(
    &UartTransceiverInstance,
    UartHandle,
    UartRingBuffer,
    rxBuffSize,
    type);

First, two variables, type and rxBuffSize, are declared for better readability. The variable type represents the UART module the UARTTranceiver will take data from or transmit over. Since only UART is currently supported by the UART Transceiver module, it is simply set to use UART by setting it to the enumeration value UART_TRANSCEIVER_UART_TYPE_UART.

Please note: Currently LEUART is not supported by the UARTTransceiver module.

Afterwards, the variable rxBuffSize is set to the maximum length of elements the ring buffer, which was declared in the previous code sippet, can hold. Both of these variables, as well as the UartTransceiverInstance, and the obtained hardware handle for the UART module are passed to the function UARTTransceiver_Initialize(), which initializes the UARTTransceiver.

Now all configuration and initialization for UART are made. Only a few more steps are necessary to start the module to receive and transmit data.

To process incoming data, a callback for checking every incoming UART data packet is declared as shown in the following code.

static bool UartFrameEndCheck(uint8_t lastByte){
  BCDS_UNUSED(lastByte);
  return true;
}

The callback simply returns true for every incoming byte. Depending on the application use case, this function can be adapted to trigger custom events depending on the received byte.

Additionally, a callback function is declared for the receive and transmit events.

static void UartTxRxCallbacks(struct MCU_UART_Event_S event){
  if (event.RxComplete){
    portYIELD_FROM_ISR(pdTRUE);
  }
}

Since the UART module is interrupt driven, only a return from the interrupt service routine is required after a bit is received to inform freeRTOS to continue with the interrupted initial task.

Now that all necessary callback functions are declared, the UART module can be started as shown in the code below.

BSP_ExtensionPort_EnableUart();
UARTTransceiver_StartInAsyncMode(&UartTransceiverInstance, UartFrameEndCheck, UartTxRxCallbacks);

For that, the function BSP_ExtensionPort_EnableUart() is called, which enables the UART module to use the configured Extension Bus pins. Afterwards, the UARTTransceiver_StartInAsyncMode() is called to start the UARTTransceiver for incoming and outgoing data transmission, and receives the previously declared UartTransceiverInstance and the callback functions for handling data transmission.

Transmitting data over UART

Assuming that all configuration and initialization is done, data can be transmitted via UART as shown in the code below. For that, a universal function which takes a buffer holding the data and the buffer length can be declared.

void UartDataWrite(uint8_t* buffer, uint32_t bufferLength) {
  uint32_t writeTimeout = UINT32_MAX;
  UARTTransceiver_WriteData(&UartTransceiverInstance,buffer, bufferLength, writeTimeout);
}

The function simply calls UARTTransceiver_WriteData(), which takes the passed buffer and buffer length and the UartTransceiverInstance variable holding all UART-related information, as well as a predefined timeout for the write operation.

It is recommended to wrap the writing function, since only the data buffer itself and the buffer length can vary.

An example on how to transmit data using the declared function is shown in the following code.

void appInitSystem(void * CmdProcessorHandle, uint32_t param2){

  // This code omits initialization and configuration for brevity
  // Please ensure that UART is initialized and configured correctly here

  uint8_t buffer[] = "Hello";
  uint32_t bufferLength = sizeof(buffer)/sizeof(uint8_t);
  UartDataWrite(buffer,bufferLength);
}

A buffer is declared and filled with the bytes of the string "Hello". The size of this buffer is dynamically calculated and passed to the function UartDataWrite() to transmit the passed data.

Please note that for a working data transmission a secondary device using UART need to be attached to the Extension Bus of the XDK.

Transmitting Data Full Code Example

Note: The full code example is intended for XDK-Workbench versions 3.4.0 and higher.

/* --------------------------------------------------------------------------- |
 * INCLUDES & DEFINES ******************************************************** |
 * -------------------------------------------------------------------------- */

/* own header files */
#include "XdkAppInfo.h"
#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_APP_CONTROLLER

/* own header files */
#include "AppController.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "BCDS_CmdProcessor.h"
#include "FreeRTOS.h"
#include "task.h"

#include "BSP_ExtensionPort.h"
#include "BCDS_MCU_UART.h"
#include "BCDS_UARTTransceiver.h"

/* --------------------------------------------------------------------------- |
 * HANDLES ******************************************************************* |
 * -------------------------------------------------------------------------- */

static CmdProcessor_T * AppCmdProcessor;

static xTaskHandle AppControllerHandle = NULL;

/* --------------------------------------------------------------------------- |
 * VARIABLES ***************************************************************** |
 * -------------------------------------------------------------------------- */

#define MAX_UART_RING_BUFFERSIZE UINT32_C(45)

static uint8_t UartRingBuffer[MAX_UART_RING_BUFFERSIZE];
static UARTTransceiver_T UartTransceiverInstance;

/* --------------------------------------------------------------------------- |
 * EXECUTING FUNCTIONS ******************************************************* |
 * -------------------------------------------------------------------------- */

static bool UartFrameEndCheck(uint8_t lastByte){
    BCDS_UNUSED(lastByte);
    return true;
}

static void UartTxRxCallbacks(struct MCU_UART_Event_S event){
    if (event.RxComplete){
        portYIELD_FROM_ISR(pdTRUE);
    }
}

void UartDriverCallBack(UART_T uart, struct MCU_UART_Event_S event){
    if (UartTransceiverInstance.handle == uart){
        UARTTransceiver_LoopCallback(&UartTransceiverInstance, event);
    }
}

void Uart_Init(void){
    HWHandle_T UartHandle = BSP_ExtensionPort_GetUartHandle();

    MCU_UART_Initialize(UartHandle, UartDriverCallBack);

    enum UARTTransceiver_UartType_E type = UART_TRANSCEIVER_UART_TYPE_UART;
    uint8_t rxBuffSize = (MAX_UART_RING_BUFFERSIZE-1);
    UARTTransceiver_Initialize(
        &UartTransceiverInstance,
        UartHandle,
        UartRingBuffer,
        rxBuffSize,
        type);
}

void UartDataWrite(uint8_t* buffer, uint32_t bufferLength) {
    uint32_t writeTimeout = UINT32_MAX;
    UARTTransceiver_WriteData(&UartTransceiverInstance,buffer, bufferLength, writeTimeout);
}

static void AppControllerFire(void* pvParameters)
{
    BCDS_UNUSED(pvParameters);

    uint8_t buffer[] = "Hello";
    uint32_t bufferLength = sizeof(buffer)/sizeof(uint8_t);
    UartDataWrite(buffer,bufferLength);

    vTaskDelete(NULL);
}

/* --------------------------------------------------------------------------- |
 * BOOTING- AND SETUP FUNCTIONS ********************************************** |
 * -------------------------------------------------------------------------- */

static void AppControllerEnable(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    Retcode_T retcode = RETCODE_OK;

    BSP_ExtensionPort_EnableUart();
    UARTTransceiver_StartInAsyncMode(&UartTransceiverInstance, UartFrameEndCheck, UartTxRxCallbacks);

    if (RETCODE_OK == retcode)
    {
        if (pdPASS != xTaskCreate(AppControllerFire, (const char * const ) "AppController", TASK_STACK_SIZE_APP_CONTROLLER, NULL, TASK_PRIO_APP_CONTROLLER, &AppControllerHandle))
        {
            retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_OUT_OF_RESOURCES);
        }
    }

    if (RETCODE_OK != retcode) {
        printf("AppControllerEnable : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0);
    }
}

static void AppControllerSetup(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    Retcode_T retcode = RETCODE_OK;

    BSP_ExtensionPort_Connect();
    BSP_ExtensionPort_ConnectUart();
    BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_PARITY, BSP_EXTENSIONPORT_UART_NO_PARITY, NULL);
    BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_BAUDRATE, UINT32_C(9600), NULL);
    BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_STOPBITS, BSP_EXTENSIONPORT_UART_STOPBITS_ONE, NULL);

    Uart_Init();

    retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerEnable, NULL, UINT32_C(0));

    if (RETCODE_OK != retcode) {
        printf("AppControllerSetup : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0);
    }
}

void AppController_Init(void * cmdProcessorHandle, uint32_t param2)
{
    BCDS_UNUSED(param2);

    Retcode_T retcode = RETCODE_OK;

    if (cmdProcessorHandle == NULL)
    {
        printf("AppController_Init : Command processor handle is NULL \r\n");
        retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER);
    }
    else
    {
        AppCmdProcessor = (CmdProcessor_T *) cmdProcessorHandle;
        retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerSetup, NULL, UINT32_C(0));
    }

    if (RETCODE_OK != retcode)
    {
        Retcode_RaiseError(retcode);
        assert(0);
    }
}

Receiving data over UART

Assuming that all configuration and initialization is done, data can be received via UART as shown in the code below. For that, a universal function which takes a buffer, that will hold the incoming data, and the buffer length can be declared.

void UartDataRead(uint8_t * buffer, uint32_t bytesRead){
  uint32_t timeout = UINT32_MAX;
  uint32_t actualLength = 0;
  UARTTransceiver_ReadData(&UartTransceiverInstance, buffer, bytesRead, &actualLength, timeout);
}

The function receiver a buffer, that stores the data read from UART, and the number of bytes read from the internal ring buffer of the UARTTransceiver. As such, these variables are passed to the function UARTTransceiver_ReadData(), along with the global variable UartTransceiverInstance and a predefined timeout for the read operation.

An example on how to receive data using the declared function is shown in the following code.

void appInitSystem(void * CmdProcessorHandle, uint32_t param2){

  // This code omits initialization and configuration for brevity
  // Please ensure that UART is initialized and configured correctly here

  uint8_t buffer[20];
  uint32_t dataLength = 5;
  UartDataRead(buffer, dataLength);
}

For its usage, a buffer with a fixed data size is declared and the number of read bytes from the internal ring buffer of the UARTTransceiver is set. Both variables are passed to the UartDataRead() function.

Please note that this is the easiest approach to read data from the internal ring buffer of the UARTTransceiver. It does not contain any detection if there is any stored data in the ring buffer or if a data transmission is ongoing. For that kind of logic, the callback function UartFrameEndCheck, which is explained and declared in chapter Initializing and configuring UART, can be adapted. For example an event can be triggered when a data transmission occurs. An alternative approach could also be to build a logic with the properties of the variable UartTransceiverInstance, which holds information about the internal ring buffer.

Receiving Data Full Code Example

Note: The full code example is intended for XDK-Workbench versions 3.4.0 and higher.

/* --------------------------------------------------------------------------- |
 * INCLUDES & DEFINES ******************************************************** |
 * -------------------------------------------------------------------------- */

/* own header files */
#include "XdkAppInfo.h"
#undef BCDS_MODULE_ID  /* Module ID define before including Basics package*/
#define BCDS_MODULE_ID XDK_APP_MODULE_ID_APP_CONTROLLER

/* own header files */
#include "AppController.h"

/* system header files */
#include <stdio.h>

/* additional interface header files */
#include "BCDS_CmdProcessor.h"
#include "FreeRTOS.h"
#include "task.h"

#include "BSP_ExtensionPort.h"
#include "BCDS_MCU_UART.h"
#include "BCDS_UARTTransceiver.h"

/* --------------------------------------------------------------------------- |
 * HANDLES ******************************************************************* |
 * -------------------------------------------------------------------------- */

static CmdProcessor_T * AppCmdProcessor;

static xTaskHandle AppControllerHandle = NULL;

/* --------------------------------------------------------------------------- |
 * VARIABLES ***************************************************************** |
 * -------------------------------------------------------------------------- */

#define MAX_UART_RING_BUFFERSIZE UINT32_C(45)

static uint8_t UartRingBuffer[MAX_UART_RING_BUFFERSIZE];
static UARTTransceiver_T UartTransceiverInstance;

/* --------------------------------------------------------------------------- |
 * EXECUTING FUNCTIONS ******************************************************* |
 * -------------------------------------------------------------------------- */

static bool UartFrameEndCheck(uint8_t lastByte){
    BCDS_UNUSED(lastByte);
    return true;
}

static void UartTxRxCallbacks(struct MCU_UART_Event_S event){
    if (event.RxComplete){
        portYIELD_FROM_ISR(pdTRUE);
    }
}

void UartDriverCallBack(UART_T uart, struct MCU_UART_Event_S event){
    if (UartTransceiverInstance.handle == uart){
        UARTTransceiver_LoopCallback(&UartTransceiverInstance, event);
    }
}

void Uart_Init(void){
    HWHandle_T UartHandle = BSP_ExtensionPort_GetUartHandle();

    MCU_UART_Initialize(UartHandle, UartDriverCallBack);

    enum UARTTransceiver_UartType_E type = UART_TRANSCEIVER_UART_TYPE_UART;
    uint8_t rxBuffSize = (MAX_UART_RING_BUFFERSIZE-1);
    UARTTransceiver_Initialize(
        &UartTransceiverInstance,
        UartHandle,
        UartRingBuffer,
        rxBuffSize,
        type);
}

void UartDataRead(uint8_t * buffer, uint32_t bytesRead){
  uint32_t timeout = UINT32_MAX;
  uint32_t actualLength = 0;
  UARTTransceiver_ReadData(&UartTransceiverInstance, buffer, bytesRead, &actualLength, timeout);
}

static void AppControllerFire(void* pvParameters)
{
    BCDS_UNUSED(pvParameters);

    uint8_t buffer[20];
    uint32_t dataLength = 5;
    UartDataRead(buffer, dataLength);

    vTaskDelete(NULL);
}

/* --------------------------------------------------------------------------- |
 * BOOTING- AND SETUP FUNCTIONS ********************************************** |
 * -------------------------------------------------------------------------- */

static void AppControllerEnable(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    Retcode_T retcode = RETCODE_OK;

    BSP_ExtensionPort_EnableUart();
    UARTTransceiver_StartInAsyncMode(&UartTransceiverInstance, UartFrameEndCheck, UartTxRxCallbacks);

    if (RETCODE_OK == retcode)
    {
        if (pdPASS != xTaskCreate(AppControllerFire, (const char * const ) "AppController", TASK_STACK_SIZE_APP_CONTROLLER, NULL, TASK_PRIO_APP_CONTROLLER, &AppControllerHandle))
        {
            retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_OUT_OF_RESOURCES);
        }
    }

    if (RETCODE_OK != retcode) {
        printf("AppControllerEnable : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0);
    }
}

static void AppControllerSetup(void * param1, uint32_t param2)
{
    BCDS_UNUSED(param1);
    BCDS_UNUSED(param2);
    Retcode_T retcode = RETCODE_OK;

    BSP_ExtensionPort_Connect();
    BSP_ExtensionPort_ConnectUart();
    BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_PARITY, BSP_EXTENSIONPORT_UART_NO_PARITY, NULL);
    BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_BAUDRATE, UINT32_C(9600), NULL);
    BSP_ExtensionPort_SetUartConfig(BSP_EXTENSIONPORT_UART_STOPBITS, BSP_EXTENSIONPORT_UART_STOPBITS_ONE, NULL);

    Uart_Init();

    retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerEnable, NULL, UINT32_C(0));

    if (RETCODE_OK != retcode) {
        printf("AppControllerSetup : Failed \r\n");
        Retcode_RaiseError(retcode);
        assert(0);
    }
}

void AppController_Init(void * cmdProcessorHandle, uint32_t param2)
{
    BCDS_UNUSED(param2);

    Retcode_T retcode = RETCODE_OK;

    if (cmdProcessorHandle == NULL)
    {
        printf("AppController_Init : Command processor handle is NULL \r\n");
        retcode = RETCODE(RETCODE_SEVERITY_ERROR, RETCODE_NULL_POINTER);
    }
    else
    {
        AppCmdProcessor = (CmdProcessor_T *) cmdProcessorHandle;
        retcode = CmdProcessor_Enqueue(AppCmdProcessor, AppControllerSetup, NULL, UINT32_C(0));
    }

    if (RETCODE_OK != retcode)
    {
        Retcode_RaiseError(retcode);
        assert(0);
    }
}