搜索
bottom↓
回复: 15

keil中,按4字节对齐给函数指针赋值,跳转时会触发HardFault

[复制链接]

出0入0汤圆

发表于 2018-4-9 16:00:45 | 显示全部楼层 |阅读模式
本帖最后由 liansh2002 于 2018-4-9 16:11 编辑
  1. void A(uint32_t flag)             //此函数被定位到0x20003000地址处
  2. {
  3.     ......
  4. }

  5. main()
  6. {
  7.     p = (void(*)(uint32_t))(0x20003000 - 0);
  8.     (*p)(0x1234);
  9.     while(1)
  10.     {
  11.         ........
  12.     }
  13. }
复制代码
某函数通过分散加载的方式放在0x20003000地址(通过调试也确认函数地址正确)。调用函数时,通过函数指针方式调用。
比较奇葩的现象是,如果仿真单步执行,函数正常调用,且运行正常。如果直接连续运行,则在调用(*p)(0x1234)时进入HardFault中断。
但是,如果将跳转地址不按照4字节对齐(如0x20002FFF),则不管是连续运行还是单步运行,均正常。

另外使用p=&a;方式赋值时,也能正常运行。对比汇编,这种方式使用的汇编指令时BL.W,而直接给定地址时使用的汇编是BLX。如果原因是汇编指令的问题,仿真单步运行为什么又没问题!

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入24汤圆

发表于 2018-4-9 16:22:48 | 显示全部楼层
Thumb模式和ARM模式的原因
根据arm spec, 跳转地址最低位( lsb ) 为0表示 arm 指令;最低位为1表示thumb指令。
STM32没有ARM模式,所以不能用四字节对齐的地址
参考:https://blog.csdn.net/beyond702/article/details/51201027

出0入0汤圆

发表于 2018-4-9 16:25:25 | 显示全部楼层
你看下keil的编译map,函数地址并不是4字节对齐

出0入22汤圆

发表于 2018-4-9 16:25:51 | 显示全部楼层
20061002838 发表于 2018-4-9 16:22
Thumb模式和ARM模式的原因
根据arm spec, 跳转地址最低位( lsb ) 为0表示 arm 指令;最低位为1表示thumb指 ...

不错,又学习了一点小知识

出0入24汤圆

发表于 2018-4-9 16:45:41 | 显示全部楼层
补充一条 LZ应该用0x20003000+1这个地址
0x20002FFF这个地址歪打正着是因为那里的flash是空白的,是0xFF,被当做NOP指令处理,因此没造成任何影响。如果那个位置有其他数据,跳过去会出事

出0入0汤圆

 楼主| 发表于 2018-4-9 16:46:23 | 显示全部楼层
20061002838 发表于 2018-4-9 16:22
Thumb模式和ARM模式的原因
根据arm spec, 跳转地址最低位( lsb ) 为0表示 arm 指令;最低位为1表示thumb指 ...

感谢大佬,学习了。google了半天,都没找到关键点,来论坛一问,几分钟就解决了

出0入0汤圆

 楼主| 发表于 2018-4-9 16:49:01 | 显示全部楼层
20061002838 发表于 2018-4-9 16:45
补充一条 LZ应该用0x20003000+1这个地址
0x20002FFF这个地址歪打正着是因为那里的flash是空白的,是0xFF, ...

是的是的,因为在调试,我就试着把地址加一或者减一,减一会刚好跳转到一个空指令地方,加一正好。但是这么做自己心理没底,所以就来论坛问问

出0入0汤圆

发表于 2018-4-9 17:09:30 | 显示全部楼层
厉害大神,研究的很透彻

出0入0汤圆

发表于 2018-4-9 17:19:19 | 显示全部楼层
mark.谢谢

出0入0汤圆

发表于 2018-4-9 17:33:50 来自手机 | 显示全部楼层
呵呵,当年也遇到这样的问题。也是歪打正着的+1就解决问题。今天才知道真正的原因。

出0入0汤圆

发表于 2018-4-9 21:28:05 | 显示全部楼层
正是这样,不提还有点忘了,知识还得重复。

出0入0汤圆

发表于 2018-4-9 22:23:28 | 显示全部楼层
这样写有什么好处吗

出0入0汤圆

发表于 2018-4-10 06:44:21 来自手机 | 显示全部楼层
又学到一个小知识。

出0入0汤圆

 楼主| 发表于 2018-4-10 09:16:19 | 显示全部楼层
miaoguoqiang 发表于 2018-4-9 22:23
这样写有什么好处吗

用途是实现bootloader时,bootloader与app是两个不同的HEX文件,但是由app进入boot时,需要传递一些数据给boot,所以将boot的入口函数固定在一个地址上,app直接跳转到这个地址完成数据传递。

出0入0汤圆

发表于 2018-4-10 12:10:01 来自手机 | 显示全部楼层
参考普通boot工程就行  你这只是反过来

出0入0汤圆

发表于 2019-5-25 09:52:26 | 显示全部楼层
感谢各位大神,很有参考价值。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-22 07:02

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表