今天繼續(xù)看Erika2 OS代碼,發(fā)現(xiàn)這不是我理想中的操作系統(tǒng),因?yàn)樗鼪](méi)有類(lèi)似于delay這樣的阻塞函數(shù),最主要的是task切換居然不用給A11地址賦值。而是采用指針函數(shù)直接call地址。
讓我覺(jué)得鄙視,它主要是鑒別出最高優(yōu)先級(jí)task,在切換task函數(shù)前僅初始化了stack,所以callstack調(diào)試窗口中還能看到來(lái)龍去脈,也就是說(shuō)我理解Erika2應(yīng)該是不支持Freertos中類(lèi)似task函數(shù)中使用delay的函數(shù)設(shè)計(jì)機(jī)制進(jìn)行掛起,而只是event沒(méi)有置位,但是alarm周期時(shí)間到后,需要添加if(event==ok)來(lái)判斷是否能進(jìn)入if中的函數(shù)進(jìn)行執(zhí)行。當(dāng)然它也有優(yōu)點(diǎn),不用指針那么就符合misra,另外可以支持協(xié)作式OS。對(duì)應(yīng)周期task非時(shí)間的,stack空間可以共用。汽車(chē)行業(yè)一般也就是alarm觸發(fā)純周期任務(wù),或者再加一個(gè)event觸發(fā)的任務(wù)。種類(lèi)比較少。不想看這種保守設(shè)計(jì)了。我現(xiàn)在想想之前看到過(guò)的miniOS就是用bitmask來(lái)判斷優(yōu)先級(jí)然后通過(guò)指針函數(shù)調(diào)用對(duì)應(yīng)bit位的task,并且初始化的時(shí)候stack空間都mapping到固定地址段,就完成了miniOS,基本思路和Erika2是類(lèi)似的。
static void __NEVER_INLINE__ EE_tc_dummy_context( EE_TID tid )
{
/* Previous Context from this point is the first context to be freed */
EE_terminate_data[tid] = EE_tc_get_pcxi();
/* Task funtion call */
EE_terminate_real_th_body[tid]();
....
}
如下為task上下文切換的關(guān)鍵函數(shù)和code
EE_rq_queryfirst();/*取出最高優(yōu)先級(jí)的任務(wù)。*/
EE_th_status[rq] = RUNNING/* 將此任務(wù)設(shè)置為最高優(yōu)先級(jí) */
EE_th_next[temp] = EE_stkfirst; /* next thread入隊(duì) */
EE_std_change_context(); /*切換上下文函數(shù)*/
/* Switch Stack */
if ( tos_from != tos_new ) {
/* Save context information per Stack */
EE_tc_stack_save(tos_from);
EE_tc_active_tos = tos_new;
EE_tc_stack_restore(tos_new);
}
__INLINE__ void __ALWAYS_INLINE__ EE_CHANGE_STACK_POINTER
EE_tc_stack_restore( EE_UREG tos )
{
struct EE_TC_TOS * const p_tos = &EE_tc_system_tos[tos];
EE_ADDR const sp = p_tos->ram_tos;
EE_UREG const pcxi = p_tos->pcxi_tos;
EE_tc_set_SP(sp);
EE_tc_set_pcxi(pcxi);
}