OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7240|回复: 8
打印 上一主题 下一主题

韦东山老师的中断控制器代码BUG详解

[复制链接]

27

主题

708

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
14044
金钱
14044
注册时间
2015-11-5
在线时间
2334 小时
跳转到指定楼层
楼主
发表于 2016-4-21 03:35:19 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 FreeRTOS 于 2016-4-21 10:41 编辑

INT.rar (22.24 KB, 下载次数: 1108)

开发板:TQ2440
开发平台:Ubuntu 12.04
编译环境:arm-linux-gcc (gcc version 4.3.3)

看了韦东山老师的视频《第06课 中断控制器》后,直接用他的代码没问题,但将它的代码稍稍改动就有问题了,先贴上具体问题:

在中断函数里面屏蔽他的点灯代码,然后加上自己的LED控制代码,程序就跑飞了,下面贴上我自己的LED代码:

这么简单的LED代码也会导致程序跑飞?经验告诉我这是不可能的,接下来就开展了为期2个晚上的找BUG的游戏
为何找了2个晚上呢。。。因为我之前没试过在Linux系统下仿真跟踪代码,没啥经验,所以搞了两个晚上才知道如何使用JLINK的调试器(一直以为只能在终端里面对着命令行调试。。。)

接下来就贴出仿真的过程:
仿真跟踪一:进入中断函数时寄存器跟踪

在进入中断时跟踪了下寄存器,也就是将寄存器压栈,没发现啥问题

仿真跟踪二:LED点灯代码跟踪

跟刚进入中断函数时的LR寄存器(R14)做对比,当执行完Led_On(LED1)这句后LR寄存器的值发生了变化,也就是说因为中断函数里面又调用了Led_On()函数,发生了函数嵌套,结果直接导致了进入中断函数时发生了压栈操作!这也意味着中断返回时会有对应的出栈操作!

仿真跟踪三:中断函数返回

中断函数返回前的出栈操作,仔细观察下出栈结果可以发现,中断返回的命令是“BX LR”,而此时LR寄存器的值是0xFFFFFFFF

仿真跟踪四:返回后出现异常

从仿真跟踪三已经可以得出结论,中断返回地址不对!所以已经找出程序跑飞的原因了,原因就是中断返回地址出错跳转到了一个未定义指令的地址处
结果是引发了未定义指令异常!

找了下原因,终于发现问题出现在哪里了,原因就是我的开发板选择了从NOR FLASH启动,所以从0x00000000开始的2M空间都是NOR FLASH的空间,
而韦东山老师的启动代码从一开始就设置了各个模式下的栈顶地址为4096、3072等:

不幸的是这些地址都是NOR FLASH的范围,NOR FLASH的特性就是可以快速读取数据,但没法快速写入(必须按照NOR FLASH的时序才能写入)
因此在进入中断函数前发生的压栈操作都是无效的!因为数据压根儿就写不进4096、3072等NOR FLASH空间!既然压栈没压成功,那么中断返回时
的出栈也肯定获取错误的值了。

可是还有一个问题,为何下载韦东山老师的代码却正常运行呢?!唯一的解释就是他的代码在中断里面没有调用任何函数,因此没有发生任何函数嵌套!
既然没有任何函数嵌套,也就说进入中断前没必要将LR寄存器(返回地址)压栈!为了验证这个猜想,我又用老师的代码跟踪了一遍:
仿真跟踪五:进入中断函数EINT_Handle前LR寄存器(R14)保存了返回地址


仿真跟踪六:中断返回时LR寄存器(R14)没有相应的出栈操作(值没有发生任何变化),因而能正确返回



代码改进:
既然知道了问题出现在栈空间设置错误,那么改进就容易了,可以增加一段SDRAM的初始化代码,然后将栈空间设置到SDRAM中
但这并非最优的选择,因为S3C2440内部有4KB的SRAM,在选择NOR FLASH启动时,这4KB的SRAM被映射到0x40000000开始的4KB处
下面是本人修改后的启动代码:

将栈地址修改到SRAM

仿真跟踪七:跟踪中断压栈结果

在0x40000C00开始处已经看到成功压栈,包括LR寄存器

仿真跟踪八:跟踪中断返回前LR寄存器的值

由于调用了Led_On函数,因此LR寄存器的值发生了改变

仿真跟踪九:中断返回前成功出栈

LR寄存器成功获取到返回值,成功返回!


总结:
        至此,整个出错过程和出错解决过程已经描述完毕,或许有人会认为韦东山老师这部分代码并不算是BUG,因为S3C2440既可以从NOR  FLASH启动,也可以从NAND FLASH启动,当选择NAND FLASH启动时,CPU内部的4KB SRAM是映射到0x00000000的,上面这部分测试代码便不会受到NOR FLASH的限制。本人仍然认为代码最好还是应该作出修改,毕竟问题十分隐蔽,初学者并不擅长查找问题出错的原因。虽然接触ARM9已经3年了,但由于以前对ARM不熟悉以至于一直无法深入学习,直到近几个月才开始玩回ARM9是因为自己觉得对ARM有一定的了解,在此衷心感谢原子的STM32资料助我入门ARM。限于本人水平,文章难免有错漏之处,还望各路大神多多提点!我是@一直在跑灯,欢迎交流学习!


拿来长岛冰茶换我半晚安睡
回复

使用道具 举报

14

主题

1589

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
2622
金钱
2622
注册时间
2014-7-17
在线时间
350 小时
2#
发表于 2016-4-21 10:12:02 | 只看该作者
帮顶
回复 支持 反对

使用道具 举报

4

主题

53

帖子

0

精华

高级会员

Rank: 4

积分
527
金钱
527
注册时间
2015-12-11
在线时间
57 小时
3#
发表于 2016-5-7 00:14:35 | 只看该作者
恭喜!!!仿佛看到了一位高人即将出现!
回复 支持 反对

使用道具 举报

0

主题

32

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2016-3-16
在线时间
48 小时
4#
发表于 2016-6-16 11:51:11 | 只看该作者
回复 支持 反对

使用道具 举报

2

主题

20

帖子

0

精华

高级会员

Rank: 4

积分
604
金钱
604
注册时间
2016-1-2
在线时间
81 小时
5#
发表于 2016-7-6 00:17:16 | 只看该作者
楼主,你用的这个软件叫什么??
回复 支持 反对

使用道具 举报

27

主题

708

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
14044
金钱
14044
注册时间
2015-11-5
在线时间
2334 小时
6#
 楼主| 发表于 2016-7-6 09:19:40 | 只看该作者
xichuangxue 发表于 2016-7-6 00:17
楼主,你用的这个软件叫什么??

Linux下的JLINK调试软件
拿来长岛冰茶换我半晚安睡
回复 支持 反对

使用道具 举报

11

主题

1043

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3752
金钱
3752
注册时间
2011-5-23
在线时间
2018 小时
7#
发表于 2016-7-6 09:53:53 | 只看该作者
仿佛看到了一位高人即将出现!
回复 支持 反对

使用道具 举报

27

主题

708

帖子

0

精华

版主

Rank: 7Rank: 7Rank: 7

积分
14044
金钱
14044
注册时间
2015-11-5
在线时间
2334 小时
8#
 楼主| 发表于 2016-7-6 12:07:59 | 只看该作者
aozima 发表于 2016-7-6 09:53
仿佛看到了一位高人即将出现!

你们都别逗我了,我就跑灯的水平
拿来长岛冰茶换我半晚安睡
回复 支持 反对

使用道具 举报

2

主题

29

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5475
金钱
5475
注册时间
2013-11-10
在线时间
649 小时
9#
发表于 2016-7-27 15:36:46 | 只看该作者
如何获取  楼主“Linux下的JLINK调试软件”?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-11-7 00:06

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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