μ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 ...
随机推荐
- MSIL指令集
名称 说明 Add 将两个值相加并将结果推送到计算堆栈上. Add.Ovf 将两个整数相加,执行溢出检查,并且将结果推送到计算堆栈上. Add.Ovf.Un 将两个无符号整数值相加,执行溢出检查,并且 ...
- JPA(4)表表关联关系
在我们做数据库设计的时候,最烦的就是各种表之间的关联关系了,关联关系有:一对多,多对一,一对一,其中还有单向和双向的区别. 1.双向一对多及多对一映射:既然是双向,那么就是同一类的了:双向一对多关系中 ...
- No.003:Longest Substring Without Repeating Characters
问题: Given a string, find the length of the longest substring without repeating characters.Example:Gi ...
- 环境搭建二 secureCRT配置
上一篇里面讲到了虚拟机安装,以及secureCRT的远程连接.此篇文章介绍secureCRT的配置. 颜色设置 参考 http://jingyan.baidu.com/article/a681b0 ...
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q94-Q96)
Question 94You need to create a custom application that provides users with the ability to create a ...
- CoreAnimation动画(CALayer动画)
#pragma mark - CABasicAnimation动画 - (IBAction)basicAnimation:(UIButton *)sender { // 1.创建动画对象 CABasi ...
- JAVA基础学习day22--IO流四-对象序列化、管道流、RandomAccessFile、DataStream、ByteArrayStream、转换流的字符编码
一.对象序列化 1.1.对象序列化 被操作的对象需要实现Serializable接口 1.2.对象序列化流ObjectOutputStream与ObjectInputStream ObjectInpu ...
- 实验:传输层:UDP协议 学习笔记
一.传输层协议 从之前介绍的网络层协议来看,通信的两端是两台主机,IP数据报首部就标明了这两台主机的IP地址.但是从传输层来看,是发送方主机中的一个进程与接收方主机中的一个进程在交换数据,因此,严格地 ...
- Runtime(动态添加属性)
下面通过一个实例展示一下Runtime(动态添加属性)的用法 下面对运行时添加属性用到的策略参数进行补充: 这样看来,前面的NSString* name用的策略是retain nonatomic就知道 ...
- Java 之 内部类
(static修饰的成员属于整个类,而不属于单个对象) 定义:将一个类放到另一个类的内部定义,这个在内部定义的类就叫做内部类(也有的成嵌套类),包含内部类的类被称为外部类(也有的称宿主类). 1.非静 ...