51简单操作系统OS

51简单操作系统OS

ID:41062203

大小:30.50 KB

页数:4页

时间:2019-08-15

51简单操作系统OS_第1页
51简单操作系统OS_第2页
51简单操作系统OS_第3页
51简单操作系统OS_第4页
资源描述:

《51简单操作系统OS》由会员上传分享,免费在线阅读,更多相关内容在工程资料-天天文库

1、当然,这里要申明一下,这玩意儿其实算不上真正的操作系统,它除了并行多任务并行外根本没有别的功能.但凡事都从简单开始,搞懂了它,就能根据应用需求,将它扩展成一个真正的操作系统.好了,代码来了.将下面的代码直接放到KEIL里编译,在每个task?()函数的"task_switch();"那里打上断点,就可以看到它们的确是"同时"在执行的.#include #define MAX_TASKS 2       //任务槽个数.必须和实际任务数一至#define MAX_TASK_DEP 12   //最大栈深.最低不得少于2个,保守值为12.unsigned char idat

2、a task_stack[MAX_TASKS][MAX_TASK_DEP];//任务堆栈.unsigned char task_id;    //当前活动任务号//任务切换函数(任务调度器)void task_switch(){        task_sp[task_id] = SP;        if(++task_id == MAX_TASKS)                task_id = 0;        SP = task_sp[task_id];}//任务装入函数.将指定的函数(参数1)装入指定(参数2)的任务槽中.如果该槽中原来就有任务,则原任务丢失,但系统本身不

3、会发生错误.void task_load(unsigned int fn, unsigned char tid){        task_sp[tid] = task_stack[tid] + 1;        task_stack[tid][0] = (unsigned int)fn & 0xff;        task_stack[tid][1] = (unsigned int)fn >> 8;}//从指定的任务开始运行任务调度.调用该宏后,将永不返回.#define os_start(tid) {task_id = tid,SP = task_sp[tid];return;}

4、/*============================以下为测试代码============================*/void task1(){        static unsigned char i;        while(1){                i++;                task_switch();//编译后在这里打上断点        }}void task2(){        static unsigned char j;        while(1){                j+=2;               

5、 task_switch();//编译后在这里打上断点        }}void main(){        //这里装载了两个任务,因此在定义MAX_TASKS时也必须定义为2        task_load(task1, 0);//将task1函数装入0号槽        task_load(task2, 1);//将task2函数装入1号槽        os_start(0);}限于篇幅我已经将代码作了简化,并删掉了大部分注释,大家可以直接下载源码包,里面完整的注解,并带KEIL工程文件,断点也打好了,直接按ctrl+f5就行了.现在来看看这个多任务系统的原理:这个多任务系

6、统准确来说,叫作"协同式多任务".所谓"协同式",指的是当一个任务持续运行而不释放资源时,其它任务是没有任何机会和方式获得运行机会,除非该任务主动释放CPU.在本例里,释放CPU是靠task_switch()来完成的.task_switch()函数是一个很特殊的函数,我们可以称它为"任务切换器".要清楚任务是如何切换的,首先要回顾一下堆栈的相关知识.有个很简单的问题,因为它太简单了,所以相信大家都没留意过:我们知道,不论是CALL还是JMP,都是将当前的程序流打断,请问CALL和JMP的区别是什么?你会说:CALL可以RET,JMP不行.没错,但原因是啥呢?为啥CALL过去的就可以用RE

7、T跳回来,JMP过去的就不能用RET来跳回呢?很显然,CALL通过某种方法保存了打断前的某些信息,而在返回断点前执行的RET指令,就是用于取回这些信息.不用多说,大家都知道,"某些信息"就是PC指针,而"某种方法"就是压栈.很幸运,在51里,堆栈及堆栈指针都是可被任意修改的,只要你不怕死.那么假如在执行RET前将堆栈修改一下会如何?往下看:当程序执行CALL后,在子程序里将堆栈刚才压入的断点地址清除掉,并将一个函数的地址压入,那么执

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。