TI RTOS BLE System_printf 打印

环境

  1. 系统:Windows 10
  2. SDK:simplelink_cc13x2_26x2_sdk_4_30_00_54
  3. IDE:Code Composer Studio, Version: 10.1.1.00004
  4. 例程:simple_peripheral_oad_offchip_CC26X2R1_LAUNCHXL_tirtos_ccs (已删除不必要的代码,请看:删除simple_peripheral_oad_offchip工程多余的代码)

原因

问:为什么要使用 System_printf ?
答:因为Display每次打印都会换行。

1. 移除 Display

在这里插入图片描述在这里插入图片描述

2. 配置打印UART

在这里插入图片描述

3. 更改配置文件

  1. 启用TI-RTOS的打印;
  2. 重定向 myUserPutch(char ch)函数;
  3. 实现 myUserFlush() 刷新函数。
    在这里插入图片描述
/*
 * The System.SupportProxy defines a low-level implementation of System
 * functions such as System_printf(), System_flush(), etc.
 *
 * Pick one pair:
 *  - SysMin
 *      This module maintains an internal configurable circular buffer that
 *      stores the output until System_flush() is called.
 *      The size of the circular buffer is set via SysMin.bufSize.
 *  - SysCallback
 *      SysCallback allows for user-defined implementations for System APIs.
 *      The SysCallback support proxy has a smaller code footprint and can be
 *      used to supply custom System_printf services.
 *      The default SysCallback functions point to stub functions. See the
 *      SysCallback module's documentation.
 */
//var SysMin = xdc.useModule('xdc.runtime.SysMin');
//SysMin.bufSize = 768;
//System.SupportProxy = SysMin;
var SysCallback = xdc.useModule('xdc.runtime.SysCallback');
System.SupportProxy = SysCallback;
//SysCallback.abortFxn = "&myUserAbort";
//SysCallback.exitFxn  = "&myUserExit";
SysCallback.flushFxn = "&myUserFlush";
SysCallback.putchFxn = "&myUserPutch";
//SysCallback.readyFxn = "&myUserReady";
//var Idle = xdc.useModule('ti.sysbios.knl.Idle');
//Idle.addFunc('&myUserFlush');

4. 代码

4.1. C文件


#include "user/debug/debug.h"

/*********************************************************************
 * CONSTANTS
 */
#define UART_PRINTF_BUF_LEN      128
/*********************************************************************
 * LOCAL VARIABLES
 */
static uint8_t  uartPrintf_outArray[UART_PRINTF_BUF_LEN];
static uint16_t uartPrintf_head = 0;
static uint16_t uartPrintf_tail = 0;
static UART_Handle hUart = NULL;



/*********************************************************************
 * PUBLIC FUNCTIONS
 */

/*********************************************************************
 * @fn      DebugPrintf_init
 *
 * @brief   Initializes the putchar hooks with the handle to the UART.
 *
 * @param   handle - UART driver handle to an initialized and opened UART.
 *
 * @return  None.
 */
void DebugPrintf_init(UART_Handle handle)
{
    hUart = handle;
}

/*********************************************************************
 * SYSTEM HOOK FUNCTIONS
 */

/*********************************************************************
 * @fn      myUserPutch
 *
 * @brief   User supplied PutChar function.
 *          typedef Void (*SysCallback_PutchFxn)(Char);
 *
 *          This function is called whenever the System module needs
 *          to output a character.
 *
 *          This implementation fills a very basic ring-buffer, and relies
 *          on another function to flush this buffer out to UART.
 *
 *          Requires SysCallback to be the system provider module.
 *          Initialized via SysCallback.putchFxn = "&myUserPutch"; in the
 *          TI-RTOS configuration script.
 *
 * @param   ch - Character
 *
 * @return  None.
 *
 * @post    ::uartPrintf_head is incremented by one with wrap at UART_PRINTF_BUF_LEN
 *          if there is room.
 */
void myUserPutch(char ch)
{
    // uartPrintf_tail should never catch up with uartPrintf_head. Discard in-between bytes.
    if ( (uartPrintf_head + 1) % UART_PRINTF_BUF_LEN == uartPrintf_tail )
        return;

    uartPrintf_outArray[uartPrintf_head] = ch;
    uartPrintf_head++;

    if (uartPrintf_head >= UART_PRINTF_BUF_LEN)
        uartPrintf_head = 0;
}

/*********************************************************************
 * @fn      myUserFlush
 *
 * @brief   Printf-buffer flush function
 *
 *          In this implementation it is intended to be called by the
 *          Idle task when nothing else is running.
 *
 *          This is achieved by setting up the Idle task in the TI-RTOS
 *          configuration script like so:
 *
 *          var SysCallback = xdc.useModule('xdc.runtime.SysCallback');
 *          System.SupportProxy = SysCallback;
 *          SysCallback.flushFxn = "&myUserFlush";
 *
 * @param   None. Relies on global state.
 *
 * @return  None.
 *
 * @post    ::uartPrintf_tail is incremented to where uartPrintf_head
 *          was at the time the function was called.
  */
void myUserFlush(void)
{
    // Abort in case UART hasn't been initialized.
    if (NULL == hUart)
        return;

  // Lock head position to avoid race conditions
  uint16_t curHead = uartPrintf_head;

  // Find out how much data must be output, and how to output it.
    bool needWrap = curHead < uartPrintf_tail;
  uint16_t outLen = needWrap?(UART_PRINTF_BUF_LEN-uartPrintf_tail+curHead):(curHead-uartPrintf_tail);

    if (outLen)
    {
        if (needWrap)
        {
            UART_write(hUart, &uartPrintf_outArray[uartPrintf_tail], UART_PRINTF_BUF_LEN - uartPrintf_tail);
            UART_write(hUart, uartPrintf_outArray, curHead);
        }
        else
        {
            UART_write(hUart, &uartPrintf_outArray[uartPrintf_tail], outLen);
        }
    }

    uartPrintf_tail = curHead;
}

4.2. 头文件

#ifndef USER_DEBUG_DEBUG_H_
#define USER_DEBUG_DEBUG_H_

#include <stdint.h>
#include <stdbool.h>
#include <ti/display/Display.h>
#include <xdc/runtime/System.h>
#include <ti/drivers/UART.h>

extern Display_Handle dispHandle;

extern void DebugPrintf_init(UART_Handle handle);
extern void myUserFlush(void);
/*
 * Display module will output "\n" every times
 *
 */
#if !defined(Display_DISABLE_ALL) || (!Display_DISABLE_ALL)

#define Debug(fmt, ...)                Display_printf(dispHandle, 0, 0, fmt, ##__VA_ARGS__)

#else

#define DEBUG_NEW_LINE  "\r\n"
#define Debug(fmt, ...)                  do{System_printf(fmt, ##__VA_ARGS__);myUserFlush();}while(0)
#define Debugln(fmt, ...)                do{System_printf(fmt, ##__VA_ARGS__);System_printf(DEBUG_NEW_LINE);myUserFlush();}while(0)
#define DebugHex(buf, len)               do{for(uint8_t _z = 0; _z < len; _z++)\
                                           {System_printf("%02x ", buf[_z]);} \
                                            System_printf(DEBUG_NEW_LINE);\
                                            myUserFlush();}\
                                            while(0)


#  undef Display_init
#  undef Display_open
#  undef Display_Params_init
#  undef Display_clear
#  undef Display_clearLines
#  undef Display_printf
#  undef Display_print0
#  undef Display_print1
#  undef Display_print2
#  undef Display_print3
#  undef Display_print4
#  undef Display_print5
#  undef Display_vprintf
#  undef Display_getType
#  undef Display_control
#  undef Display_close

#  define Display_init()
#  define Display_open(id, params)    NULL
#  define Display_Params_init(params)
#  define Display_clear(handle)
#  define Display_clearLines(handle, fromLine, toLine)
#  define Display_printf(handle, line, col, fmt, ...)                   Debugln(fmt, ##__VA_ARGS__);
#  define Display_print0(handle, line, col, fmt)                        Debugln(fmt)
#  define Display_print1(handle, line, col, fmt, a0)                    Debugln(fmt, a0)
#  define Display_print2(handle, line, col, fmt, a0, a1)                Debugln(fmt, a0, a1)
#  define Display_print3(handle, line, col, fmt, a0, a1, a2)            Debugln(fmt, a0, a1, a2)
#  define Display_print4(handle, line, col, fmt, a0, a1, a2, a3)        Debugln(fmt, a0, a1, a2, a3)
#  define Display_print5(handle, line, col, fmt, a0, a1, a2, a3, a4)    Debugln(fmt, a0, a1, a2, a3, a4)
#  define Display_vprintf(handle, line, col, fmt, va)                   Debugln(fmt, va)
#  define Display_getType(handle) Display_Type_INVALID
#  define Display_control(handle, cmd, arg) (DISPLAY_STATUS_UNDEFINEDCMD)
#  define Display_close(handle)
#endif


#endif /* USER_DEBUG_DEBUG_H_ */

5. 刷新方法

  1. 即时刷新

调用 System_printf() 后调用 myUserFlush()。

var SysCallback = xdc.useModule('xdc.runtime.SysCallback');
System.SupportProxy = SysCallback;
//SysCallback.abortFxn = "&myUserAbort";
//SysCallback.exitFxn  = "&myUserExit";
SysCallback.flushFxn = "&myUserFlush";
SysCallback.putchFxn = "&myUserPutch";
//SysCallback.readyFxn = "&myUserReady";
//var Idle = xdc.useModule('ti.sysbios.knl.Idle');
//Idle.addFunc('&myUserFlush');
#define DEBUG_NEW_LINE  "\r\n"
#define Debug(fmt, ...)                  do{System_printf(fmt, ##__VA_ARGS__);myUserFlush();}while(0)
#define Debugln(fmt, ...)                do{System_printf(fmt, ##__VA_ARGS__);System_printf(DEBUG_NEW_LINE);myUserFlush();}while(0)
#define DebugHex(buf, len)               do{for(uint8_t _z = 0; _z < len; _z++)\
                                           {System_printf("%02x ", buf[_z]);} \
                                            System_printf(DEBUG_NEW_LINE);\
                                            myUserFlush();}\
                                            while(0)
  1. 空闲刷新

空闲刷新是使用 Idle 任务在睡眠前调用myUserFlush()进行刷新。

var SysCallback = xdc.useModule('xdc.runtime.SysCallback');
System.SupportProxy = SysCallback;
//SysCallback.abortFxn = "&myUserAbort";
//SysCallback.exitFxn  = "&myUserExit";
SysCallback.flushFxn = "&myUserFlush";
SysCallback.putchFxn = "&myUserPutch";
//SysCallback.readyFxn = "&myUserReady";
var Idle = xdc.useModule('ti.sysbios.knl.Idle');
Idle.addFunc('&myUserFlush');
#define DEBUG_NEW_LINE  "\r\n"
#define Debug(fmt, ...)                  do{System_printf(fmt, ##__VA_ARGS__);}while(0)
#define Debugln(fmt, ...)                do{System_printf(fmt, ##__VA_ARGS__);System_printf(DEBUG_NEW_LINE);}while(0)
#define DebugHex(buf, len)               do{for(uint8_t _z = 0; _z < len; _z++)\
                                           {System_printf("%02x ", buf[_z]);} \
                                            System_printf(DEBUG_NEW_LINE);\
                                            while(0)
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值