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

ops/2024/9/20 1:19:49/ 标签: 单片机, 物联网, 嵌入式硬件, 算法, c语言

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

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

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

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

错误排查与问题定位

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

实时反馈

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

代码验证和逻辑分析

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

验证硬件连接

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

状态监控

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

性能分析

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

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

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.ppmy.cn/ops/97074.html

相关文章

day_45

115. 不同的子序列 class Solution:def numDistinct(self, s: str, t: str) -> int:dp [[0] * (len(t) 1) for _ in range(len(s) 1)]for i in range(len(s)):dp[i][0] 1for j in range(1, len(t)):dp[0][j] 0for i in range(1, len(s) 1):for j in range(1, len(t) …

编译Android使用的ffmpeg库

1 下载NDK 官网&#xff1a;NDK 下载 | Android NDK | Android Developers 2 下载ffmpeg 官网&#xff1a;FFmpeg 3 下载配置msys2 在我之前的博客中有写windows下编译ffmpeg 最详细教程_windows 编译 ffmpeg-CSDN博客 4 编写编译脚本 在ffmpeg的路径下新建一个脚本…

接口加密解决方案,Python的各种加密实现!

01、前言 在现代软件开发中&#xff0c;接口测试已经成为了不可或缺的一部分。随着互联网的普及&#xff0c;越来越多的应用程序都采用了接口作为数据传输的方式。接口测试的目的是确保接口的正确性、稳定性和安全性&#xff0c;从而保障系统的正常运行。 在接口测试中&…

c++ 智能指针--std::shared_ptr

在C中&#xff0c;std::shared_ptr是智能指针的一种&#xff0c;它用于自动管理具有动态生命周期的对象。当std::shared_ptr的实例被销毁或重置时&#xff0c;它所指向的对象&#xff08;如果仍然存在&#xff09;将被自动删除&#xff08;调用delete&#xff09;&#xff0c;前…

C语言---栈

在C语言中&#xff0c;栈是一种数据结构&#xff0c;主要用于管理函数调用和局部变量。以下是栈的基本概念&#xff1a; 1. **栈的结构**&#xff1a;栈是一种后进先出&#xff08;LIFO&#xff09;的数据结构&#xff0c;最后压入栈的元素最先被弹出。 2. **函数调用**&…

字符设备应用之私有ioctl的使用

ioctl和netlink是用于用户态程序和内核态模块交互的两种方法&#xff0c;这里主要讲解ioctl的使用方法&#xff1b; -----再牛逼的梦想&#xff0c;也抵不住傻逼般的坚持&#xff01; ----20240722 08:26 留一个思考问题&#xff0c;ioctl和netlink的优缺点分别是什么&#xff…

C# 不一样的洗牌算法---Simd指令

洗牌算法&#xff0c;以随机打乱数组中元素的位置 测试数据创建 int[] _data; Random rng new Random(); protected override void CreateData() {_data new int[_size];for (int i 0; i < _data.Length; i){_data[i] i;} } 普通打乱数组元素位置 protected overrid…

oracle中创建视图,将一个表中多条数据整合成一条

要求&#xff1a;根据coil_id和passnum检索出多组数据&#xff0c;根据coil_id和passnum求M2-M16的平均值保留三位小数&#xff0c;并写入到新的视图中 创建视图 FEEDBACK_L1 CREATE VIEW FEEDBACK_L1 AS SELECT COIL_ID, PASSNUM, ROUND(AVG(M2),3) AS avg_M2, ROUND(AVG(M3),…

ESP32智能设备:蓝牙音箱、AI语音助手、环境监测与调节以及智能控制,基于BLE与MQTT技术(代码详解)

本文将介绍如何实现一个功能丰富的ESP32项目&#xff0c;集成蓝牙音箱、AI语音助手、智能设备控制器、环境监测与调节等功能。通过本项目&#xff0c;您将学习到硬件设计、嵌入式编程、蓝牙技术、音频处理、人工智能与语音识别、物联网平台、数据分析及用户界面构建等技术。 一…

建设项目跟踪与展示系统

这是在翻旧文件时翻到的16年写的一个项目 建设项目跟踪与展示系统 建设方案 一、系统建设目的及意义 建设工程项目进度控制的最终目的是确保建设项目按预定的时间完成。能否在预定的时间内交付使用&#xff0c;直接影响到投资效益。为解决施工组织过程中存在问题&#xff0c;…

企业财务自动化:RPA机器人的优势与挑战

随着数字化浪潮的推进&#xff0c;企业财务自动化已成为企业提升效率和降低成本的关键策略。在这一背景下&#xff0c;RPA以其独特的优势&#xff0c;正逐渐成为企业财务自动化的重要工具&#xff0c;然而&#xff0c;RPA在实际应用中也面临着一些挑战。本文金智维将围绕RPA机器…

快速排序的改进(超详细!!!)

改进前的快速排序 代码实现&#xff1a; //快速排序 void quick(int arr[],int start,int end){int i start;int j end;int mid arr[start];int tmp;while(i < j){//从头往后找,比基准小就继续while(arr[i] < mid){i;}//循环结束,i的位置大于等于基准元素//从后往前…

【企业高性能web服务器】

目录 一、Nginx 介绍1、 Nginx 功能介绍2、基础特性3、Nginx 模块介绍 二、Nginx 编译安装1、编写systemd服务 三、平滑升级和回滚1、平滑升级的流程2、升级2、回滚 四、 Nginx 核心配置详解1、实现 nginx 的高并发配置2、Nginx 账户认证功能3、nginx作为下载服务器配置 五、re…

vue3--定时任务cron表达式组件比较

## 背景&#xff1a; 之前使用vue2开发项目时&#xff0c;使用了cron组件&#xff0c;比较了两种组件的使用效果。现在需要把原有的vue2项目升级为vue3&#xff0c;需要对应的cron组件。 方案一&#xff0c;vue3-cron-plus 具体实现&#xff1a; 安装插件 npm install vue3-…

SEO之网站结构优化(十二-绝对路径和相对路径)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、“新手上云”能够为你开启探索云世界的第一步 博客&#xff1a;阿幸SEO~探索搜索排名之道 绝对路径指的是包含城名的完…

奇异递归Template有啥奇的?

如果一个模版看起来很头痛&#xff0c;那么大概率这种模版是用来炫技&#xff0c;没啥用的&#xff0c;但是CRTP这个模版&#xff0c;虽然看起来头大&#xff0c;但是却经常被端上桌~ 奇异递归模板模式&#xff08;Curiously Recurring Template Pattern, CRTP&#xff09;是一…

数字人的形象克隆与语音克隆是伪需求

形象克隆与语音克隆技术&#xff0c;在当前的环境上已经可以成熟的实现&#xff0c;但真的解决了痛点问题吗&#xff1f; 普通人或者一般的公司克隆自己内部人的形象有必要吗&#xff1f;对外界而言&#xff0c;克隆的形象与虚拟的形象并无二致&#xff0c;本身并没有什么知名…

【区块链+商贸零售】消费券 2.0 应用方案 | FISCO BCOS应用案例

方案基于FISCO BCOS区块链技术与中间件平台WeBASE&#xff0c;实现新一代消费券安全精准高效发放&#xff0c;实现消费激励&#xff0c; 促进消费循环。同时&#xff0c;方案将用户消费数据上链&#xff0c;实现账本记录与管理&#xff0c;同时加密机制保证了数据安全性。

【Axure视频教程】中继器表格——设置文字颜色

今天教大家在Axure制作将控制中继器内部控制文字颜色的原型模板&#xff0c;效果包括&#xff1a; 1、用中继器表格的数据来控制文字的颜色&#xff0c;例如60分以下红色文字&#xff0c;90分以上绿色文字双击分值的格子2 2、可以填写或修改分值&#xff0c;修改后根据新值自…

当SOA遇到DDD

本文讨论软件设计中的决策&#xff0c;特别是关于将较大的系统拆分为多个可独立部署的服务端点。不会特别讨论【服务端点设计】&#xff0c;但我想探讨一下为创建多个服务应用程序进行构思的阶段。 面对复杂问题&#xff0c;通常试图理解复杂性的各部分。将问题拆解为更易于理…