NOTICE: The Processors Wiki will End-of-Life on January 15, 2021. It is recommended to download any files or other content you may need that are hosted on processors.wiki.ti.com. The site is now set to read only.

CC26xx Ouput TI-RTOS Log statements over UART

From Texas Instruments Wiki
Jump to: navigation, search

The logging system in TI-RTOS is quite useful and configurable. In the below we will set the logging system up to give us log events which are stored in a circular buffer and then printed out later in the idle thread.

Log system[edit]

The short version is, xdc.runtime.Log provides an interface (a lot of macros) that you can use. The RTOS config file can then be set up to make the RTOS precompiler route the logs to whichever logger implementation you want.

We are going to use xdc.runtime.LoggerCallback, which is a lightweight implementation, to hand us the arguments to the Log call for storage and output.

Implementation[edit]

LoggerCallback allows us to specify an outputFxn which will be called each time Log_xx is called. It receives a user-specified argument (ignored in this example), a Log_EventRec struct which contains the pointers to the strings to be printed, and finally the number of arguments.

To interfere as little as possible with the operation of the device, the uartLog_outputFxn does not print anything, just stores the string pointers, and adds a serial number and a timestamp. Each stored record is 40 bytes, and if more than UARTLOG_NUM_EVT_BUF events are received before the device has entered the Idle thread, the oldest record is lost.

In the Idle thread, we add uartLog_flush which loops through the records in the buffer, formats using System_snprintf into a local buffer of length UARTLOG_OUTBUF_LEN, and sends the formatted string array to the UART driver for transport.

Note: The UART driver must be opened in blocking mode, as the uartLog_flush loop depends on this.

Both the above defines for string length and buffer length can be overridden via precompiler defines, or source code changes.

References[edit]

Compiler options[edit]

Remove global Log disable[edit]

If it's present, change predefined symbol below (or remove entirely) to avoid removing all Log statements from the code, which we don't want now.
<syntaxhighlight inline enclose="none" lang="text"> xdc_runtime_Log_DISABLE_ALL --> X_xdc_runtime_Log_DISABLE_ALL</syntaxhighlight>

Configure what __FILE__ does[edit]

Log_info/warning/error will by default include the file and line they were called from. To avoid excessively long paths, you can change how the __FILE__ macro is made.

IAR[edit]

Add extra compiler option --no_path_in_file_macros

CCS[edit]

Add an extra precompiler define: xdc_FILE="\"${InputFileName}\""



TI-RTOS config file[edit]

This is where the magic happens. We will include the Log module/interface from the XDC Runtime package, and the LoggerCallback plugin for the Log module, and we will tell LoggerCallback to route Log calls to our own output handler function.

<syntaxhighlight lang="javascript"> // Need Text loaded for formatting of Log_info/warning/error, but not for Log_print. Text.isLoaded = true;

// Logging var Log = xdc.useModule('xdc.runtime.Log');

// Override error output color with ANSI codes, and use shorter (file.c:line) format. Log.L_error = {

   mask: Diags.STATUS,
   level: Diags.ERROR,
   msg: "\x1b[31;1mERROR:\x1b[0m (%s:%d) %$S"

};

Log.L_info = {

   mask: Diags.INFO,
   msg: "\x1b[32;1mINFO:\x1b[0m (%s:%d) %$S"

};

Log.L_warning = {

   mask: Diags.STATUS,
   level: Diags.WARNING,
   msg: "\x1b[33;1mWARNING:\x1b[0m (%s:%d) %$S"
   };

// Pull in LoggerCallback var LoggerCallback = xdc.useModule('xdc.runtime.LoggerCallback');

// Tell LoggerCallback to call our output function LoggerCallback.outputFxn = "&uartLog_outputFxn";

// Tell the Idle module to add our flush() function to the idle loop (before Power) var Idle = xdc.useModule('ti.sysbios.knl.Idle'); // Add if Idle isn't already imported. Idle.addFunc('&uartLog_flush');

// Create a static instance of LoggerCallback and set as default Main logger var loggerParams = new LoggerCallback.Params(); loggerParams.arg = 1; Main.common$.logger = LoggerCallback.create(loggerParams); // Only for Main (code that's not in an rtsc module) //Defaults.common$.logger = LoggerCallback.create(loggerParams); // Use for all log events

// Turn on USER1 logs and INFO in Main module (user code). Turn off USER2 for fun. Main.common$.diags_USER1 = Diags.ALWAYS_ON; Main.common$.diags_USER2 = Diags.ALWAYS_OFF; Main.common$.diags_INFO = Diags.ALWAYS_ON; </syntaxhighlight>

main.c or other init[edit]

Even though our function is now being called each time Log_xx is called, we need to set up the UART and tell the output function about it.

<syntaxhighlight lang="c"> // To open the UART

  1. include <ti/drivers/UART.h>

// To initialize the uart log output (only needed here)

  1. include "uart_logs.h"

// ... int main() {

 PIN_init(BoardGpioInitTable);
 // ...
 UART_Params uartParams;
 UART_Params_init(&uartParams);
 uartParams.baudRate = 115200;
 UART_Handle hUart = UART_open(Board_UART, &uartParams);
 // Initialize the logger output
 UartLog_init(hUart);
 // ...

</syntaxhighlight>

Add log statements[edit]

<syntaxhighlight lang="c">

  1. include <xdc/runtime/Log.h> // For Log_warning1("Warning number #%d", 4); things
  2. include <xdc/runtime/Diags.h> // For Log_print0(Diags_USER1, "hello"); things.

// ... int myfunc() {

 // ...
 Log_info0("Hello world via Log_info0");
 Log_error0("Out of cheese error!");

} </syntaxhighlight>

Include uart_logs.c[edit]

Both the function uartLog_outputFxn(...) and uartLog_flush(), along with a sample modified TI-RTOS .cfg file can be downloaded here: File:Cc26xx uart log loggercallback example.zip

How it looks[edit]

The above example, and Simple BLE Peripheral plus a custom service instrumented with Log_info and Log_error statements looks like this:

Putty session
E2e.jpg {{
  1. switchcategory:MultiCore=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article CC26xx Ouput TI-RTOS Log statements over UART here.

Keystone=
  • For technical support on MultiCore devices, please post your questions in the C6000 MultiCore Forum
  • For questions related to the BIOS MultiCore SDK (MCSDK), please use the BIOS Forum

Please post only comments related to the article CC26xx Ouput TI-RTOS Log statements over UART here.

C2000=For technical support on the C2000 please post your questions on The C2000 Forum. Please post only comments about the article CC26xx Ouput TI-RTOS Log statements over UART here. DaVinci=For technical support on DaVincoplease post your questions on The DaVinci Forum. Please post only comments about the article CC26xx Ouput TI-RTOS Log statements over UART here. MSP430=For technical support on MSP430 please post your questions on The MSP430 Forum. Please post only comments about the article CC26xx Ouput TI-RTOS Log statements over UART here. OMAP35x=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article CC26xx Ouput TI-RTOS Log statements over UART here. OMAPL1=For technical support on OMAP please post your questions on The OMAP Forum. Please post only comments about the article CC26xx Ouput TI-RTOS Log statements over UART here. MAVRK=For technical support on MAVRK please post your questions on The MAVRK Toolbox Forum. Please post only comments about the article CC26xx Ouput TI-RTOS Log statements over UART here. For technical support please post your questions at http://e2e.ti.com. Please post only comments about the article CC26xx Ouput TI-RTOS Log statements over UART here.

}}

Hyperlink blue.png Links

Amplifiers & Linear
Audio
Broadband RF/IF & Digital Radio
Clocks & Timers
Data Converters

DLP & MEMS
High-Reliability
Interface
Logic
Power Management

Processors

Switches & Multiplexers
Temperature Sensors & Control ICs
Wireless Connectivity