DSP开发例程(4): logbuf_print_to_uart

目录

DSP开发例程: logbuf_print_to_uart

SYS/BIOS 提供了 xdc.runtime.Log , xdc.runtime.LoggerBufxdc.runtime.LoggerSys 这几个模块用于日志记录. 日志信息在 应用程序调试和状态监控中非常实用. 日志记录函数相较于 System_printf() 占用的时间更短, 且可以区分事件的等级, 如: Info , WarningError 等.

此例程实现将 SYS/BIOS 日志信息通过串口输出, 并在 EVM6678L 开发板上进行了测试. 例程源码可从我的 gitee 仓库上克隆或下载. 点击 DSP 开发教程(0): 汇总查看其他例程说明.

新建工程

此示例工程直接在 sys_print_to_uart 工程基础上修改.

  • 选中 sys_print_to_uart 工程, 右键选择 Copy 或 使用快捷键 Ctrl+C 复制工程.
  • 在工程浏览视图中, 右键选择 Paste 或使用快捷键 Ctrl+V 粘贴工程.
  • 在弹出的 Copy Project 对话框中 修改工程名为: logbuf_print_to_uart , 点击 OK.
  • 删除 logbuf_print_to_uart 工程中的 Debug 目录, 右键选择 Build Project, 编译此工程.

源码编辑

app.cfg

  • 使用 XGCONF 打开 app.cfg 文件.
  • 点击 logger0.

- 将 logger0 的句柄设置为 logger0.

- 点击 Timestamp 模块.

  • 勾选 Add Timestamp to my configuration.
  • 保存修改.

os.c

编辑 os.c 源文件, 其内容如下:

c 复制代码
/*
 * os.c
 *
 *  Created on: 2023-10-26
 *      Author: falwa
 */
#include <xdc/std.h>
#include <xdc/runtime/Log.h>
#include <xdc/runtime/LoggerBuf.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Text.h>
#include <xdc/runtime/Types.h>
#include <xdc/runtime/Timestamp.h>

extern LoggerBuf_Handle logger0;

/*
 *  ======== doPrint ========
 */
Void myLog_doPrint(Log_EventRec *er)
{
    Text_RopeId rope;
    String fmt;
    Bits32 hi, lo;
    Types_FreqHz freq;
    uint32_t msec;

    Timestamp_getFreq(&freq);

    /* print timestamp if there is one; ~0 isn't a valid timestamp value */
    hi = er->tstamp.hi;
    lo = er->tstamp.lo;
    msec = (((uint64_t)hi << 32) | lo) / (freq.lo/1000);

    System_printf("[%5d.%03ds] ", msec/1000, msec%1000);

    /* print event */
    rope = Types_getEventId(er->evt);   /* the event id is the message rope */
    if (rope == 0) {
        /* Log_print() event */
        System_aprintf((String)iargToPtr(er->arg[0]),
            er->arg[1], er->arg[2], er->arg[3], er->arg[4],
            er->arg[5], er->arg[6], 0,          0);
    }
    else {
        /* Log_write() event */
        fmt = Text_ropeText(rope);

        if (Text_isLoaded) {
            System_aprintf(fmt, er->arg[0], er->arg[1], er->arg[2], er->arg[3],
                er->arg[4], er->arg[5], er->arg[6], er->arg[7]);
        }
        else {
            System_aprintf("{evt: fmt=%p, args=[0x%x, 0x%x ...]}",
                fmt, er->arg[0], er->arg[1]);
        }
    }

    System_putch('\n');
}

/*
 *  ======== LoggerBuf_flush ========
 */
Void myLoggerBuf_flush(LoggerBuf_Object *obj)
{
    Int nEntries;
    Log_EventRec evtRec;

    for (;;) {
        nEntries = LoggerBuf_getNextEntry(obj, &evtRec);
        if (nEntries == 0) {
            break;
        }
        else {
            if (nEntries != -1) {
            	myLog_doPrint(&evtRec);
            }
        }
    }
}


/**
 * 添加此函数到 Idle Thread.
 *
 * ```xdc
 * var Idle = xdc.useModule('ti.sysbios.knl.Idle');
 *
 * Idle.idleFxns[0] = "&os_systemFlush";
 * ```
 */
void os_systemFlush()
{
	if (logger0)
		myLoggerBuf_flush(logger0);
	System_flush();
}

/**
 * 将  System_printf() 重定向到  platform_uart_write().
 *
 * 请在 .cfg 中添加:
 * ```
 * SysMin.outputFxn = "&os_systemOutput";
 * ```
 */
Void os_systemOutput(Char *str, UInt len)
{
	UInt i;
	for(i = 0; i < len; i++)
	{
		platform_uart_write(str[i]);
	}
}

其中新增了两个函数 myLog_doPrint()myLoggerBuf_flush() , 这两个函数参考 C:\ti\xdctools_3_25_03_72\packages\xdc\runtime\LoggerBuf.c 中的 Log_doPrint()LoggerBuf_flush() 进行设计. 其中,

  • myLog_doPrint() 用于调用 System_printf() 格式化打印一条日志事件;
  • myLoggerBuf_flush() 负责调用 myLog_doPrint() 格式化 并 flush logBuf 中的所有日志事件.

os_systemFlush() 函数中调用 myLoggerBuf_flush(logger0); 完成日志的 flush.

main.c

编辑 main.c, 其内容如下:

c 复制代码
/*
 *  ======== main.c ========
 */
#include <stdio.h>
#include <string.h>

#include <xdc/std.h>

#include <xdc/runtime/Error.h>
#include <xdc/runtime/Log.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/BIOS.h>

#include <ti/sysbios/knl/Task.h>

#include <ti/platform/platform.h>

/*
 *  ======== taskFxn ========
 */
Void task_ledFlash(UArg a0, UArg a1)
{
	int i = 1;
    Log_info0("enter task_ledFlash().");

    while(1)
    {
    	platform_led(0, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
    	Log_info1("LED 0 ON at %d times.", i);
    	Task_sleep(500);
    	platform_led(0, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
    	Log_info1("LED 0 OFF at %d times.", i);
    	Task_sleep(500);
    	i++;
    }
}

/**
 * 平台初始化
 */
void EVM_init()
{
	platform_init_flags init_flags;
	platform_init_config init_config;

	// plaform initialize
	memset(&init_flags, 1, sizeof(platform_init_flags));
	init_flags.phy = 0;
	memset(&init_config, 0, sizeof(platform_init_config));
	if (platform_init(&init_flags, &init_config) != Platform_EOK)
	{
		printf("Platform failed to initialize, errno = 0x%x \n", platform_errno);
		while(1);
	}
	platform_uart_init();
}

/*
 *  ======== main ========
 */
Int main()
{ 
    Task_Handle task;
    Error_Block eb;

    Log_info0("enter main().");

    Log_error1("Log_error1(%d)", 1);

    Log_warning2("log_warnning2(%d, %d)", 1, 2);

    Error_init(&eb);
    task = Task_create(task_ledFlash, NULL, &eb);
    if (task == NULL) {
        System_printf("Task_create() failed!\n");
        BIOS_exit(0);
    }

    BIOS_start();    /* does not return */
    return(0);
}

其中 调用了 Log_info#(), Log_error#()Log_warning#() 这几个日志事件记录函数进行测试.

保存上述更改, 并编译工程.

调试

完成编译后, 在 EVM6678L 上调试.

串口通过USB连接计算机. 请确保 COM_SEL1 跳线设置在正确位置. 且在计算机设备管理器中能够找到对应板卡的串口.

打开串口终端, 连接对应串口, 串口设置如下:

点击运行按钮, 运行程序. 此时在串口终端中能够看到打印的日志信息. 相较于 System_printf(), 增加了 时间戳, 文件名, 行数等信息.

说明

这只是 打印日志信息到串口的一种方式. 启用 xdc.runtime.LoggerSys 模块, 也可以实现日志信息的打印, 不过打印的格式不是很好看, 其中的时间戳是16进制显示的. 看图自行体会.

相关推荐
FakeOccupational5 天前
【电路笔记 TMS320F28335DSP】DSP项目文件说明
笔记·dsp
江山如画,佳人北望3 个月前
智能平衡移动机器人-MBD开发介绍
dsp·ccs·matlab simulink
Mike_6664 个月前
高通DSP、HVX、HMX
dsp·高通·hvx·hmx
Mr.Cssust4 个月前
【研发日记】嵌入式处理器技能解锁(三)——TI C2000 DSP的C28x内核
dsp·嵌入式软件·matlab/simulink·嵌入式处理器·基于模型开发·c2000·c28x内核
孤独的单刀5 个月前
基于FPGA的数字信号处理(18)--半加器和全加器
fpga开发·信号处理·xilinx·dsp·定点数·verilog入门·浮点数
孤独的单刀7 个月前
基于FPGA的数字信号处理(9)--定点数据的两种溢出处理模式:饱和(Saturate)和绕回(Wrap)
fpga开发·信号处理·xilinx·数字ic·dsp·定点数·verilog入门
深圳信迈科技DSP+ARM+FPGA7 个月前
多核DSP并行计算跨平台通信解决方案
dsp
网易独家音乐人Mike Zhou9 个月前
【TI毫米波雷达】利用MMWAVEICBOOST的板载XDS110模块来调试开发板(以IWR6843AOPEVM为例)
单片机·mcu·物联网·iot·dsp·毫米波雷达
网易独家音乐人Mike Zhou9 个月前
【TI毫米波雷达】官方工业雷达包的生命体征检测环境配置及避坑(Vital_Signs、IWR6843AOPEVM)
单片机·mcu·物联网·嵌入式·iot·dsp·毫米波雷达
网易独家音乐人Mike Zhou9 个月前
【TI毫米波雷达】IWR6843AOP的官方文件资源名称BUG,选择xwr68xx还是xwr64xx,及需要注意的问题
单片机·mcu·物联网·嵌入式·iot·dsp·毫米波雷达