μc/osⅡ简化版任务机制浅析
去年玩过一阵单片机,也用过μc/osⅡ的系统,但是就理解内核而言,整个即时操作系统还是过于冗杂,很多的东西很不适合初学者来动手操作,多方查找我发现他的任务机制可以进行功能的进一步简化,
可以类似于任务栈的方式,使用纯C写成而不用汇编代码,闲话少说上代码吧。
我的github上有我的渣代码=_=:https://github.com/lfkdsk
灵魂画作任务图:
随手就是灵魂画作=-=
1.主函数:
#include "OS_task.h"
#include "89c51.h"
#include "main.h"
#include "task_switch.h"
#include <reg52.h>
sbit K1=P0^;
void del10ms()
{
unsigned char a,b,c;
for (c=;c>;c--)
for(b=;b<;b++)
for(a=;a<;a++);
}
void task_1()
{
while()
{
if(K1==)
del10ms();
if(K1==)
{
task_switch();
}
}
} void task_2()
{
while()
{
if(K1==)
del10ms();
if(K1==)
{
task_switch();
}
}
} void task_3()
{ while()
{
if(K1==) //这里是五个放在任务栈里的空函数,只用里一个循环来循环监听按键,可以再循环中加入自己的东西,比如亮起小灯啊,什么的易于观察的现象
del10ms();
if(K1==)
{
task_switch();
}
}
} void task_4()
{
while()
{
if(K1==)
del10ms();
if(K1==)
{
task_switch();
}
}
} void task_5()
{
while()
{
if(K1==)
del10ms();
if(K1==)
{
task_switch();
}
}
}
void main(void)
{
// 载入函数 优先级 任务名 任务ID
task_load(,task_1, );
task_load(,task_2, );
task_load(,task_3, );
task_load(,task_4, );
task_load(,task_4, );
OS_Start();
}
2.任务装载(核心):
#ifndef __OS_TASK_H__
#define __OS_TASK_H__
//任务功能
//最大任务数
#define MAX_TASK 5
//堆栈深度
#define SRACK_DEPTH 20
//保存切换任务时软件压栈字节数
#define Num_PUSH_bytes 13
//程序控制块结构
typedef struct
{
unsigned char Task_SP; //任务堆栈指针
unsigned char Priority; //优先级,值越小,优先级越高 }PCB; extern idata volatile PCB OS_PCB[MAX_TASK];//定义堆栈
extern volatile unsigned char OS_TASK_ID;//定义任务ID
void task_load(unsigned char PRI,unsigned int FN,unsigned char T_ID);
void OS_Start(T_ID);
#endif
//系统任务程序
#include "OS_task.h"
#include "89c51.h"
#include "main.h"
#include "task_switch.h"
#include <reg52.h>
//程序控制块
idata volatile PCB OS_PBC[MAX_TASK]; //volatile是为了每次必须读值 这个是任务栈的最大任务数,任务栈名字叫PCB=-= //当前运行任务的ID号
volatile unsigned char OS_TASK_ID; //声明堆栈,由最大任务数和栈深定义的二维数组
unsigned char idata OS_Stack[MAX_TASK][SRACK_DEPTH]; //任务装载函数
void task_load(unsigned char PRI,unsigned int FN,unsigned char T_ID)
{
OS_PCB[T_ID].Priority=PRI; //因为是简化的,所以我手动设置了优先级
OS_PCB[T_ID].Task_SP=OS_Stack[T_ID]+; //这里取出了当前正在运行的任务的函数地址的高八位存为指针
OS_Stack[T_ID][] = (unsigned int)FN & 0xff; //低八位存0
OS_Stack[T_ID][] = (unsigned int)FN << ; //高八位存在1里
} //任务运行函数
void OS_Start(T_ID)
{
OS_TASK_ID=T_ID;
SP=OS_PCB[OS_TASK_ID].Task_SP; //传入一个id,然后把sp指针指向它,sp指针是系统的任务指针,用于指向执行任务的
//之后就不管了,就会按照自己的方式运行了
}
3.任务切换:
//任务交换程序
#include "OS_task.h"
#include "89c51.h"
#include "main.h"
#include "task_switch.h"
#include <reg52.h>
//任务调度函数
void task_switch(){
static int i;
unsigned char j,MAX;
OS_PCB[OS_TASK_ID].Task_SP = SP; //先把运行的指针地址存到该任务id对应的指针空间中
for(i=;i<MAX_TASK;i++)
{
MAX=j; //然后在循环找到优先级最高的(Priority最小的)
if(OS_PCB[j].Priority<OS_PCB[i].Priority||j!=OS_TASK_ID) //如果优先级高,则切换之
{
j=i;
}
}
OS_TASK_ID=j;
SP = OS_PCB[OS_TASK_ID].Task_SP;
}
好了,到这我们的精简版任务机制就搞定了,大家可以去试试啦,利用类堆栈的存储函数运行地址的方式进行挂起操作,来循环运行任务
么么哒,求赞=_=
μc/osⅡ简化版任务机制浅析的更多相关文章
- Linux模块机制浅析
Linux模块机制浅析 Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...
- InnoDB的锁机制浅析(二)—探索InnoDB中的锁(Record锁/Gap锁/Next-key锁/插入意向锁)
Record锁/Gap锁/Next-key锁/插入意向锁 文章总共分为五个部分: InnoDB的锁机制浅析(一)-基本概念/兼容矩阵 InnoDB的锁机制浅析(二)-探索InnoDB中的锁(Recor ...
- InnoDB的锁机制浅析(All in One)
目录 InnoDB的锁机制浅析 1. 前言 2. 锁基本概念 2.1 共享锁和排它锁 2.2 意向锁-Intention Locks 2.3 锁的兼容性 3. InnoDB中的锁 3.1 准备工作 3 ...
- Linux模块机制浅析_转
Linux模块机制浅析 转自:http://www.cnblogs.com/fanzhidongyzby/p/3730131.htmlLinux允许用户通过插入模块,实现干预内核的目的.一直以来,对l ...
- 【ARM-Linux开发】Linux模块机制浅析
Linux模块机制浅析 Linux允许用户通过插入模块,实现干预内核的目的.一直以来,对linux的模块机制都不够清晰,因此本文对内核模块的加载机制进行简单地分析. 模块的Hello World! ...
- typecho流程原理和插件机制浅析(第二弹)
typecho流程原理和插件机制浅析(第二弹) 兜兜 393 2014年04月02日 发布 推荐 1 推荐 收藏 14 收藏,3.7k 浏览 上一次说了 Typecho 大致的流程,今天简单说一下插件 ...
- typecho流程原理和插件机制浅析(第一弹)
typecho流程原理和插件机制浅析(第一弹) 兜兜 393 2014年03月28日 发布 推荐 5 推荐 收藏 24 收藏,3.5k 浏览 虽然新版本0.9在多次跳票后终于发布了,在漫长的等待里始终 ...
- oracle的resetlogs机制浅析
oracle的resetlogs机制浅析 alter database open resetlogs 这个命令我想大家都很熟悉了,那有没有想过这个resetlogs选项为什么要用?什么时候用?它的原理 ...
- webpack模块机制浅析【一】
webpack模块机制浅析[一] 今天看了看webpack打包后的代码,所以就去分析了下代码的运行机制. 下面这段代码是webpack打包后的最基本的形式,可以说是[骨架] (function(roo ...
随机推荐
- 【转载】JS获取屏幕大小
前些日子需要给项目的弹窗上面罩,因为项目左侧是树形菜单,右侧嵌套的iframe ,iframe 的内容不是固定大小,那么,面罩的大小也就不是固定的 因此,用到了JQuery获取当前页面的窗口大小,于是 ...
- 运用Microsoft.DirectX.DirectSound和Microsoft.DirectX实现简单的录音功能
1.首先要使用Microsoft.DirectX.DirectSound和Microsoft.DirectX这两个dll进行录音,需要先安装microsoft directx 9.0cz这个组件, 百 ...
- 与众不同 windows phone (47) - 8.0 其它: 锁屏信息和锁屏背景, 电池状态, 多分辨率, 商店, 内置协议, 快速恢复
[源码下载] 与众不同 windows phone (47) - 8.0 其它: 锁屏信息和锁屏背景, 电池状态, 多分辨率, 商店, 内置协议, 快速恢复 作者:webabcd 介绍与众不同 win ...
- 状态压缩DP--Mondriaan's Dream
题目网址:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=110044#problem/A Description Squares and ...
- transfer between javabean and map
1. java bean 转化成 map import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.P ...
- js 倒计时 跳转
1. setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. setTimeout() 只执行 code 一次.如果要多次调用,请使用 setInterval() 或者让 code ...
- R语言-妹子被追后的选择分析
前提假设 妹子们一生中可以遇到100个追求者,追求者的优秀程度符合正态分布: 每个妹子都具备判断并比较追求者优秀程度的能力: 接受或拒绝一个追求者后永远无法后悔. 那么,问题来了 当遇到追求者时,如何 ...
- JavaScript来实现打开链接页面(转载)
在页面中的链接除了常规的方式以外,如果使用javascript,还有很多种方式,下面是一些使用javascript,打开链接的几种方式: 1.使用window的open方法打开链接,这里可是在制定页面 ...
- netty Failed to submit an exceptionCaught() event异常
最近测试netty开发的服务端应用在关闭时,出现下列异常: ->###WARN#########nioEventLoopGroup-3-2###io.netty.util.internal.lo ...
- DigitalOcean上SSH Key的创建(附DigitalOcean邀请)
DigitalOcean是一家云主机商家,最低配置512M内存,20G的SSD,每月只有5刀.半个月前刚刚在这上面买了一个VPS,创建Droplet的时候看见创建SSH Key的时候就有点懵,不知道这 ...