0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

AWorksLP应用笔记:重定向printf函数

ZLG致远电子 2023-11-25 08:24 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

printf函数作为标准库定义的格式化输出方式,本文将介绍其在AWorksLP下默认适配以及重映射至热拔插设备端口的实现。

默认适配

AWorksLP中默认已经对printf函数完成相关适配工作,且默认被适配在UART设备。用户可以在图形化配置界面中使能 support the stdio functions ,并选择期望UART设备进行输出,具体配置如下图所示。

0745adc0-8b29-11ee-9788-92fbcf53809c.png

注:若用户未使能 stdio function 时,调用printf函数时,将不会有任何输出。

本文将使用 EPC6450-AWI 平台,选择标有丝印为DUART的调试串口(UART0设备)进行printf功能演示测试。将TTL转USB串口模块的TXD与板子的RXD丝印连接,RXD与板子的TXD丝印,将另一端的USB口接入电脑07591f5e-8b29-11ee-9788-92fbcf53809c.png启动串口调试助手,搜索并打开串口模块的设备端口号后,在工程中调用printf函数,根据下图可知,printf函数适配UART0设备成功。076d89e4-8b29-11ee-9788-92fbcf53809c.png

重定向至其他设备嵌入式的诸多应用在UART设备资源受限的情况下,可能存在将printf函数重定向到其他设备需求。为此,笔者将以EPC6450-AWI平台的USB串口设备为例进行说明。077d1c56-8b29-11ee-9788-92fbcf53809c.png1.实施步骤

与UART设备不同,USB设备为动态设备,因此重定向printf函数时,需要注意以下几个关键步骤:

1.1 支持NEWLIB标准库函数

由于AWorksLP中利用posix file相关操作接口对printf函数进行适配,故在重映射端口时,需将 support libc file operations 使能,并取消默认选择UART设备作为printf函数的适配,具体如下图所示。

08005670-8b29-11ee-9788-92fbcf53809c.png1.2 检测动态设备

USB设备为动态设备,因此需要持续检测设备的是否存在情况。可通过初始化一个动态设备检测任务,对设备的是否存在情况进行周期性检测。

while true: access (device) delay()

1.3 关联标准文件流

在检测到USB设备存在时,仅需将设备与标准文件流(stdio中的stdin、stdout、stderr,且在C库中被假定为交互设备,并约定了这些设备的文件描述符依次为0、1、2)关联起来。故在使用时,我们仅需将描述符0、1、2与USB串口设备即可,其伪代码如下所示。

while true: if access (device): 0 = open (device) duplicate 1 to 0 duplicate 2 to 0 delay()

1.4 清理文件描述符

检测到USB设备不存在时,需及时取消设备与标准文件流的关联。即根据设备的打开情况,对文件描述符进行清理,以便之后重新关联标准文件流。

while true: if access (device): 0 = open (device) duplicate 1 to 0 duplicate 2 to 0 else: close (device) delay()

2. 基础配置在EPC6450-AWI平台标有丝印为Type-C的接口处,插上Type-C线,将Type-C线的另一端USB口连接电脑。并在图形化配置界面,将USB设备选择为CDC串口设备。

0812e6e6-8b29-11ee-9788-92fbcf53809c.png

3.简单示例

static int __dynamic_stdin_fd = -1;static aw_err_t __dynamic_stdout_ret = -AW_EBADF;static aw_err_t __dynamic_stderr_ret = -AW_EBADF;
aw_err_t aw_printf_redirect_dynamic_dev(void){ int find = -AW_ENODEV;
// 检测动态设备 find = aw_access(AW_DYNAMIC_DEV_PATH, AW_F_OK);
if(find == AW_OK) { // 关联标准文件流 if(__dynamic_stdin_fd < 0)        {            __dynamic_stdin_fd = \             aw_open_at(AW_DYNAMIC_DEV_PATH,AW_O_RDWR,0,0);            __dynamic_stdout_ret = aw_dup2(0, 1);            __dynamic_stderr_ret = aw_dup2(0, 2);            return AW_OK;        }    }    else {        // 清理文件描述符        if(__dynamic_stdin_fd >= 0) { aw_close(0); __dynamic_stdin_fd = -1; } if (__dynamic_stdout_ret == AW_OK) { aw_close(1); __dynamic_stdout_ret = -AW_EBADF; } if (__dynamic_stderr_ret == AW_OK) { aw_close(2); __dynamic_stderr_ret = -AW_EBADF; } }
return -AW_ENODEV;}
int aw_main(void){ int ret;
aw_kprintf("hello world\n"); printf("hello world\n");
while(1) { ret = aw_printf_redirect_dynamic_dev(); if (AW_OK == ret) break;
// 设置检测周期 AW_TASK_DELAY(100); }
aw_kprintf("hello world, ZLG\n"); printf("hello world, ZLG\n");
return 0;}

启动串口调试助手,搜索并打开DEBUG UART设备与CDC串口设备的端口号后,运行上文示例程序。根据下图可知,USB设备枚举后,printf函数成功重定向到了CDC串口设备。0825bf28-8b29-11ee-9788-92fbcf53809c.png

0831239a-8b29-11ee-9788-92fbcf53809c.png


07799d06-8b29-11ee-9788-92fbcf53809c.jpg 总结实现重定向printf函数时主要关注以下两个关键点:

  1. 重写NEWLIB标准库中printf函数的底层实现;
  2. 将指定设备以标准文件流约定的文件描述符打开。


07799d06-8b29-11ee-9788-92fbcf53809c.jpg 扩展阅读

本文所演示平台使用的是GCC编译器,其对应C库为NEWLIB标准库。在AWorksLP中printf函数的底层输出接口在AWorksLP中实现为_write_r 函数,其具体代码实现如下所示。

__attribute__((__used__)) _ssize_t_write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes){ return aw_write(fd,buf,nbytes);}

需要值得注意的是,上述适配方式仅兼容NEWLIB,若是其他编译器,其实现以及接口不尽相同,下表仅给出部分以供参考,在使用时需根据实际情况进行调整。

工具链

标准库

底层接口

GCC

NEWLIB

_write_r

ARMCC

ARMCLIB

_sys_write

ARMCLANG

ARMCLIB

_sys_write

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 设备
    +关注

    关注

    2

    文章

    4785

    浏览量

    73286
  • uart
    +关注

    关注

    22

    文章

    1304

    浏览量

    106118
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66843
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    printf重定向之后无法运行是怎么回事?

    参考 CW32F003_StandardPeripheralLib_V1.6ExamplesUARTUART_Printf,在代码中添加了#ifdef __GNUC__ /* With GCC
    发表于 11-13 08:07

    TI Driverlib 标准输出完整重定向的改进方案

    探索出了一种用于TI Driverlib的完整输出重定向方案
    的头像 发表于 11-11 00:33 273次阅读

    UART在5.2.0版本E2S中的重定向

    随着FSP库版本更新到5.2.0,在开发过程中就会发现4.0.0版本的串口重定义并不适用于最新版本。继续使用原来的重定向代码时,编译器就会报错。根据报错的信息发现,缺少了几个函数的定义,这里补全定义即可。
    的头像 发表于 10-31 15:28 3748次阅读
    UART在5.2.0版本E2S中的<b class='flag-5'>重定向</b>

    e203仿真helloworld例程printf能在终端显示的原理

    名是有特殊意义的,它会将printf的字符输出重定向到这里,通过这个函数传递参数、输出数据。 __WEAK表示这个函数是弱定义。如果我们想通过其他方式
    发表于 10-27 06:56

    【RA4E2开发板评测】FSP5.2之后的串口重定向问题解决方法

    代码时,编译器就会报错。 根据报错的信息发现,缺少了几个函数的定义,这里补全定义即可。 【解决方法】 在野火的教程里有提到过如何处理的方法。 添加重定向函数内容如下: #if defined
    发表于 08-29 07:02

    GPDV6624C应用笔记1.0版

    电子发烧友网站提供《GPDV6624C应用笔记1.0版.pdf》资料免费下载
    发表于 06-06 17:20 0次下载

    无传感器磁场定向控制

    控制,FOC 控制降低了转矩脉动,从而消除了转矩脉动所产生的噪声,降低了电机发热,同时提高了系统效率,增大了最大转矩。本应用笔记讨论了使用 JMT1808R 控制芯片对无刷直流电机(Brushless Direct Current Motor, BLDC)进行无感 FOC 的算法控制。 点击免费下载~~~~
    发表于 03-14 16:26

    CDK应用笔记

    电子发烧友网站提供《CDK应用笔记.pdf》资料免费下载
    发表于 01-16 16:17 0次下载
    CDK应<b class='flag-5'>用笔记</b>

    ES32VF2264应用笔记

    电子发烧友网站提供《ES32VF2264应用笔记.pdf》资料免费下载
    发表于 01-16 16:14 0次下载
    ES32VF2264应<b class='flag-5'>用笔记</b>

    ES7P0214应用笔记

    电子发烧友网站提供《ES7P0214应用笔记.pdf》资料免费下载
    发表于 01-16 16:06 0次下载
    ES7P0214应<b class='flag-5'>用笔记</b>

    ES7P0213应用笔记

    电子发烧友网站提供《ES7P0213应用笔记.pdf》资料免费下载
    发表于 01-16 15:26 0次下载
    ES7P0213应<b class='flag-5'>用笔记</b>

    AT32F423 PWC应用笔记

    电子发烧友网站提供《AT32F423 PWC应用笔记.pdf》资料免费下载
    发表于 01-15 15:30 0次下载
    AT32F423 PWC应<b class='flag-5'>用笔记</b>

    全面掌握Linux重定向技巧:让命令行操作效率翻倍的秘密

    #1 linux输出重定向 $ command > file 2>1 这里的 ,表示重定向的目标不是一个 文件 ,而是一个 文件描述符 ,内置的文件描述符如下 1 => stdout2
    的头像 发表于 01-08 10:19 753次阅读

    S32K3xxICU应用笔记

    S32K3xxICU应用笔记
    发表于 12-30 15:38 2次下载

    stdio.h实现了printf函数?

    我们平时包含的 stdio.h 头文件,里面是不是实现了 printf 函数? 为什么会有这个疑问?因为每次使用 printf,就得包含 stdio.h ,这就导致很多同学误以为,stdio.h
    的头像 发表于 12-18 10:28 871次阅读