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进制显示的. 看图自行体会.

相关推荐
轻微的风格艾丝凡8 天前
两电平三相VSC整流模式从不控整流平滑切换至有源整流调试记录
算法·dsp·c2000
轻微的风格艾丝凡2 个月前
三相不平衡电流调试经验记录
算法·dsp
GateWorld3 个月前
FPGA内部模块详解之四 算力引擎——数字信号处理单元(DSP Slice)深度解析
fpga开发·dsp
北京青翼科技3 个月前
基于6U VPX架构-DSP FT-M6678实时信号处理平台-青翼全国产化嵌入式产品
信号处理·国产化·dsp·fpga开发板·6678·嵌入式平台
FPGA-ADDA3 个月前
第一篇:软件无线电(SDR)基础与FPGA的角色
fpga开发·fpga·数字电路·dsp·软件无线电
南檐巷上学4 个月前
基于FPGA的正弦信号发生器、滤波器的设计(DAC输出点数受限条件下的完整正弦波产生器)
fpga开发·数字信号处理·dsp·dds
南檐巷上学4 个月前
基于MATLAB的麦克风音频效果测试
matlab·信号处理·数字信号处理·dsp·信号与系统·快速傅里叶变换·麦克风测试
ting_zh4 个月前
使用ARM DSP库去音频直流偏置
stm32·dsp·fir·iir·直流偏置
啊阿狸不会拉杆5 个月前
《数字信号处理》第5章-数字滤波器的基本结构
python·算法·机器学习·matlab·信号处理·数字信号处理·dsp
啊阿狸不会拉杆5 个月前
《数字信号处理 》第 7 章-无限长单位冲激响应 (IIR) 数字滤波器设计方法
数据结构·算法·信号处理·数字信号处理·dsp