51单片机最简单的多任务操作系统_第1页
51单片机最简单的多任务操作系统_第2页
51单片机最简单的多任务操作系统_第3页
51单片机最简单的多任务操作系统_第4页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、/* 51单片机最简单的多任务操作系统其实只有个任务调度切换,把说它是OS有点牵强,但它对于一些简单的开发应用来说,简单也许就是最好的.尽情的扩展它吧 . 别忘了把你的成果分享给大家 .这是一个最简单的OS,切以运行效率为重,经测试,切换一次任务仅个机器周期,也就是在标准(工作于M晶振) 上uS.而为速度作出的牺牲是 , 为了给每个任务都分配一个私有堆栈 , 而占用了较多的内存 . 作为补偿 , 多任务更容易安 排程序逻辑 , 从而可以节省一些用于控制的变量 .任务槽越多 ,占用内存越多 ,但任务也越好安排 ,以实际需求合理安排任务数目 .一般来说 ,4个已足够 .况且可以 拿一个槽出来作为活

2、动槽 , 换入换入一些临时任务 .task_load( 函数名 , 任务槽号 )装载任务os_start( 任务槽号 )启动任务表 . 参数必须指向一个装载了的任务 , 否则系统会崩溃 .task_switch()切换到其它任务. 编写任务函数注意事项 :KEIL C编译器是假定用户使用单任务环境,所以在变量的使用上都未对多任务进行处理,编写任务时应注意变量覆盖和代码重入问题 .1. 覆盖:编译器为了节省内存 ,会给两个没用调用关系的函数分配同一内存地址作为变量空间 .这在单任务下是 很合理的 , 但对于多任务来说 , 两个进程会互相干扰对方 .解决的方法是 : 凡作用域内会跨越 task_s

3、witch() 的变量 , 都使用 static 前辍 , 保证其地址空间分配时的唯一性 .2. 重入:重入并不是多任务下独有的问题,在单任务时 ,函数递归同样会导致重入 ,即,一个函数的不同实例 (或者叫作 "复本 ") 之间的变量覆盖问题 .解决的方法是:使用reentrant函数后辍(例如:void function1() reentrant.).当然,根本的办法还是避免重入 , 因为重入会带来巨大的目标代码量 , 并极大降低运行效率 .3. 额外提醒一句 , 在本例中 , 任务函数必须为一个死循环 . 退出函数会导致系统崩溃 . 任务函数如果是用汇编写成或内嵌汇编

4、, 切换任务时应该注意什么问题 ?由于KEIL C编译器在处理函数调用时的约定规则为”子函数有可能修改任务寄存器",因此编译器在调用前已释放所有寄存器 , 子函数无需考虑保护任何寄存器 .这对于写惯汇编的人来说有点不习惯 : 汇编习惯于在子程序中保护寄存器 .请注意一条原则 : 凡是需要跨越 task_switch() 的寄存器 , 全部需要保护 ( 例如入栈 ). 根本解决办法还是 , 不要让 寄存器跨越任务切换函数 task_switch()事实上这里要补充一下 , 正如前所说 ,由于编译器存在变量地址覆盖优化 ,因此凡是非静态变量都不得跨越 task_switch().任务函数

5、的书写 :void 函数名 (void)/ 任务函数必须定义为无参数型 while(1)/ 任务函数不得返回 , 必须为死循环/ 这里写任务处理代码task_switch();每执行一段时间任务,就释放CPUH下,让别的任务有机会运行 任务装载 :task_load( 函数名 , 任务槽号 )装载函数的动作可发生在任意时候 ,但通常是在 main() 中.要注意的是 ,在本例中由于没考虑任务换出 所以在执行 os_start() 前必须将所有任务槽装满 .之后可以随意更换任务槽中的任务 .启动任务调度器 :os_start( 任务槽号 )调用该宏后 ,将从参数指定的任务槽开始执行任务调度 .本

6、例为每切换一次任务需额外开销个机器周期 ,用于迁 移堆栈.*/#include <reg51.h> /*=以下为任务管理器代码 =*/#define MAX_TASKS 3/ 任务槽个数 .在本例中并未考虑任务换入换出 ,所以实际运行的任务有多少个 ,就定义多 少个任务槽 , 不可多定义或少定义/ 任务的栈指针unsigned char idata task_spMAX_TASKS;#define MAX_TASK_DEP 12/ 最大栈深 . 最低不得少于个 , 保守值为 ./预估方法:以为基数,每增加一层函数调用 ,加字节.如果其间可能发生中断 , 则还要再加上中断需要的栈深

7、./ 减小栈深的方法 :1. 尽量少嵌套子程序 2. 调子程序前关中断 .unsigned char idata task_stackMAX_TASKSMAX_TASK_DEP; / 任务堆栈 .unsigned char task_id; / 当前活动任务号 / 任务切换函数 ( 任务调度器 )void task_switch() task_sptask_id = SP;if (+task_id = MAX_TASKS)task_id = 0;SP = task_sptask_id;/ 任务装入函数 . 将指定的函数 ( 参数 ) 装入指定 ( 参数 ) 的任务槽中 . 如果该槽中原来就有任

8、务 , 则原任务丢失 , 但系统本身不会发生错误 .void task_load( unsigned int fn, unsigned char tid) task_sptid = task_stacktid + 1;task_stacktid0 = (unsigned int )fn & 0xff;task_stacktid1 = (unsigned int )fn >> 8;/ 从指定的任务开始运行任务调度 . 调用该宏后 , 将永不返回 .#define os_start(tid) task_id = tid,SP = task_sptid;return ; unsi

9、gned char stra3, strb3; / 用于内存块复制测试的数组=以下为测试代码=*/测试任务:复制内存块.每复制一个字节释放 CPUH次void task1()/每复制一个字节释放CPUH次,控制循环的变量必须考虑覆盖static unsigned char i; / 如果将这个变量前的 static 去掉 , 会发生什么事 ?i = 0;while (1) / 任务必须为死循环 , 不得退出函数 , 否则系统会崩溃strai = strbi;if (+i = sizeof (stra)i = 0;/ 变量 i 在这里跨越了 task_switch(), 因此它必须定义为静态 (

10、static), 否则它将会被其它进程修改 , 因为在另一个进程里也会用到该变量所占用的地址 .task_switch(); /释放CPUH会儿,让其它进程有机会运行.如果去掉该行,则别的进程永远不会被调 用到 /测试任务:复制内存块.每复制一个字节释放 CPUH次.void task2()/每复制一个字节释放CPUH次,控制循环的变量必须考虑覆盖static unsigned char i; /如果将这个变量前的 static 去掉,将会发生覆盖问题.task1() 和task2()会被 编译器分配到同一个内存地址上 , 当两个任务同时运行时 ,i 的值就会被两个任务改来改去i = 0;wh

11、ile (1) / 任务必须为死循环 ,不得退出函数 ,否则系统会崩溃strai = strbi;if (+i = sizeof (stra)i = 0;/ 变量 i 在这里跨越了 task_switch(), 因此它必须定义为静态 (static), 否则它将会被其它进程修改 , 因为在另一个进程里也会用到该变量所占用的地址 .task_switch(); /释放CPUh会儿,让其它进程有机会运行.如果去掉该行,则别的进程永远不会被调用到/测试任务:复制内存块.复制完所有字节后释放 CPU一次.void task3()/复制全部字节后才释放CPU控制循环的变量不须考虑覆盖unsigned c

12、har i; / 这个变量前不需要加 static, 因为在它的作用域内并没有释放过 CPUwhile (1) / 任务必须为死循环 ,不得退出函数 , 否则系统会崩溃i = sizeof (stra);dostrai-1 = strbi-1; while (-i);/变量i在这里已完成它的使命,所以无需定义为静态.你甚至可以定义为寄存器型(regiter)task_switch(); /释放CPU一会儿,让其它进程有机会运行.如果去掉该行,则别的进程永远不会被调 用到 void main()/ 在这个示例里并没有考虑任务的换入换出 , 所以任务槽必须全部用完 , 否则系统会崩溃 ./这里装载了三个任务,因此在定义MAX_TASKS也必须定义为task_load(task1,0)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论