一种裸奔多任务嵌入式操作系统模型Word文档格式.docx

上传人:b****2 文档编号:3794317 上传时间:2023-05-02 格式:DOCX 页数:20 大小:20.68KB
下载 相关 举报
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第1页
第1页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第2页
第2页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第3页
第3页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第4页
第4页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第5页
第5页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第6页
第6页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第7页
第7页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第8页
第8页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第9页
第9页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第10页
第10页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第11页
第11页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第12页
第12页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第13页
第13页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第14页
第14页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第15页
第15页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第16页
第16页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第17页
第17页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第18页
第18页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第19页
第19页 / 共20页
一种裸奔多任务嵌入式操作系统模型Word文档格式.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

一种裸奔多任务嵌入式操作系统模型Word文档格式.docx

《一种裸奔多任务嵌入式操作系统模型Word文档格式.docx》由会员分享,可在线阅读,更多相关《一种裸奔多任务嵌入式操作系统模型Word文档格式.docx(20页珍藏版)》请在冰点文库上搜索。

一种裸奔多任务嵌入式操作系统模型Word文档格式.docx

例如后面讲的如何在裸奔环境实现taskDelay()。

消息队列既适用于OS环境,也适用于裸奔环境。

在OS环境下,消息队列机制由OS提供。

在裸奔环境下,消息队列要自己来实现。

如果对队列的概念不清楚,可参考《数据结构》教材。

这个队列机制,可做成通用模块,在不同的程序中复用。

消息队列用于缓冲事件。

事件不知道什么时候会到来,也不能保证来了就能迅速得到处理。

使用消息队列,可以保证每个事件都被处理到,以及处理顺序。

一般在两种情况下会用到消息队列:

存储外部事件:

外部事件由中断收集,然后存储到队列。

串口接收程序中的接收循环缓冲区,可理解为消息队列。

任务间通讯:

一个任务给其它任务发送消息。

timerTick,就是系统中的时钟基准。

OS中总是有一个这样的基准。

在裸奔时,我们要用一个定时器(或RTC或watchdog)来建立这个时间基准。

一个tick间隔可以设置为10ms(典型RTOS的缺省设置)。

让定时器10ms中断一次,中断发生时给tickNum++。

以前,我在定时器中断中设置1S标志、200ms标志等等。

时间相关的任务根据这些标志判断是否要执行。

近来,一般让任务直接去察看tickNum。

两次相减来判断定时是否到达。

也可以在系统中建立一个通用定时器任务,管理与不同任务相关的多个定时器;

在定时到达时,由定时器任务去调用相应的callback。

系统时钟基准是所谓“零耗时裸奔”的基础。

timerTick的分辨率,决定了只适于于较大的时间延时。

在做时序时的小延时,用传统方法好了。

OS中的taskDelay()在裸奔环境下的一种实现:

OS环境:

void 

xxxTask(void)

//waitEvent

//do 

step_1

taskDelay(TIME_OUT_TICK_NUM);

step_2

}

裸奔环境:

static 

unsigned 

int 

taskStat 

STAT_GENERAL;

//任务状态变量

timer_t 

startTick;

currTick;

if 

(taskStat 

== 

STAT_GENERAL)

//check 

event

//if 

no 

return;

startTick 

sysGetTick();

//sysGetTick()就是察看系统时间

STAT_WAIT;

else 

STAT_WAIT)

currTick 

((currTick 

startTick) 

>

TIME_OUT_TICK_NUM)

step_2 

else

老生常谈---一种裸奔多任务模型ourdev_629752P0O6JH.txt(文件大小:

4K) 

(原文件名:

老生常谈---一种裸奔多任务模型.txt)

C51多任务编程思想ourdev_629753EWA0LM.pdf(文件大小:

143K) 

C51多任务编程思想.pdf) 

基于51单片机的C语言多任务操作 

完美版ourdev_629754PETS4B.rar(文件大小:

3K) 

完美版.rar)

Easy51RTOS的原理

//Easy51RTOS操作系统头文件

#include 

"

os_cfg.h"

functns.h"

//常用一些功能函数

char 

TempBuffer[6];

//显示温度字符串

str2[12]={'

'

'

0,0,0,0,0,0,0xdf,0x43,0};

//任务0:

测温度送显

task0(void)

temp=ReadTemperature();

IntToStr(temp,TempBuffer);

str2[3]=TempBuffer[0];

str2[4]=TempBuffer[1];

str2[5]=TempBuffer[2];

str2[6]=TempBuffer[3];

str2[7]=TempBuffer[4];

str2[8]=TempBuffer[5];

GotoXY(0,1);

Print(str2);

delay_nms(300);

//任务1:

键盘扫描,LCD显示 

task1(void)

if(CHANGE==0) 

//判断change温度键是否按下

set_temp=key_set();

//设定需要更改的温度值

if(set_temp<

temp)

fengshan();

//设定的温度<

实际温度,则打开电机风扇

if(set_temp>

dianlu();

//若大于,则打开电炉(这里用LED模拟一下)

//任务2

task2()

//任务3

task3()

//任务4

task4(void)

//任务5 

task5(void)

//任务6 

task6()

//任务7

task7()

//main主函数

main(void)

OS_InitTimer0();

EA=1;

LCD_Init();

LCD_w_data(1,1,Temp_Str);

LCD_w_data(2,1,Key_Str);

while

(1)

(OS_Delay[0]==0){task0();

OS_Delay[0]=100;

//温度测量,每秒1次

(OS_Delay[1]==0){task1();

OS_Delay[1]=10;

//键盘扫描,键值存储

(OS_Delay[2]==0){task2();

OS_Delay[2]=100;

//读出存储的键值,LCD显示 

(OS_Delay[3]==0){task3();

OS_Delay[3]=50;

(OS_Delay[4]==0){task4();

OS_Delay[4]=100;

(OS_Delay[5]==0){task5();

OS_Delay[5]=60;

(OS_Delay[6]==0){task6();

OS_Delay[6]=70;

(OS_Delay[7]==0){task7();

OS_Delay[7]=80;

Delay(50);

//Taskturn;

//定时中断服务

OS_Timer0(void) 

interrupt 

using 

2

uchar 

i;

//CRY_OSC,TIME_PER_SEC在easycfg.h中配置

TH0 

255-CRY_OSC/TIME_PER_SEC/12/256;

TL0 

255-CRY_OSC/TIME_PER_SEC/12%256;

//每节拍对任务延时变量减1 

,减至 

后,任务就绪。

for(i=0;

i<

MAX_TASK;

i++)

if(OS_Delay[i]!

=0) 

OS_Delay[i]--;

//Runing(On);

//和传统的前后感觉基本上是一样的…

//唯一的优点呢,是感觉OS_Delay[n]数组起到了分配各

Easy51RTOS的原理ourdev_629755MEIQGP.txt(文件大小:

Easy51RTOS的原理.txt) 

完美版

/*

1.本程序不使用任何汇编指令

2.由定时器T0产生中断,切换进程

3.由于中断或调用子程序,要把PC堆栈,故可以以SP为基址的地方找到PC

4.中断或子程序返回,要把SP出栈给PC,故可以操作SP改变程序入口

5.本程序经调试运行 

电路图已上传

6.程序编译是会有一个警告提示,为正常现象,因为保存R0-R7时,重新定义地址,

出现地址覆盖的警告提示。

7.用户以此模板写程序只需写用户的进程子程序和用户初始化子程序,并把各进程参数

放在规定地方,各程序放在规定地方就可以;

所有的任务调度已处理好。

*/

//头文件

#include<

reg52.h>

//#include<

absacc.h>

intrins.h>

//宏定义

#defineuchar 

char

#define 

uint 

int 

TN 

65436

//进程1,2,3执行时间之比为 

T1:

T2:

T3 

(时间单位us)

TN1 

55536 

//1个进程循环周期内进程1执行的时间T1us 

TN1=(65536-T1)

TN2 

//1个进程循环周期内进程2执行的时间T2us 

TN2=(65536-T1)

TN3 

//1个进程循环周期内进程3执行的时间T3us 

TN3=(65536-T1)

//

N1 

// 

进程1的延时参数 

N2 

进程2的延时参数 

N3 

进程3的延时参数 

idata 

temp[8] 

_at_ 

0x00;

 

//R0--R7

tempbf1[8];

//用于保存R0--R7 

进程1

tempbf2[8];

进程2

tempbf3[8];

进程3

//定义全局变量

address1,address2,address3;

test1_1=0,test2_1=0,test3_1=0,PID=1;

//各进程的标志位,是否为第一次执行,0第一次,非0非第一次;

PID进程号;

ac1,ac2,ac3;

//, 

PC_Next;

各进程的初始地址寄存器.

//test1 

的参数 

由于进程切换时 

没有保存普通变量,

//所以各进程的普通参数需要定义成全局变量.

m1,i1,j1,k1;

table1[4];

//在此加入 

用户进程1参数

//test2 

m2,i2,j2,k2;

table2[4];

用户进程2参数

//test3 

的参数

m3,i3,j3,k3;

table3[4];

//声明

//unsigned 

Get_Next_PC(void);

//调用子程序,获取PC

chushihua(void);

//初始化函数

yonghuchushihua(void);

//用户初始化函数

test1(void);

//进程一

test2(void);

test3(void);

//main函数

PC_Next=Get_Next_PC();

chushihua();

ac1=(unsigned 

int)(test1);

//获取进程1的入口地址

ac2=(unsigned 

int)(test2);

//获取进程2的入口地址

ac3=(unsigned 

int)(test3);

//获取进程3的入口地址

yonghuchushihua();

TR0=1;

while

(1);

//初始化时钟

chushihua(void)

TMOD=0x01;

// 

ET0=1;

TH0=TN/256;

TL0=TN%256;

//中断处理,进程调度

time0() 

1

ib;

TR0=0;

//进程顺序分配

PID++;

if(PID==4)

{PID=1;

//进程调度

switch(PID)

case 

1:

if(test3_1!

=0)//第一次否?

//保存现场,还回地址

address3=*((unsigned 

*)(SP-4));

//PC的高字节

address3 

<

8;

address3+=*((unsigned 

*)(SP-5));

//PC的低字节

table3[0]=*((unsigned 

*)(SP));

//现场保护

table3[1]=*((unsigned 

*)(SP-1));

table3[2]=*((unsigned 

*)(SP-2));

table3[3]=*((unsigned 

*)(SP-3));

for(ib=0;

ib<

=7;

ib++) 

//保护R0--R7

tempbf3[ib]=temp[ib];

if(test1_1==0) 

//第一次执行

//执行新进程,恢复现场

test1_1=1;

*((unsigned 

*)(SP-4))=ac1>

//PC的高字节

*)(SP-5))=ac1 

&

0x00ff;

else//非第一次执行

*)(SP-4))=address1>

*)(SP-5))=address1 

*)(SP))=table1[0];

//现场恢复

*)(SP-1))=table1[1];

*)(SP-2))=table1[2];

*)(SP-3))=table1[3];

//恢复R0--R7

temp[ib]=tempbf1[ib];

TH0=TN1/256;

TL0=TN1%256;

}break;

2:

if(test1_1!

=0) 

//第一次否?

//保存现场,还回地址,否

address1=*((unsigned 

address1 

address1+=*((unsigned 

table1[0]=*((unsigned 

table1[1]=*((unsigned 

//现场保护

table1[2]=*((unsigned 

table1[3]=*((unsigned 

tempbf1[ib]=temp[ib];

if(test2_1==0)//第一次

//执行进程2,恢复现场

test2_1=1;

*)(SP-4))=ac2>

*)(SP-5))=ac2 

else 

//非第一次

*)(SP-4))=address2>

*)(SP-5))=address2 

*)(SP))=table2[0];

*)(SP-1))=table2[1];

*)(SP-2))=table2[2];

*)(SP-3))=table2[3];

ib++)//恢复R0--R7

temp[ib]=tempbf2[ib];

TH0=TN2/256;

TL0=TN2%256;

3:

if(test2_1!

=0)

address2=*((unsigned 

address2 

address2+=*((unsigned 

table2[0]=*(

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

当前位置:首页 > 临时分类 > 批量上传

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2