嵌入式开发输出调试信息的常用方法

news2024/11/14 16:26:34

嵌入式开发为什么需要输出调试信息?

稳严文因为输出调试信息是嵌入式开发中一项非常重要的实践,它有助于保证软件的可靠性、稳定性和性能,也是故障排查的关键工具之一。

白话文程序猿想知道自己敲的代码是否正确、是否按照要求运行,但是代码跑起来看不见、摸不着,那么就可以通过输出调试信息可以自由看到结果。

嵌入式开发输出调试信息主要有以下作用:

错误排查与问题定位

输出调试信息可以帮助你在代码中发现和定位错误。当程序出现异常行为或崩溃时,通过查看输出的调试信息,你可以更容易地找到问题的根本原因, 比如内存泄漏或者越界访问。通过查找异常条件、变量值、函数调用堆栈等信息,有助于快速定位和解决问题。

实时反馈

在开发过程中逐步增加新功能或者修改现有功能时,输出调试信息可以提供实时反馈。这使得可以快速地检查修改的效果。

代码验证和逻辑分析

输出调试信息可用于验证代码是否按预期工作。你可以在关键代码段插入打印语句,以监视变量的值和程序的流程,从而确保代码的逻辑正确性。这有助于提前发现潜在问题,减少后期调试的工作量。

验证硬件连接

通过输出与外部设备或模块的通信信息,可以验证硬件连接是否正确,是否能够正确地与外部设备进行通信。

状态监控

输出调试信息可以实时监控系统的状态。这对于嵌入式系统特别有用,你可以实时追踪传感器数据、设备状态、通信状态等,并在需要时采取相应的措施。

性能分析

输出调试信息可以帮助你评估程序的性能。你可以测量程序的执行时间,查看代码路径是否有效率,以及检查是否有不必要的延迟。

嵌入式开发输出调试信息常用的几种方法

1. 通过串口输出log

这是一种常见的调试方法。可以在STM32微控制器上配置一个UART(串口通信)模块,将调试信息发送到计算机或者其他设备上,然后在相应的终端软件(比如串口调试工具)中查看输出的log信息。

2. 输出log信息到SRAM

这种方法通常用于在没有外部调试接口(比如串口)的情况下,将调试信息保存在芯片的内部存储器中,比如SRAM(Static Random Access Memory)。可以使用类似于sprintf函数的方式将调试信息格式化后写入SRAM中,然后通过其他手段(例如JTAG/SWD接口)将SRAM中的信息读取出来进行分析。

3. 通过SWO输出log

Serial Wire Output (SWO) 是一种用于调试的硬件接口,进行调试信息的输出。这种方法相对于串口输出更为灵活,但需要相应的硬件和调试工具的支持。可以在调试器/编程器(如ST-Link)中配置SWO输出,然后使用调试工具进行连接并查看log信息。SWO可以在不影响CPU执行速度的情况下,以高速输出调试信息。

如何通过串口输出log?

要通过串口输出log信息,需要配置STM32的串口模块并使用相应的库函数或者驱动程序来发送数据。具体步骤如下:

CubeMX配置

1)启用 Debug Serial Wire

2)启用串口USART1

3)启用ADC的ADC_IN4(PA4引脚作为光照模块的模拟输入引脚,用于产生数据)

编写程序

在代码中,可以使用类似于C语言标准库中的printf函数来格式化输出log信息。

因为要使用printf,所以需要添加stdio.h头文件,并且为其重定向输出。

1)添加头文件

2) 重定向标准输出(注意:每个MCU的重定向有区别,根据自己的芯片自行配置,将标准输出重定向至USART的发送数据寄存器,查看自己MCU的手册自行配置)

3)编写代码,定义一个变量接收ADC转换的值,再将其打印至串口进行调试输出

终端调试输出

1)下载并运行代码

通过IDE将代码烧录到STM32芯片上,然后运行。

2)连接串口线

确保你的开发板上已经连接了串口线,一端连接到STM32的相应串口引脚(例如:PA9、PA10),另一端连接到计算机或者其他设备的串口接口(或者通过串口转USB模块连接到计算机的USB接口)。

3)用串口调试助手输出信息

如何输出log信息到SRAM?

要将调试信息输出到STM32的SRAM(静态随机存取存储器),可以使用类似于sprintf函数将格式化的字符串写入SRAM中。具体步骤如下:

1. 初始化SRAM

在你的工程中,确保你已经正确初始化了SRAM。通常,SRAM会被映射到特定的地址空间中,你可以使用相应的地址来访问它。(因为芯片不同,请自行查阅手册或百度)

2. 使用sprintf函数

在你的代码中,你可以使用类似于C语言标准库中的sprintf函数将格式化的字符串写入一个缓冲区中。例如:

1)先定义一个缓冲区

2)再把格式化后的字符串写入到buf中

3. 将字符串写入SRAM

使用SRAM的地址,将buf中的内容写入到SRAM中。可以使用指针或者类似于memcpy的函数来实现。(注意加头文件 #include <string.h> )代码如下:

注意:SRAM的具体地址和大小取决于你的STM32型号和硬件配置,需要根据具体情况进行相应的调整(可在Keil IDE中点击Books跳转查找),在STM32F051中SRAM的起始地址为0x20000000。

4. 读取SRAM中的信息

在需要查看log信息的时候,您可以从SRAM的地址中读取信息并输出到串口或者其他输出设备上。(这里,我们直接输出到串口)

当然,也可以在IDE的中用Debug进行查看

这种方法的好处是,即使你的STM32芯片上没有外部调试接口(如串口),仍然可以在设备上保存和查看调试信息。但请注意,SRAM是易失性内存,断电后信息会丢失,因此只适用于临时调试目的。

如何通过SWO输出log?

  1. 温馨小TOP

名词解释:

SWD:串行线调试(Serial Wire Debug)

SWO:串行线输出(Serial Wire Output)

SWV:串行线查看器(Serial Wire Viewer)

ITM:指令跟踪宏单元(Instrumentation Trace Macrocell)

  1. 关于SWO和ITM

SWO串行线输出是单引脚、异步串行通信,可在Cortex-M3/M4/M7上使用,并由主调试器探测支持。

它是利用Cortex内核中ITM模块来实现此功能。连接引脚如下所示:

SWO输出,需要一根SWO(引脚)线,同时需要借助SWV(查看器)查看数据。

ITM 的一个主要用途,就是支持调试消息的输出(如printf 格式的输出)。ITM 包含 32 个刺激(Stimulus)端口,允许不同的软件把数据输出到不同的端口,从而让调试主机可以把它们的消息分离开。 和基于 UART 的文字输出不同,使用 ITM 输出不会对应用程序造成很大的延迟,在 ITM 内部有一个 FIFO,它使写入的输出消息得到缓冲。

  1. SWO引脚配置

SWO引脚可以理解为UART的Tx引脚,如果不连接此引脚,则(SWV)终端不会接收打印信息。

对于STM32而言,只要是Cortex-M3/M4/M7内核的MCU都有SWO引脚。

而Cortex-M0则没有此项功能,包含STM32F0、STM32L0和STM32G0等。

在STM32CubeMX工具中,Debug选项进行如下配置即可。

(注意:此处使用的是最常用的芯片STM32F103C8T6)

  1. 发送源码

此方法和前面UART实现printf打印输出区别就是:将重定义代码中UART发送字符,改为ITM发送字符。

  1. Keil SWO输出配置

点击魔术棒——>点击Debug——>点击Settings

注意:Clock和ITM STimulus Ports根据情况自行设置

  1. 输出调试

这里使用Debug(printf)Viewer输出调试信息,当然,还有其他方法(比如:基于IAR的Terminal IO 、基于ST-LINK Utility的Serial Wire Viewer、基于J-Link的SWO Viewer)。 直接点击Debug,按照以下步骤操作:

点击运行即可看到调试输出的结果

优缺点总结

通过串口输出log

优点:

易于实现:串口通信是一种相对简单的通信方式,适用于大多数STM32微控制器。

实时性:可以实时输出信息,便于实时监控设备状态。

稳定性:稳定可靠,通常不容易出现干扰或错误。

缺点:

占用硬件资源:需要占用一个UART模块,如果需要同时使用多个UART模块,资源分配可能会成为问题。

物理连接:需要连接物理的串口线,有时需要繁琐的线路布线。

有线连接:通常需要连接到计算机或者其他设备,不适用于远程调试。

输出log信息到SRAM

优点:

适用于无外部接口:当设备没有外部调试接口时,这是一种有效的调试手段。

低成本:不需要额外的硬件,仅需要一个可用的SRAM。

缺点:

临时性:SRAM是易失性内存,断电后信息会丢失,只适用于临时调试目的。

需要额外的代码:需要编写代码将信息写入SRAM,增加了开发工作量。

不适用于远程调试:无法将信息传输到远程地点,只适用于本地调试。

通过SWO输出log

优点:

灵活性:SWO接口提供了一种灵活的调试方法,可以用于实时调试和性能分析。

无需额外硬件:只需要一个支持SWO的调试器/编程器,无需额外的硬件设备。

适用于远程调试:可以通过SWD接口进行远程调试。

缺点:

相对复杂:相对于串口输出,SWO输出的配置和使用可能需要更多的设置和调试工作。

需要支持SWO的硬件:不是所有的STM32开发板和调试器都支持SWO功能。

注意:每种方法都有其适用的场景,要根据具体的项目需求、硬件资源和调试环境,选择合适的输出调试信息的方法。有时候也可以根据实际情况结合多种方法,以获取更全面的调试信息。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nginx反向代理功能

反向代理&#xff1a;reverse proxy&#xff0c;指的是代理外网用户的请求到内部的指定的服务器&#xff0c;并将数据返回给用户的 一种方式&#xff0c;这是用的比较多的一种方式。 Nginx 除了可以在企业提供高性能的web服务之外&#xff0c;另外还可以将 nginx 本身不具备的…

如何选择最佳路线?

交通线路的选择 日常交通线路的选择&#xff0c;并不是按最短路径选择的。还要参考道路的等级&#xff0c;道路是否拥堵&#xff0c;道路通行速度等多种情形。本程序列举出所有能通行的线路&#xff0c;并计算出行驶距离&#xff0c;来供用户选择。当然&#xff0c;也可以加入…

linux | ubuntu虚拟机创建硬盘、磁盘分区、分区挂载、自动挂载、磁盘清理

点击上方"蓝字"关注我们 01、创建硬盘 >>> 什么使硬盘? 点击虚拟机设置,这里有两个硬盘,一个100G,一个20G 应用场景,下载yocto时,磁盘空间不足,所以写下这篇文章,供大家参考 >>> 开始创建一个新的硬盘 点击添加 【选择硬盘 下一步】 【推…

三、Vuex是什么?Vuex详解

什么是Vuex 在理解Vuex之前&#xff0c;首先需要理解我们为什么要使用它&#xff1f;它解决了什么问题&#xff1f; 为什么要使用它 在Vue开发中&#xff0c;我们常常会用到组件直接的传值、通讯。有父子通讯&#xff0c;兄弟组件通讯…但是传参对于多层嵌套就显得非常繁琐&am…

分享思源笔记的几个骚操作

文章目录 思维导图复习法效果视频制作过程使用方法 大纲复习方法制作过程 人工智能简易使用效果制作过程 思维导图复习法 效果视频 bandicam20240817222246034.mp4 制作过程 首先下载【写味】主题或者是[自定义块样式]插件 他两个的区别是 思维导图以列表形式写出来 选择转…

计算机毕业设计选题推荐-旅游景点数据分析-Python爬虫可视化

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

Unity教程(十一)使用Cinemachine添加并调整相机

Unity开发2D类银河恶魔城游戏学习笔记 Unity教程&#xff08;零&#xff09;Unity和VS的使用相关内容 Unity教程&#xff08;一&#xff09;开始学习状态机 Unity教程&#xff08;二&#xff09;角色移动的实现 Unity教程&#xff08;三&#xff09;角色跳跃的实现 Unity教程&…

武林外传书生版单机安装教程+GM工具+虚拟机一键端

今天给大家带来一款单机游戏的架设&#xff1a;武林外传书生版。 另外&#xff1a;本人承接各种游戏架设&#xff08;单机联网&#xff09; 本人为了学习和研究软件内含的设计思想和原理&#xff0c;带了架设教程仅供娱乐。 教程是本人亲自搭建成功的&#xff0c;绝对是完整…

快速带你玩转高性能web服务器后续

目录 一、Nginx 高级配置 1.1 Nginx 状态页 1.2 Nginx 压缩功能 1.3 Nginx的版本隐藏 1.4 Nginx 变量使用 1.4.1 内置变量 二、 Nginx Rewrite 相关功能 2.1 ngx_http_rewrite_module 模块指令 2.1.1 if 指令 2.1.2 set 指令 2.1.3 break 指令 2.1.4 return 指令 2…

cmake install setlocal错误

cmake中的代码如下&#xff1a; #设置安装目录的前缀 set(CMAKE_INSTALL_PREFIX $ENV{PUBLISH_DIR}) #这边的输出满足要求 message(STATUS "install dir:${CMAKE_INSTALL_PREFIX}") #指定安装 install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION bin …

数据埋点系列总结|从基础到实践的深度总结

在当今数字化时代,数据已成为企业的核心资产,而数据驱动决策则是充分利用这一资产的关键方法。本系列文章全面探讨了从数据收集到分析,再到实际应用的整个过程,为读者提供了深入而实用的指导。让我们深入回顾这个journey,详细探讨每个主题的核心内容,并思考数据驱动决策的未来发…

SHOPLINE x TiDB丨集群成本降低 50%!跨境电商 SHOPLINE 交易、商品管理等核心业务的数据库升级之路

导读 本文整理自 TiDB 社区深圳站——SHOPLINE 数据库/TiDB 负责人车佳蔚的演讲《SHOPLINE & TiDB 在跨境电商中的应用实践》。本次分享深入探讨了 SHOPLINE 在跨境电商领域的数字化转型过程中&#xff0c;如何通过 TiDB 技术应对技术挑战&#xff0c;实现降本增效。 本文…

《重生到现代之从零开始的C语言生活》—— 指针3

数组名的理解 在我们使用&arr[0]的方式拿到了数组第一个元素的地址&#xff0c;但是其实&#xff0c;数组名本来就地址&#xff0c;而且是数组首元素的地址 所以数组名就是数组首元素的地址 但是会有两个例外 sizeof(数组名)&#xff0c;sizeof中单独放数组名&#xff0c…

『功能项目』移动后的光标显示【04】

我们打开上一篇03的射线双击项目&#xff0c; 本章要做的事情是在PlayerRayNavgation脚本中添加一个移动光标&#xff0c;实现人物在场景中鼠标点击移动后在移动过程中出现移动目标光标的效果。 在unity编辑器中创建一个Plane 重命名为MovementSign 删掉碰撞器 创建一个材质 选…

杰发科技AC7840——CAN通信简介(8)_通过波特率和时钟计算SEG_1/SEG_2/SJW/PRESC

通过公式计算 * 波特率和采样点计算公式&#xff1a;* tSeg1 (S_SEG_1 2); tSeg2 (S_SEG_2 1).* BandRate (SCR_CLK / (S_PRESC 1) / ((S_SEG_1 2) (S_SEG_2 1))), SCR_CLK 为CAN 模块源时钟* SamplePoint (tSeg1 / (tSeg1 tSeg2)). {0x0D, 0x04, 0x04, 0x3B},…

avue-crud 自定义搜索项 插槽

加上 -search 就可以自定义查询项了

制定sbti科学碳目标的主要原则是什么?

制定科学碳目标主要遵循以下原则&#xff1a; 科学性&#xff1a; 基于气候科学&#xff1a;科学碳目标的设定必须依据可靠的气候科学研究成果&#xff0c;以确保目标能够真实反映对气候变化的有效应对。例如&#xff0c;要考虑到将全球平均气温升幅控制在远低于工业化前水平 2…

全国产化服务器:飞腾FT2000+/64核密集计算、显控及存储一体式加固服务器

飞腾FT2000/64核的加固服务器是一款专为高安全性、高可靠性及能在严苛环境下稳定运行而设计的服务器产品。以下是对该服务器的详细介绍&#xff1a; 一、处理器与核心组件 处理器&#xff1a;搭载飞腾FT2000/64核处理器&#xff0c;该处理器基于ARM架构&#xff0c;集成了64个…

C语言--01基础数据类型

1.整型 概念&#xff1a;表达整数类型的数据语法&#xff1a; int a 123; // 定义了一个专门用来存储整数的变量a a 456 ; 需要注意的地方&#xff1a; int 的本意是 integer&#xff0c;即整数的意思int a 代表在内存中开辟一块小区域&#xff0c;称为 a&#xff0c;用来…

Kafka快速入门:Kafka驱动JavaApi的使用

生产者和消费者是Kafka的核心概念之一&#xff0c;它们在客户端被创建和使用&#xff0c;并且包含了许多与Kafka性能和机制相关的配置。虽然Kafka提供的命令行工具能够执行许多基本操作&#xff0c;但它无法实现所有可能的性能优化。相比之下&#xff0c;使用Java API可以充分利…