一个简单的不可剥夺型内核
最近看ucos-ii,看了前后台系统、不可剥夺型内核和可剥夺型内核,作为复习,写了个简单的不可剥夺型内核。
基本假设:
1。 任务自动让出CPU,即处于就绪态的任务运行一次后,该任务变为未就绪态
2。 和任务相关的后台事件或者其他任务可使任务再次处于就绪态
其实这个内核的目的仅仅是缩短任务响应时间,让系统不至于像前后台系统那样轮询完整个标志位才能再次执行到判断
源码:
1. 头文件:os.h
typedef unsigned int INT16U; typedef unsigned char INT8U; typedef struct { void (*OSTask)(void); }OS_TCB; #define MAX_TASK 16 // 最大任务数,最低级被TaskIdle占用 void OS_Init(void); void Task_Create(void (*task)(void), INT8U prio,INT8U status); void OS_Sched(void);
2. 源文件:os.c
#include "os.h" OS_TCB OSTCBTbl[MAX_TASK]; INT16U OSTaskRdy; // 任务就绪表,每一位表示一个任务,0表示未就绪,1表示就绪 INT16U TaskMask[16] = { 0x0001,0x0002,0x0004,0x0008, 0x0010,0x0020,0x0040,0x0080, 0x0100,0x0200,0x0400,0x0800, 0x1000,0x2000,0x4000,0x8000 }; // ======================================= // 空闲任务,无操作 // ======================================= static void TaskIdle(void) { } // ======================================= // 系统初始化函数 // ======================================= void OS_Init(void) { INT8U i; for(i = 0; i < MAX_TASK; i++) OSTCBTbl[i].OSTask = TaskIdle; // 所有指针都指向TaskIdle,以免出错 OSTaskRdy = 0x8000; // 最高位为空闲任务 } // ======================================= // 创建任务函数 // 注意,无参数检查,要求用户自己小心 // task:函数指针, // prio: 优先级,0-14 // status: 任务状态,0,1 // ======================================= void Task_Create(void (*task)(void), INT8U prio,INT8U status) { OSTCBTbl[prio].OSTask = task; if(status == 0) OSTaskRdy &= ~TaskMask[prio]; else if(status == 1) OSTaskRdy |= TaskMask[prio]; } // ======================================= // 调度函数 // 调度和运行任务 // ======================================= void OS_Sched(void) { INT8U i; // 查找处于就绪态的最高优先级任务 for(i = 0; i < MAX_TASK;i++) { if(OSTaskRdy & TaskMask[i]) break; } // 运行任务 OSTCBTbl[i].OSTask(); // 将任务切换到未就绪态,让出CPU if(i != 15) // 最低优先级为TaskIdle()任务占有,永远为就绪态 OSTaskRdy &= ~TaskMask[i]; }
3. 测试文件:main.c (芯片:MC9S12XDP512)
#include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ #include "os.h" extern INT16U OSTaskRdy; extern INT16U TaskMask[]; void Device_Init(void); void TaskA(void); void TaskB(void); void main(void) { /* put your own code here */ EnableInterrupts; Device_Init(); OS_Init(); Task_Create(TaskA,0,1); Task_Create(TaskB,1,1); for(;;) OS_Sched(); } void Device_Init(void) { PITMTLD0 = 199; PITMUX = 0x00; // 所有都接micro time base 0 // PIT1 PITLD1 = 4999; PITCE |= 0x02; // PIT1通道使能 PITINTE |= 0x02; // PIT1通道中断使能 PITCFLMT |= 0x80; // 使能PIT // PIT0 PITLD0 = 4999; PITCE |= 0x01; PITINTE |= 0x01; // PORT DDRB = 0xFF; // output } void TaskA(void) { PORTB_PB2 = ~PORTB_PB2; } void TaskB(void) { PORTB_PB3 = ~PORTB_PB3; } #pragma CODE_SEG NON_BANKED void interrupt 66 PIT0(void) { PITTF = 0x01; // 写1清零 OSTaskRdy |= TaskMask[0]; // 任务0处于就绪态 } void interrupt 67 PIT1(void) { PITTF = 0x02; OSTaskRdy |= TaskMask[1]; }
一个简单的不可剥夺型内核相关推荐
- 可剥夺型内核与不可剥夺型内核的区别
由于嵌入式系统只有一个CPU,因此在一个具体时刻只能允许多个任务中的一个任务使用CPU.根据系统中的任务获得使用CPU的权利的方式,多任务实时操作系统的内核分为可剥夺型内核和不可剥夺型内核两种类型.但 ...
- 可剥夺型内核与“不可剥夺型内核”
1.不可剥夺型内核 概念:不可剥夺型内核要求每个任务自我放弃 CPU 的所有权. 不可剥夺型调度法也称作合作型多任务,各个任务彼此合作共享一个CPU.异步事件还是由中断服务来处理.中断服务可以使一个高 ...
- uC/OS-II 学习笔记之:不可剥夺型内核与可剥夺型内核
// 更多原创"uC/OS-II学习笔记之:系列"基础及嵌入式相关知识详解,请访问可乐虎博客: http://blog.csdn.net/dcx1205 相信不会让您失望!! // ...
- 实时内核:可剥夺型与不可剥夺型
不可剥夺型内核 不可剥夺型内核(或非抢占式内核,Non-Preemptive Kernel) 不可剥夺型内核要求每个任务自我放弃CPU的所有权. 不可剥夺型调度法也称作合作型多任务,各个任务彼此合作共 ...
- netfilter编程实例——一个简单的防火墙
一.iptables防火墙netfilter介绍 Linux 防火墙包含两部分,内核 netfilter 和用户空间工具 iptables.管理员通过 iptables 工具集和内核打交道,将防火墙规 ...
- linux内核计算代码时间,完成一个简单的时间片轮转多道程序内核代码
<Linux 内核分析>实验二:How Does a Operating System Work? 1.函数调用堆栈和中断 在上一节实验中我们已经明白了,存储程序计算机的运行原理,就是通过 ...
- 4.9一个简单的多任务内核实例
第四章第9节 本节描述了一个简单多任务内核的设计和实现方法,这个内核包括两个特权级3的用户任务和一个系统调用中断过程. 本节给出的内核实例由两个文件构成.一个是使用as86语言编制的引导启动程序boo ...
- Linux内核分析:完成一个简单的时间片轮转多道程序内核代码
PS.贺邦 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 1.m ...
- ASP.NET Core Web API下事件驱动型架构的实现(一):一个简单的实现
很长一段时间以来,我都在思考如何在ASP.NET Core的框架下,实现一套完整的事件驱动型架构.这个问题看上去有点大,其实主要目标是为了实现一个基于ASP.NET Core的微服务,它能够非常简单地 ...
最新文章
- 通过NFS实现简单的文件共享
- SQL Server 跨数据库查询
- 推送提交到另一个分支
- Win10+tensorflow:SSD调试问题:Unable to open table file ../checkpoints/ssd_300_vgg.ckpt
- oracle天数加个随机数,如何给一个表某列加上指定的随机数
- 从Sun离职后,我“抛弃”了Java,拥抱JavaScript和Node
- Linux学习总结(六十六)打印一串数字的脚本
- Log4Net 配置日志按日期和日志级别分类写入
- 顺序查找、折半查找及索引顺序查找
- python爬取付费音乐包_用Python代码来下载任意指定网易云歌曲(超详细版)
- 神经网络学习小记录63——Keras 图像处理中注意力机制的代码详解与应用
- Android stuido中更改图片编辑软件
- 计算机网络计算题:时延
- Nodejs+MongoDB+WebRTC搭建视频通话协同应用
- 性能测试指标、监控平台
- java 监听控制台输入
- 海德汉角度编码器RCN727F与替代型号RCN8390F参数对比
- 【NIO详解】基于NIO的client与server
- CVPR 2023 论文分类汇总:一个专为计算机视觉领域研究者打造的学术资源宝库
- 炎炎夏日,谈一谈低功耗云终端的重要性
热门文章
- 肥波效果器合集 – FabFilter Total Bundle 2020.5 macOS
- jsp 前台页面 img base64图片显示方法
- arm c语言开发环境搭建,利用proteus学习ARM(LPC2103)之二:熟悉IAR C语言开发环境...
- Aha!设计模式(57)-装饰模式(1)
- 关于sublime text 4 的注册破解
- 推荐一款Linux本。
- 全栈开发学习路线总结(全网最详细的全栈开发资源汇总)
- 数据探索:相关性分析
- 实现 JavaScript 计算器的多种方案
- IDEA的web项目的创建极其服务器的配置