曾经工作中用过arm7,没有MMU,也没有用任何OS.现在回想其时的代码结构,我觉得能够叫无限循环的有限状况机.arm7不跑OS,就相当于单片机,单片机跑的肯定是无限死循环.有限状况机是因为整个代码要处理许多外部的工作,那便是大的循环里边来套小循环,以轮询的方法来查看外界的改变,然后体系作出改变,体系在有限的状况中切换.
OS的一个标识便是支撑多使命的并发.比方说linux,咱们看起来是多个进程在一起运转,实际上仍是cpu运转一下这个进程,再运转一下其他进程.这个就涉及到上下文切换以及进程调度的算法.当然我这儿说的是单核的状况,如果是SMP的话,或许有些差异.暂时也没研讨linux下的进程调度,可是经过自己写个最简略的使命调度能够了解使命调度是个什么回事.其实说到底使命调度便是那么回事.听说linux的开始版别,便是两个使命在不断的打印AB…
硬件渠道是s3c2440:
使用RTC的Tick中止,在中止处理中进行使命的调度,调度算法选用最简略的轮循.
其间中心便是中止的写法,PCB的树立和使命调度中使命仓库的保存和康复:
调度的代码参阅《ARM System Developers Guide》一书.
给出scheduler.S的代码:
[cpp]view plaincopy
- 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个静态使命,第一个使命做一个简略的算术运算,第二个使命是一个流水灯,而第三个使命是使用蜂鸣器来发生旋律.
仅贴出第三个使命的代码: