本帖最后由 HonestQiao 于 2022-11-29 15:55 编辑
一、遭遇重大挫折
昨天调试程序的时候,在某次下载或者调试之后,调试突然就不灵了。然后,百般尝试,皆不灵通了。换了调试器,也不灵了。
以为调试器坏了,又换了板子,最终发现,调试器是好的,板子的SWD不灵了。
不过,板子上的程序还在跑,没死呢。
调试器,测试了三个CMSIS-DAP:
- PWLink2 Lite:9块9包邮
- ESP32-C3:DFRobot板子,自制
- ESP32-C3:乐鑫官方板子,自制
测试的板子:
测试结果,3个调试器,对GD32、RA4M2都是好好的,对MM32L0136C7P就是不灵了。
对于调试工具来说,具体现象就是:
1. Windows,Keil
2. macOS,VSCode,pyocd
二、官方大佬远程急救
后来,求助官方SY大佬,大佬开腾讯会议,远程手把手进行急救。
在大佬的指点下,按住RST按键不放,再查看调试器配置,居然能够找到了:
之前刷的程序也能跑,按住RST也能找到,这说明板子没坏,可能是自己程序里面,把SWD接口给弄死了。
从官方文档可知SWD接口所使用的端口号如下:
我信誓旦旦的跟SY大佬说:我没有操作这两个端口,我就是要点灯玩玩而已。
现在,就要想办法怎么救活了。
SY大佬说,先按住RST,然后在Keil里面,点LOAD或者DEBUG后,马上松开,看看能不能成功。
反复尝试,结果如下:
1. 如果RST松手松得早了,就会提示SWD通信失败:
或者:
2. 如果松手松得晚了,就会提示:
3. 如果松得不快也不早,有可能会出现:
点Debug,也会出现类似的问题。
SY大佬说,可能存在那么一个恰到好处的松开时间,使得能够刚好赶在SWD还没有被程序给弄死的那一刹那,下载成功。
于是,我从0.1s、0.2s、0.3s,一次加0.1s,一直尝试到3秒,结果都没有成功搞定。
最终,还是没有救活,SY大佬说,寄回来吧,我找快给你寄回去。
和SY大佬断开会议后,我有反复尝试了好多次,依然不行。
最终,只好叫了一个快递小哥,上门取件。
我已经把板子包好了,盒子还是用寄来时的盒子,怎么来的,怎么回去,就等快递小哥了。
SY大佬说,"我看其他人也有类似的情况,我请marcom的同事安排一下回收问题板子的事情,都要召回,我们复现一下情况"。
我心想,是你,是你,就是你们板子有问题嘛!
怀着送佛送上西的想法,我把可能是我最后一次下载的代码,打包发给了SY大佬,好帮助调试查找问题。
然后,就是静等快递小哥上门了。
随手拿了一本《哲学起步》学习学习:
三、生与死只在一线之间
几乎就是先后脚的顺序,SY老大再次打来电话,随之快递小哥也打来电话说马上上门。
SY老大知道情况紧急,让我少废话,马上试一试。我心想,这死马还能当做活马医?
但大佬就是大佬,我照着做就是了。
大佬说,快照跟杜邦线,把PH0和GND连起来,再不按RST和按RST,分别测试。
哈哈,不灵,就是不灵。
大佬又说,那赶紧把PH0和VDD连起来,再不按RST和按RST,分别测试。
天灵灵地灵灵,这次,真灵了,调试器里面,总算识别出来:
能下载,那就赶紧LOAD试试,结果还是出错:
SY大佬说,下载完成后,把PH0和VDD断开,重启。
重启后,再次烧录,一切恢复正常:
久违的OK,终于回来了。
此时,门铃,响了,快递小哥,来了。赶紧给快递小哥赔不是,小哥恹恹的走了。
我赶紧把调试器接到macOS电脑上,也下载成功:
赶紧在沟通群里同步,其他两位出现类似问题的同学,也救活了。
四、复盘
最终确认,我的程序有问题,我信誓旦旦说没有问题的程序有问题。
1. 为了能够使用所有的KEY,我偷了个懒,用数组定义:
2. 但我发现GPIOA、GPIOB、GPIOC、GPIOD这些,是一个struct指针
于是,我把group和pin分开定义:
3. 定义调整,代码没修改完全:
就是这样的代码,最终导致SWD接口出现了问题。
正确的代码如下:
把板子救活后,使用错误的代码,立马弄死板子SWD。
把板子救活后,使用正确的代码,一切正常进行。
五、结论:
经过反复确认,要救活板子,这么简单就行:
1. PH0接VDD:
PH0接VDD,就不会从flash启动了。
2. 接上调试器:
3. 按一下RST,再去Keil打开gpio_basic,然后在调试器配置中检查,确保找到设备:
4. 编译并下载:
出现上述错误不用怕,说明能够成功下载了。
5. 断开PH0和VDD,按一次RST,然后重新下载:
这次没有任何错误提示了,说明好事来了。
6. 再按一次RST,灯亮,板子好了:
如果要玩死板子,那么也很简单:
板子上,SWD接口,SWDIO、SWCLK用的是PA13、PA14:
只要你的代码,能够把PA13、PA14给占用了,或者是因为程序问题,把这两给弄了,保管下载后,SWD出问题:
/*!
* @addtogroup GPIO_PIN
* [url=home.php?mod=space&uid=247401]@brief[/url] GPIO pin mask codes.
* @{
*/
#define GPIO_PIN_0 (0x0001u) /*!< Pin 0 selected. */
#define GPIO_PIN_1 (0x0002u) /*!< Pin 1 selected. */
#define GPIO_PIN_2 (0x0004u) /*!< Pin 2 selected. */
#define GPIO_PIN_3 (0x0008u) /*!< Pin 3 selected. */
#define GPIO_PIN_4 (0x0010u) /*!< Pin 4 selected. */
#define GPIO_PIN_5 (0x0020u) /*!< Pin 5 selected. */
#define GPIO_PIN_6 (0x0040u) /*!< Pin 6 selected. */
#define GPIO_PIN_7 (0x0080u) /*!< Pin 7 selected. */
#define GPIO_PIN_8 (0x0100u) /*!< Pin 8 selected. */
#define GPIO_PIN_9 (0x0200u) /*!< Pin 9 selected. */
#define GPIO_PIN_10 (0x0400u) /*!< Pin 10 selected. */
#define GPIO_PIN_11 (0x0800u) /*!< Pin 11 selected. */
#define GPIO_PIN_12 (0x1000u) /*!< Pin 12 selected. */
#define GPIO_PIN_13 (0x2000u) /*!< Pin 13 selected. */
#define GPIO_PIN_14 (0x4000u) /*!< Pin 14 selected. */
#define GPIO_PIN_15 (0x8000u) /*!< Pin 15 selected. */
#define GPIO_PINS_ALL (0xFFFFu) /*!< All pins selected. */
/*!
* @}
*/
在尝试弄死板子,又救活板子的过程中,我曾经又一次,没有接PHP0和VDD,但先按住RST,再按LOAD,然后恰到好处的松开RST,出现了如下救活前兆的情况:
然后,要达到这种化腐朽为神奇的效果,需要按LOAD和松开RST之间,达到一个完美的时间间隔,才能触发。
但是,我一直没有再次复现这种神奇手法。
|