轻松自编小型嵌入式操作系统的附录基础系统源码.docx
- 文档编号:27514026
- 上传时间:2023-07-02
- 格式:DOCX
- 页数:62
- 大小:78.12KB
轻松自编小型嵌入式操作系统的附录基础系统源码.docx
《轻松自编小型嵌入式操作系统的附录基础系统源码.docx》由会员分享,可在线阅读,更多相关《轻松自编小型嵌入式操作系统的附录基础系统源码.docx(62页珍藏版)》请在冰豆网上搜索。
轻松自编小型嵌入式操作系统的附录基础系统源码
是书后的代码,用的是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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 轻松 小型 嵌入式 操作系统 附录 基础 系统 源码