📄 azrtos.c
字号:
_asm("popm r0, r1, r2, r3, a0, a1, fb");
_asm("reit");
}
}
/* 偪傖傫偲 idle 僞僗僋偑偁傟偽丄偙偙傊偼棃側偄偼偢 */
ASSERT(FALSE);
}
/****************************************************************************
* AzkiRTOS - 屄乆偺僔僗僥儉僐乕儖張棟 (偡傋偰妱傝崬傒僗僞僢僋傪巊梡)
****************************************************************************/
ER az_sta_tsk(AzTCB* tcb, INT stacd)
{
TRACE("sta_tsk()");
/* 僞僗僋傪婲摦偡傞僔僗僥儉僐乕儖
* ----------------------------------------------------------------------
* NOTE:
* DOMANT忬懺偺僞僗僋偺TCB偼丄暋悢偺僞僗僋偐傜摨帪偵婲摦偝偊偟側偗傟偽丄
* 傢偞傢偞妱傝崬傒嬛巭偵偟偰曐岇偡傞昁梫偼側偄偼偢丅廬偭偰READY僉儏乕傊
* 憓擖偡傞弖娫偩偗曐岇偟偰偄傞丅昁梫偱偁傟偽丄懠偺晹暘傕妱傝崬傒嬛巭偲
* 偡傞丅
* ---------------------------------------------------------------------*/
if (tcb->m_state != TTS_DMT || tcb->m_initpri >= arraysizeof(az_ready))
{
ASSERT(FALSE);
return E_OBJ;
}
/* TCB撪晹傪弶婜壔偟丄READY僉儏乕傊憓擖偡傞 */
az_setup_tcb(tcb, stacd);
az_di();
az_insert_ready(tcb);
az_ei();
return E_OK;
}
void az_setup_tcb(AzTCB* tcb, INT stacd)
{
/* 僞僗僋偺僄儞僩儕娭悢傊擖傞捈慜偺僗僞僢僋忬懺傪愝掕偡傞 */
struct az_stack_context _near * usp = (struct az_stack_context*)((char _near *) tcb->m_stackarea + tcb->m_stacksize) - 1;
usp->r1 = stacd;
usp->fb = (UH) (usp + 1);
usp->pcl = (UH) tcb->m_entry;
usp->flg = 0xc0; /* U=1, I=1 懠偼 0 */
usp->pch = ((UW) tcb->m_entry >> 16) & 0x0f; /* PC忋埵4-bit 偲 IPL=0 */
/* TCB 偺巆傝偺晹暘傪弶婜壔偡傞 */
tcb->m_priority = tcb->m_initpri;
tcb->m_waitfor = 0;
tcb->m_timeout = 0;
tcb->m_wupcnt = 0;
tcb->m_state = TTS_RDY;
tcb->m_usp = (UH) usp;
/* 僄儔乕僐乕僪傪僋儕傾 */
tcb->m_errno = 0;
/* 儕儞僋傪弶婜壔偡傞 */
az_init_node(&tcb->m_mainlink);
az_init_node(&tcb->m_timelink);
}
void az_ext_tsk(void)
{
/* 帺僞僗僋傪廔椆偡傞僔僗僥儉僐乕儖 */
AzTCB* tcb = az_curtcb;
ASSERT(tcb && tcb->m_state == TTS_RUN);
TRACE("ext_tsk()");
az_di();
/* 偙偺僞僗僋偺 TCB 傪 READY 僉儏乕偐傜奜偟偰忬懺傪 DOMANT 偵曄偊傞 */
az_delete_ready(tcb);
tcb->m_state = TTS_DMT;
/* 僨傿僗僷僢僠嬛巭偺傑傑帺嶦偟偰丄巆偝傟偨僞僗僋偑恎摦偒偲傟側偔側偭偰偟傑偆偺傪杊偖 */
az_enable_dispatch();
/* 僇儗儞僩僞僗僋偑廔椆偟偨偺偱丄僨傿僗僷僢僠偑昁梫 */
az_schedule_dispatch();
az_ei();
}
ER az_ter_tsk(AzTCB* tcb)
{
/* 懠僞僗僋傪嫮惂廔椆偝偣傞僔僗僥儉僐乕儖 */
ER ercd;
TRACE("ter_tsk()");
if (!tcb)
return E_ID;
ercd = E_OBJ;
az_di();
/* 婛偵 DOMANT 忬懺偺僞僗僋傗丄帺僞僗僋傪廔椆偝偣傞偙偲偼偱偒側偄 */
if (tcb->m_state != TTS_DMT && tcb != az_curtcb)
{
/* (偁傟偽)儊僀儞儕儞僋傪奜偡(儗僨傿乕僉儏乕偲偼尷傜側偄)丅*/
if (tcb->m_mainlink.m_next)
az_unlink_node(&tcb->m_mainlink);
/* 僞僀儉傾僂僩儕儞僋傕偁傟偽奜偡(側偄偙偲傕偁傞) */
az_unlink_timeout(tcb);
/* 僞僗僋偺忬懺傪 DOMANT 偵偟偰姰椆 */
tcb->m_state = TTS_DMT;
ercd = E_OK;
}
az_ei();
return ercd;
}
ER az_dis_dsp(void)
{
/* 僨傿僗僷僢僠傪嬛巭偡傞僔僗僥儉僐乕儖 */
TRACE("dis_dsp()");
az_disable_dispatch();
return E_OK;
}
ER az_ena_dsp(void)
{
/* 僨傿僗僷僢僠傪嫋壜偡傞僔僗僥儉僐乕儖 */
TRACE("ena_dsp()");
az_enable_dispatch();
return E_OK;
}
ER az_chg_pri(AzTCB* tcb, PRI tskpri)
{
/* 僞僗僋偐傜桪愭弴埵傪曄峏偡傞僔僗僥儉僐乕儖 */
return az_change_priority(tcb, tskpri, TRUE);
}
ER ichg_pri(ID tcbid, PRI tskpri)
{
/* 妱傝崬傒僴儞僪儔偐傜桪愭弴埵傪曄峏偡傞僔僗僥儉僐乕儖 */
return az_change_priority(tcbid, tskpri, FALSE);
}
ER az_change_priority(AzTCB* tcb, PRI tskpri, BOOL bSyscall)
{
/* 僞僗僋偺桪愭弴埵傪 tskpri 偵曄峏偡傞 */
PRI oldpri;
if (tskpri < 0 || tskpri > AZ_NPRIORITIES)
return E_PAR;
if (bSyscall && tcb == TSK_SELF)
tcb = az_curtcb;
if (!tcb)
return E_ID;
TRACE("chg_pri()");
az_pushflag();
az_di();
/* tskpri == TPRI_INI 偼僞僗僋惗惉帪偺桪愭弴埵傪堄枴偡傞 */
/* 僔僗僥儉僐乕儖偺桪愭弴埵偼 1-based 偱偁傞偑丄撪晹偱偼 0-based 偱埖偆 */
if (--tskpri < 0)
tskpri = tcb->m_initpri;
oldpri = tcb->m_priority;
if (oldpri == tskpri)
{
/* 僞僗僋偺桪愭弴埵偵曄壔偑側偄応崌偱傕丄僞僗僋偼 READY 僉儏乕偺嵟屻傊堏摦偡傞 */
if (tcb->m_state == TTS_RUN || tcb->m_state == TTS_RDY)
{
if (tcb->m_mainlink.m_next != tcb->m_mainlink.m_prev)
{
/* READY僉儏乕偵偼2偮埲忋偺僞僗僋偑偁傞偨傔丄愭摢偺僞僗僋傪嵟屻旜傊堏摦偡傞偙偲偵堄枴偑偁傞 */
/* 偙偙偱偼僞僗僋偺忬懺傪曄偊側偄丅僨傿僗僷僢僠嬛巭忬懺偱偼丄愭摢偱側偔偰傕幚峴偟懕偗傞偨傔 */
az_delete_ready(tcb);
az_insert_before(&az_ready[tskpri], &tcb->m_mainlink);
/* 僉儏乕偺嵟屻傊堏摦偝偣偨偺偑僇儗儞僩僞僗僋側傜丄僨傿僗僷僢僠傪僗働僕儏乕儖偡傞 */
if (tcb == az_curtcb)
az_schedule_dispatch();
}
}
}
else /* 桪愭弴埵偑曄壔偟偨 */
{
/* 怴偟偄桪愭弴埵傪愝掕偡傞 */
tcb->m_priority = tskpri;
if (tcb->m_state == TTS_RUN || tcb->m_state == TTS_RDY)
{
/* 尰嵼偺桪愭弴埵偺 READY 僉儏乕偐傜奜偡 */
az_delete_ready(tcb);
if (tcb == az_curtcb)
{
/* 僇儗儞僩僞僗僋偺桪愭弴埵偑壓偑偭偨応崌丄僇儗儞僩僞僗僋
埲忋偺桪愭弴埵傪帩偭偨 READY 僞僗僋偑懚嵼偡傟偽丄僨傿僗
僷僢僠傪僗働僕儏乕儖偡傞 */
if (oldpri < tskpri)
{
do {
if (az_ready[oldpri].m_next != &az_ready[oldpri])
{
az_schedule_dispatch();
break;
}
} while (++oldpri <= tskpri);
}
}
else /* 懠僞僗僋 */
{
/* 懠僞僗僋偺桪愭弴埵傪曄偊偰丄偦傟偑僇儗儞僩僞僗僋傛傝傕
桪愭側傜丄僨傿僗僷僢僠傪僗働僕儏乕儖偡傞 */
if (tskpri < az_curtcb->m_priority)
az_schedule_dispatch();
}
/* 怴偟偄桪愭弴埵偺READY僉儏乕偺嵟屻傊擖傟傞 */
/* 偙偙偱偼僞僗僋偺忬懺傪曄偊側偄丅僨傿僗僷僢僠嬛巭忬懺偱偼丄愭摢偱側偔偰傕幚峴偟懕偗傞偨傔 */
az_insert_before(&az_ready[tskpri], &tcb->m_mainlink);
}
}
az_popflag();
return E_OK;
}
ER irot_rdq(PRI tskpri)
{
/* 桪愭弴埵 tskpri 偺READY僉儏乕傪夞揮偡傞僔僗僥儉僐乕儖 */
/* tskpri == TPRI_RUN (== 0) 偼丄僇儗儞僩僞僗僋偺桪愭弴偺 READY 僉儏乕偲夝庍偡傞 */
AzLink* queue;
if (tskpri < 0 || tskpri > AZ_NPRIORITIES)
return E_PAR;
az_pushflag();
az_di();
/* 桪愭弴埵偼丄API 偑 1-based丄撪晹偼 0-based */
if (--tskpri < 0)
tskpri = az_curtcb->m_priority;
queue = &az_ready[tskpri];
if (queue->m_next != queue->m_prev)
{
/* 僉儏乕偵2偮埲忋偺TCB偑偁傞側傜丄愭摢偺TCB傪嵟屻偵堏摦偝偣傞丅
偟偐偟 az_insert_ready() 偼 tcb 偺忬懺傪 READY 偵愝掕偡傞偺偱
巊傢側偄丅偡偱偵 tcb 偼 READY 偐 RUN 忬懺偱偁傞偟丄僨傿僗僷僢僠
嬛巭忬懺偱偼丄READY 僉儏乕偺愭摢偱側偔偰傕 RUN 偺傑傑幚峴傪
懕偗傞偙偲偵側傞偐傜偱偁傞丅 */
AzTCB* tcb = MAINLINK_TO_TCB(queue->m_next);
az_delete_ready(tcb);
az_insert_before(queue, &tcb->m_mainlink);
/* 夞揮偝偣偨偺偑僇儗儞僩僞僗僋側傜丄僨傿僗僷僢僠傪僗働僕儏乕儖偡傞 */
if (tcb == az_curtcb)
az_schedule_dispatch();
}
az_popflag();
return E_OK;
}
ER az_rel_wai(AzTCB* tcb)
{
/* 僞僗僋偐傜偺僔僗僥儉僐乕儖偱丄懠僞僗僋偺懸偪忬懺傪嫮惂夝彍偡傞 */
return az_release_wait(tcb, TRUE);
}
ER irel_wai(ID tcbid)
{
/* 妱傝崬傒僴儞僪儔偐傜偺僞僗僋偺懸偪忬懺傪嫮惂夝彍偡傞僔僗僥儉僐乕儖 */
return az_release_wait(tcbid, FALSE);
}
ER az_release_wait(AzTCB* tcb, BOOL bSyscall)
{
/* 僞僗僋偺懸偪忬懺傪嫮惂夝彍偡傞 */
ER ercd;
if (!tcb)
return E_ID;
az_pushflag();
az_di();
if ((bSyscall && tcb == az_curtcb) || tcb->m_state != TTS_WAI)
{
/* 懸偪忬懺偱偼側偄 */
ercd = E_OBJ;
}
else /* tcb->m_state == TTS_WAI */
{
/* 壗偐偺懸偪僉儏乕偵擖偭偰偄傟偽奜偡 */
if (tcb->m_mainlink.m_next)
az_unlink_node(&tcb->m_mainlink);
/* 僞僀儉傾僂僩偑愝掕偝傟偰偄傟偽丄夝彍偡傞 */
az_unlink_timeout(tcb);
/* 僞僗僋傪 READY 偵偟丄*/
az_insert_ready(tcb);
/* 懸偪傪敪惗偝偣偨僔僗僥儉僐乕儖偺儕僞乕儞抣傪 E_RLWAI 偵偡傞 */
az_store_result(tcb, E_RLWAI);
}
az_popflag();
return E_OK;
}
ER az_get_tid(AzTCB** p_tskid)
{
/* 偙偺僞僗僋偺 ID丄偮偐傝僇儗儞僩 TCB 傊偺億僀儞僞傪曉偡丅
僨傿僗僷僢僠儍傪屇傇傑偱偼僇儗儞僩僞僗僋(az_curtcb)偑曄壔偡傞偙偲
偼側偄偺偱丄妱傝崬傒嬛巭偵偟偰曐岇偡傞昁梫偼側偄 */
ASSERT(az_curtcb);
*p_tskid = az_curtcb;
return E_OK;
}
ER az_ref_tsk(T_RTSK* pk_rtsk, AzTCB* tcb)
{
/* 僞僗僋偐傜僞僗僋偺忬懺傪嶲徠偡傞僔僗僥儉僐乕儖 */
return az_reference_task(pk_rtsk, tcb, TRUE);
}
ER iref_tsk(T_RTSK* pk_rtsk, AzTCB* tcb)
{
/* 妱傝崬傒僴儞僪儔偐傜僞僗僋偺忬懺傪嶲徠偡傞僔僗僥儉僐乕儖 */
return az_reference_task(pk_rtsk, tcb, FALSE);
}
ER az_reference_task(T_RTSK* pk_rtsk, AzTCB* tcb, BOOL bSyscall)
{
/* 僞僗僋偺忬懺傪庢摼偡傞 */
if (!pk_rtsk)
return E_PAR;
if (tcb == TSK_SELF && bSyscall)
tcb = az_curtcb;
if (!tcb)
return E_ID;
az_pushflag();
az_di();
pk_rtsk->tskpri = tcb->m_priority + 1;
pk_rtsk->tskstat = tcb->m_state;
pk_rtsk->tskwait = tcb->m_waitfor;
/* TODO: 傕偭偲懠偵僞僗僋偺忬懺傪挷傋傞昁梫偑偁傞偲偒偼丄偙偙傊捛壛偡傞 */
az_popflag();
return E_OK;
}
ER az_tslp_tsk(TMO tmout)
{
/* 帺僞僗僋傪婲彴懸偪忬懺偵偡傞僔僗僥儉僐乕儖 */
ER ercd;
AzTCB* tcb = az_curtcb;
ASSERT(tcb && tcb->m_state == TTS_RUN);
az_di();
if (is_dispatch_disabled())
{
/* 僨傿僗僷僢僠嬛巭拞偼柊傟側偄 */
ercd = E_CTX;
}
else if (tcb->m_wupcnt > 0)
{
/* 偡偱偵婲彴僇僂儞僩偺挋嬥偑偁偭偨 */
tcb->m_wupcnt--;
ercd = E_OK;
}
else if (tmout == 0)
{
/* 億乕儕儞僌幐攕 */
ercd = E_TMOUT;
}
else /* 懸偪敪惗 */
{
/* 僞僀儉傾僂僩偑巜掕偝傟偰偄傟偽丄僞僀儅乕僉儏乕傊擖傟傞 */
if (tmout > 0)
az_link_timeout(tcb, tmout);
/* 偙偺僞僗僋偺 TCB 傪 READY 僉儏乕偐傜奜偟偰忬懺傪 WAIT 偵曄偊傞 */
az_delete_ready(tcb);
tcb->m_state = TTS_WAI;
tcb->m_waitfor = TTW_SLP;
/* 僇儗儞僩僞僗僋偑懸偪忬懺偲側偭偨偺偱丄僨傿僗僷僢僠偑昁梫 */
az_schedule_dispatch();
ercd = E_OK;
}
az_ei();
return ercd;
}
ER az_wup_tsk(AzTCB* tcb)
{
/* 僞僗僋偐傜懠偺僞僗僋傪婲彴偝偣傞僔僗僥儉僐乕儖 */
return az_wakeup_task(tcb, TRUE);
}
ER iwup_tsk(ID tskid)
{
/* 妱傝崬傒僴儞僪儔偐傜僞僗僋傪婲彴偝偣傞僔僗僥儉僐乕儖 */
return az_wakeup_task(tskid, FALSE);
}
ER az_wakeup_task(AzTCB* tcb, BOOL bSyscall)
{
/* 僞僗僋傪婲彴偝偣傞 */
ER ercd = E_OK;
az_pushflag();
az_di();
if (!tcb)
{
/* 晄惓僞僗僋 ID */
ercd = E_ID;
}
else if ((bSyscall && tcb == az_curtcb) || tcb->m_state == TTS_DMT)
{
/* DOMANT 忬懺偺僞僗僋傪婲偙偡偙偲偼偱偒側偄 */
/* 僞僗僋偐傜屇偽傟偨応崌偼丄帺僞僗僋傪巜掕偟偰婲彴梫媮傪憲傟側偄 */
ercd = E_OBJ;
}
else if (tcb->m_state != TTS_WAI || tcb->m_waitfor != TTW_SLP)
{
/* 婲彴懸偪偱側偄僞僗僋偱偼丄婲彴梫媮傪僉儏乕僀儞僌偡傞 */
if (++tcb->m_wupcnt < 0)
{
--tcb->m_wupcnt;
ercd = E_QOVR;
}
}
else /* (婲彴懸偪) */
{
/* 僞僗僋傪婲偙偡 */
az_unlink_timeout(tcb);
az_insert_ready(tcb);
}
az_popflag();
return ercd;
}
ER az_can_wup(INT* p_wupcnt, AzTCB* tcb)
{
/* 僉儏乕僀儞僌偝傟偰偄傞婲彴梫媮傪僉儍儞僙儖偡傞僔僗僥儉僐乕儖 */
ER ercd = E_OK;
az_di();
if (tcb == TSK_SELF)
tcb = az_curtcb;
if (!tcb)
ercd = E_NOEXS;
else if (tcb->m_state == TTS_DMT)
ercd = E_OBJ;
else /* tcb->m_wupcnt >= 0 */
{
*p_wupcnt = tcb->m_wupcnt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -