打印

OSSemPost()导致异常

[复制链接]
5007|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
runmo420|  楼主 | 2009-7-19 11:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32F103VB,移植好ucosii后,当在任务中没有调用OSSemPost()时,可以正常跑下来,但是只要一调用这个函数,程序执行到此处就进入以下异常:

而且,在汇编代码和正常的代码显示的不是同一个异常,以下是同时显示的C中的异常代码处:

不知道这个事什么原因?

相关帖子

沙发
runmo420|  楼主 | 2009-7-19 11:46 | 只看该作者

OSSemPost()导致异常

第一张图片如下:
显示的存储器管理,难道是堆栈溢出吗?
而第二张图显示的是硬件失效异常,这个不知道是什么原因呢?

使用特权

评论回复
板凳
lonely8122| | 2009-7-19 13:26 | 只看该作者

RE

感觉像是调用OSSemPost的过程中意外修改了其它全局变量,比如TCB中的元素,或者任务就绪表里的内容。可以单步调试OSSemPost这个函数,估计异常是在运行到OSSched的时候出现的。

使用特权

评论回复
地板
runmo420|  楼主 | 2009-7-19 16:43 | 只看该作者

为何不可以修改TCB中的元素

谢谢。先执行到OSSemPend()处,没有问题,然后单步,执行完其中的OS_Sched()也没有问题,而且,prio也像预期的能得到下个要执行的任务值,但是,执行到下图处,就会就如HardFaultException:
OSTCBStat和OSTCBStatPend确实是TCB中的元素,但是难道就不允许修改其值吗?(我用的是V2.86)虽然这几个值除OSTCBEventPtr在此处有必要改写之外,另外两个没必要再重写一遍了(2.52版本的就没有这两行代码)。
去掉OSTCBCur->OSTCBStat          =  OS_STAT_RDY;
    OSTCBCur->OSTCBStatPend      =  OS_STAT_PEND_OK;
这两行代码后,单步,果然不会进入异常,但是,却不能切换到所预期的那个任务,prio值也变得莫名奇妙了!有没有可能我下的代码有问题?

使用特权

评论回复
5
lonely8122| | 2009-7-19 20:28 | 只看该作者

看看是不是任务栈空间不够了

TCB中的内容最好不要在应用程序里修改,但是上面的程序是ucosii的函数,应该没问题,走到出错的那一步时看看汇编窗口的代码,看看是不是存储指令的地址范围有问题,或者堆栈空间不够。

使用特权

评论回复
6
runmo420|  楼主 | 2009-7-19 23:00 | 只看该作者

郁闷

存储空间看来是没有问题的,堆栈也不会有问题,但是,只要单步执行到OSSemPend()中的
    OSTCBCur->OSTCBStat          =  OS_STAT_RDY;    
    OSTCBCur->OSTCBStatPend      =  OS_STAT_PEND_OK;  
    OSTCBCur->OSTCBEventPtr      = (OS_EVENT  *)0;
任何一行代码,就会莫名进入MemManageException()异常,执行此行代码时的汇编如下图。更为奇怪的是,在启动代码显示的进入的异常却是HardFaultException()。分别如下两图:

使用特权

评论回复
7
runmo420|  楼主 | 2009-7-19 23:02 | 只看该作者

郁闷

使用特权

评论回复
8
lonely8122| | 2009-7-20 19:23 | 只看该作者

看汇编窗口

如果问题出在
ldr r0, [r8, #0x00]
adds r0, r0, $0x1c
就是你在七楼给出的那个图的那几条汇编指令那,可以找到引起错误的那条,看看在这条指令在执行之前所用到的寄存器都是什么值,arm7里有数据中止异常,会不会这个错误就是cortex-m3的类似数据中止异常的错误,看看是不是所访问的存储器空间有问题?

使用特权

评论回复
9
runmo420|  楼主 | 2009-7-20 22:33 | 只看该作者

查不出什么原因

(谢谢这位仁兄一直给予帮助!!)
在执行OSSemPend()中的OS_Sched()的时候,单步观察,它也能正确计算出下一个该运行的最高优先级任务的优先级,但是从OS_Sched()出来的时候,就是没有进行任务切换,而是返回到OSSemPend()中的OS_Sched()后面的那三条代码处,再单步那就出现异常了。出现异常前,r0,r7,r8这几个值感觉还是对的(如图),r0应该是OSTCBCur->OSTCBStat在RAM中的地址,好像没什么不对。

另外,要是把OSSemPend()和OSSemPost()分别替换成OSTaskSuspend()和OSTaskResume()的话,两个任务又是可以正确的切换的。这说明OS_Sched()本身事没有问题的。而且,我将OSSemPend()和OSSemPost()换成对应的Mail操作的话,居然出现一摸一样的现象!

我用的是uvision3环境(MDK),难道RVCT4.0编译器不支持ucosII?

使用特权

评论回复
10
lonely8122| | 2009-7-21 10:02 | 只看该作者

是否使用MPU(存储保护单元)了?

使用特权

评论回复
11
runmo420|  楼主 | 2009-7-21 10:31 | 只看该作者

stm32f103VB没有MPU

该型号没有MPU,从MPU 类型寄存器 MPUTR(地址:0xE000ED90)的DREGION 读出为0,是没有MPU的。

使用特权

评论回复
12
lonely8122| | 2009-7-21 11:28 | 只看该作者

hehe

实在不行把出问题的那几行注掉,改成一些别的代码,比如给几个全局变量赋值,看看是否还出问题,应该不能是编译器的问题。

使用特权

评论回复
13
runmo420|  楼主 | 2009-7-21 16:25 | 只看该作者

问题解决了!

原来是OSSemPend(OS_EVENT *pevent, INT16U timeout, INT8U *perr)中perr参数的问题。我原先是在任务里面定义了一个INT8U *perr指针变量,然后赋给OSSemPend()的,结果产生的汇编代码在*perr = OS_ERR_NONE位置处产生的指令为STRB r7,[r4,#0x00](见9楼图),此时的r4值0x00000001,所以产生了对内存的非法操作,导致异常。如果把OSSemPend()中的*perr = OS_ERR_NONE屏蔽掉,就不会有问题,说明就是这个参数不能以局部变量的形式传过来,必须存在rom中,这样定义“INT8U *pTaskErr=0”也是不行,必须先在函数外定义一个变量,然后用指正指向它才可以“INT8U err=1;INT8U *pTaskErr=&err;”
我记得以前在用arm7和ADS调试V2.52版本的时候,好像不用这样的,怎么此处会有这个问题。

使用特权

评论回复
14
runmo420|  楼主 | 2009-7-21 16:26 | 只看该作者

还是得谢谢lonely8122大侠的帮助!!感谢!!

使用特权

评论回复
15
lonely8122| | 2009-7-21 17:20 | 只看该作者

congratulations

不过你的解决办法有点绕弯子了,直接在任务里定义INT8U os_error; 然后在调用OSSemPend的时候把os_error的地址即&os_error传递到第三个参数的位置就可以了。

使用特权

评论回复
16
runmo420|  楼主 | 2009-7-21 19:31 | 只看该作者

呵呵,多谢提醒

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

142

帖子

0

粉丝