芯片解密,芯片破解,IC解密,单片机解密,MCU解密,STM解密

飞芯科技提供芯片解密,芯片破解,IC解密,单片机解密,MCU解密,STM解密逆向服务

STC8H:当 uC/OS-II 删掉 OSIntNesting单片机解密

单片机解密void OS_Sched (void) {
OS_ENTER_CRITICAL();
if (OSIntNesting == 0u) {
if (OSLockNesting == 0u) {
OS_SchedNew();
if (OSPrioHighRdy != OSPrioCur) {
OS_TASK_SW();
}
}
}
OS_EXIT_CRITICAL();
}
而像 OSSemPost 这种函数的末尾,只是普普通通地调了一下 OS_Sched ():
if (pevent->OSEventGrp != 0u) {
OS_EventTaskRdy(...);
OS_EXIT_CRITICAL();
OS_Sched();
}
把这两段代码放在一起看,妙处就出来了。
如果你在任务里调用 OSSemPost,此时 OSIntNesting 等于 0,OS_Sched () 里的 if 成立,立刻做任务切换。
如果你在中断里调用 OSSemPost,此时 OSIntNesting 大于 0,OS_Sched () 里的 if 不成立,函数直接返回,什么都不做。
那中断里 Post 之后,任务切换什么时候发生?
答案是:等你在 ISR 末尾调用 OSIntExit () 的时候。OSIntExit () 内部把 OSIntNesting 减一,只有减到 0,说明所有嵌套中断都退完了,才真正做一次任务切换。
这就是官方设计的三层分工:
第一层,API 层,比如 OSSemPost,只负责把任务放进就绪表,末尾无脑调 OS_Sched ()。
第二层,OS_Sched () 内部用 OSIntNesting 做闸门,任务态真切,中断态空转。
第三层,OSIntExit () 在最外层中断退出时统一调度。
这套设计的好处是什么?应用程序开发者根本不需要知道自己现在是在任务里还是在中断里。Post 类函数,比如 OSSemPost、OSMboxPost、OSQPost、OSFlagPost、OSxxxPendAbort、OSTimeDlyResume,天生就是双上下文通用的。
你在任务里调它没问题,你在中断里调它也没问题,内核自己判断。所以官方 API 表里只有一个 OSSemPost,没有 OSSemPost_FROM_ISR。一个函数就够了。
那 TZZ1 为什么要搞出 14 个 _FROM_ISR 函数?因为他把 OSIntNesting 删了。
删了之后,OS_Sched () 里那行 if 没有判断依据了,只能注释掉。注释掉之后,OS_Sched () 变成 "谁调都做切换"。这就完蛋了。
ISR 里调 OSSemPost,一路走到 OS_Sched (),再走到 OS_TASK_SW (),在中断上下文里直接触发任务切换,栈就坏了。
作者的补救办法,就是把所有 "会引起调度" 的函数都复制一份。
我们看 os_sem.c 源码就一目了然。普通版 OSSemPost 末尾调的是 OS_Sched ()。
新增的 OSSemPost_FROM_ISR 末尾调的是 OS_Sched_FROM_ISR ()。两个函数从入口到出口,业务逻辑逐字一样,就改了最后一行。
OS_Sched_FROM_ISR () 做的事情,也和 OS_Sched () 几乎一样,唯一区别是最后调 OS_TASK_SW_FROM_ISR ()。而 OS_TASK_SW_FROM_ISR () 这个宏,只做一件事:给 PendSV 软件标志写个 1,完事。不忙等,不切换,不开中断。
ISR 继续跑完自己的后半段,最后 RETI。等所有嵌套中断都退完,PendSV 硬件中断被响应,才在 PendSV 里真正切任务。这套设计本身是自洽的。



联系方式

地址:石家庄市新华区民族路77号华强广场D座2009
电话:0311-88816616/87087811
手机:13315190088
传真:0311-67901001
联系人:张工
网址:www.taihedz.cn
邮箱:feixindz@163.com
微信:xinpianjiemi
QQ:527263666/568069805

在线客服
热线电话

企业微信