DSP开发例程(3): 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 系统打印的信息通过串口输出, , 并在 EVM6678L 开发板上进行了测试. 例程源码可从我的 gitee 仓库上克隆或下载. 点击 DSP 开发教程(0): 汇总查看其他例程说明.

创建工程

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

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

在这里插入图片描述

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

在这里插入图片描述

  • 在弹出的 Copy Project 对话框中 修改工程名为: sys_print_to_uart, 点击 OK.
    在这里插入图片描述
  • 删除 sys_print_to_uart 工程中的 Debug目录, 右键选择 Build Project, 编译此工程.

源码编辑

os.c

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

#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/platform/platform.h>

/**
 * 添加此函数到 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 模块.

在这里插入图片描述- 勾选 Add the Idle function management module to my configuration, 并将 os_systemFlush 添加到 User idle function 中.

在这里插入图片描述或者直接在 app.cfg 中输入:

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

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

在这里插入图片描述或者直接在 app.cfg 中添加:

SysMin.outputFxn = "&os_systemOutput";

main.c

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

/*
 *  ======== main.c ========
 */
#include <stdio.h>
#include <string.h>

#include <xdc/std.h>

#include <xdc/runtime/Error.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)
{
    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() 函数打印的信息.

在这里插入图片描述

原理分析

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/109296.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

nodejs+vue食力派网上订餐系统-计算机毕业设计

采用当前流行的B/S模式以及3层架构的设计思想通过 技术来开发此系统的目的是建立一个配合网络环境的食力派网上订餐系统&#xff0c;这样可以有效地解决食力派网上订餐管理信息混乱的局面。 本设计旨在提高顾客就餐效率、优化餐厅管理、提高订单准确性和客户的满意度。本系统采…

GLoRE:大型语言模型的逻辑推理能力探究

最新研究揭示&#xff0c;尽管大语言模型LLMs在语言理解上表现出色&#xff0c;但在逻辑推理方面仍有待提高。为此&#xff0c;研究者们推出了GLoRE&#xff0c;一个全新的逻辑推理评估基准&#xff0c;包含12个数据集&#xff0c;覆盖三大任务类型。 实验对比发现&#xff0c;…

后门程序分析1

临时补充一个内容&#xff0c;这是一个后门程序&#xff0c;通过IDA分析&#xff0c;之后把里面收集的信息点全部整理出来&#xff08;包括:反虚拟机&#xff0c;系统信息等等&#xff09;pass&#xff1a;guet 用IDA打开先看看主函数的样子 查阅一些这些API InternetOpenA&…

【机器学习合集】模型设计之网络宽度和深度设计 ->(个人学习记录笔记)

文章目录 网络宽度和深度设计1. 什么是网络深度1.1 为什么需要更深的模型浅层学习的缺陷深度网络更好拟合特征学习更加简单 2. 基于深度的模型设计2.1 AlexNet2.2 AlexNet工程技巧2.3 VGGNet 3. 什么是网络宽度3.1 为什么需要足够的宽度 4. 基于宽度模型的设计4.1 经典模型的宽…

EM算法解析+代码

大纲 数学基础&#xff1a;凸凹函数&#xff0c;Jensen不等式&#xff0c;MLEEM算法公式&#xff0c;收敛性HMM高斯混合模型 一、数学基础 1. 凸函数 通常在实际中&#xff0c;最小化的函数有几个极值&#xff0c;所以最优化算法得出的极值不确实是否为全局的极值&#xff…

初学编程入门基础教学视频,中文编程开发语言工具箱之豪华编辑构件,免费版中文编程软件下载

初学编程入门基础教学视频&#xff0c;中文编程开发语言工具箱之豪华编辑构件&#xff0c;免费版中文编程软件下载 构件的其中一个属性、方法&#xff0c;查找内容&#xff0c;替换内容。 构件工具箱非常丰富&#xff0c;其中该构件在 文本件构件板菜单下。 编程系统化课程总目…

web - 前段三剑客

目录 前言 一. HTML 常用标签演示 图片标签 ​编辑 表格标签(重点) ​编辑 表单标签 (重点) 布局标签 其余标签 二. CSS 2.1 . css的三种引入方式 2.2 . 三大选择器 2.3 . css样式 - 浮动 2.4 . css样式 - 定位 1.static 2.absolute(绝对位置) 3.relavite(相…

【设计模式】第13节:结构型模式之“享元模式”

一、简介 所谓“享元”&#xff0c;顾名思义就是被共享的单元。享元模式的意图是复用对象&#xff0c;节省内存&#xff0c;前提是享元对象是不可变对象。 实现&#xff1a;通过工厂模式&#xff0c;在工厂类中&#xff0c;通过一个Map或者List来缓存已经创建好的享元对象&am…

LeetCode 415 字符串相加 简单

题目 - 点击直达 1. 415 字符串相加 简单1. 题目详情1. 原题链接2. 题目要求3. 基础框架 2. 解题思路1. 思路分析2. 时间复杂度3. 代码实现 1. 415 字符串相加 简单 1. 题目详情 给定两个字符串形式的非负整数 num1 和num2 &#xff0c;计算它们的和并同样以字符串形式返回。…

LeetCode题:88合并两个有序数组,283移动零,448找到所有数组中消失的数字

目录 88合并两个有序数组 1、题目要求 2、解题思路 &#xff08;1&#xff09;、暴力解法&#xff1a; &#xff08;2&#xff09;、双指针&#xff0c;使用第三数组的解法&#xff1a; 3、代码展示 &#xff08;1&#xff09;、暴力解法&#xff1a; &#xff08;2&am…

画时钟(turtle库)

思路&#xff1a; 总体来看&#xff0c;分为两个部分&#xff1a;固定的表盘&#xff0c;和不断刷新的指针&#xff08;和时间显示&#xff09; 固定的表盘 我的表盘长这个样子&#xff1a; 分为三个部分&#xff1a;60个dot点&#xff08;分、秒&#xff09;&#xff0c;12条…

漏洞复现--用友 畅捷通T+ .net反序列化RCE

免责声明&#xff1a; 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直…

树莓派基金会近日发布了新版基于 Debian 的树莓派操作系统

导读树莓派基金会&#xff08;Raspberry Pi Foundation&#xff09;近日发布了新版基于 Debian 的树莓派操作系统&#xff08;Raspberry Pi OS&#xff09;&#xff0c;为树莓派单板电脑带来了新的书虫基础和一些重大变化。 新版 Raspberry Pi OS 的最大变化是它现在基于最新的…

竞赛选题 深度学习图像修复算法 - opencv python 机器视觉

文章目录 0 前言2 什么是图像内容填充修复3 原理分析3.1 第一步&#xff1a;将图像理解为一个概率分布的样本3.2 补全图像 3.3 快速生成假图像3.4 生成对抗网络(Generative Adversarial Net, GAN) 的架构3.5 使用G(z)生成伪图像 4 在Tensorflow上构建DCGANs最后 0 前言 &#…

《数字图像处理-OpenCV/Python》连载(33)使用掩模图像控制处理区域

**本书京东优惠购书链接&#xff1a;https://item.jd.com/14098452.html** **本书CSDN独家连载专栏&#xff1a;https://blog.csdn.net/youcans/category_12418787.html** 第 5 章 图像的算术运算 在OpenCV中&#xff0c;图像是以Numpy数组格式存储的&#xff0c;图像的算术运…

大数据Flink(一百零三):SQL 表值聚合函数(Table Aggregate Function)

文章目录 SQL 表值聚合函数(Table Aggregate Function) SQL 表值聚合函数(Table Aggregate Function) Python UDTAF,即 Python TableAggregateFunction。Python UDTAF 用来针对一组数据进行聚合运算,比如同一个 window 下的多条数据、或者同一个 key 下的多条数据等,与…

grafana InfluxDB returned error: error reading influxDB 400错误解决

问题&#xff1a; 如图提示错误解决 确认自己的docker容器是否配置了以下3个字段 DOCKER_INFLUXDB_INIT_USERNAMExxx DOCKER_INFLUXDB_INIT_PASSWORDyyy DOCKER_INFLUXDB_INIT_ADMIN_TOKENzzz 如果有&#xff0c;在grafana中需要添加header配置Header: Authorization , Value…

docker应用部署---nginx部署的配置

1. 搜索nginx镜像 docker search nginx2. 拉取nginx镜像 docker pull nginx3. 创建容器&#xff0c;设置端口映射、目录映射 # 在/root目录下创建nginx目录用于存储nginx数据信息 mkdir ~/nginx cd ~/nginx mkdir conf cd conf# 在~/nginx/conf/下创建nginx.conf文件,粘贴下…

VScode 调试 linux内核

VScode 调试 linux内核 这里调试的 linux 内核是通过 LinuxSD卡(rootfs)运行的内核 gdb 命令行调试 编辑 /home/tyustli/.gdbinit 文件&#xff0c;参考 【GDB】 .gdbinit 文件 set auto-load safe-path /home/tyustli/code/open_source/kernel/linux-6.5.7/.gdbinit在 lin…

C笔记:引用调用,通过指针传递

代码 #include<stdio.h> int max1(int num1,int num2) {if(num1 < num2){num1 num2;}else{num2 num1;} } int max2(int *num1,int *num2) {if(num1 < num2){*num1 *num2; // 把 num2 赋值给 num1 }else{*num2 *num1;} } int main() {int num1 0,num2 -2;int…