DSP开发例程: sys_print_to_uart

目录

  • DSP开发例程: sys_print_to_uart
    • 创建工程
    • 源码编辑
      • os.c
      • app.cfg
      • main.c
    • 调试
    • 原理分析

DSP开发例程: sys_print_to_uart

在DSP 应用的执行过程中, 我们经常需要调用 System_printf() 来显示当前的执行状态. 不只是 System_printf() 函数, SYS/BIOS 打印信息的函数还包括: System_aprintf() , System_aprintf(), System_aprintf() , System_putch() System_vprintf() . 默认情况下, 这些函数打印的信息只能在 RTOS Object View 中查看. 此例程实现将 SYS/BIOS 系统打印的信息通过串口输出. 例程源码可从我的 gitee 仓库上克隆或下载.

创建工程

此实例工程直接在 led_flash 工程基础上修改.

  • 选中 led_flash 工程, 右键选择 Copy 或 使用快捷键 Ctrl+C 复制工程.

在这里插入图片描述

  • 在工程浏览视图中, 右键选择 Paste 或使用快捷键 Ctrl+V 粘贴工程.

在这里插入图片描述

  • 在弹出的 Copy Project 对话框中 修改工程名为: sys_print_to_uart, 点击 OK.
    DSP开发例程: sys_print_to_uart_第1张图片
  • 删除 uart_echo 工程中的 Debug目录, 右键选择 Build Project, 编译此工程.

源码编辑

os.c

新建 os.c 源文件. 内容如下:

#include 
#include 
#include 

/**
 * 添加此函数到 Idle Thread.
 *
 * ```xdc
 * var Idle = xdc.useModule('ti.sysbios.knl.Idle');
 *
 * Idle.idleFxns[0] = "&os_systemFlush";
 * ```
 */
void os_systemFlush()
{
	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]);
	}
}

其中包含两个函数:

  • os_systemFlush(): 用来 flush 系统打印的信息.
  • os_systemOutput(): 将系统打印的信息通过串口输出.

app.cfg

  • 使用 XGCONF 打开 app.cfg 文件.
    在这里插入图片描述
  • 点击 Idle 模块.

DSP开发例程: sys_print_to_uart_第2张图片- 勾选 Add the Idle function management module to my configuration, 并将 os_systemFlush 添加到 User idle function 中.

DSP开发例程: sys_print_to_uart_第3张图片或者直接在 app.cfg 中输入:

var Idle = xdc.useModule('ti.sysbios.knl.Idle');

Idle.idleFxns[0] = "&os_systemFlush";
  • 点击 Outline 视图中的 SysMin, 将 Output function 设置为 os_systemOutput

DSP开发例程: sys_print_to_uart_第4张图片或者直接在 app.cfg 中添加:

SysMin.outputFxn = "&os_systemOutput";

main.c

修改 main.c 源文件, 在平台初始化函数 EVM_init 中调用 串口初始化函数platform_uart_init(). 在 任务函数 task_ledFlash() 中添加两条周期打印信息. 修改后的 main.c 内容如下:

/*
 *  ======== main.c ========
 */
#include 
#include 

#include 

#include 
#include 

#include 

#include 

#include 

/*
 *  ======== taskFxn ========
 */
Void task_ledFlash(UArg a0, UArg a1)
{
    System_printf("enter task_ledFlash()\n");

    while(1)
    {
    	platform_led(0, PLATFORM_LED_ON, PLATFORM_USER_LED_CLASS);
    	System_printf("LED 0 ON\n");
    	Task_sleep(500);
    	platform_led(0, PLATFORM_LED_OFF, PLATFORM_USER_LED_CLASS);
    	System_printf("LED 0 OFF\n");
    	Task_sleep(500);
    }
}

/**
 * 平台初始化
 */
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;

    System_printf("enter main()\n");

    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);
}

调试

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

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

在这里插入图片描述

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

在这里插入图片描述
点击运行按钮, 运行程序. 此时在串口中断能够看到 System_printf() 函数打印的信息.

DSP开发例程: sys_print_to_uart_第5张图片

原理分析

需要说明的是, 调用System_printf() 打印信息时, 并不直接调用我们添加的 os_systemOutput() 函数, 而是将 打印的字符串添加到 Output Buffer(输出缓存) 中. 只有调用 System_flush()时, os_systemOutput() 才会被执行. 所以我们需要应用程序能够自觉执行 System_flush() 函数.

我们可以将 System_flush() 函数的执行, 交给 Idle 线程. 只要所有任务因为某些原因被阻塞(Sleep, 等待信号量等), Idle线程就会被执行. 这样做的好处是, 打印信息的串口输出不会占用 任务的执行时间.

你可能感兴趣的:(DSP,DSP)