搜索
bottom↓
回复: 107

一个简单的51单片机操作系统的实现

  [复制链接]

出0入0汤圆

发表于 2012-2-7 21:57:38 | 显示全部楼层 |阅读模式
复习到操作系统这本书,在看到进程管理的时候,想起以前费了相当大的时间去做一个属于自己的操作系统,结果什么都没弄出来。

趁着看到这个章节,又一次地萌生了这个想法,于是网上各种寻找资料。发现现在的大多数操作系统都已经比较完善,换而言之,就是太庞大。无法去理解,无法自己照搬原文去弄一个属于自己的操作系统出来。

       机缘偶得之下,发现了一篇关于在单片机下面实现一个实时操作系统的文章, 即《建立一个属于自己的AVR的RTOS》,这篇文章比起讲什么操作系统原理、unix内核分析、linux内核分析、xx内核分析等等来说,简单明了了很多(有兴趣的同学们可以去研究一下这篇文章)。在参考这篇文章以及在51单片机下面使用汇编语言编程,以及众多网上资料之后。总结地写出了一个"在51单片机下具有延时功能占先式内核的操作系统“,并仿真成功,加深了我对操作系统这个东西的小小理解。下面附上程序代码以及实现。
如果网页复制代码有错误,操作系统的完整代码请从这里下载:http://www.51hei.com/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) {
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) {
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.os_task_wait_tick) {
os_tcb.os_task_wait_tick--;
if(os_tcb.os_task_wait_tick == 0) {
os_task_rdy_tbl |= os_map_tbl;
}
}
}
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();
}
实现的图片:






讲解一下实现的内容:

task_0是个空循环

task_1的作用是提取task_2的等待时间,显示在数码管上

task_2是在P3口上的跑马灯(2秒跑一个灯)

task_3是单纯地调用任务延时

task_4在P1口上的跑马灯(100ms跑一个灯)


程序使用定时器2计数器产生的中断作为时钟源,时钟的节拍是10ms一次。



当然这个渺小的操作系统只实现了一些相当基本的功能:多任务和系统延时以及抢占优先级。还有信号量、内存管理、事件、邮箱等等机制尚未实现,但是懂了这个基础内容之后,其它的东西,都是在上面做扩充的。

记得在一篇资料里面听到过这个:会写状态机的程序员,肯定会写操作系统。这句话到现在觉得相当正确。操作系统就是一个另类的状态机,人为地干预了子程序调用和返回的过程。庆幸当年的汇编没白学,操作系统需要懂得一些基本的硬件结构,汇编,C语言,当懂得这些之后,再去网上多搜索点相关的资料,并且自己去用代码一行行实现,加以时日,操作系统便能轻松地玩转与手.


在此,感谢黄健昌在网上的发表的《 建立一个属于自己的AVR的RTOS》,这篇文章让我对RTOS有了一个浅显的了解

风城少主发表的《建立一个属于自己的51实时操作系统》,指导我在熟悉的51单片机上实现这个操作系统。

芯源老师的《芯源的单片机教程》为我提供了51单片机汇编及其硬件架构的深入了解。
感谢http://www.51hei.com/mcu/1111.html&#160;这个作者的激励与鼓励
真诚地感谢上面提及的人,让我能够入门操作系统,进而了解到什么是嵌入式操作系统,怎么去具体实现。

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2012-2-7 22:18:04 | 显示全部楼层
一篇好文章,复制以后慢慢学习,thank you lz

出0入0汤圆

发表于 2012-2-7 22:19:58 | 显示全部楼层
楼主怎样弄出外网链接来的?感兴趣~

出0入0汤圆

发表于 2012-2-7 22:24:43 | 显示全部楼层
很强大

出0入0汤圆

发表于 2012-2-7 22:26:13 | 显示全部楼层
d

出0入0汤圆

发表于 2012-2-7 22:39:15 | 显示全部楼层
很不错

出0入0汤圆

发表于 2012-2-7 23:08:40 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-8 00:02:14 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2012-2-8 00:16:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-8 08:12:41 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-8 08:32:37 | 显示全部楼层
学习啦 感谢楼主 一直想学习操作系统 晚点结束裸奔的程序

出0入0汤圆

发表于 2012-2-8 10:07:10 | 显示全部楼层
mark、 留用

出0入0汤圆

发表于 2012-2-8 11:00:48 | 显示全部楼层
顶!

出0入0汤圆

发表于 2012-2-8 11:21:52 | 显示全部楼层
收下了,感謝分享!

出0入0汤圆

发表于 2012-2-8 19:57:28 | 显示全部楼层
好文,支持

出0入0汤圆

发表于 2012-2-8 21:30:54 | 显示全部楼层
good

出0入0汤圆

发表于 2012-2-8 21:34:14 | 显示全部楼层
标记

出0入0汤圆

发表于 2012-2-8 22:11:40 | 显示全部楼层
回复【楼主位】heicad
-----------------------------------------------------------------------

牛人太多了···

出0入0汤圆

发表于 2012-2-9 09:59:07 | 显示全部楼层
楼主真的很厉害,学习一下,谢谢1

出0入0汤圆

发表于 2012-2-9 12:13:56 | 显示全部楼层
楼主好厉害啊,不知道有没有电子密码锁的C程序呢?

出0入0汤圆

发表于 2012-2-11 19:02:37 | 显示全部楼层
“操作系统需要懂得一些基本的硬件结构,汇编,C语言,当懂得这些之后,再去网上多搜索点相关的资料,并且自己去用代码一行行实现,加以时日,操作系统便能轻松地玩转与手.”

是啊,学习。。

出0入0汤圆

发表于 2012-2-27 19:03:14 | 显示全部楼层
很好啊,这是一篇很值得学习的文章。

出0入0汤圆

发表于 2012-4-5 18:04:29 | 显示全部楼层
太厉害了,楼主,以前就有想过能不能再单片机上运行一个操作系统,强力支持啊
头像被屏蔽

出0入0汤圆

发表于 2012-4-24 13:03:57 | 显示全部楼层
cool !

出0入0汤圆

发表于 2012-4-24 14:10:55 | 显示全部楼层
MARK

出0入0汤圆

发表于 2012-4-24 21:47:28 | 显示全部楼层
值得学习……

出0入0汤圆

发表于 2012-4-24 22:06:54 | 显示全部楼层
先mark!

出0入0汤圆

发表于 2012-4-25 12:05:37 | 显示全部楼层
必须的markkk!

出0入0汤圆

发表于 2012-4-30 01:48:45 | 显示全部楼层
本帖最后由 Pony279 于 2012-4-30 01:50 编辑

通篇没有提到变量的覆盖和函数的重入问题。。。
看写法应该是在keil下编译的,
任务再写复杂点,估计这个系统就挂了。

出0入0汤圆

发表于 2012-4-30 13:15:52 | 显示全部楼层
mark,以前怎没看到

出0入0汤圆

发表于 2012-4-30 13:39:57 | 显示全部楼层
跟small rtos for 51很像,

出0入0汤圆

发表于 2012-4-30 14:07:24 | 显示全部楼层
顶一个!

出0入0汤圆

发表于 2012-4-30 15:06:17 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-5-4 15:46:54 | 显示全部楼层
不错,mark~

出0入0汤圆

发表于 2012-5-4 16:05:32 | 显示全部楼层
先mask一个

出0入0汤圆

发表于 2012-5-5 09:25:17 | 显示全部楼层
蛮厉害的 呵呵

出0入0汤圆

发表于 2012-5-5 10:33:33 | 显示全部楼层
一直很想做自己的系统,榜样啊

出0入0汤圆

发表于 2012-5-5 11:16:51 | 显示全部楼层
好复杂啊,挺厉害的啊

出0入0汤圆

发表于 2012-5-5 11:18:04 | 显示全部楼层
谢谢分享

出0入0汤圆

发表于 2012-5-5 13:20:45 | 显示全部楼层
mark,学习下

出0入0汤圆

发表于 2012-5-5 19:34:30 | 显示全部楼层
谢谢楼主分享

出0入0汤圆

发表于 2012-5-6 01:35:23 | 显示全部楼层
楼主,麻烦上传一下《建立一个属于自己的51实时操作系统》,网上下不了,谢谢!

出0入0汤圆

发表于 2012-5-17 14:12:09 | 显示全部楼层
楼主或者其他大侠能不能给个函数级的解释和原理的说明啊。

出0入0汤圆

发表于 2012-5-17 14:31:13 | 显示全部楼层
不错,有空学习

出0入0汤圆

发表于 2012-5-17 14:36:16 | 显示全部楼层
这个值得学习,下来慢慢啃,多谢分享!

出0入0汤圆

发表于 2012-5-17 16:58:33 | 显示全部楼层
呵呵,现在还没学到那种程度,mark以后用

出0入0汤圆

发表于 2012-5-17 18:51:03 | 显示全部楼层
学习学习!

出0入0汤圆

发表于 2012-5-17 20:06:19 | 显示全部楼层
支持OS ! 一直裸奔中!

出0入0汤圆

发表于 2012-5-20 10:35:52 | 显示全部楼层
操作系统,还有外链,肿么搞出来的

出0入0汤圆

发表于 2012-5-25 14:17:56 | 显示全部楼层
没用过、更没写过基于单片机的操作系统,学习一下

出0入0汤圆

发表于 2012-5-25 14:41:15 | 显示全部楼层
新手 学习中 感谢lz

出0入0汤圆

发表于 2012-5-26 09:52:59 | 显示全部楼层
这个要好好学习下……

出0入0汤圆

发表于 2012-5-26 18:57:20 | 显示全部楼层
虽然不用51,还是要顶

出0入0汤圆

发表于 2012-5-27 12:12:44 | 显示全部楼层
mark一下咯

出0入0汤圆

发表于 2012-6-1 10:46:55 | 显示全部楼层
make 学习

出0入0汤圆

发表于 2012-6-14 17:55:05 | 显示全部楼层
mark一下咯

出0入0汤圆

发表于 2012-6-14 19:34:17 | 显示全部楼层
还没又想到这个,留下学学

出0入0汤圆

发表于 2012-6-15 07:13:30 | 显示全部楼层
先收藏,以后学

出0入0汤圆

发表于 2012-6-15 07:57:43 | 显示全部楼层
make 学习

出0入0汤圆

发表于 2012-10-17 18:38:49 | 显示全部楼层
MARK

出0入0汤圆

发表于 2013-11-26 13:37:28 | 显示全部楼层
好东西,先收藏了

出0入0汤圆

发表于 2013-11-28 17:23:11 来自手机 | 显示全部楼层
学习一下                       

出0入0汤圆

发表于 2014-1-31 18:36:51 | 显示全部楼层
值得学习

出0入0汤圆

发表于 2014-1-31 19:36:57 来自手机 | 显示全部楼层
标记,现在8位机RAM都很丰富了,操作系统有意义了

出0入0汤圆

发表于 2014-2-1 17:36:34 | 显示全部楼层
谢谢了,值得用心学习下~

出0入54汤圆

发表于 2014-2-8 10:42:22 | 显示全部楼层
好东西 值得学习一下

出0入0汤圆

发表于 2014-2-8 11:42:52 | 显示全部楼层
好文章,收藏了

出0入0汤圆

发表于 2014-2-8 12:28:00 | 显示全部楼层
  好文收藏了

出0入0汤圆

发表于 2014-2-8 15:33:46 | 显示全部楼层
好文果断藏了啊

出0入0汤圆

发表于 2014-2-9 15:14:23 | 显示全部楼层
下好程序及教材慢慢学习。

出0入0汤圆

发表于 2014-2-9 20:34:56 | 显示全部楼层
先标记下,然后开始学习学习!

出0入0汤圆

发表于 2014-2-14 12:08:49 | 显示全部楼层
赞一个,,,,,,

出0入0汤圆

发表于 2014-2-15 23:39:05 | 显示全部楼层
一篇好文章,复制以后慢慢学习,thank you lz

出0入0汤圆

发表于 2014-2-28 20:05:16 | 显示全部楼层
很好,谢谢楼主,

出0入0汤圆

发表于 2014-2-28 20:28:52 | 显示全部楼层
谢谢楼主

出0入0汤圆

发表于 2014-9-13 15:10:27 | 显示全部楼层
真的是谢谢楼主了

出0入0汤圆

发表于 2014-9-13 15:10:47 | 显示全部楼层
真的是谢谢楼主了,好好研究

出0入0汤圆

发表于 2014-9-13 15:54:19 | 显示全部楼层
真的是谢谢楼主了,好好研究

出0入0汤圆

发表于 2014-9-13 16:07:17 | 显示全部楼层
看看,学习一下

出0入0汤圆

发表于 2014-9-13 16:34:25 | 显示全部楼层
一篇好文章,得好好学习

出0入10汤圆

发表于 2014-9-13 16:44:22 | 显示全部楼层
好强大。。。

出0入0汤圆

发表于 2014-9-13 17:58:54 | 显示全部楼层
51简单操作系统,mark

出0入0汤圆

发表于 2014-9-13 18:32:44 | 显示全部楼层
研究研究                                    

出0入0汤圆

发表于 2014-9-13 18:46:21 | 显示全部楼层
51的操作系统,mark!

出0入0汤圆

发表于 2014-9-13 19:21:47 | 显示全部楼层
学习学习。。。。。

出0入0汤圆

发表于 2014-9-29 10:03:49 | 显示全部楼层
好东西,准备学习单片机的操作系统

出0入0汤圆

发表于 2014-9-29 10:23:12 | 显示全部楼层
很强大,多谢分享

出0入0汤圆

发表于 2014-9-29 12:25:06 | 显示全部楼层
好好学习下

出0入0汤圆

发表于 2014-9-29 12:29:47 | 显示全部楼层
mark            

出0入0汤圆

发表于 2014-12-12 00:13:47 | 显示全部楼层
非常感谢 !玩玩看。。。。。。。。。。。。。

出0入0汤圆

发表于 2014-12-12 09:08:37 | 显示全部楼层
好文章,果断学习了

出0入0汤圆

发表于 2014-12-12 10:43:43 | 显示全部楼层
资料不错                        

出50入0汤圆

发表于 2014-12-18 23:32:48 | 显示全部楼层
果断收藏

出0入0汤圆

发表于 2014-12-19 09:17:00 | 显示全部楼层
其实学习ucos就可以很好的理解操作系统,没必要自己写一个更小的,也没有实际应用的意义。如果只是想了解的更深入,倒不如把时间用来深入学习ucos,也能达到同样的效果。

出10入4汤圆

发表于 2014-12-19 12:06:32 | 显示全部楼层
想看操作系统原理,这个正合适,mark

出0入270汤圆

发表于 2014-12-19 13:01:41 | 显示全部楼层
好东西 收藏一下

出0入0汤圆

发表于 2016-11-2 14:21:47 | 显示全部楼层
太厉害了

出0入0汤圆

发表于 2016-11-30 18:28:11 | 显示全部楼层
一篇好文章,复制以后慢慢学习,thank you lz

出0入0汤圆

发表于 2016-12-3 09:46:45 | 显示全部楼层
没有什么实际的价值,学术研究可以做

出0入0汤圆

发表于 2016-12-8 21:42:14 | 显示全部楼层
赞,mark!!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 11:01

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表