作者:赵博钧石博 | 来源:互联网 | 2023-05-18 02:24
一个关于ucos_II代码临界区的一个问题:UCOS_II在进入系统临界代码区之前要关闭中断,等到退出临界区后再打开。然后书中提出两个方法:第一种方法是:直接将OS_ENTER_CRITICA
一个关于ucos_II代码临界区的一个问题:
UCOS_II在进入系统临界代码区之前要关闭中断,等到退出临界区后再打开。然后书中提出两个方法:
第一种方法是:直接将OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()定义为处理器的关闭(CLI)和打开(STI) 中断指令。但这种方法有一个隐患,如果在关闭中断后调用UC0S_II函数,当函数返回后,中断将被打开。
第二种方法是:执行OS_ENTER_CRITICAL()是先将中断关闭的状态保存到堆栈中,然后关闭中断。与之对应的
OS_EXIT_CRITICAL()的操作是从堆栈中恢复中断状态。
关于这两个方法我有两点疑问:
关于第一种方法的疑问是:“如果在关闭中断后调用UC0S_II函数,当函数返回后,中断将被
打开。”为什么会自动打开呢?
关于第二种方法的疑问是:显然,OS_EXIT_CRITICAL()并没有开中断,那是谁呢?(我猜测也是由
OS_EXIT_CRITICAL()开的,不知对不对?),这个问题和上一个问题实际是同一个问题。
敬请有嵌入式系统开发的高手指点,顺便留下本人的E_mail:sdqdhx@china.com
6 个解决方案
我得看法,不知道你觉着如何
1)在OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()中调用UCOS函数,就有可能在OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()中间又嵌套调用了一次这两个函数,而嵌套中的OS_EXIT_CRITICAL()就会开中断啦。
2)如果你调用OS_ENTER_CRITICAL()前的中断是开放的,就会把它压到堆栈中,然后关中断。调用OS_EXIT_CRITICAL()时就又把先前的中断状态恢复,此时中断就是开放的了。
应该在OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()之间尽快完成操作,同时最好不要call系统调用,除非你能保证在所调用的系统调用里没有OS_EXIT_CRITICAL()操作。
第一种方法CLI STI 当然会开中断了.
第二种方法
#define OS_ENTER_CRITICAL() __asm PUSHFD __asm CLI
#define OS_EXIT_CRITICAL() __asm POPFD
只是恢复原来状态.