MDK下99%用户都不知道的万能printf方法!

嵌入式ARM 2023-03-21 12:00

【写在前面】

你听说过J-LinkRTT吗?官方宣传是这样的:

简单来说,只要拥有J-Link,你就能享受以下便利:
  • 无需占用USART或者USB转串口工具
    ,将
    printf
    重定位到一个由J-LINK提供的虚拟串口上;


  • 支持任何J-LINK声称支持的芯片;


  • 高速通信,不影响芯片的实时响应。

不过,它的缺点也是明显的:
  • 你必须拥有一个J-Link
    ,如果你使用的是 
    CMSIS-DAP
    或者
    ST-Link
    之类的第三方调试工具,就无法享受这一福利;
  • 你必须在工程中手动插入一段代码。



曾几何时,J-Link的这一福利让多少非J-Link用户羡慕嫉妒恨,看看手中的ST-LinkULINKpro和各类廉价的CMSIS-DAP板载调试器——“隔壁邻居的小孩都馋哭了”。


如果我告诉你,其实MDK中内置了一种非常简单廉价的方式,可以让你实现类似的功能,并具有以下特点:
  • 支持所有的调试仿真器,哪怕自己手搓的CMSIS-DAP都行;

  • MDK

    原生功能,连CMSIS-Pack都不用安装;

  • 点几下鼠标就可以通过
    RTE
    完成部署;
  • 除了简单的初始化函数外,
    无需手动插入代码;
  • 可以将你的printf输出直接打印在MDK的Debug (printf) View窗口中。


你是否心动了呢?


【部署从未如此简单】

步骤一:RTE配置

依次通过菜单 Project->Manage->Run-Time Environment 打开RTE配置窗口:

找到并展开Compiler选项卡,勾选Event Recorder,并确保Variant下拉列表选中的是默认的DAP

展开 Compiler 下的 I/O ,勾选STDOUT,并在 Variant 下拉列表中选择 EVR——这里 EVREvent Recorder 的缩写。单击确定后,我们会在工程管理器中看到以下的内容:

至此,所需的工具都已经成功地加入到工程中了。


虽然这里EventRecorderConf.h 是一个可以编辑的状态,但实践中,我们基本不用去碰他——使用默认配置即可。



步骤二:服务初始化
在包含 main() 函数的C代码文件中,按照如下的格式添加对头文件的包含:
#include #if defined(RTE_Compiler_EventRecorder)#   include #endif

main() 函数中添加对EventRecorder服务的初始化:

void main(void){    ...#if defined(RTE_Compiler_EventRecorder) \ && defined(RTE_Compiler_IO_STDOUT_EVR)    EventRecorderInitialize(0, 1);#endif    ...}

如果你从未使用过EventRecorder也不必惊慌,这段代码的主要作用是为printf专门开启一个数据通道。

理论上,到这里就已经完成了部署了,可以在进入调试模式后,通过MDKDebug (printf) View窗口来观察 printf 的输出结果了。比如,我们在 main() 函数中打印一个 "hello world\r\n":
#include 
#include #if defined(RTE_Compiler_EventRecorder)# include #endif
void main(void){ ...#if defined(RTE_Compiler_EventRecorder) \ && defined(RTE_Compiler_IO_STDOUT_EVR) EventRecorderInitialize(0, 1);#endif ...
printf("Hello World\r\n"); ...}
编译,一切顺利的话,进入调试模式后通过菜单 View->Serial Windows->Debug (printf) View 打开窗口:

运行后,可以在 Debug (printf) View窗口中看到如下的结果:


【常见的问题】

如果你的工程中从未提供过对 ".bss.noinit" 数据段的处理,那么很可能会发现通过上述方法实现的 printf 输出似乎不是很稳定——时有时无——处于一种薛定谔的状态。

这是由于 EventRecorder 有一段数据放置在了 “.bss.noinit” section中——以求芯片复位后不会破坏其中原有的内容。
如果你的工程没有专门针对 “.bss.noinit” 的处理,那么就会在进入调试模式后,从Command 窗口中看到类似如下的信息:

即:

Warning: Event Recorder not located in uninitialized memory!

如果遇到这种情况,应该怎么办呢?

打开工程配置窗口“Options for Target”,切换到“Linker”选项卡:


首先,一定要确保你勾选了图中的“Use Memory Layout from Target Dialog”选项。在这一前提下,再次取消对它的勾选:

我们会看到,MDK基于当前的Memory Layout,为我们在Out目录下生成了一个与工程同名的链接脚本(比如图中的工程名叫example,因此生成的链接脚本为 example.sct)。

单击 Edit 按钮,可以看到脚本的内容:


先别着急半路开香槟——该文件是系统自动生成的,如果我们不移动它的位置,那么只要哪次手抖勾选了“Use Memory Layout from Target Dialog”,它的内容就会立即被覆盖掉——意味着我们在后续步骤中所做的改就会付诸东流。


为了避免该问题,应该将它从 Object 目录中移动到工程目录下。具体步骤为:右键单击脚本文件名:

选择“Open Container Folder”来打开文件所在目录:


找到Scatter Script脚本文件后,将其拷贝到上一级目录下(也就是工程目录):

重新打开工程配置窗口:

确保我们“没有”选中“Use Memory Layout from Target Dialog”选项,并在Scatter File文本框中,直接填写我们刚刚拷贝出来的脚本文件名(由于我们直接放在工程目录下,因此这里直接用相对路径"./example.scat"或者"example.scat"就行)。单击OK保存配置。

打开example.sct,在 RW_IRAM1 后面追加如下的代码:

    ZI_RAM_UNINIT +0 UNINIT {        .ANY (.bss.noinit)    }
效果大约类似这样:

保存后重新编译,再次进入 Debug 模式,问题就应该解决了。

这里步骤的核心思想是在 scatter script 内紧接着为 RWZIexecution region.bss.noinit 提供一个属性为UNINIT的专属execution region

在领会精神的情况下,如果你的工程原本就使用了scatter script也可以如法炮制。俗话说解铃还须系铃人,如果你还是不知道怎么处理,那么就去找 你工程中scatter script 的作者吧。


需要强调的是,如果你的MDK版本太老,为了确保最佳的用户体验,还是推荐尽快升级吧!

【写在后面】

总的来说,MDK 通过 EventRecorder 为我们提供了一个通用便捷的方式来重定向 printf——无论你使用什么调试仿真器,甚至是FVP,都可以享受来自“MDK”的阳光普照。
对很多有分发自己工程作为模板的小伙伴来说,使用该方法后将不再限制用户必须使用 J-Link 之类的工具,而是可以放开手脚,获得了“开袋即食”的调试体验。
最后强调一下,EventRecorder只在调试阶段有意义,如果我们需要在产品的正常工作模式下使用 printf,还是老老实实把 Compiler->IO->STDOUT 配置为 User:

实现 stdout_putchar() 函数——用它来发送字符到具体的外设吧,比如:
int stdout_putchar(int ch){    if ('\n' == ch) {        int temp = '\r';        while(Driver_USART0.Send(&temp, 1) != ARM_DRIVER_OK);    }        if (Driver_USART0.Send(&ch, 1) == ARM_DRIVER_OK) {        return ch;    }        return -1;}

END

来源:裸机思维

版权归原作者所有,如有侵权,请联系删除。

推荐阅读
从STM32转到嵌入式Linux驱动开发
让嵌入式工程师欲罢不能的7个小网站(资源篇)
ChatGPT实现51、STM32、树莓派等各种点灯程序

→点关注,不迷路←

嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论 (0)
  • 感谢面包板论坛组织的本次测评活动,本次测评的对象是STM32WL Nucleo-64板 (NUCLEO-WL55JC) ,该测试板专为LoRa™应用原型构建,基于STM32WL系列sub-GHz无线微控制器。其性能、功耗及特性组合经过精心挑选,支持通过Arduino® Uno V3连接,并利用ST morpho接头扩展STM32WL Nucleo功能,便于访问多种专用屏蔽。STM32WL Nucleo-64板集成STLINK-V3E调试器与编程器,无需额外探测器。该板配备全面的STM
    无言的朝圣 2025-05-13 09:47 151浏览
  •   定制软件开发公司推荐清单   在企业数字化转型加速的2025年,定制软件开发需求愈发多元复杂。不同行业、技术偏好与服务模式的企业,对开发公司的要求大相径庭。以下从技术赛道、服务模式及行业场景出发,为您提供适配的定制软件开发公司推荐及选择建议。   华盛恒辉科技有限公司:是一家专注于高端软件定制开发服务和高端建设的服务机构,致力于为企业提供全面、系统的开发制作方案。在部队政企开发、建设到运营推广领域拥有丰富经验,在教育,工业,医疗,APP,管理,商城,人工智能,部队软件、工业软件、数字化转
    华盛恒辉l58ll334744 2025-05-12 15:55 332浏览
  • ‌磁光克尔效应(Magneto-Optic Kerr Effect, MOKE)‌ 是指当线偏振光入射到磁性材料表面并反射后,其偏振状态(偏振面旋转角度和椭偏率)因材料的磁化强度或方向发生改变的现象。具体表现为:1、‌偏振面旋转‌:反射光的偏振方向相对于入射光发生偏转(克尔旋转角 θK)。2、‌椭偏率变化‌:反射光由线偏振变为椭圆偏振(克尔椭偏率 εK)。这一效应直接关联材料的磁化状态,是表征磁性材料(如铁磁体、反铁磁体)磁学性质的重要非接触式光学探测手段,广泛用于
    锦正茂科技 2025-05-12 11:02 297浏览
  •   舰艇电磁兼容分析与整改系统平台解析   北京华盛恒辉舰艇电磁兼容分析与整改系统平台是保障海军装备作战效能的关键技术,旨在确保舰艇电子设备在复杂电磁环境中协同运行。本文从架构、技术、流程、价值及趋势五个维度展开解析。   应用案例   目前,已有多个舰艇电磁兼容分析与整改系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润舰艇电磁兼容分析与整改系统。这些成功案例为舰艇电磁兼容分析与整改系统的推广和应用提供了有力支持。   一、系统架构:模块化智能体系   电磁环境建模:基
    华盛恒辉l58ll334744 2025-05-14 11:22 45浏览
  • 在当下竞争激烈的 AI 赛道,企业高层的变动往往牵一发而动全身,零一万物近来就深陷这样的动荡漩涡。近日,零一万物联合创始人、技术副总裁戴宗宏离职创业的消息不胫而走。这位在大模型基础设施领域造诣颇深的专家,此前在华为云、阿里达摩院积累了深厚经验,在零一万物时更是带领团队短期内完成了千卡 GPU 集群等关键设施搭建,其离去无疑是重大损失。而这并非个例,自 2024 年下半年以来,李先刚、黄文灏、潘欣、曹大鹏等一众联创和早期核心成员纷纷出走。
    用户1742991715177 2025-05-13 21:24 109浏览
  •   电磁数据管理系统深度解析   北京华盛恒辉电磁数据管理系统作为专业的数据处理平台,旨在提升电磁数据的处理效率、安全性与可靠性。以下从功能架构、核心特性、应用场景及技术实现展开分析:   应用案例   目前,已有多个电磁数据管理系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁数据管理系统。这些成功案例为电磁数据管理系统的推广和应用提供了有力支持。   一、核心功能模块   数据采集与接入:实时接收天线、频谱仪等设备数据,兼容多协议接口,确保数据采集的全面性与实时性
    华盛恒辉l58ll334744 2025-05-13 10:59 271浏览
  •   基于 2025 年行业权威性与时效性,以下梳理国内知名软件定制开发企业,涵盖综合型、垂直领域及特色技术服务商:   华盛恒辉科技有限公司:是一家专注于高端软件定制开发服务和高端建设的服务机构,致力于为企业提供全面、系统的开发制作方案。在部队政企开发、建设到运营推广领域拥有丰富经验,在教育,工业,医疗,APP,管理,商城,人工智能,部队软件、工业软件、数字化转型、新能源软件、光伏软件、汽车软件,ERP,系统二次开发,CRM等领域有很多成功案例。   五木恒润科技有限公司:是一家专业的部队信
    华盛恒辉l58ll334744 2025-05-12 16:13 250浏览
  • 在全球供应链紧张和国产替代需求推动下,国产存储芯片产业快速发展,形成设计到封测一体化的完整生态。北京君正、兆易创新、紫光国芯、东芯股份、普冉股份和佰维存储等六大上市公司在NOR/NAND Flash、DRAM、嵌入式存储等领域布局各具特色,推动国产替代提速。贞光科技代理的品牌紫光国芯,专注DRAM技术,覆盖嵌入式存储与模组解决方案,为多领域客户提供高可靠性产品。随着AI、5G等新兴应用兴起,国产存储厂商有望迎来新一轮增长。存储芯片分类与应用易失性与非易失性存储芯片易失性存储芯片(Volatile
    贞光科技 2025-05-12 16:05 200浏览
  •   电磁数据展示系统平台解析   北京华盛恒辉电磁数据展示系统平台是实现电磁数据高效展示、分析与管理的综合性软件体系,以下从核心功能、技术特性、应用场景及发展趋势展开解读:   应用案例   目前,已有多个电磁数据展示系统在实际应用中取得了显著成效。例如,北京华盛恒辉和北京五木恒润电磁数据展示系统。这些成功案例为电磁数据展示系统的推广和应用提供了有力支持。   一、核心功能模块   数据采集与预处理   智能分析处理   集成频谱分析、时频变换等信号处理算法,自动提取时域频域特征;
    华盛恒辉l58ll334744 2025-05-13 10:20 361浏览
  • 文/Leon编辑/cc孙聪颖‍2025年1月至今,AI领域最出圈的除了DeepSeek,就是号称首个“通用AI Agent”(智能体)的Manus了,其邀请码一度被炒到8万元。很快,通用Agent就成为互联网大厂、AI独角兽们的新方向,迅速地“卷”了起来。国外市场,Open AI、Claude、微软等迅速推出Agent产品或构建平台,国内企业也在4月迅速跟进。4月,字节跳动、阿里巴巴、百度纷纷入局通用Agent市场,主打复杂的多任务、工作流功能,并对个人用户免费。腾讯则迅速更新腾讯元器的API接
    华尔街科技眼 2025-05-12 22:29 148浏览
  • 在 AI 浪潮席卷下,厨电行业正经历着深刻变革。AWE 2025期间,万得厨对外首次发布了wan AiOS 1.0组织体超智能系统——通过AI技术能够帮助全球家庭实现从健康检测、膳食推荐,到食材即时配送,再到一步烹饪、营养总结的个性化健康膳食管理。这一创新之举并非偶然的个案,而是整个厨电行业大步迈向智能化、数字化转型浪潮的一个关键注脚,折射出全行业对 AI 赋能的热切渴求。前有标兵后有追兵,万得厨面临着高昂的研发成本与技术迭代压力,稍有懈怠便可能被后来者赶
    用户1742991715177 2025-05-11 22:44 180浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦