<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > 帶信號量和搶占式的中斷調度的mini操作系統(基于8051)

帶信號量和搶占式的中斷調度的mini操作系統(基于8051)

作者: 時(shí)間:2012-08-10 來(lái)源:網(wǎng)絡(luò ) 收藏

做了7個(gè)文件,分別是
os_core.h //核心文件的參數定義
os_core.c //核心文件,包含進(jìn)程的6種操作,系統級別的操作
task_switch.h //任務(wù)切換函數的定義
task_switch.c //任務(wù)切換函數的實(shí)現,采用搶占式中斷調用(T2自動(dòng)重載)
sem.h //的定義,其實(shí)也就是3個(gè)函數,創(chuàng )建,發(fā)送一個(gè),接收信號量,在教材里面講得那么復雜,差點(diǎn)把人搞暈了,實(shí)現起來(lái)不要太簡(jiǎn)單
sem.c //信號量實(shí)現
main.c //任務(wù)以及它的操作和主函數包括在這里

//---------------------------------------------------os_core.h---------------------------------------------------------------//#ifndef __OS_CORE_H__#define __OS_CORE_H__#include reg52.h>typedef signed char int8s;typedef unsigned char int8u;typedef signed int int16s;typedef unsigned int int16u;typedef signed long int32s;typedef unsigned long int32u;//任務(wù)的5種狀態(tài)#define TASK_STATUS_CREATE 0x00#define TASK_STATUS_RDY 0x01#define TASK_STATUS_SUSPEND 0x02#define TASK_STATUS_ENDED0x04#define TASK_STATUS_SEM0x08//任務(wù)控制塊typedef struct {int8u task_status;//任務(wù)狀態(tài)int8u task_priority;//任務(wù)的優(yōu)先級int8u task_stack_top;//任務(wù)棧頂地址(保存任務(wù)棧頂的地址)int8u task_wait_tick;//任務(wù)延時(shí)等待次數}OS_TCB;#define MAX_TASKS 4//最大的任務(wù)數量//任務(wù)的優(yōu)先級從小到大一次排列,數值越小,優(yōu)先級越高#define TASK_STACK_DEPTH 17//最大任務(wù)堆棧深度(2字節程序地址+13字節寄存器數據+2字節中斷過(guò)程保存字節)#define NUM_RESISTER_PUSHED 13//人工堆棧中需要被保存的寄存器數量(這里因為是8051,所以有13字節)extern idata volatile OS_TCB os_tcb[MAX_TASKS];//任務(wù)控制塊列表extern volatile int8u task_running_id;//正在運行任務(wù)的標號extern volatile int8u os_res_list;//系統資源表,表示哪些資源是否被占用(最大為8個(gè))extern volatile int8u idata task_stack[MAX_TASKS][TASK_STACK_DEPTH];//每個(gè)任務(wù)的任務(wù)棧extern volatile int8u task_int_list;//任務(wù)中斷標記(最大為8個(gè))extern volatile int8u int_count;//進(jìn)入中斷次數extern volatile int8u os_en_cr_count;//進(jìn)入臨界區次數#define os_enter_critical() {EA=0;os_en_cr_count++;} //進(jìn)入臨界區#define os_exit_critical() {if(os_en_cr_count>0){os_en_cr_count--;if(os_en_cr_count==0){EA=1;}}}//退出臨界區//任務(wù)的六種操作void task_create(void (*task)(void),int8u task_priority);void task_delete(int8u task_id);void task_sleep();void task_wake();void task_suspend(int8u task_id);void task_resume(int8u task_id);//系統操作void os_init();//初始化系統void os_start();//開(kāi)始系統void os_delay(int8u tick);//任務(wù)延時(shí)void os_task_idle();//空任務(wù),具有最低優(yōu)先級#endif//---------------------------------------------------os_core.c---------------------------------------------------------------//#include "os_core.h"#include "task_switch.h"idata volatile OS_TCB os_tcb[MAX_TASKS];//任務(wù)控制塊列表volatile int8u task_running_id;//正在運行任務(wù)的標號volatile int8u os_res_list;//系統資源表,表示哪些資源是否被占用(最大為8個(gè))volatile int8u idata task_stack[MAX_TASKS][TASK_STACK_DEPTH];//每個(gè)任務(wù)的任務(wù)棧volatile int8u task_int_list;//任務(wù)中斷標記(最大為8個(gè))volatile int8u int_count;//進(jìn)入中斷次數volatile int8u os_en_cr_count;//進(jìn)入臨界區次數/*********************************************************************************************************任務(wù)操作*********************************************************************************************************/void task_create(void (*task)(void),int8u task_priority) {static int8u i;static int8u task_id;static int8u *stack_point;for(i=0; iMAX_TASKS;i++) {//為任務(wù)分配id和資源(注意,task的id和資源的分配是自動(dòng)的)if((os_res_list(0x01i))==0) {//如果是空的話(huà),那么會(huì )從第0個(gè)開(kāi)始分配,即第一個(gè)任務(wù)的ID號肯定是0,也就是空閑任務(wù)ID肯定是0task_id = i;os_res_list|=0x01i;break;}}os_tcb[task_id].task_status = TASK_STATUS_CREATE;//將任務(wù)置于創(chuàng  )建態(tài)//為任務(wù)分配堆??臻gstack_point = task_stack[task_id];for(i=0; iTASK_STACK_DEPTH; i++) {//先清除堆棧*(stack_point+i) = 0;}*stack_point = (int16u)task; //任務(wù)低8位給task_stack[task_id][0]stack_point++;*stack_point = (int16u)task>>8; //任務(wù)高8位給task_stack[task_id][1]stack_point += NUM_RESISTER_PUSHED; //將13個(gè)寄存器位置保存起來(lái)//為任務(wù)添加屬性os_tcb[task_id].task_stack_top = (int8u)stack_point;os_tcb[task_id].task_priority = task_priority;os_tcb[task_id].task_wait_tick = 0;os_tcb[task_id].task_status = TASK_STATUS_RDY;//將任務(wù)置于就緒態(tài)}void task_suspend(int8u task_id) { //掛起一個(gè)任務(wù)os_enter_critical();os_tcb[task_id].task_status = TASK_STATUS_SEM;//將該任務(wù)的狀態(tài)置于被掛起的狀態(tài)(由于信號量)os_exit_critical();if(task_id == task_running_id) {os_task_switch(); //調用一下任務(wù)切換,切換到其它任務(wù)}}void task_resume(int8u task_id) {os_enter_critical();if(os_res_list(0x01task_id) != 0) { //如果要恢復的任務(wù)存在os_tcb[task_id].task_status = TASK_STATUS_RDY;//將任務(wù)狀態(tài)置于就緒態(tài)os_exit_critical();if(os_tcb[task_id].task_priority  os_tcb[task_running_id].task_priority) {os_task_switch(); //調用一下任務(wù)切換,切換到優(yōu)先級更高的任務(wù)}}}/*void task_delete(int8u task_id) { //刪除一個(gè)任務(wù)os_enter_critical();if(os_res_list(0x01task_id) != 0) { //如果要刪除的任務(wù)存在os_tcb[task_id].task_status = TASK_STATUS_ENDED; //將任務(wù)狀態(tài)置于結束態(tài)os_res_list = ~(0x01task_id); //釋放任務(wù)使用的堆棧等資源os_tcb[task_id].task_wait_tick = 0;os_exit_critical();os_task_switch();}}*//*********************************************************************************************************系統操作*********************************************************************************************************/void os_init(){ //初始化系統EA = 0;//關(guān)閉總中斷ET2 = 1;//開(kāi)啟定時(shí)器2中斷T2CON = 0x00;//自動(dòng)重載//T2MOD = 0x00;RCAP2H = 0xD8; //晶振使用12MHZ,定時(shí)時(shí)間10msRCAP2L = 0xF0;os_res_list = 0x00; //資源全部置空os_en_cr_count = 0; //進(jìn)入臨階段0次task_create((os_task_idle),MAX_TASKS-1);//創(chuàng  )建空閑進(jìn)程,優(yōu)先級為MAX_TASKS-1}void os_start(){//開(kāi)始系統task_running_id = 0;//指示task_idle 為第一個(gè)運行的任務(wù)os_tcb[task_running_id].task_stack_top -= NUM_RESISTER_PUSHED;//去掉寄存器的堆棧,以免在調用的時(shí)候出現堆棧溢出SP = os_tcb[task_running_id].task_stack_top; //將空閑任務(wù)置于運行態(tài)TR2 = 1;//開(kāi)啟定時(shí)器2中斷EA = 1;//開(kāi)啟總中斷//while(1);//等待定時(shí)器中斷的調用}void os_delay(int8u tick){//任務(wù)延時(shí)os_enter_critical();os_tcb[task_running_id].task_wait_tick = tick;//設置延時(shí)節拍數os_tcb[task_running_id].task_status = TASK_STATUS_SUSPEND;//將置于處于掛起態(tài),等待延時(shí)os_exit_critical();os_task_switch();os_exit_critical();}void os_task_idle() {//空任務(wù),具有最低優(yōu)先級//static int8u i;while(1) {//os_enter_critical();//i++;//os_exit_critical();}}//---------------------------------------------------task_switch.h---------------------------------------------------------------//#ifndef __TASK_SWITCH_H__#define __TASK_SWITCH_H__#include "os_core.h"void os_task_switch();//任務(wù)調度#endif//---------------------------------------------------task_switch.c---------------------------------------------------------------//#include "task_switch.h"void os_task_switch(){//任務(wù)調度static int8u i;EA = 0;__asm PUSH ACC//保存寄存器__asm PUSH B__asm PUSH PSW__asm PUSH DPH__asm PUSH DPL__asm MOV A,R0__asm PUSH ACC__asm MOV A,R1__asm PUSH ACC__asm MOV A,R2__asm PUSH ACC__asm MOV A,R3__asm PUSH ACC__asm MOV A,R4__asm PUSH ACC__asm MOV A,R5__asm PUSH ACC__asm MOV A,R6__asm PUSH ACC__asm MOV A,R7__asm PUSH ACCos_tcb[task_running_id].task_stack_top = SP;//保存當前的堆棧指針//os_tcb[task_running_id].task_status = TASK_STATUS_RDY;//不用在這里修改當前任務(wù)的狀態(tài),已經(jīng)在任務(wù)函數中修改過(guò)了task_running_id = 0;for(i=0; iMAX_TASKS; i++) {if((os_res_list(0x01i)) != 0) {//判斷任務(wù)的資源是否還在使用,即任務(wù)是否還存在if(os_tcb[i].task_status == TASK_STATUS_RDY) {if(os_tcb[i].task_priorityos_tcb[task_running_id].task_priority) {task_running_id = i; //找到優(yōu)先級最高的,而且處于就緒狀態(tài)的任務(wù),將它置位當前要運行的任務(wù)}}}}SP = os_tcb[task_running_id].task_stack_top;__asm POP ACC//恢復寄存器__asm MOV R7,A__asm POP ACC__asm MOV R6,A__asm POP ACC__asm MOV R5,A__asm POP ACC__asm MOV R4,A__asm POP ACC__asm MOV R3,A__asm POP ACC__asm MOV R2,A__asm POP ACC__asm MOV R1,A__asm POP ACC__asm MOV R0,A__asm POP DPL__asm POP DPH__asm POP PSW__asm POP B__asm POP ACCEA = 1;}void timer2_isr(void) interrupt 5 using 1 {int8u i;EA = 0;__asm MOV A,R0__asm PUSH ACC__asm MOV A,R1__asm PUSH ACC__asm MOV A,R2__asm PUSH ACC__asm MOV A,R3__asm PUSH ACC__asm MOV A,R4__asm PUSH ACC__asm MOV A,R5__asm PUSH ACC__asm MOV A,R6__asm PUSH ACC__asm MOV A,R7__asm PUSH ACCTF2 = 0;os_tcb[task_running_id].task_stack_top = SP;task_running_id = 0;for(i=0; iMAX_TASKS; i++) {if((os_res_list(0x01i)) != 0) {//判斷任務(wù)的資源是否還在使用,即任務(wù)是否還存在if(os_tcb[i].task_status == TASK_STATUS_SUSPEND) { //只有被掛起的任務(wù)才能時(shí)間減少if(os_tcb[i].task_wait_tick != 0) {os_tcb[i].task_wait_tick--;if(os_tcb[i].task_wait_tick == 0) {os_tcb[i].task_status = TASK_STATUS_RDY;}}}if(os_tcb[i].task_status == TASK_STATUS_RDY) {if(os_tcb[i].task_priorityos_tcb[task_running_id].task_priority) {task_running_id = i; //找到優(yōu)先級最高的,而且處于就緒狀態(tài)的任務(wù),將它置位當前要運行的任務(wù)}}}}SP = os_tcb[task_running_id].task_stack_top;__asm POP ACC//恢復寄存器__asm MOV R7,A__asm POP ACC__asm MOV R6,A__asm POP ACC__asm MOV R5,A__asm POP ACC__asm MOV R4,A__asm POP ACC__asm MOV R3,A__asm POP ACC__asm MOV R2,A__asm POP ACC__asm MOV R1,A__asm POP ACC__asm MOV R0,AEA = 1;}//---------------------------------------------------sem.h---------------------------------------------------------------//#ifndef __SEM_H__#define __SEM_H__#include "os_core.h"#define MAX_SEMS 2typedef struct {int8u os_event_state;//0:不可用,1:可用int8u os_task_pend_tbl;//等待信號量的任務(wù)列表}OS_EVENT;extern volatile OS_EVENT os_sem[MAX_SEMS];void os_task_sem_pend(int8u index);void os_task_sem_post(int8u index);void os_sem_create(int8u index,int8u state);#define os_sem_clean(index) os_sem[index].os_event_state = 0#endif//---------------------------------------------------sem.c---------------------------------------------------------------//#include "sem.h"volatile OS_EVENT os_sem[MAX_SEMS];void os_task_sem_pend(int8u index) {os_enter_critical();if(index MAX_SEMS) {if(os_sem[index].os_event_state!=0) {//信號量可用os_sem[index].os_event_state--;} else {os_sem[index].os_task_pend_tbl |= (0x01task_running_id);task_suspend(task_running_id);}}os_exit_critical();}void os_task_sem_post(int8u index) {int8u i;os_enter_critical();if(indexMAX_SEMS) {for(i=0; iMAX_TASKS; i++) { //找到的i是優(yōu)先級最高且處于等待狀態(tài)的任務(wù)if((os_sem[index].os_task_pend_tbl(0x01i)) != 0) {//如果要恢復的任務(wù)存在break;}}if(i  MAX_TASKS) {os_sem[index].os_task_pend_tbl = ~(0x01i);task_resume(i);} else {os_sem[index].os_event_state++;}}os_exit_critical();}void os_sem_create(int8u index,int8u state) { //初始化信號量if(index  MAX_SEMS) {os_sem[index].os_task_pend_tbl = 0;os_sem[index].os_event_state = state;}}//---------------------------------------------------main.c---------------------------------------------------------------//#include "os_core.h"#include "task_switch.h"#include "sem.h"void task_1(void) {static int8u i;while(1) {os_task_sem_pend(1);i++;P1 = 0x01(i%8);os_delay(100);os_task_sem_post(1);}}sbit led = P2^1;void task_2(void) {while(1) {os_task_sem_pend(0);os_task_sem_pend(1);led = 1;os_delay(10);led = 0;os_delay(10);os_task_sem_post(0);os_task_sem_post(1);}}void task_3(void) {static int8u j;while(1) {os_task_sem_pend(0);j++;P3 = 0x01(j%8);os_delay(100);os_task_sem_post(0);}}int main(void) {os_init();P1=0;P2=0;P3=0;os_sem_create(0,1);os_sem_create(1,1);task_create((task_2),0);task_create((task_1),1);task_create((task_3),2);os_start();return 0;} 

總結:
在51單片機上實(shí)現是我們不常討論的話(huà)題,其實(shí)還是有蠻大的用處的,上次我寫(xiě)了一篇文章:一個(gè)簡(jiǎn)單的51單片機的實(shí)現,連接是:http://www.51hei.com/mcu/1325.html,這篇其實(shí)是對上篇文章的補充.實(shí)現更多的一些功能,希望大家多多指點(diǎn)啊.

實(shí)現了任務(wù)的互斥,使得兩個(gè)任務(wù)之間能夠互斥運行,但是不能是兩個(gè)以上,因為系統采用的是搶占式的,所以?xún)蓚€(gè)以上任務(wù)公用一個(gè)信號量,會(huì )出現優(yōu)先級較低的那個(gè)任務(wù)出現饑餓的情況。
任務(wù)的實(shí)時(shí)性是很有保障的,因為內部函數比較簡(jiǎn)單,所以不存在嵌套中斷的說(shuō)法。
計算一下程序使用的RAM,一共使用大概101字節,剩余107字節可用,感覺(jué)還不錯.
現在已經(jīng)成功地實(shí)現信號量的功能。
剩下的還有郵箱、事件、內存等等了,不過(guò)由于8051RAM空間還是小了些,如果能擴充到4KB以上,發(fā)展潛力倒是會(huì )有很大的提高,不過(guò)外置RAM肯定速度上比不了內置的。
自己動(dòng)手做51操作系統現在暫時(shí)告一段落,操作系統還是在片上資源豐富的系統上用比較好,不過(guò)STC的那個(gè)最NB的STC90C516AD擁有4KB的RAM和62KB的ROM用起來(lái)也可以的。價(jià)格也不貴,有空再去嘗試...
當任務(wù)多了的時(shí)候,任務(wù)的配置模塊也很多,RAM里面84%以上的空間都是用于任務(wù)的各種屬性的配置,包括任務(wù)堆棧和任務(wù)的互斥。
希望接下來(lái)的復習能夠更加認真?。?!現在算是了卻了我內心中的一樁心愿吧,真正實(shí)現了自己的操作系統?。。。üδ軈T乏,只有進(jìn)程調度和互斥實(shí)現)

現在我才知道鏈表的操作是多么地耗費內存.創(chuàng )建一個(gè)指針就要3個(gè)字節,如果搞個(gè)鏈表出來(lái),包括結構體,在資源不那么豐富的8051上(操作系統中),簡(jiǎn)直是宰牛用殺雞刀,完全吃不消.但是如果是AVR或者ARM等片上資源豐富的單片機,那就不存在了.

為什么手機的操作系統里面一個(gè)安裝文件動(dòng)不動(dòng)就幾MB的大小,為什么Android中的程序動(dòng)不動(dòng)就占用幾MB的內存?

這就和操作系統有很大關(guān)系了,創(chuàng )建一個(gè)任務(wù),給它定義進(jìn)程控制塊,堆棧,還要包括它的GUI,別看圖形界面特別簡(jiǎn)單,實(shí)際上采用圖形界面還是相當吃?xún)却娴?在進(jìn)程切換中,保存堆棧和一些進(jìn)程信息,這又得占用一部分內存.Android因為采用虛擬機的緣故,這虛擬機它也得吃?xún)却姘?開(kāi)個(gè)程序就有個(gè)虛擬機跟著(zhù),速度當然不如symbian了.可惜symbian內存和cpu的頻率比較低...

所以?xún)却嬲加煤拖到y任務(wù)的個(gè)數是線(xiàn)性關(guān)系的.當某個(gè)程序比較大,它占用內存越多,而且可能會(huì )頻繁地讀取內存,這樣就會(huì )造成其它程序速度變慢.這就是為什么在聽(tīng)歌的時(shí)候,上網(wǎng)有時(shí)會(huì )有點(diǎn)卡的原因之一.

系統啟動(dòng)的時(shí)候,會(huì )把程序加載進(jìn)入內存中,當需要加載的程序數量過(guò)多時(shí),自然就會(huì )比較卡.所以開(kāi)機的時(shí)候會(huì )有一段延遲.

linux操作系統文章專(zhuān)題:linux操作系統詳解(linux不再難懂)


關(guān)鍵詞: 信號量 中斷調度 操作系統

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>