GNU ARM匯編--(十四)GNU ARM匯編下做任務(wù)調(diào)度
OS的一個(gè)標(biāo)識(shí)就是支持多任務(wù)的并發(fā).比方說linux,我們看起來是多個(gè)進(jìn)程在同時(shí)運(yùn)行,實(shí)際上還是cpu運(yùn)行一下這個(gè)進(jìn)程,再運(yùn)行一下其他進(jìn)程.這個(gè)就涉及到上下文切換以及進(jìn)程調(diào)度的算法.當(dāng)然我這里說的是單核的情況,如果是SMP的話,可能有些區(qū)別.暫時(shí)也沒研究linux下的進(jìn)程調(diào)度,但是通過自己寫個(gè)最簡單的任務(wù)調(diào)度可以理解任務(wù)調(diào)度是個(gè)什么回事.其實(shí)說到底任務(wù)調(diào)度就是那么回事.據(jù)說linux的最初版本,就是兩個(gè)任務(wù)在不停的打印AB...
本文引用地址:http://m.butianyuan.cn/article/201611/321717.htm硬件平臺(tái)是s3c2440:
利用RTC的Tick中斷,在中斷處理中進(jìn)行任務(wù)的調(diào)度,調(diào)度算法采用最簡單的輪循.
其中核心就是中斷的寫法,PCB的建立和任務(wù)調(diào)度中任務(wù)堆棧的保存和恢復(fù):
調(diào)度的代碼參考《ARM System Developers Guide》一書.
給出scheduler.S的代碼:
- kernelScheduler:
- /*
- @---------------------------------------------------
- @RoundRobinScheduler
- @---------------------------------------------------
- */
- CurrentTask:
- ldrr3,=PCB_CurrentTask
- ldrr0,[r3]
- ldrr1,=PCB_Table
- ldrr1,[r1,r0,LSL#2]
- ldrr2,=PCB_PtrCurrentTask
- strr1,[r2]
- /*
- @**PCB_PtrCurrentTask-updatedwiththenewaddress
- */
- NextTask:
- addr0,r0,#1
- cmpr0,#3
- moveqr0,#0
- strr0,[r3]
- ldrr1,=PCB_Table
- ldrr1,[r1,r0,LSL#2]
- ldrr0,=PCB_PtrNextTask
- strr1,[r0]
- /*
- @**PCB_PtrCurrentTask=currentPCB
- @**PCB_PtrNextTask=nextPCB
- @**PCB_CurrentTask=newTASK_ID
- @------------------------------------------------------
- @ContextSwitch
- @------------------------------------------------------
- */
- handler_contextswitch:
- ldmfdsp!,{r0-r12,r14}
- ldrr13,=PCB_PtrCurrentTask
- ldrr13,[r13]
- subr13,r13,#60
- stmiar13,{r0-r14}^
- mrsr0,SPSR
- stmdbr13,{r0,r14}
- ldrr13,=PCB_PtrNextTask
- ldrr13,[r13]
- subr13,r13,#60
- ldmdbr13,{r0,r14}
- msrspsr_cxsf,r0
- ldmiar13,{r0-r14}^
- ldrr13,=PCB_TopOfIRQStack
- ldrr13,[r13]
- movspc,r14
- .end
一共寫了3個(gè)靜態(tài)任務(wù),第一個(gè)任務(wù)做一個(gè)簡單的算術(shù)運(yùn)算,第二個(gè)任務(wù)是一個(gè)流水燈,而第三個(gè)任務(wù)是利用蜂鳴器來產(chǎn)生旋律.
僅貼出第三個(gè)任務(wù)的代碼:
評(píng)論