CC26xx Adding basic printf over uart with TI-RTOS

From Texas Instruments Wiki
Jump to: navigation, search

Most of the Bluetooth Smart sample applications use SysCallback as the system provider for TI-RTOS. See TI-RTOS User's Guide for more information about the system providers.

In this case, SysCallback is ideal. It is very lightweight, and it is up to us to provide the hooks used by the system helpers such as System_printf(). See the CDOCs for XDC the Runtime module for information about printf formatting. See also the CDOCs for SysCallback for documentation on the hooks.

We will provide a handler for SysCallback.putchFxn. This is invoked by the system provider proxy whenever System_printf() is called.

This is configured by editing the TI-RTOS config file, usually called appBLE.cfg in the Bluetooth sample apps.

var SysCallback = xdc.useModule('xdc.runtime.SysCallback'); // Already present
SysCallback.putchFxn = "&uartPrintf_putch";                 // Our callback

The example implementation of uartPrintf_putch provided below will simply add characters to a circular buffer. To get the data out on the UART, we also need some kind of flushing function.

In order to be unobtrusive to the rest of the system, we will make TI-RTOS call our flushing function when nothing else is going on, i.e. when the Idle task is running. Typically, when the Idle task is called it will in turn call the power manager which puts the system to the lowest power mode allowed. Right now we will insert our UART flush function before that point.

var Idle = xdc.useModule('ti.sysbios.knl.Idle'); // Must be added to the .cfg file for correct parsing. Would have been added by the Power module in any case.
Idle.addFunc('&uartPrintf_flush');               // Our flushing function.

The example uartPrintf_flush() provided below will simply use the TI-RTOS UART driver and call UART_write() with the data in the circular buffer.

In order to use the flush function, the user is required to call UART_open() with valid parameters and a valid UART configuration and give the UART object's handle (returned from UART_open) to UartPrintf_init(). Example usage for main.c:

#include "uart_printf.h"
#include <xdc/runtime/System.h>
...
int main()
{
  PIN_init(BoardGpioInitTable);
 
  // Enable System_printf(..) UART output
  UART_Params uartParams;
  UART_Params_init(&uartParams);
  uartParams.baudRate = 115200;
  UartPrintf_init(UART_open(Board_UART, &uartParams));
 
  System_printf("Hello, universe!\r\n");
 
  //...
 
  /* enable interrupts and start SYS/BIOS */
  BIOS_start();

The above example will set up the UART for Blocking mode (this is important) and use the Board_UART index define (usually 0 since there's only one UART) from Board.h. It is expected that Board.c contains the setup for the UART driver's hardware configurations. The sample applications' Board.c files should have this set up out of the box.

Download example

Both the function uartPrintf_putch() and uartPrintf_flush(), along with a sample modified TI-RTOS .cfg file can be downloaded here: File:Cc26xx system printf syscallback example.zip