Microchip® Advanced Software Framework

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Debug Print Service for FreeRTOS

This service provides a thread-safe, buffered debug print facility via UART for FreeRTOS-based applications.

It can also be used without FreeRTOS, but will then not be thread-safe nor have efficient waiting when the buffer is full.

The following peripherals are used by this module:

The outline of this documentation is as follows:

Prerequisites

The reader is assumed to be familiar with configuration of the SERCOM USART driver since this service uses similar configuration settings.

To enable FreeRTOS-support, the symbol FREERTOS must be defined. This will typically be done automatically if FreeRTOS is included from ASF. As this service is meant to be used in tasks, the FreeRTOS scheduler should be started before any of the print functions are called.

To get thread-safety and efficient waiting with other OS or schedulers, the following functions in dbg_print.c must be modified:

Module Overview

This service essentially consists of a print buffer and functions for doing protected writes to it, and an interrupt handler which performs transmission of the buffer contents using a SERCOM module in UART mode. It has been written for use in FreeRTOS-based applications where concurrent tasks need to output debug messages, for example via the Communication Device Class (CDC) of the Embedded Debugger (EDBG) on Xplained Pro boards.

This service can be used without FreeRTOS, but will then not be thread safe nor have efficient waiting when the buffer is full. To support other OSes and schedulers, see Prerequisites for a list of the functions that must be modified.

This service should not be used within interrupts.

Print Buffer

The reason for using a print buffer is to minimize the time it takes for a task to output its debug message, so the impact on application response time and functionality is reduced. Instead of waiting for the debug message to be sent, the calling task only needs to wait for the message to get into the print buffer. Of course, if the print buffer becomes full, the tasks must wait for buffer space to free up.

Both buffer size and UART baud rate are configurable, so one may find a reasonable balance between memory usage and interrupt rate. As a minimum requirement, the print buffer should not be smaller than the longest debug message in the application.

Access Control

Access control for the print buffer is built into this service to prevent concurrent calls from corrupting each other's print output. The FreeRTOS mechanism for this access control, a mutex, will keep other calling tasks waiting while the print buffer is being modified by one task. Once the print buffer becomes available again, the waiting task with the highest priority is given access to the buffer.

Note that this mechanism may cause tasks of lower priority to be kept waiting indefinitely if the print buffer is small and there is a lot of waiting for buffer space to free up. In such cases, the higher priority tasks may end up taking turns waiting for enough buffer space to get their respective debug messages into it.

Configuration

This service implements a single debug print interface, which is compile-time configured via the header file conf_dbg_print.h to ensure the smallest size code and highest execution speed.

The available configuration symbols are:

Name Description
CONF_DBG_PRINT_BUFFER_SIZE Print buffer size. Must be a power of 2 (.., 32, 64, 128, ..).
CONF_DBG_PRINT_SERCOM The SERCOM module to use as UART.
CONF_DBG_PRINT_GCLK_SOURCE The GCLK that the SERCOM shall use as clock source
CONF_DBG_PRINT_BAUD_RATE Target baud rate for computation of the SERCOM's BAUD register value.
CONF_DBG_PRINT_BAUD_VALUE Optional override of CONF_DBG_PRINT_BAUD_RATE, lets user explicitly set the register value to reduce code size.
CONF_DBG_PRINT_SERCOM_MUX The SERCOM signal MUX setting to use.
CONF_DBG_PRINT_PINMUX_PAD0 Pin MUX setting for connecting pin with SERCOM pad 0.
CONF_DBG_PRINT_PINMUX_PAD1 Pin MUX setting for connecting pin with SERCOM pad 1.
CONF_DBG_PRINT_PINMUX_PAD2 Pin MUX setting for connecting pin with SERCOM pad 2.
CONF_DBG_PRINT_PINMUX_PAD3 Pin MUX setting for connecting pin with SERCOM pad 3.
Note
If CONF_DBG_PRINT_BAUD_VALUE is defined, the symbol CONF_DBG_PRINT_BAUD_RATE will not have any effect, and does not need to be defined at all.

Extra Info

For extra information see Extra Information for Debug Print Service for FreeRTOS. This includes:

Examples

For a list of examples related to this driver, see Examples for Debug Print Service for FreeRTOS.

API Overview

Modules

 Quick Start Guide(s)
 In this section you can find a list of all Quick Start guides related to the Debug Print Service for FreeRTOS.
 

Configuration macros

#define CONF_DBG_PRINT_BAUD_RATE
 Desired baud rate. More...
 
#define CONF_DBG_PRINT_BAUD_VALUE
 Hardcoded BAUD register value (optional) More...
 

Initialization

enum status_code dbg_init (void)
 Initialize and enable debug UART. More...
 

Print to string

void dbg_sprint_hexint (char *outstr, uint32_t outint)
 Write an integer as hex digits (ASCII) into string. More...
 

Print to buffer

void dbg_print_hexint (uint32_t outint)
 Print an integer as hex digits. More...
 
void dbg_print_str (const char *outstr)
 Print a zero-terminated string. More...
 
void dbg_print_char (const char outchar)
 Print a single character. More...
 

#define CONF_DBG_PRINT_BAUD_RATE

Desired baud rate.

Note
This macro can be overridden with a hardcoded BAUD register value in CONF_DBG_PRINT_BAUD_VALUE.

Referenced by dbg_init().

#define CONF_DBG_PRINT_BAUD_VALUE

Hardcoded BAUD register value (optional)

To reduce code size, a hardcoded BAUD register value can be supplied via this configuration macro.

The formula to use is: \( 65536 \times (1 - \frac{16 \times f_{baud}}{f_{gclk}}) \) where f_gclk is the rate of the GCLK source.

Note
If this macro is defined, the macro CONF_DBG_PRINT_BAUD_RATE will have no effect.

Referenced by dbg_init().

enum status_code dbg_init ( void  )

Initialize and enable debug UART.

This function sets up the configured SERCOM with the following static features:

  • asynchronous, internally clocked (UART)
  • TX only
  • 1 stop bit
  • 8-bit data
  • LSB first
  • no parity bit

The baud rate, SERCOM signal MUX and pin MUX are set up as configured in conf_debug_print.h, which also contains the configuration of which SERCOM to use.

The SERCOM UART is left enabled after this function call.

Returns
Indication whether or not initialization succeeded.
Return values
STATUS_OKif initialization was successful.
STATUS_ERR_BAUDRATE_UNAVAILABLEif configured baud rate is too high.
Note
This function is based on usart_init() from ASF, but is modified to use a single instance in order to reduce code size.

References _dbg_interrupt_handler(), _sercom_get_async_baud_val(), _sercom_get_default_pad(), _sercom_get_interrupt_vector(), _sercom_get_sercom_inst_index(), _sercom_set_handler(), CONF_DBG_PRINT_BAUD_RATE, CONF_DBG_PRINT_BAUD_VALUE, dbg_is_free, system_pinmux_config::direction, system_pinmux_config::mux_position, PINMUX_DEFAULT, PINMUX_UNUSED, requested_space_is_free, SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC, SERCOM_ASYNC_SAMPLE_NUM_16, sercom_set_gclk_generator(), sercom_uart, system_gclk_chan_config::source_generator, status, STATUS_OK, system_apb_clock_set_mask(), SYSTEM_CLOCK_APB_APBC, system_gclk_chan_enable(), system_gclk_chan_get_config_defaults(), system_gclk_chan_get_hz(), system_gclk_chan_set_config(), system_interrupt_enable(), system_is_debugger_present(), system_pinmux_get_config_defaults(), SYSTEM_PINMUX_PIN_DIR_INPUT, system_pinmux_pin_set_config(), vSemaphoreCreateBinary, xSemaphoreCreateMutex, and xSemaphoreTake.

void dbg_print_char ( const char  out_char)

Print a single character.

Parameters
[in]out_charThe character to print.

References _dbg_putstr(), _dbg_unlock(), and _dbg_wait_for_lock().

void dbg_print_hexint ( uint32_t  out_int)

Print an integer as hex digits.

This function will put the hex digits of a 32-bit integer into the print buffer. It does not add the '0x'-prefix.

Parameters
[in]out_intThe integer to print.

References _dbg_putstr(), _dbg_unlock(), _dbg_wait_for_lock(), and dbg_sprint_hexint().

void dbg_print_str ( const char *  out_str)

Print a zero-terminated string.

Parameters
[in]out_strThe string to print.

References _dbg_putstr(), _dbg_unlock(), _dbg_wait_for_lock(), and length.

void dbg_sprint_hexint ( char *  out_str,
uint32_t  out_int 
)

Write an integer as hex digits (ASCII) into string.

This function will convert a 32-bit integer into a string of hexadecimal digits (0-9, A-F) and store them to the specified location, most significant digit first.

Note that this function does not add the '0x'-prefix, which.

Parameters
[in]out_strPointer to where digits shall be written.
[in]out_intThe integer to write.

References TRANSLATE_NIBBLE_TO_ASCII.

Referenced by dbg_print_hexint().