下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、当然,这里要申明一下,这玩意儿其实算不上真正的操作系统,它除了并行多任务并行外根本没有别的功能.但凡事都从简单开始,搞懂了它,就能根据应用需求,将它扩展成一个真正的操作系统.好了,代码来了.将下面的代码直接放到KEIL里编译,在每个task?()函数的"task_switch();"那里打上断点,就可以看到它们的确是"同时"在执行的.#include<reg51.h>#defineMAX_TASKS2/任务槽个数.必须和实际任务数一至#defineMAX_TASK_DEP12/最大栈深.最低不得少于2个,保守值为12.unsignedchar
2、idatatask_stackMAX_TASKSMAX_TASK_DEP;/任务堆栈.unsignedchartask_id;/当前活动任务号/任务切换函数(任务调度器)voidtask_switch()task_sptask_id=SP;if(+task_id=MAX_TASKS)task_id=0;SP=task_sptask_id;/任务装入函数.将指定的函数(参数1)装入指定(参数2)的任务槽中.如果该槽中原来就有任务,则原任务丢失但系统本身不会发生错误.voidtask_load(unsignedintfn,unsignedchartid)task_sptid=task_stackt
3、id+1;task_stacktid0=(unsignedint)fn&0xff;task_stacktid1=(unsignedint)fn>>8;/从指定的任务开始运行任务调度.调用该宏后,将永不返回.#defineos_start(tid)task_id=tid,SP=task_sptid;return;/*=以下为测试代码=*/voidtask1()staticunsignedchari;while(1)i+;task_switch();/编译后在这里打上断点voidtask2()staticunsignedcharj;while(1)j+=2;task_switc
4、h();/编译后在这里打上断点voidmain()/这里装载了两个任务,因此在定义MAX_TASKS时也必须定义为2task_load(task1,0);/将task1函数装入0号槽task_load(task2,1);/将task2函数装入1号槽os_start(0);限于篇幅我已经将代码作了简化,并删掉了大部分注释,大家可以直接下载源码包,里面完整的注解,并带KEIL工程文件,断点也打好了,直接按ctrl+f5就行了.现在来看看这个多任务系统的原理:这个多任务系统准确来说,叫作"协同式多任务".所谓"协同式",指的是当一个任务持续运行而不释放资源时,
5、其它任务是没有任何机会和方式获得运行机会,除非该任务主动释放CPU.在本例里,释放CPU是靠task_switch()来完成的.task_switch()函数是一个很特殊的函数,我们可以称它为"任务切换器".要清楚任务是如何切换的,首先要回顾一下堆栈的相关知识.有个很简单的问题,因为它太简单了,所以相信大家都没留意过:我们知道,不论是CALL还是JMP,都是将当前的程序流打断,请问CALL和JMP的区别是什么?你会说:CALL可以RET,JMP不行.没错,但原因是啥呢?为啥CALL过去的就可以用RET跳回来,JMP过去的就不能用RET来跳回呢?很显然,CALL通过某种方法保
6、存了打断前的某些信息,而在返回断点前执行的RET指令,就是用于取回这些信息.不用多说,大家都知道,"某些信息"就是PC指针,而"某种方法"就是压栈.很幸运,在51里,堆栈及堆栈指针都是可被任意修改的,只要你不怕死.那么假如在执行RET前将堆栈修改一下会如何?往下看:当程序执行CALL后,在子程序里将堆栈刚才压入的断点地址清除掉,并将一个函数的地址压入,那么执行完RET后,程序就跳到这个函数去了.事实上,只要我们在RET前将堆栈改掉,就能将程序跳到任务地方去,而不限于CALL里压入的地址.重点来了首先我们得为每个任务单独开一块内存,这块内存专用于作为对应的
7、任务的堆栈,想将CPU交给哪个任务只需将栈指针指向谁内存块就行了.接下来我们构造一个这样的函数:当任务调用该函数时,将当前的堆栈指针保存一个变量里,并换上另一个任务的堆栈指针.这就是任务调度器了.OK了,现在我们只要正确的填充好这几个堆栈的原始内容,再调用这个函数,这个任务调度就能运行起来了.那么这几个堆栈里的原始内容是哪里来的呢?这就是"任务装载"函数要干的事了.在启动任务调度前将各个任务函数的入口地址放在上面所说的"任务专用的内存块"里就行了!对了,顺便说一下,这个"任务专用的内存块"叫作"私栈",私栈的意思就
8、是说,每个任务的堆栈都是私有的,每个任务都有一个自已的堆栈.话都说到这份上了,相信大家也明白要怎么做了:1. 分配若干个内存块,每个内存块为若干字节:这里所说的"若干个内存块"就是私栈,要想同时运行几少个任务就得分配多少块.而"每个子内存块若干字节就是栈深.记住,每调一层子程序需要2字节.如果不考虑中断,4层调用深度,也就是8字节栈深应该差不多了unsignedcharidatatask_stackMAX_TASKSMAX_TASK_DEP当然,还有件事不能忘,就是堆指针的保存处.不然光有堆栈怎么知道应该从哪个地址取数据啊unsignedcharidatatask
9、_spMAX_TASKS上面两项用于装任务信息的区域,我们给它个概念叫"任务槽".有些人叫它"任务堆",我觉得还是"槽"比较直观对了,还有任务号.不然怎么知道当前运行的是哪个任务呢?unsignedchartask_id当前运行存放在1号槽的任务时,这个值就是1,运行2号槽的任务时,这个值就是22. 构造任务调度函函数:voidtask_switch()task_sptask_id=SP;/保存当前任务的栈指针if(+task_id=MAX_TASKS)/任务号切换到下一个任务task_id=0;SP=task_sptask_id;/
10、将系统的栈指针指向下个任务的私栈.3. 装载任务:将各任务的函数地址的低字节和高字节分别入在task_stack任务号0和task_stack任务号1中:为了便于使用,写一个函数:task_load(函数名,任务号)voidtask_load(unsignedintfn,unsignedchartid)task_sptid=task_stacktid+1;task_stacktid0=(unsignedint)fn&0xff;task_stacktid1=(unsignedint)fn>>8;4. 启动任务调度器:将栈指针指向任意一个任务的私栈,执行RET指令.注意,这可很
11、有学问的哦,没玩过堆栈的人脑子有点转不弯:这一RET,RET到哪去了?嘿嘿,别忘了在RET前已经将堆栈指针指向一个函数的入口了.你别把RET看成RET,你把它看成是另一种类型的JMP就好理解了.SP=task_sp任务号;return;做完这4件事后,任务"并行"执行就开始了.你可以象写普通函数一个写任务函数,只需(目前可以这么说)注意在适当的时候(例如以前调延时的地方)调用一下task_switch(),以让出CPU控制权给别的任务就行了.最后说下效率问题.这个多任务系统的开销是每次切换消耗20个机器周期(CALL和RET都算在内了),贵吗?不算贵,对于很多用状态机方式实现的多任务系统来说,其实效率还没这么高-caseswitch和if()可不像你想像中那么便宜.关于内存的消耗我要说
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年通信电子计算机技能考试-中兴认证考试历年参考题库含答案解析
- 2026年贵州住院医师-贵州住院医师内科历年参考题库含答案解析
- 2026年社会建设城市建设知识竞赛-市场监管公共服务知识历年参考题库含答案解析
- 2026年石油石化技能考试-液氨储存与装卸安全生产技术历年参考题库含答案解析
- 2026年环保知识生态建设知识竞赛-造林绿化知识竞赛历年参考题库含答案解析
- 2026年煤炭矿山职业技能鉴定考试-跳汰选煤工历年参考题库含答案解析
- 2026年煤炭矿山职业技能鉴定考试-井筒掘砌工历年参考题库含答案解析
- 2026年火电电力职业技能鉴定考试-电厂全能值班员考试历年参考题库含答案解析
- 2026年湖南住院医师-湖南住院医师儿内科历年参考题库含答案解析
- 2026年水路交通运输技能考试-海事局适任考试历年参考题库含答案解析
- T/CAR 24-2025数据中心泵驱两相冷板式液冷系统技术规范
- 4.2《让家更美好》 课件 2026-2027学年道德与法治七年级上册 统编版
- 分析化学-专 期末考试试题及参考答案
- 2026年硕士研究生《306临床医学综合能力(西医)》试题
- 2026年9月广东深圳市光明区事业单位选聘博士13人笔试备考试题及答案详解
- 石油化工仪表工程监理作业手册
- 2026年秋人教版新八年级英语上册 Unit 1(单元测试卷)
- 新教材语文五上20分钟微课创新教学设计详案:示儿
- (正式版)T∕CSNAME 178-2025 甲醇燃料动力大型油船 燃料系统联合调试试验指南
- (2025年)亳州市辅警协警笔试笔试真题(附答案)
- 脑出血伴吞咽障碍个案护理
评论
0/150
提交评论