说一下事情的经过,首先我自己移植了一份基于UCOS操作系统的代码,一直以来用的也挺好,当然使用的也是小项目,什么TCP/IP,USB之类的没有用过,最多的任务量也就用到7—8个,可最近有个项目任务量用了12个,一下子出问题了(不是堆栈溢出),现象是调用了操作系统进入临界区的代码后,然后退出调用代码,再进去观察中断仍然是开着的,最后导致系统逻辑混乱。
大家用UCOS也用得多,所以这里进行简单的修改就可以测试。
首先修改os_cpu.a.asm文件中的OS_CPU_SR_Save,OS_CPU_SR_Restore函数,修改后如下,其实就是添加了红 {MOD}字体的2条语句,意思就是在执行OS_CPU_SR_Save后监视有没有对primask操作成功,同时在进入OS_CPU_SR_Restore时监控当前的中断是否是处于屏蔽状态。
OS_CPU_SR_Save
MRS R0, PRIMASK
CPSID I
MRS R1, PRIMASK
BX LR
OS_CPU_SR_Restore
MRS R1, PRIMASK
MSR PRIMASK, R0
BX LR
在用户的任务里面先进行初始化工作,然后进行临界区的进入和退出函数调用
void Task_1(void *p_arg)
{
OS_CPU_SR cpu_sr = 0u;
(void)p_arg;
RCC_Config();
NVIC_Config();
while(1)
{
OS_ENTER_CRITICAL(); //在这里加断点,然后单步调试
OS_EXIT_CRITICAL();
OSTimeDly(1000);
}
}
5.JPG (79.09 KB, 下载次数: 0)
下载附件
2017-1-11 19:50 上传
可以看到从PRIMASK
寄存器里面读出来的值仍然是0
,说明中断并没有关闭成功,于是把自己搞蒙了。大家如何解释这个问题呢?
附件是基于KEIL的工程
stm32f103c8t6 ucos_II(v2.91).rar
(3.27 MB, 下载次数: 8)
2017-1-11 19:53 上传
点击文件名下载附件
你用仿真模式试验过了吗?
换个高版本的 MDK 吧,你的版本太 low 了啊,我已经 2 年多没用 MDK 了,2 年前用的版本就已经是 5.11 了。
我用高版本的,跑了一下你的 demo,用仿真模式,运行是正常的。
一周热门 更多>