CosyOS
发表于 2023-9-21 14:26:57
本帖最后由 CosyOS 于 2023-9-21 14:35 编辑
熊仔 发表于 2023-9-21 12:59
中段发生后能执行两条指令,如果两条都不是特殊指令,那就进入中断服务程序,分析确实能打断。
讨论:是不是 ...
我认为你的分析是对的,如果有人在中断中EA = 0,那也是临时的关闭,是要保护一段代码,退出中断前会再次开启的,否则也是忘了开启(bug)。
如果他忘记了开启,当返回后你又关了中断,最后又恢复原状态(开启),还算是帮他修复了bug。
再有,Arm内核的话,无论是primask、faultmask、basepri,保存原状态和关中断也只能分成两步执行,无法一条指令完成。
如:
mrs r0, primask
cpsid i
所以说,如果EA的读和写必须要一条指令完成不可分割的话,那Arm内核就废了,可以退出市场了。
但由于51/251有JBC指令,不用白不用。
所以我看这个问题还是在于自己的选择,不是绝对的该如何如何。
tzz1983
发表于 2023-9-21 14:38:50
CosyOS 发表于 2023-9-21 14:26
我认为你的分析是对的,如果有人在中断中EA = 0,那也是临时的关闭,是要保护一段代码,退出中断前会再次 ...
两位, 你们是做什么工作的呀, 聊聊你们的工作呗, 我看你们全天在线啊
CosyOS
发表于 2023-9-21 14:44:37
还有一点,Arm内核虽然读和写中断寄存器是两条指令(可分割),但读是保存到本地的,退出临界区的时候再传参进去恢复中断的原状态。
熊仔
发表于 2023-9-21 18:13:56
CosyOS 发表于 2023-9-21 14:26
我认为你的分析是对的,如果有人在中断中EA = 0,那也是临时的关闭,是要保护一段代码,退出中断前会再次 ...
是的,我也想到了ARM的方式,都是这么干的。
只是类似STC8在中断中代码切换任务方式,中断RETI退出后是不会返回打断的位置,这个属于特殊情况。
使用场景不一样,只能说分开讨论了。
tzz1983
发表于 2023-9-22 08:23:18
熊仔 发表于 2023-9-21 18:13
是的,我也想到了ARM的方式,都是这么干的。
只是类似STC8在中断中代码切换任务方式,中断RETI退出后是 ...
熊仔: 刚才去看了一下你的代码,
//OSPrioCur = OSPrioHighRdy;
//OSTCBCur= OSTCBHighRdy;
这两句你真的不保护了呀.
你说不用保存EA, 直接EA=0 , EA=1; 这个我可以认同.
但现在为何EA=0也取消了呢, 我没搞懂, 能解释一下吗
tzz1983
发表于 2023-9-22 08:49:26
tzz1983 发表于 2023-9-22 08:23
熊仔: 刚才去看了一下你的代码,
看错了, 这里是代码切换任务, 不用解释了
熊仔
发表于 2023-9-22 08:50:14
tzz1983 发表于 2023-9-22 08:49
看错了, 这里是代码切换任务, 不用解释了
嵌套的时候代码切换任务,不需要保护,因为处于嵌套区域,本来关闭中断的。
tzz1983
发表于 2023-9-22 09:09:06
熊仔 发表于 2023-9-22 08:50
嵌套的时候代码切换任务,不需要保护,因为处于嵌套区域,本来关闭中断的。 ...
我查了一下, OS_TASK_SW(), 全OS文中只用一次, 在未退出临界区时使用的,也就是说:
1,任务级主动切换任务, 必然是代码切换模式
2,在第一张图片时, 看到先退出临界区, 再调OSCtxSw(),如果未嵌套, 此时EA已打开, 将在切换任务时缺少临界段保护
3. 应该还有其它问题 , 等会再说, 你先解释一下
熊仔
发表于 2023-9-22 10:13:00
tzz1983 发表于 2023-9-22 09:09
我查了一下, OS_TASK_SW(), 全OS文中只用一次, 在未退出临界区时使用的,也就是说:
1,任务级主动切换 ...
你看注释,嵌套的时候提前退出,退出也是EA=0
tzz1983
发表于 2023-9-22 10:45:02
熊仔 发表于 2023-9-22 10:13
你看注释,嵌套的时候提前退出,退出也是EA=0
现在假我的常规操作:
OSTimeDly(500);
此时是不是会由OS调用 OS_Sched()切换任务;(当前没有深度临界区嵌套)
然后在OS_Sched()调用 OS_ENTER_CRITICAL(); 进入临界区, (此时是一级临界区,未发生嵌套)
然后再调用 OS_TASK_SW();
在 OS_TASK_SW()中, 提前退出临界区, 使用的是OS_EXIT_CRITICAL(); 此时EA恢复到 EA=1了
然后又调用了OSCtxSw();
此时是不是开了中断, 用代码切换任务?