久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網(wǎng) >> MCU設計實例 >> 瀏覽文章

一個簡單的51單片機操作系統(tǒng)的實現(xiàn)

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2011年11月01日   【字體:

    復習到操作系統(tǒng)這本書,在看到進程管理的時候,想起以前費了相當大的時間去做一個屬于自己的操作系統(tǒng),結果什么都沒弄出來。

趁著看到這個章節(jié),又一次地萌生了這個想法,于是網(wǎng)上各種尋找資料。發(fā)現(xiàn)現(xiàn)在的大多數(shù)操作系統(tǒng)都已經(jīng)比較完善,換而言之,就是太龐大。無法去理解,無法自己照搬原文去弄一個屬于自己的操作系統(tǒng)出來。

       機緣偶得之下,發(fā)現(xiàn)了一篇關于在單片機下面實現(xiàn)一個實時操作系統(tǒng)的文章, 即《建立一個屬于自己的AVR的RTOS》,這篇文章比起講什么操作系統(tǒng)原理、unix內核分析、linux內核分析、xx內核分析等等來說,簡單明了了很多(有興趣的同學們可以去研究一下這篇文章)。在參考這篇文章以及在51單片機下面使用匯編語言編程,以及眾多網(wǎng)上資料之后。總結地寫出了一個"在51單片機下具有延時功能占先式內核的操作系統(tǒng)“,并仿真成功,加深了我對操作系統(tǒng)這個東西的小小理解。下面附上程序代碼以及實現(xiàn)。
如果網(wǎng)頁復制代碼有錯誤,操作系統(tǒng)的完整代碼請從這里下載:http://www.zg4o1577.cn/f/12545.rar

以下是部分代碼:

#include <regx52.h>

#define MAX_TASKS 5

typedef struct os_task_control_table {
unsigned char os_task_wait_tick;
unsigned char os_task_stack_top;
}TCB;

volatile unsigned char int_count;
volatile unsigned char os_en_cr_count;
#define enter_int() EA=0;int_count++;
#define os_enter_critical() EA=0;os_en_cr_count++;
#define os_exit_critical() if(os_en_cr_count>=1){os_en_cr_count--;if(os_en_cr_count==0)EA=1;}
unsigned char code os_map_tbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};

volatile unsigned char os_task_int_tbl;
idata volatile TCB os_tcb[MAX_TASKS];
volatile unsigned char os_task_running_id;
volatile unsigned char os_task_rdy_tbl;
unsigned char idata os_task_stack[MAX_TASKS][20];

void os_init(void);
void os_task_create(unsigned char task_id ,unsigned int task_point,unsigned char stack_point);
void os_delay(unsigned char ticks);
void os_start(void);
void os_task_switch(void);
void exit_int(void);

void os_init(void) {
EA = 0;
ET2 = 1;
T2CON = 0X00;
T2MOD = 0X00;
RCAP2H = 0x0D8;
RCAP2L = 0x0F0;
os_task_rdy_tbl = 0;
os_task_int_tbl = 0xff;
int_count = 0;
os_en_cr_count = 0;
}

void os_task_create(unsigned char task_id ,unsigned int task_point,unsigned char stack_point) {
os_enter_critical();
((unsigned char idata *)stack_point)[0] = task_point;
((unsigned char idata *)stack_point)[1] = task_point>>8;
os_tcb[task_id].os_task_stack_top = stack_point+14;
os_task_rdy_tbl |= os_map_tbl[task_id];
os_tcb[task_id].os_task_wait_tick = 0;
os_exit_critical();
}

void os_delay(unsigned char ticks) {
os_enter_critical();
os_tcb[os_task_running_id].os_task_wait_tick = ticks;
os_task_rdy_tbl &= ~os_map_tbl[os_task_running_id];
os_exit_critical();
os_task_switch();
}

void os_start(void) {
os_task_running_id = 0;
os_tcb[os_task_running_id].os_task_stack_top -= 13;
EA = 1;
SP = os_tcb[os_task_running_id].os_task_stack_top;
TR2 = 1;
}

void os_task_switch(void) {
unsigned char i;
EA = 0;
os_tcb[os_task_running_id].os_task_stack_top = SP;
os_task_int_tbl &= ~os_map_tbl[os_task_running_id];
for(i=0; i<MAX_TASKS; i++) {
if(os_task_rdy_tbl&os_map_tbl[i]) {
break;
}
}
os_task_running_id = i;
SP = os_tcb[os_task_running_id].os_task_stack_top;
if(os_task_int_tbl&os_map_tbl[os_task_running_id]) {
__asm POP 7
__asm POP 6 //恢復任務寄存器
__asm POP 5
__asm POP 4
__asm POP 3
__asm POP 2
__asm POP 1
__asm POP 0
__asm POP PSW
__asm POP DPL
__asm POP DPH
__asm POP B
__asm POP ACC
}
EA = 1;
__asm RETI
}

void exit_int(void) {
unsigned char i;
SP -= 2;
if(--int_count == 0) {
os_tcb[os_task_running_id].os_task_stack_top = SP;
os_task_int_tbl |= os_map_tbl[os_task_running_id];
for(i=0; i<MAX_TASKS; i++) {
if(os_task_rdy_tbl&os_map_tbl[i]) {
break;
}
}
os_task_running_id = i;
SP = os_tcb[os_task_running_id].os_task_stack_top;
if(os_task_int_tbl&os_map_tbl[os_task_running_id]) {
__asm POP 7
__asm POP 6 //恢復任務寄存器
__asm POP 5
__asm POP 4
__asm POP 3
__asm POP 2
__asm POP 1
__asm POP 0
__asm POP PSW
__asm POP DPL
__asm POP DPH
__asm POP B
__asm POP ACC
}
EA = 1;
__asm RETI
}
__asm POP 7
__asm POP 6 //恢復任務寄存器
__asm POP 5
__asm POP 4
__asm POP 3
__asm POP 2
__asm POP 1
__asm POP 0
__asm POP PSW
__asm POP DPL
__asm POP DPH
__asm POP B
__asm POP ACC
EA=1;
__asm RETI
}

void timer2_isr(void) interrupt 5 {
unsigned char i;
TF2=0;
enter_int();
for(i=0; i<MAX_TASKS; i++) {
if(os_tcb[i].os_task_wait_tick) {
os_tcb[i].os_task_wait_tick--;
if(os_tcb[i].os_task_wait_tick == 0) {
os_task_rdy_tbl |= os_map_tbl[i];
}
}
}
exit_int();
}

void task_0(void) {
while(1) {

}
}

sbit seg2 = P2^5;
sbit seg3 = P2^6;
sbit seg4 = P2^7;

void delay_ms(unsigned int xms){
unsigned int x,y;
for(x=xms; x>0; x--)
for(y=248; y>0; y--);
}
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0};
void task_1(void) {
unsigned char gw,sw,bw;
while(1) {
bw = os_tcb[2].os_task_wait_tick/100;
sw = os_tcb[2].os_task_wait_tick%100/10;
gw = os_tcb[2].os_task_wait_tick%10;
P0 = table[bw];
seg2=0;
delay_ms(3);
seg2=1;
P0 = table[sw];
seg3=0;
delay_ms(3);
seg3=1;
P0 = table[gw];
seg4=0;
delay_ms(3);
seg4=1;
}
}

void task_2(void) {
unsigned char i;
while(1) {
i++;
P3 = 0x01<<(i%8);
os_delay(200);
}
}

void task_3(void) {
unsigned char i;
while(1) {
i++;
//P2 = 0x01<<(i%8);
os_delay(7);
}
}

void task_4(void) {
unsigned char i;
while(1) {
i++;
P1 = 0x01<<(i%8);
  os_delay(10);
}
}

void main(void) {
os_init();
os_task_create(4,(unsigned int)&task_0,(unsigned char)os_task_stack[4]);
os_task_create(3,(unsigned int)&task_1,(unsigned char)os_task_stack[3]);
os_task_create(2,(unsigned int)&task_2,(unsigned char)os_task_stack[2]);
os_task_create(1,(unsigned int)&task_3,(unsigned char)os_task_stack[1]);
os_task_create(0,(unsigned int)&task_4,(unsigned char)os_task_stack[0]);
os_start();
}

實現(xiàn)的圖片:

 
 

 

講解一下實現(xiàn)的內容:

task_0是個空循環(huán)

task_1的作用是提取task_2的等待時間,顯示在數(shù)碼管上

task_2是在P3口上的跑馬燈(2秒跑一個燈)

task_3是單純地調用任務延時

task_4在P1口上的跑馬燈(100ms跑一個燈)


程序使用定時器2計數(shù)器產(chǎn)生的中斷作為時鐘源,時鐘的節(jié)拍是10ms一次。

 

當然這個渺小的操作系統(tǒng)只實現(xiàn)了一些相當基本的功能:多任務和系統(tǒng)延時以及搶占優(yōu)先級。還有信號量、內存管理、事件、郵箱等等機制尚未實現(xiàn),但是懂了這個基礎內容之后,其它的東西,都是在上面做擴充的。

記得在一篇資料里面聽到過這個:會寫狀態(tài)機的程序員,肯定會寫操作系統(tǒng)。這句話到現(xiàn)在覺得相當正確。操作系統(tǒng)就是一個另類的狀態(tài)機,人為地干預了子程序調用和返回的過程。慶幸當年的匯編沒白學,操作系統(tǒng)需要懂得一些基本的硬件結構,匯編,C語言,當懂得這些之后,再去網(wǎng)上多搜索點相關的資料,并且自己去用代碼一行行實現(xiàn),加以時日,操作系統(tǒng)便能輕松地玩轉與手.


在此,感謝黃健昌在網(wǎng)上的發(fā)表的《 建立一個屬于自己的AVR的RTOS》,這篇文章讓我對RTOS有了一個淺顯的了解

風城少主發(fā)表的《建立一個屬于自己的51實時操作系統(tǒng)》,指導我在熟悉的51單片機上實現(xiàn)這個操作系統(tǒng)。

芯源老師的《芯源的單片機教程》為我提供了51單片機匯編及其硬件架構的深入了解。

感謝http://www.zg4o1577.cn/mcu/1111.html 這個作者的激勵與鼓勵

真誠地感謝上面提及的人,讓我能夠入門操作系統(tǒng),進而了解到什么是嵌入式操作系統(tǒng),怎么去具體實現(xiàn)。

關閉窗口

相關文章

主站蜘蛛池模板: 黄频视频 | 国产精品久久久久久久 | 中文字幕国产 | 成人在线看片 | 免费日韩av网站 | 久草福利| 亚洲精品一区二区三区蜜桃久 | 国产区精品 | 黄色三级免费 | 日韩免费一区 | 一级特黄色毛片 | 亚洲一视频 | 久久久久国产精品一区 | 99久热在线精品视频观看 | 亚洲欧美国产精品久久 | 精品国产伦一区二区三区观看说明 | 成人性视频免费网站 | 久草网在线视频 | 日韩欧美在线一区 | 亚洲综合在线网 | 欧美a在线 | 久久免费视频网 | 成人精品鲁一区一区二区 | 国产91九色 | 在线观看黄色 | 国产综合区 | 欧美日韩久 | 成人精品国产免费网站 | 国产成人一区二区三区精 | 精品国产欧美一区二区 | 视频三区| 盗摄精品av一区二区三区 | 欧美精品在线播放 | 91精品国产高清一区二区三区 | 超碰av在线 | 成人老司机 | 97久久精品午夜一区二区 | 欧美日本久久 | 三极网站 | 中文字幕久久精品 | 国产精品一区二区视频 |