这两个月没有怎么更新博文,最近换工作了,根据新工作安排,大半年内都做MCU开发(就不要叫单片机了,太老土了)。

入职新工作了,需重构拳头产品的软件,所以每天加班加点。

单片机与linux应用开发,开发过程中有什么区别之近日个人感悟:

第一点,单片机往往配合仿真器调试,linux应用开发往往使用串口打印,或者经由以太网的gdb调试、生成coredump文件来定位常见的段错误。

linux应用开发调试手段,可以参考我的博文:

嵌入式交叉编译GDB,结合vscode图形化调试C和C++代码 coredump定位段错误

第二点,单片机开发会涉及中断,而linux应用开发不会涉及中断的概念。

(linux驱动开发会涉及中断,但是一般驱动开发工作量少,某个SPI或IIC外设的驱动开发好了以后就可以一直被使用)

近日遇到问题,迷糊了挺久,最后得以解决,在此总结心得。

我的硬件环境:        MDK-ARM下调试stm32

我的软件环境:        RT-Thread          PS:以前也常在业余时间了解RT-Thread,这次终于有机会用它做项目了,跃跃欲试。

我遇到的问题:

翻车在一个GPIO上 开启pin中断 导致程序卡死

具体描述:开启pin中断,就会导致程序卡死,rt_pin_mode()参数配置调整了几次也没用。 翻车在一个GPIO上了。

     硬件触发的信号是正常的高低变化的信号,示波器看过。 同时,我当前使用的是gitee-master版本,不是发布版。

1. 仿真后运行程序,外界给入高低电平的信后,这时程序就会卡死,之后停止运行程序,MDK下并没有箭头指示当前C代码运行到哪里去了。

但是这里显示PC是0x08004EE4.

我不知道是否可以根据此PC值定位出当前运行到哪里,以及如何根据此PC值定位出当前运行到了哪里。

需要补充一个技能:根据当前的汇编代码定位出当前运行的C代码。

2. RT-Thread版本,当前是 gitee-master版本,不是发布版。这个有点疑虑,不排除怀疑gitee-master版本的可靠性。但是基本认为gitee-master版本是可靠的。如果实在不行,可以换成release版本去试试。

由于能力有限,目前这个仿真效果对我来说,没什么参考意义,所以我就只能想其他办法了。

图省事,我直接在原工程上屏蔽了其他也操作了该PIN操作相关的地方,然后再次测试,还是卡死。《== 假设这是我改的一个测试程序,称呼其为测试程序1吧。

问题解决后,回顾该调试过程,重现了下该测试过程,

这里我犯错了,因为总共就涉及到三四句代码而已,我图省事,直接在原工程上屏蔽一些代码然而当时我确实没有屏蔽完全!那么这样,造成的最终效果还是卡死!

即我在修改出测试程序1的过程中又犯下了低级错误, 所以导致我又加深了对这个难点O的疑惑。

展示下我的低级错误:

我的外部中断是配合一个人感传感器使用的,由于manager_initialization()函数内没有屏蔽掉人感相关代码,间接导致device_human_sensor_init函数被调用,如下图所示,
这里又再次配置了该外部中断脚。 

编译程序并烧录,由于没有进行规范的外部中断脚的配置,造成的最终效果还是卡死!

接着说当时的调试,偶然又发现如果烧录该工程到0x08000000的flash起始地址上,我的中断可以正常跑。

我的项目是使用了OTA的,我当前所编写的是APP代码,所以我就开始怀疑是我的OTA或者称为IAP导致的这个问题。

Q群讨论,知道了如何查看当前的异常向量表的地址,如下图

重新实操了下,回顾再次回顾该步骤调试过程:

我当时肯定又进行了一些代码的修改,假设这是测试程序2 ,测试程序2直接烧录到0x08000000后外部中断正常,之前测试程序1是个有问题的程序,当时这个测试程序2恰好又被我改对了而已!

我认为当时这个测试程序2作为APP,烧录到我的APP的0X08020000这个地址肯定也是可以正常运行和响应外部中断的。

所以当时,我又没能调试好我的这个中断响应后卡死的问题。

后来是怎么调试好的呢?接着说

因为我使用的外部中断脚是PD11,那么它的中断服务函数归属于EXTI15_10_IRQHandler

我一看,是个弱定义,又没搜索到函数定义,虽然我以前还阅读分析过RT-Thread的GPIO驱动框架的源码,但那都是一年半之前的一点兴趣爱好而已,早就忘干净了。

于是又没继续下去了,现在回顾之前在MDK下的搜索方式,正确的方式应该是这样:

全都勾选上。

我当时只勾选了左侧两个,所以没有搜索到RT-Thread的drv_gpio.c内的 EXTI15_10_IRQHandler()函数定义。

后来我在此处打上断点,然后外界给入高低电平,发现可以进入到这里!一步步运行, 能进入我的中断服务程序,在中断服务程序内打断点,发现一直在里面打转出不来。

终于定位问题了。

最后的问题原因在于:

中断服务程序内一个链表头忘记初始化了,导致ISR内没出来,双向循环链表没初始化,for循环出不来了。

总结: 

1. 习惯要好。 如果要编写测试程序,哪怕只是三四句代码,最好也重新搞一个工程,或者,假设我要修改main函数,就屏蔽掉原来的main函数,重新搞一个main函数,而不是直接在main函数内部去修改。

并且最好做到屏蔽掉无关的代码,即使自己以为很有把握,但是一句话说得好:难得糊涂。一糊涂可就完事了,完蛋了。难得糊涂是不被允许的。

2. 要注重加强打断点调试,遇到相关的问题,从源头开始打断点,一步步仿真执行下去。仿真不是点击一个开始允许,和一个停止运行。

  例如我遇到的问题是STM32的基于HAL库的中断问题,那么就从对应引脚的HAL库中断服务函数处开始设置第一个断电,然后一步步进去。

  MDK的各个调试按钮、各类观察窗口要熟悉。

3. 单片机上也会遇到段错误,没有coredump咋搞? RT-Thread官网介绍的CmBacktrace可以了解一下。

.

心得小结,关于注重加强MCU下调试能力的意识的更多相关文章

  1. 痞子衡嵌入式:IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link / CMSIS-DAP)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致. 做Cortex-M内核MCU嵌入式软件开发,可用的集成开发环境( ...

  2. 痞子衡嵌入式:Keil在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link/DAPLink)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是Keil在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致. 本篇是 <IAR EWARM复位类型>.<M ...

  3. 痞子衡嵌入式:浅析IAR下调试信息输出机制之硬件UART外设

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR下调试信息输出机制之硬件UART外设. 在嵌入式世界里,输出打印信息是一种非常常用的辅助调试手段,借助打印信息,我们可以比较容易地 ...

  4. 痞子衡嵌入式:浅析IAR下调试信息输出机制之半主机(Semihosting)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR下调试信息输出机制之半主机(Semihosting). 在嵌入式世界里,输出打印信息是一种非常常用的辅助调试手段,借助打印信息,我 ...

  5. sqlserver下调试sql语句

    现在版本的sqlServer已经支持调试功能了,但是在使用的时候用到的却很少(毕竟print习惯了..) 这里做一个笔记,简单的说明一下在sqlserver下调试的方法: declare @i int ...

  6. VS2005--设置Release模式下调试

    今天初略看了下,所谓Release和Debug只是大家和编译器约定的一些生成规则而已,所以调试是无所谓Release和Debug的,只是由于生成的规则不同,可能Release的一些调试结果没Debug ...

  7. Windows下调试hadoop

    1.   本地模式 本地模式下调试hadoop:下载winutils.exe和hadoop.dll hadoop.lib等windows的hadoop依赖文件放在D:\proc\hadoop\bin目 ...

  8. python代码在IDE下调试设置命令行参数

    带命令行参数的代码在IDE下调试,需要把参数赋值,本文mark一下具体的命令行参数在代码中赋值方法. if __name__ == "__main__": sys.argv = [ ...

  9. 使用ffmepg的lib库调试,debug版本下调试无问题,但release版本会出现跑飞的现象

    如题(“使用ffmepg的lib库调试,debug版本下调试无问题,但release版本会出现跑飞的现象”). 今天使用ffmpeg进行宿放和颜色格式转换,很简单的代码,却折腾了我一天,这里说来就气啊 ...

  10. 【转】 VC++6.0 在Win7 64位下调试,Shift+F5无法退出

    Win7 64位VC++6.0调试代码无法关闭窗口解决方法 VC++6.0 在64位Windows7下调试的时候,再结束调试,程序无法退出,只能关闭VC++6.0 IDE环境. 问题描述:当我击F5开 ...

随机推荐

  1. Django 通过自定义context_processors实现自定义tag

    通过自定义context_processors实现自定义tag by:授客 QQ:1033553122 测试环境 Win7 Django 1.11 实践 步骤1 应用根目录下,新建自定义context ...

  2. 题解:P10320 勇气(Courage)

    P10320 勇气(Courage) 推导过程 本题是一道数学题,重点是如何推导出正确式子. 首先,先特判几个特殊点: 当 \(n>=2\) 且 \(x=2\) 时,是不存在解的,战斗力无论何时 ...

  3. php8.3开启jit技术

    查看是否开启:$jitEnabled = ini_get('jit.enabled'); echo "JIT Enabled: " . ($jitEnabled == '1' ? ...

  4. docker部署苍穹外卖

    首先修改配置信息和自己的docker部署信息相符:MySQL.redis.记得把MySQL数据导上去(记得数据库信息的完整) 1.通过maven下载三个jar包 2.上传,编写dockerfile,注 ...

  5. 手把手使用 SVG + CSS 实现渐变进度环效果

    效果 轨道 使用 svg 画个轨道 <svg viewBox="0 0 100 100"> <circle cx="50" cy=" ...

  6. 【转载】 传统PID算法解决不了的情况,应该怎么办?

    原文地址: http://www.51hei.com/bbs/dpj-152844-1.html --------------------------------------------------- ...

  7. 使用ChatGPT时的信息安全问题

    ChatGPT由于其在对话方面的AI性能的卓越表现已经远远超越了同类的产品,因此赢得了国际科研领域的极大重视,并且也得到了广大用户的支持,但是在人们尽情使用的时候往往忘记了关于ChatGPT的信息安全 ...

  8. SeaTunnel毕业!首个国人主导的数据集成项目成为Apache顶级项目

    采访嘉宾 | 郭炜.高俊 编辑 | Tina 北京时间 2023 年 6 月 1 日,全球最大的开源软件基金会 Apache Software Foundation(以下简称 ASF)正式宣布 Apa ...

  9. 【单调栈+倍增】[P7167 [eJOI2020 Day1] Fountain

    [单调栈+倍增][P7167 [eJOI2020 Day1] Fountain 思路 用单调栈处理每个圆盘溢出后流到的第一个位置,然后倍增优化. 代码 #include <bits/stdc++ ...

  10. Ubuntu 安装 Docker Desktop

    介绍 Docker 有两种版本:Docker Desktop 和 Docker Engine (也称作 Docker CE).Docker Desktop 是带图形界面的版本,非常适合需要在桌面环境中 ...