MCUXpresso Using of printf

另一篇参考文档:https://community.nxp.com/docs/DOC-334074

MCUXpresso帮助文档中的“Using of printf”

默认情况下,借由semihost机制,printf()和puts()的输出会显示在debugger console上。
要想让printf()这样工作,就必须在链接过程中把一个"semihost"或“semihost-nf”变种库链接到程序中。
注意:如果只要显示固定字符串,则使用puts()即可,它比printf()节约很多代码空间。

Redlib printf变种

Redlib提供如下两种printf变种。在创建新工程时,MCUXpresso新工程向导会提供选项,允许你从这两种中选择其中一种。

字符 VS 字符串输出
默认情况下,printf()和puts()会立即输出生成的字符串,这样,单独一次semihost操作就可以把字符串输出到debugger console。注意:这种printf()/ puts()使用malloc在堆中创建一个临时缓冲区来生成字符串。
另一个版本是“按字符依次发送”,它不需要堆空间。这种版本需要在工程中宏定义"CR_PRINTF_CHAR"。如果你要把printf()重定向到UART(下面详述),这种方法就特别有用,因为在使用UART时没必要创建一个缓冲区来储存整个字符串,只要每次向UART输出一个字符即可。

只打印整数 VS 打印全部类型数字(包括浮点数)
Redlib中的printf()比Newlib中的小的多。因此,如果很在意代码尺寸,就尽量尝试使用Redlib。另外,如果你的应用不打印浮点数,就可以选择一个“仅整数”(不兼容浮点)变种的printf。这又能减少代码尺寸。
要使能Redlib中的“仅整数”printf,须在工程中宏定义“CR_INTEGER_PRINTF”。在使用SDK新工程向导时,这是默认定义的。

NewlibNano printf变种

默认情况下,NewlibNano变种仅支持整数的printf和scanf,从而减少代码尺寸。
如果确实需要支持浮点数,则需:
工程属性——C/C++ Build——Settings——MCU Linker——Managed Linker Script,勾选“Enable printf / scanf float”。

Newlib printf变种

Newlib提供了一个“iprintf”函数来实现“仅整形”printf。

使用LPCOpen时的printf

使用SDK时的printf

MCUXpresso SDK代码仓库通过宏PRINTF提供它自己的printf功能。PRINTF宏在fsl_debug_console.h中定义,它既可以指向C库中的printf函数,也可以指向SDK中的伪printf函数DbgConsole_Printf()。典型地,这【指向DbgConsole_Printf()】会通过一个UART(它可能连接到板上的调试probe,从而通过USB VCOM通道回传给host)来发送。通过宏SDK_DEBUGCONSOLE来控制:
  如果SDK_DEBUGCONSOLE == 0
    PRINTF定向到C库中的printf()
  如果SDK_DEBUGCONSOLE == 1
    PRINTF定向到SDK的DbgConsole_Printf()
SDK新工程向导,以及导入SDK样例向导时,在Advanced页面中,提供配置选项来控制SDK_DEBUGCONSOLE的值。

另外,如果PRINTF被定向到C库printf(),并且也定义了SDK_DEBUGCONSOLE_UART,则printf依然定向到UART。同样的,在SDK新工程向导以及导入SDK样例向导的Advanced页面中,提供了配置选项来控制这一点。

重定向printf/scanf

默认情况下,借由semihost机制,printf()把文本输出到debug console上。
有时这种输出机制不符合你的应用需求,你希望通过一个通信通道(UART,或者Cortex-M3/M4上的ITM SWO Trace)来输出。这时,你可以重定向底层库的某些部分来达到目的。
下面的“如何使用ITM Printf”展示了一个例子。
注意:重定向这些函数时,一般在链接时要选择C库的“nohost”变种,而非“semihost”变种。

Redlib
要重定向Redlib的printf(),需要你自己来完善__sys_write()函数:
int __sys_write(int iFileHandle, char *pcBuffer, int iLength)
成功时返回0,失败时返回未发送的字节数。

类似地,如果要重定向scanf(),需要你自己来完善__sys_readc():
int __sys_readc(void)
函数返回读到的字符。

注意:这2个函数直接有效地映射到底层的“semihost”操作。【啥意思?没懂】

Newlib / NewlibNano
要重定向printf(),需要你自己来完善_write()函数:
int _write(int iFileHandle, char *pcBuffer, int iLength)
成功时返回0,失败时返回未发送的字节数。

要重定向scanf(),需要你自己来完善_read():
int read(int iFileHandle, char *pcBuffer, int iLength)
函数返回读到的字符数,读到的字符保存在pcBuffer里。
更多Newlib系统调用信息,参见https://sourceware.org/newlib/libc.html#Syscalls

如何使用ITM Printf

ITM Printf是一种通过debug probe访问应用IO的机制,不使用semihosting。

ITM概览

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值