开云-重新认识ARM断点机制

从头熟悉ARM断点机制 时候:2024-12-14 19:59:07 手机看文章

扫描二维码随时随地手机看文章

1. 问题描写:

2. 问题阐发:

3. 断点类型和实现道理阐发

3.1 硬件断点:

3.2 Flash断点:

3.3 软件断点:

3.4 数据断点:

4. 断点尝试证实:

4.1 IAR+I-JET 强迫利用2个Flash断点,无硬件断点:

4.2 IAR+JLINK 利用2个硬件断点+1个Flash断点:

4.3 IAR+JLINK利用2个硬件断点+2个软件断点:

4.4 IAR+JLINK 利用6个软件断点+1个硬件断点:

5. 若何预防Flash断点带来的潜伏风险:

6. 几个结论:

7. 免责声明:

1. 问题描写:

比来很久没做笔记了,时代收到的良多后台问题留言和新的粉丝存眷,感受花时候码的这些文字仍是有效户在当真浏览的,节流了很多反复劳动。仿佛每一个夏日到了,离谱撞脑门子的问题就会变多,特别一些车上的偶提问题复现难度很年夜甚是使人上头,虽然阐发进程中很花时候和精神,可是深究下去感受仍是收成颇多。比来在撑持BLE KW客户时就碰到一个很隐藏的问题,让我对ARM断点又有了倾覆性的熟悉,此处聊作记实,也为读者阐发问题供给一个思绪。

客户在统一批次的KW36板子上烧录一样的代码,都可以正常运行,但有几块板子会稀里糊涂Hard fault,并且这几块板呈现Hard fault的地址各不不异,此中一块KW36板子是在收到某个固定UDS诊断办事履行处置时呈现Hard fault,并且一旦问题呈现该板子一向能反复复现问题。借助之前的一篇旧文《KW36 MCU Hard Fault问题查找和破解方式》经由过程Attach体例在Ozone IDE(Segger 出品的一个Debug神器)中毗连上去Debug,很快查到致使Hard fault问题现场(没白瞎之前花时候研究,年夜有一番练就打狗棒法,终究碰到一条狗的喜出望外),发现每次犯错的位置都在统一行C代码,细心查抄该段代码只是个平平无奇的一个函数挪用,查抄过stack空间也确认没有溢出,那为什么会犯错呢?一样的代码为什么只有这几个板子犯错呢?

2. 问题阐发:

本开花里胡哨的问题都是埋没在最俭朴无华角落的真谛,去对照了下二者的汇编(现实上是真的没啥思绪),偶尔发此刻Attach到问题板别离履行全速运行到犯错代码行和单步运行到犯错代码行时,二者汇编居然差别。以下图右边是正常履行Attach到芯片获得的汇编代码,左侧是犯错时的汇编代码,发现出问题时汇编居然呈现了DC16和CDP2。DC16对应常量声明,明显DC16不该该在此处呈现,CDP2是协处置器数据处置指令,KW36作为一个单核芯片,必定无协处置器,更谈不上协处置器指令。

斟酌到上述的调试操作都是在Attach体例,不存在由于代码下载致使Flash内容被点窜的可能,那可能只有两个:IDE解析毛病和代码被不测点窜,明显前者是个死胡同,无从查起。在是顺着第二条路Dump芯片内二进制(左边)和原始二进制文件(右边)对照发现二者Flash确切有差别。以下图所示,F000的值被点窜成了BE00,同时处置CRC校验值也被点窜,So甚么缘由致使Flash被点窜了呢?

之前有概念说断点会法式代码做点窜,但这个二进制码的点窜若何和断点扯上关系呢?在是最先了漫长的Google/Bing/度娘/ARM各类文档里面轮流挖呀挖呀挖,直到挖出Cortex-M3权势巨子指南中提到以下一句"BKPT 指令的机械码是 0xBE00",马上名顿开,坐实了断点致使Flash内容被点窜。

可新的问题来了,断点是若何点窜到这段Flash内容的呢?甚么类型的断点会点窜Flash?断点改了Flash内容为什么不会被还原?打断点要留意甚么才能包管点窜后的Flash内容被准确还原?打软件断点是不是会点窜Flash内容?Flash断点,硬件断点和法式断点的区分?芯片明明写着撑持2个breakpoint,为什么统一个IDE共同分歧的调试东西现实上可以打出的断点个数有差别?带着一堆问号继续探访...

3. 断点类型和实现道理阐发

断点的实现道理网上有良多介绍,年夜请安思都是说在法式运行的某个处所提早设置一个住手操作,CPU运行到该位置以后就会主动暂停,此时开辟者便可以查看CPU寄放器的工作状况。可这里的”设置一个住手操作“是若何实现的呢?又意味着甚么呢?网上找到的都是基在X86的实现细节介绍,针对ARM的实现细节找了半天也都是语焉不详。阐扬绝知此事要躬行的精力(客户需要复现现场),笔者利用JLINK/I-JET+IAR在KW38 demo板子上做了一番测试,得出几个很成心思的结论,完全倾覆了之前对断点的一些熟悉,此处先抛出结论。

按照IDE和调试器的分歧,断点类型也被分为良多种包罗硬件断点、软件断点、Flash断点、数据断点、法式断点、前提断点、代码断点和Trace断点等。从实现道理上来说,一共有四年夜类:硬件断点、软件断点、数据断点和Flash断点,由于法式断点和代码断点从道理上讲可以归属在硬件断点或Flash断点(具体哪种取决在节制器撑持的硬件断点个数),前提断点属在数据断点,Trace断点是连系Trace东西的法式断点。下面别离深切介绍这四种断点的实现机制:

3.1 硬件断点:

硬件断点需要MCU内部撑持,其数目通常为有限的,具体取决在芯片厂商的实现,对应KW38、KW45、S32K1和S32K3断点撑持个数统计以下表所示。从实现道理上讲硬件断点是经由过程FPB模块来实现的,虽然这块是芯片厂商自行实现的,可是ARM架构已为其分派固定的地址区域,以下图红色方框。所以非论哪一个公司的cortex芯片,用户都可以经由过程该地址查看已设置的硬件断点地点地址。FPB供给了两个功能:断点功能和Flash地址重载, Flash地址重载是其一个高阶功能,此处用到的是其断点功能。当在法式中设置了硬件断点后,该断点处的地址就会被写入到FPB的存储区域,即E000_2000 – E000_3FFF区域,当CPU拜候该地址时,由于该地址在FPB中已注册过,硬件就会主动触发一个断点事务。

芯片型号 KW38(M0+) KW45(M33) S32K1(M4) S32K3(M7) 硬件断点个数 2个 8个 6个 8个 3.2 Flash断点:

Flash断点也就是本次问题的祸首罪魁了,也是从道理上来说最最轻易呈现问题的断点。其实现道理是在设置Flash断点时,IDE和仿真器会共同点窜节制器Flash上的内容,进一步说就是将断点处的指令点窜为断点指令0xBE00,响应地就会牵扯到对Flash的擦除和编程操作。因为Flash内容长短易掉的,所以有可能在调试器不测断开后对Flash断点处插入的断点指令还保存着,在用户复位直接运行法式可能就会致使法式没法正常运行。

今朝市场上各类传播鼓吹撑持Unlimited Breakpoint无穷断点的仿真器采取的就是这个道理,以下截图的JLINK东西。需要提出的是Flash断点不是肆意仿真器+IDE的组合都撑持的,需要IDE和仿真器共同起来,比方Ozone/Embeded Studio共同JLINK,IAR需要共同I-JET才能在断点设置时指定利用Flash断点,假如IAR共同JLINK只能选择软件断点(现实利用的其实也是Flash断点,只是标注上不带F标识表记标帜)。I-JET和JLINK在撑持Flash断点的不同首要是对Flash履行点窜的策略,比方一个Sector地址区域的多个Flash断点是履行一次仍是屡次的Flash操作,和Flash插入的断点恢复策略等,需要利用时自行体味。

3.3 软件断点:

软件断点最最先首要用在RAM中设置断点,它的实现机制是将RAM华夏有的指令替代为一个断点指令,当CPU履行到该指令以后就会主动暂停,这个时辰调试器便会将原本的指令放回本来位置。这个进程都是调试器主动实现的,对RAM的更新速度很快,所以用户一般发觉不到。但现实环境是此刻良多MCU受限在RAM巨细,法式都是寄存在Flash区域的,所以当断点年夜在硬件断点数目后,即使新的断点选成软件断点,良多时辰也会被设置为Flash断点,意味着Flash断点有的问题在利用软件断点时也需要留意,这也是为什么将软件断点的讲授放在Flash断点以后。

3.4 数据断点:

数据断点又称为前提断点,在ARM内核手册上称为watchpoint断点,是在CPU对特定地址拜候时会触发的一种断点,在芯片内部实现上需要DWT和FPB配合共同完成,在设置断点的时辰可以设置触发的前提,好比对特定地址的读拜候仍是写拜候。这类断点对追踪仓库溢出相干的问题有奇效。数据断点一样需要硬件撑持,数目一般也是有限的,如对应KW38、KW45、S32K1和S32K3数据断点撑持个数统计以下表所示。

芯片型号 KW38(M0+) KW45(M33) S32K1(M4) S32K3(M7) 数据断点个数 2个 4个 4个 4个 4. 断点尝试证实:

为了证实以上不雅点,笔者在KW38板子上做了一系列的测试以下:

4.1 IAR+I-JET 强迫利用2个Flash断点,无硬件断点:

以下截图可以看到,在汇编和memory窗口中的数据都是原始的binary文件,可是经由过程额外的JLINK同时去Attach上去读取可以看到对应0x16996地址和0x169A0物理地址的数据已被点窜为了0xBE00;此处要特殊鸣谢下IAR的Wen hao兄给的开导,确切没想到IAR Memory窗口读取的数据和汇编窗口的指令竟然都是假数据。

Note: IAR需要共同IAR公司本身的I-JET才能选择Flash断点,假如选择JLINK等其他东西只能设置软件断点;

4.2 IAR+JLINK 利用2个硬件断点+1个Flash断点:

以下图1 可以看到,两个硬件断点地址0x1FA2和0x1FA6都被注册到了FPB寄放器的0xE0002000地址了。要指出的是,此处提到的Flash断点在IAR中显示为软件断点,由于IAR中默许仅撑持利用I-JET的东西去打Flash断点,其标记就是会在红点里面显示一个F图标。所以这也就是前文说到的,对Flash运行的代码软件断点在实现上素质也仍是Flash断点。

下图2 可以看到,强迫设置为line 38和line40处为硬件断点以后,由于KW38只撑持2个硬件断点,main处这个断点就被强迫设定为了Flash断点,别离去读取0x1F98, 0x1FA2和0x1FA6地址的值,可以看到main处断点地点的地址内容被点窜为了0xBE00,0x1FA2和0x1FA6地址是正常的原始数据,存储在硬件断点地址,完全合适预期。

4.3 IAR+JLINK利用2个硬件断点+2个软件断点:

可以看到,line36,line40被强行设置为硬件断点,line38被设置为软件断点,main断点也主动被分派为了软件断点,对照0x1F98, 0x1F9A, 0x1FA2, 0x1FA6地址的内容,只有0x1F98,0x1FA2两个软件断点地址处的内容被点窜为了0xBE00,即插入BKPT指令。0x1F9A和0x1FA6两个硬件地址的内容没有被点窜,再次证实软件断点对在Flash调试的节制器,素质上就是Flash断点。

4.4 IAR+JLINK 利用6个软件断点+1个硬件断点:

由于IAR中默许优先利用硬件断点,而当前debug中设置了6个软件断点,所以main处的断点被主动分派为硬件断点。可以看到,全数6个软件断点对应地址区域的值都被点窜为了0xBE00,也就是前文提到的软件断点其实也酿成了Flash断点,main地址处内容没有产生转变,合适预期。

5. 若何预防Flash断点带来的潜伏风险

对硬件断点和数据断点来讲,他们是基在寄放器的实现,离开Debug状况没法继续生效,不会影响用户代码的脱机运行。可是Flash断点由于牵扯到点窜非易掉的Flash数据,就有风险致使法式不测被点窜没法运行,比方说忽然断电,不公道退出debug状况等。

并且对该类问题,假如断点断在main函数的主使命上还轻易不雅察到,由于代码很直不雅的没法运行,而假如断在了某个不常挪用的但又会用到的子使命的某个switch case中,就轻易埋下隐藏的bug(本案例碰到的就是这个状态)。还一种环境是实车现场阐发进程中,经常使用的一种体例就是Attach不雅察阐发问题,假如利用到Flash断点(特别是Flash运行的软件断点),且退出时没留意断根该类型断点,可能会带来新的潜伏问题。

设置完Flash断点,对忽然断电这类体例,天然是无解的,只能从头下载代码。而在debug状况时若何退出才是最优雅的体例(还原本来Flash内容)呢?笔者利用IAR+JLINK在KW38 demo板上上做了一系列测试,结论以下;

序号 测试前提(此处软件断点利用的是Flash断点) 运行成果 1 利用6个软件断点+忽然断电+上电重启: 没法运行 2 利用6个软件断点+IDE中正常stop debug后+上电重启: 没法运行 3 利用6个软件断点+在breakpoint窗口中Disable 所有Flash断点+上电重启: 没法运行 4 利用6个软件断点+在breakpoint窗口中Disable 所有Flash断点+履行一次SW reset+上电重启: 正常运行 5 IAR+JLINK+KW38 利用6个软件断点+在breakpoint串口中Delete所有Flash断点+上电重启 正常运行

总的来讲,为了不Flash断点带来的Flash点窜后没有恢复的问题,需要在退出Debug模式时,先delete失落所有断点,再去stop debug,或先在在breakpoint窗口中Disable 所有Flash断点后,再debug状况下履行一次SW reset,让Flash恢复回来,前者的错误谬误是下次debug时本来的断点都丢掉了,需要从头设置,长处是更完全。

6. 结论:

基在以上阐发可以得出几个结论:

Flash断点是会点窜到Flash内容的,并且IDE和汇编中是表现不出该转变的,比力隐藏; Flash断点致使Flash内容点窜后未恢复的问题需要特别正视,需要在退出debug前按章节5的两种法子加以处置; 软件断点对非RAM中调试来讲,IAR共同Jlink利用时素质上也是Flash断点; 不是所有的调试器都撑持Flash断点,当设置的断点个数跨越硬件断点个数,就会提醒没法设置新的断点,例如CMSIS DAP;硬件断点的撑持个数有限,会在调试时默许采取,跨越硬件断点个数后的断点JLINK默许会采取Flash断点, IJET提醒跨越上限,需要选择Flash断点,断点小红点标记带有F标记; IAR+JLINK中JLINK撑持Flash断点是JLINK仿真器和其驱动的撑持,IAR+IJET撑持Flash断点是IAR东西+I-JET硬件的撑持,和IAR+JLINK的区分是其可以直接设置Flash类型断点; 假如是Flash断点打在了主函数致使重启儿女码没法运行倒轻易排查,假如是不谨慎打在了某个不常挪用的子函数分支上,而功能测试时笼盖度假如不敷,便可能致使埋下一个潜伏的隐患; 欲知详情,请下载word文档 下载文档

上一篇:开云-Automechanika Shanghai 20周年盛会圆满收官:参展商及观众人数再创新高,彰显行业强劲增长态势、创新成果及全球合作新篇章 下一篇:开云-【VISION GUIDE