stm32一个强制类型转换死机bug解读

发布时间:2024-04-02  

1情景

售后 : X工,现场出大事了,今天升级的程序跑着跑着就挂了!现在整个产线都等着这个设备恢复,能安排个人过来支援下吗?


bug菌 : my god !别慌,我问一下负责的A工。

bug菌 : 喂,A工,昨天升级的程序有问题,程序卡死,售后在现场你联系一下,支援他一波,顺便把程序发送给我一份,一起看看!

A工 : 啊,还有这种事,程序没改什么呀,行,我跟售后联系一下。

经过一番折腾,发现由于程序测试不到位,导致了一个强制类型转化引发的进入异常,这里就分享给大家。

2bug演示

这是一个老项目,采用stm32F4芯片为主控,由于硬件限制而客户又不愿意花大价钱改造,所以程序架构等等都没有再大动作,由于通信上的传输和解析都是字节流,一些小的需求都只是在原来的通信架构上把4个字节拆成2个字节来用,然而这一次实在没办法没改接收数据类型,然后把一个double类型拆成了4个uint16来使用,没想到出问题了。

所以这里简单的模拟演示了一下:

wKgZomVn56OAAs5LAADmeanYIhM305.png

wKgZomVn56OADaDMAACfMRZs60g097.png

A工用一个double类型取地址,然后把地址强制转为uint64_t类型,以此类型指针取内容,当这段代码执行完程序就跳到了异常中断,导致死机。

其实这段代码对于经验丰富的人来说,一看就觉得很变扭,但是无论如何也不至于死机呀,毕竟强制类型转化大部分人拿来都是随便用。

3bug解读

当看到A工写的这一套代码,bug菌其实隐隐约约就感觉这块有些问题,但是没敢确定,毕竟整套代码也是前人留下的,全是逻辑没什么精华也没有过细研究,最后看这段代码的汇编才知道问题所在。

在之前bug菌也曾比较详细的出过一篇分析此类问题的文章,可能这一块并没有吸引到你,不过还是一句话:"出来混都是要还的!"。

其实问题就出在LDRD这个ARM汇编指令上,LDRD指令表示从指定内存地址取double word,上面图片代码中的LDRD R0,R1,[R2,#0x2EC],可以分解为下面两个ldr步骤 :

wKgaomVn56OAUv0xAAApXkusAO4757.png

在ARM汇编指令集中LDRD和STRD是一对加载和提取指令,一般都需要使用__align(8)修饰来保证数据对象进行8直接对齐,而使用#pragma pack(8)是来指定结构体成员变量相对于第一个变量的地址的偏移量的对齐方式。

__align指示编译器在 n 字节边界上对齐变量,是一个存储类修饰符,当然也可以以让2字节的对象进行4字节对齐其与8字节对齐是等价的,一定要记得是存储的起始地址为8的整数倍。

对齐可以在一定程度上提高数据提取的效率,一旦起始地址没有对齐会导致对齐错误,所以上面的double浮点类型的结构体变量没有8字节地址对齐,当进行强制类型转化并使用LDRD指令就导致未对齐故障。

3更专业点

当然对于跳转到硬件异常的故障是非常好排查的,下面这篇文章教你如何迅速的定位故障位置和故障信息 :

对于非对齐指令的执行会导致指令用法上的故障,那么Cortex芯片中相应的故障寄存器标志位会置位。

wKgZomVn56OAXsjIAAD6gtbDfa0001.png

wKgaomVn56OAFxOyAAEE4KKaqeA008.png

以上来自于Cortex技术文档,文档中也写得非常的详细。

当CPU尝试做一个未对齐的内存访问,然后就会发生此错误。特别是对于未对齐的LDM/STM/LDRD/STRD指令,所以进入异常中断以后查询芯片内部故障寄存器也是可以找到问题所在的,对于使用仿真器排查是再简单不过了,如果是离线排查就需要进行上篇文章那样打印相关日志来定位问题。

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    就放心大胆地跳转到用户固件去执行。 如果哈希值验证不通过,则系统直接重启。 对于 AES-GCM 来计算固件的验证码,也与算 SHA256 相同,都是对固件重新计算出一个值,然后......
    镓、锗等半导体关键材料出口管制 台积电回应:没有任何直接影响;此前商务部宣布对镓、锗相关物项实施出口管制,未经许可不得出口。这两种都是半导体行业中的关键材料之一,引发行业关注,台积电也回应了。台积......
     Nano非常相似,但它包含更多功能。 在本文中,我将向您展示如何使用Arduino IDE设置STM32并向您展示如何直接来自USB UART模块的程序。 STM32概述“Blue Pill......
    以一个 NUCLEO-H723ZG 的 CRC_Example 为例。它是 STM32Cube 包中的一个完善的工程,可以正常使用配套的 Pack 进行编译下载调试。我们只是使用这个工程说明如何直接......
    如何实现stm32单片机每次接上电源就进行一次重启动?;如何实现stm32单片机每次接上电源就进行一次重启动?在嵌入式系统中,单片机的重启有时是十分必要的,它可以解决一些系统启动过程中的问题、恢复......
    在于介绍keil单片机编程软件如何将hex下载进STM32如何烧写hex文件以及如何直接使用二进制数。如果你对本文内容具有兴趣,不妨继续往下阅读哦。 一、使用Keil下载Hex文件进STM32 初学......
    最大的镓采购商弗莱伯格复合材料公司此前表示客户正在疯狂囤积这些材料,整个行业非常紧张。 至于对半导体行业的影响,此前台积电及英飞凌等半导体公司都表态过,台积电称原材料镓和锗的出口限制不会对台积电的生产产生任何直接影响,将继......
    需要先注意下半部分 Main memory 主存储区 通常,我们编写的代码,是放到主存储区的起始位置(0x0800 0000)开始运行的,烧录程序时,直接将程序烧录到这里即可(KEIL软件给STM32烧录......
    的状态,来选择在复位后的启动模式。   Main Flash memory   是STM32内置的Flash,一般我们使用JTAG或者SWD模式下载程序时,就是下载到这个里面,重启后也直接......
    需要先注意下半部分 Main memory 主存储区 通常,我们编写的代码,是放到主存储区的起始位置(0x0800 0000)开始运行的,烧录程序时,直接将程序烧录到这里即可(KEIL软件给STM32......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>