轻松自编小型嵌入式操作系统的附录基础系统源码.docx

上传人:b****3 文档编号:27514026 上传时间:2023-07-02 格式:DOCX 页数:62 大小:78.12KB
下载 相关 举报
轻松自编小型嵌入式操作系统的附录基础系统源码.docx_第1页
第1页 / 共62页
轻松自编小型嵌入式操作系统的附录基础系统源码.docx_第2页
第2页 / 共62页
轻松自编小型嵌入式操作系统的附录基础系统源码.docx_第3页
第3页 / 共62页
轻松自编小型嵌入式操作系统的附录基础系统源码.docx_第4页
第4页 / 共62页
轻松自编小型嵌入式操作系统的附录基础系统源码.docx_第5页
第5页 / 共62页
点击查看更多>>
下载资源
资源描述

轻松自编小型嵌入式操作系统的附录基础系统源码.docx

《轻松自编小型嵌入式操作系统的附录基础系统源码.docx》由会员分享,可在线阅读,更多相关《轻松自编小型嵌入式操作系统的附录基础系统源码.docx(62页珍藏版)》请在冰豆网上搜索。

轻松自编小型嵌入式操作系统的附录基础系统源码.docx

轻松自编小型嵌入式操作系统的附录基础系统源码

是书后的代码,用的是keil51软件,目标器件是AT89C52

我把它放在一个文件中了,然后建立工程添加Main.c后,右键Main.c

选择第一项,

勾选GenerateAssemblerSRCfIle

和AssembleSRCfile

然后由于是内嵌汇编,所以还得做一件事:

右键SourceGroup添加文件

然后去安装keil的命令下找到C51文件夹下的Lib文件,找到

个文件,加入进去

然后就编译运行

调试的时候全速运行,LED灯就闪亮了

 

 #include

   

sbitLED1=P0^1;

sbit LED2=P0^2;

sbit LED3=P0^3;

sbit LED4=P0^4;

voidrenwu_0();

voidrenwu_1();

voidrenwu_2();

voidrenwu_3();

voidrenwu_4();

 #definerwzons5//任务总数

#define ch_danzhan_zs18 //任务栈长度配置

#definech_sjzs 3//任务时间片长度总数,如果定时时间是10ms,那么单个任务连续一次的运行时间是50ms

#define ch_tick_zs 0xdc//10ms系统时间粒度配置

#definech_ticks 10//10ms延时节拍=时间粒度

#definech_rwtd_xs 1//堆栈操作模式

#definech_gn_rw 0//功能函数配置  \

//信号量使能配置

#define ch_xhl_en 0

#definech_xhl_zs 0

//邮箱使能配置

#definech_yx_en 0

#define ch_yx_zs0

//消息队列使能配置

#definech_xxdl_en0

#definech_xxdl_zs0

#definech_fuwu_en0

 

typedefunsignedcharuc8;

typedefunsignedintui16;

typedefunsignedlongul32;

//系统状态模式的宏标志

#definech_tzms0x00 //系统处于停止的状态

 #definech_yxms0x01//运行

 #definech_hcms0x02//互斥

 #definech_fwms0x04//服务运行

 //任务状态宏标志

 #definech_yunxing0x01 //任务是处于就绪运行态之中的

 #definech_yanshi0x02  //任务处于延时运行态中

 #definech_dengdai_zd0x20//等待中断状态

 #definech_tingzhi 0x40//状态停止

//变量状态宏定义,比如P43说道,RW/CZXT小型嵌入式操作系统的系统管理器中有一个系统运行标志,ch_xtyx,如果操作系统

//进入运行,那么运行标志为真,即ch_xtyx=ch_on,如果操作系统未启动或停止运行,那么运行标志为假,即ch_xtyx=ch_off

//又比如ch_zd_on和ch_zd_off分别用来开方CPU总中断和禁止CPU总中断,EA=ch_zd_on,相等于EA=1

//等等,那么ch_xtyx不就是变量了嘛

 #definech_on0xff // 系统运行

 #definech_off0x00 //系统停止

 #definech_sj_on0xff//有任务要优先运行

 #definech_sj_off 0x00 //无任务要优先运行

 #definech_zd_on1 //中断开

 #definech_zd_off0 //中断关

 #definech_dengdai_cs_on 0xff//等待超时

 #definech_dengdai_cs_off0x00 //没有超时

 

 

 

uc8yxhao;

uc8ch_xtyx;//系统运行标志

uc8xyxhao;//存放新运行任务的任务号

uc8ch_tdsuo;//调度锁

uc8ch_zdzs;//中断嵌套计数器

uc8ch_rwsjzs;

typedefstruct  guanlikuai //管理控制块,简称系统管理器,这是RW/CZXT最核心的数据结构

{

uc8yxhao;

 uc8xyxhao;//存放新运行任务的任务号

uc8ch_xtyx;//系统运行标志

uc8ch_rwsjzs;

uc8ch_tdsuo;//调度锁

uc8ch_zdzs;//中断嵌套计数器 ;

uc8ch_xtzt;  //系统状态

uc8ch_sjyx;//优先运行标志

}GLK;

 GLK ch_xtglk;

#define ch_rwzs5// 配置任务的数量

#definech_rwzhan_cd20 //配置每个任务栈的长度

uc8idatarwzhan[ch_rwzs][ch_rwzhan_cd];

uc8idatach_yxb[ch_rwzs]; //定义任务的运行队列

uc8idatach_sj_yxb[ch_rwzs];

 

typedefstructrenwukuai

{

uc8rwsp;//任务栈顶寄存器

ui16rwys;//任务延时寄存器

uc8rwzt; //任务状态寄存器两个

uc8rwztchucun; //这两个相当于CPSR和SPSR

}RWK;

 

RWK idata ch_rwk[ch_rwzs];

  

voidxt_blcsh(void) //变量初始化

{

uc8i,j;

ch_xtglk.yxhao=0;//这个hao是指运行号的号,默认0号为空闲任务

ch_xtglk.xyxhao=0;// 新运行号

ch_xtglk.ch_rwsjzs=0;//任务时间片总数

ch_xtglk.ch_zdzs=0;//总段总数

ch_xtglk.ch_tdsuo=0;//调度锁

ch_xtglk.ch_xtyx=ch_off; //系统运行标志为关

ch_xtglk.ch_xtzt=ch_tzms; //系统状态等于停止状态

ch_xtglk.ch_sjyx=ch_sj_off;//无任务要优先运行

//

for(i=0;i

{ch_yxb[i]=0; //数组全部初始化,这个是运行队列初始化,运行队列的作用是用来登记就绪任务的任务号,

//任务在新建立的时候,必须把任务的任务号登记在运行队列中,只有在运行队列中进行就绪登记的任务,才能够

//被调度器调度进入运行

 ch_sj_yxb[i]=0;

}

for(i=0;i

 for(j=0;j

 rwzhan[i][j]=0;

}  //任务堆栈用来保存任务的断电数据

voidxt_rwkzk(void)

{

uc8i;

for(i=0;i

{

ch_rwk[i].rwsp=rwzhan[i]; //类比第一章,各种任务地址放在各自的任务空间,然后任务块是存放指向RAM存放

//任务的地址,说白了就是指向任务的五个指针就是这个数组

//也就是任务指针取得栈区的首地址

ch_rwk[i].rwsp+=11;//任务指针取得任务的栈顶地址

ch_rwk[i].rwzt=ch_yunxing;//任务状态为运行态

ch_rwk[i].rwztchucun=0;//SPSR无储存,也就是挂起前状态寄存器,0表示不储存任何状态信息

ch_rwk[i].rwys=0; //任务无延时,也就是延时寄存器清零

}

}

voidch_xt_renwu(void)

{

//任务函数的入口地址存入任务栈区中

rwzhan[0][1]=(ui16)renwu_0; //就像第一章一样保持任务入口地址

rwzhan[0][2]=(ui16)renwu_0>>8;

rwzhan[1][1]=(ui16)renwu_1;

rwzhan[1][2]=(ui16)renwu_1>>8;

rwzhan[2][1]=(ui16)renwu_2;

rwzhan[2][2]=(ui16)renwu_2>>8;

rwzhan[3][1]=(ui16)renwu_3;

rwzhan[3][2]=(ui16)renwu_3>>8;

rwzhan[4][1]=(ui16)renwu_4;

rwzhan[4][2]=(ui16)renwu_4>>8;

//任务块初始化

xt_rwkzk();

//任务就绪登记

//系统初始化时所创建的任务,其状态都是就绪运行态,那么任务就必须在运行队列中进行登记,

ch_yxb[0]=1;//队列首元素赋值为1,表示1号任务的任务号存入运行队列的0号位置中,下面同理

ch_yxb[1]=2;

ch_yxb[2]=3;

ch_yxb[3]=4;

ch_yxb[4]=0;

}

voidch_xt_int(void)

{

xt_blcsh(); //系统变量初始化

ch_xt_renwu();//创建任务

//下面是简单的任务测试代码,运行到下面的函数的末尾的时候碰到ret,然后PC=SP指向的内存地址的。

内容,然后

//就跳转到任务1了,如果没有的话就在空闲任务(任务0)运行?

不是,如果ch_xt_on函数中什么都没有,那么SP就是调用ch_xt_on的

//那个地址也就是返回函数调用

voidch_xt_on()

{

//取出1号任务的任务号

ch_xtglk.xyxhao=ch_yxb[0];//任务管理块取得任务运行队列的第一个运行任务号

ch_xtglk.yxhao=ch_xtglk.xyxhao;//系统的运行号设置为那个

//SP取得1号任务的栈顶地址

SP=ch_rwk[ch_xtglk.yxhao].rwsp;

 

}

 

//消息队列登记函数

voidch_yxbdengji(uc8dengjihao)

{

uc8wei;//位置

for(wei=0;wei

{

if(ch_yxb[wei]==0)

{

ch_yxb[wei]=dengjihao;

ch_rwk[dengjihao].rwzt=ch_yunxing;

wei=ch_rwzs;

}

}

}

//优先消息队列登记函数

voidch_sj_yxbdengji(uc8dengjihao)

{

uc8wei;

for(wei=0;wei

{

if(ch_sj_yxb[wei]==0)

{

ch_sj_yxb[wei]=dengjihao;

ch_rwk[dengjihao].rwzt=ch_yunxing;

wei=ch_rwzs;

}

}

ch_xtglk.ch_sjyx=ch_sj_on;

}

//取出就绪任务,然后队伍前移,就是取出队首,然后前移

uc8ch_rwhao(void)

{

uc8xin;

uc8jiu;

uc8rwhao;

rwhao=ch_yxb[0];

if(ch_yxb[0]!

=0)

{

for(jiu=1,xin=0;jiu

{

ch_yxb[jiu-1]=0;

if(ch_yxb[jiu]!

=0)

ch_yxb[xin]=ch_yxb[jiu];

xin++;

}

if((ch_yxb[jiu]!

=0)&&(jiu==(ch_rwzs-1)))

{

ch_yxb[jiu]=0;

}

}

}

return(rwhao);

//取出优先消息队列的任务

uc8ch_sj_rwhao(void)

{

uc8xin;

uc8jiu;

uc8rwhao;

rwhao=ch_sj_yxb[0];

if(ch_sj_yxb[0]!

=0)

{

for(jiu=1,xin=0;jiu

{

ch_sj_yxb[jiu-1]=0;

if(ch_sj_yxb[jiu]!

=0)

ch_sj_yxb[xin]=ch_sj_yxb[jiu];

xin++;

}

if((ch_sj_yxb[jiu]!

=0)&&(jiu==(ch_rwzs-1)))

{

ch_sj_yxb[jiu]=0;

}

}

}

if(ch_sj_yxb[0]==0)

{

ch_xtglk.ch_sjyx=ch_sj_off;

}

return(rwhao);

}

//更新运行队列中就绪任务的位置

voidyxb_genxin(void)

{

uc8xin;

uc8jiu;

for(xin=0,jiu=0;jiu

{

if(ch_yxb[jiu]!

=0)

{

ch_yxb[xin]=ch_yxb[jiu];

xin++;

}

if((ch_yxb[jiu]!

=0)&&(jiu==ch_rwzs-1)&&(xin

{

ch_yxb[jiu]=0;

}

}

}

voidsj_yxb_genxin(void)

{

uc8xin;

uc8jiu;

for(xin=0,jiu=0;jiu

{

if(ch_sj_yxb[jiu]!

=0)

{

ch_sj_yxb[xin]=ch_sj_yxb[jiu];

xin++;

}

if((ch_sj_yxb[jiu]!

=0)&&(jiu==ch_rwzs-1)&&(xin

{

ch_sj_yxb[jiu]=0;

}

}

}

//删除运行队列中的就绪任务

voidch_yxbqingchu(uc8qingchuhao)

{

 uc8wei;

for(wei=0;wei

{if(ch_yxb[wei]==qingchuhao)

{

ch_yxb[wei]=0;

yxb_genxin();//运行队列更新

wei=ch_rwzs;//中断循环

}

}

}

uc8ch_sj_yxbqingchu(uc8qingchuhao)

{

 uc8wei;

uc8czxx;

czxx=0x00;

for(wei=0;wei

{if(ch_sj_yxb[wei]==qingchuhao)

{

ch_sj_yxb[wei]=0;

sj_yxb_genxin();//运行队列更新

wei=ch_rwzs;//中断循环

czxx=0xff;

}

}

if(ch_sj_yxb[0]==0)

{ch_xtglk.ch_sjyx=ch_sj_off;

}

return(czxx);//删除成功标志位,cz是操作的意思

}

//任务级调度器

voidch_rwtd(void)

{

EA=ch_zd_off;

if(ch_xtglk.ch_xtyx!

=ch_on)

{EA=ch_zd_on;return;}

if(ch_xtglk.ch_tdsuo!

=0)

{EA=ch_zd_on;return;}

if(ch_xtglk.ch_zdzs!

=0)

{EA=ch_zd_on;return;}

if(ch_xtglk.ch_xtyx==ch_fwms)

{EA=ch_zd_on;return;}

if(ch_xtglk.ch_rwsjzs!

=0)

{EA=ch_zd_on;return;}

if(ch_xtglk.xyxhao==0)

{

if(ch_xtglk.ch_sjyx==ch_sj_on)

{  

ch_xtglk.xyxhao=ch_sj_rwhao();

}

else

{

ch_xtglk.xyxhao=ch_rwhao();

}

}

ch_xtglk.ch_rwsjzs=ch_sjzs;

if(ch_xtglk.yxhao!

=ch_xtglk.xyxhao)

{

/*__asmPUSHACC

__asmPUSHB

__asmPUSHPSW 

__asmPUSHAR0

__asmPUSHAR1

__asmPUSHAR4

__asmPUSHAR5

__asmPUSHAR6

__asmPUSHAR7   

*/

#pragmaasm

 PUSHACC

 PUSHB

 PUSHPSW 

 PUSHAR0

 PUSHAR1

 PUSHAR4

 PUSHAR5

 PUSHAR6

 PUSHAR7

#pragmaendasm

ch_rwk[ch_xtglk.yxhao].rwsp=SP;

ch_xtglk.yxhao=ch_xtglk.xyxhao;

ch_xtglk.xyxhao=0;

SP=ch_rwk[ch_xtglk.yxhao].rwsp;

/*__asmPOPAR7

__asmPOPAR6

__asmPOPAR5

__asmPOPAR4

__asmPOPAR1

__asmPOPAR0

__asmPOPPSW

__asmPOPB

__asmPOPACC  */

#pragmaasm

 POPAR7

 POPAR6

 POPAR5

 POPAR4

 POPAR1

 POPAR0

 POPPSW

 POPB

 POPACC 

 #pragmaendasm

}

EA=ch_zd_on;

}

//中断调度器在此,但是书上的函数名有所缺漏

 

//调度器上锁

voidch_tdsuo_on(void)

{

EA=ch_zd_off;

if(ch_xtglk.ch_tdsuo==0)

{

ch_xtglk.ch_tdsuo=1;

}

EA=ch_zd_on;

}

//解锁

voidch_tdsuo_off(void)

{

EA=ch_zd_off;

if(ch_xtglk.ch_tdsuo>0)

{

ch_xtglk.ch_tdsuo=0;

}

EA=ch_zd_on;

}

 

//定时器T0初值数据安装函数

//比如定时10ms,就是每10ms就产生一次中断,设置TF0=1,基于12M晶振就如下确定值

#definech_tick_th0 ((65536-10000)/256)

#definech_tick_tl0 ((65536-10000)%256)

//系统配置文件PZ中有对时间片总数的定义

voidch_time_sjaz(void)

{

TR0=0;//关定时器0

TH0=ch_tick_th0;

TL0=ch_tick_tl0;

TR0=1;//定时器0启动

}

voidch_time_on(void)  

{

TMOD|=0x01;//运行模式1

ch_time_sjaz();

ET0=1;//定时器中断开,当溢出时就产生中断,设置TF0=1

}

//时间节拍延时函数,就是延时的单位是以时间节拍为单位,而时间节拍由定时器产生中断产生,比如每10ms产生一次

//中断,那么时间节拍就是10ms,任务延时100个时钟节拍,那么任务的延时时间就是1s,在进入延时之前,系统清除时间片

//设置任务状态为延时状态,

 

//进入,退出中断函数,

voidch_zhongduan_on(void)

{

EA=ch_zd_off;

if(ch_xtglk.ch_zdzs<8)

{

ch_xtglk.ch_zdzs++;

}

EA=ch_zd_on;

}

voidch_zhongduan_off(void)

{

EA=ch_zd_off;

if(ch_xtglk.ch_zdzs<8)

{

ch_xtglk.ch_zdzs--;

}

EA=ch_zd_on;

}

voidch_rwyschaxun(void)

{

uc8i;

for(i=0;i

{

if((ch_rwk[i].rwys>0)&&(ch_rwk[i].rwzt!

=ch_tingzhi))

{

ch_rwk[i].rwys-=1;

if(ch_rwk[i].rwys==0)

{

if(ch_rwk[i].rwzt==ch_yanshi)

{

ch_yxbdengji(i);

}

}

}

}

}

//T0中断服务

voidch_timer0(void)interrupt1

{

ch_zhongduan_on();

EA=ch_zd_off;

ch_time_sjaz();

ch_rwyschaxun();

if((ch_xtglk.ch_rwsjzs>0)&&

(ch_xtglk.ch_tdsuo==0))

{

ch_xtglk.ch_rwsjzs--;

if(ch_xtglk.ch_rwsjzs==0)

{

if(ch_xtglk.yxhao!

=0)

{

ch_yxbdengji(ch_xtglk.yxhao);

}

}

}

ch_zhongduan_off();

if((ch_xtglk.yxhao==0)&&

(ch_xtglk.ch_rwsjzs!

=0))

{

ch_xtglk.ch_rwsjzs=0;

}

EA=ch_zd_off;

if((ch_xtglk.ch_zdzs==0)&&

(ch_xtglk.ch_tdsuo==0)&&

(ch_xtglk.ch_rwsjzs==0)&&

(ch_xtglk.ch_xtzt!

=ch_fwms))

{

if(ch_xtglk.xyxhao==0)

if(ch_xtglk.ch_sjyx==ch_sj_on)

{ch_xtglk.xyxhao=ch_sj_rwhao();}

else

{

ch_xtglk.xyxhao=ch_rwhao();

}

ch_xtglk.ch_rwsjzs=ch_sjzs;

if(ch_xtglk.yxhao!

=ch_xtglk.xyxhao)

{

ch_rwk[ch_xtglk.yxhao].rwsp=SP;

ch_xtglk.yxhao=ch_xtglk.xyxhao;

ch_xtglk.xyxhao=0;

SP=ch_rwk[ch_xtglk.yxhao].rwsp;

}

}

EA=ch_zd_on;

}

 

voidch_rwys_tk(ui16

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 法律文书 > 判决书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1