使用KEIL C51实现的简单合作式多任务操作系统内核(单片机实现版本)

2023-05-16

基于网上网友的代码,自己在单片机上实现, 特此记录分享之。

基于https://blog.csdn.net/yyx112358/article/details/78877523

//使用KEIL C51实现的简单合作式多任务操作系统内核

#include <regx52.H>
#include <INTRINS.H>

typedef unsigned char u8;
typedef unsigned int u16;

sbit LED1 = P2 ^ 0;
sbit LED2 = P2 ^ 1;
sbit LED3_idle = P2 ^ 3;

//两个宏定义是为了保护现场,不被定时中断打乱。
//主要用于需要一次性运行完毕的代码中。
#define OPEN_SYS_ISR() {EA=1;TR2=1;}
#define CLOSE_SYS_ISR() {EA=0;TR2=0;TF2=0;}

#define OS_TASK_STACK_SIZE (2+13+2*3)//存放断点2B,中断函数可能压栈13B,子程序每嵌套一层2B

#define OS_TASK_NUM 2

typedef struct OS_TASK_ST
{
    u8  delay;		//当前延时剩余时间
    u8  stack[OS_TASK_STACK_SIZE]; //私有堆栈
    u8  sp;			//私有堆栈指针
} OS_TASK; 			//任务工作块。

data OS_TASK os_task[OS_TASK_NUM];	//必须定义为data(因堆栈只能在data区)
data u8 os_idle_stack[15];


void os_switch(void);
void os_idle(void);
//void os_update_time(void);
void os_load(u8 id, void(*func));
void os_delay(u8 id, u8 delay);
void LED_Driver();
void os_task_0(void);
void sys_init(void);
void delay(u16 i);

/*******************************************************************************
* 函 数 名         : Timer2 Init
* 函数功能		   : 定时器0初始化,用于系统时钟
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer2_init()
{
    RCAP2H = (0xFFFF - 10000) / 256;
    RCAP2L = (0xFFFF - 10000) % 256;	//12MHz晶振下定10ms,自动重装
    TH2 = RCAP2H;
    TL2 = RCAP2L;					//定时器2赋初值
    T2CON = 0;					//配置定时器2控制寄存器,这里其实不用配置,T2CON上电默认就是0,这里赋值只是为了演示这个寄存器的配置
    T2MOD = 0;					//配置定时器2工作模式寄存器,这里其实不用配置,T2MOD上电默认就是0,这里赋值只是为了演示这个寄存器的配置

    IE = 0xA0;	//1010 0000开总中断,开外定时器2中断,可按位操作:EA=1; ET2=1;
    TR2 = 1;		//启动定时器2
}

void LED_Driver()
{
    LED1 = ~LED1;
}

void os_idle(void)
{
    while (1)
    {
        LED3_idle = ~LED3_idle;
        os_switch();
    }
}

/*
 *任务调度,转向当前延时时间到且优先级最高(id较小)任务
 而在一般的应用中,我们往往需要一个软件延时。例如:按键去抖、周期性采样等等。
 所以,这就要求有一个软件定时器功能。因此,修改调度器如下:
首先定义任务控制器数据结构,加入一个延时记录:
 */
void os_switch(void)//任务切换
{
    u8 i = OS_TASK_NUM;
    do
    {
        i--;
        if (os_task[i].delay == 0)//如果有任务延时时间到,则跳转至相应任务
            SP = os_task[i].sp;
    }
    while (i); //否则不改变SP,继续执行os_idle()
}

/*
 *    更新任务延时表
 *    注:应定时更新,最好放入定时器中断

void os_update_time(void)
{
    u8 i = OS_TASK_NUM;
    do
    {
        i--;
        if(os_task[i].delay)
            os_task[i].delay--;
    }
    while(i);
}
 */

//修改任务工作块并跳转入os_idle()进行任务切
void os_delay(u8 id, u8 delay)
{
    TR2 = 0;//关中断
    {
        os_task[id].delay = delay;      //延时设定
        os_task[id].sp = SP;             //保存SP
        SP = os_idle_stack + 1;            //SP指向os_idle_stack[1]
        //os_delay()结束后跳转os_idle()
    }
    TR2 = 1;
}

void os_load(u8 id, void(*func))
{
    os_task[id].sp = os_task[id].stack + 1;	//私有堆栈指针指向私有堆栈
    os_task[id].stack[0] = (u16)func & 0xFF;//私有堆栈栈底存放任务函数入口
    os_task[id].stack[1] = (u16)func >> 8;
}


void os_task_0(void)
{
#define OS_CUR_ID  (0)

    //static u8 i=0;

    //KEIL一般分配临时变量在RAM不在堆栈
    //因此为了防止任务之间改写凡是作用域跨越os_delay()应作为static

    while (1)
    {
        LED1 = ~ LED1;
        os_delay(OS_CUR_ID, 1);
    }

#undef OS_CUR_ID
}

void os_task_1(void)
{
#define OS_CUR_ID  (1)

    //static u8 i=0;

    //KEIL一般分配临时变量在RAM不在堆栈
    //因此为了防止任务之间改写凡是作用域跨越os_delay()应作为static

    while (1)
    {
        //LED_Driver();
        LED2 = ~ LED2;
        os_delay(OS_CUR_ID, 1);
    }

#undef OS_CUR_ID
}

/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
    while (i--);
}

void sys_init()
{
    u8 i;
    for (i=0; i<4; i++)
    {
        LED_Driver();
        delay(10000);
    }
}

void main()
{
    //…初始化外设
    sys_init();

    //…初始化os所用定时器

    Timer2_init();

    //…初始化其它任务控制器
    os_load(0, os_task_0);
    os_load(1, os_task_1);


    os_idle_stack[0] = (u16)os_idle & 0xFF;
    os_idle_stack[1] = (u16)os_idle >> 8;
    SP = os_task[0].sp;	//运行任务0

    return;	//跳转,永不返回。
}



//12MHz晶振下定10ms,自动重装
void timer2() interrupt 5
{
    u8 i = OS_TASK_NUM;
    //EA=0;
    //ET2=0;
    //TF2=0;
    //!!!注意!!!定时器2必须由软件对溢出标志位清零,TF2=0;硬件不能清零,
    //这里与定时器0和定时器1不同!!!
    CLOSE_SYS_ISR();

    do
    {
        i--;
        if (os_task[i].delay)
            os_task[i].delay--;
    }
    while (i);

    OPEN_SYS_ISR();
}

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用KEIL C51实现的简单合作式多任务操作系统内核(单片机实现版本) 的相关文章

  • Python3中的configparser模块

    configparser模块简介 该模块适用于配置文件的格式与windows ini文件类似 xff0c 可以包含一个或多个节 xff08 section xff09 xff0c 每个节可以有多个参数 xff08 键 61 值 xff09
  • CSDN竞赛第24期

    CSDN编程竞赛报名地址 xff1a https edu csdn net contest detail 38 这次写完第一道题时遇到一个奇怪的情况 xff1a 一直在 运行中 xff0c 然后发现每道题输入做任意代码都出现一直运行中 跟小
  • [Python开发] 使用python读取图片的EXIF

    使用python读取图片的EXIF 方法 使用PIL Image读取图片的EXIF 使用https pypi python org pypi ExifRead 读取图片的EXIF xff0c 得到EXIF标签 xff08 dict类型 xf
  • Partial Least Squares Regression 偏最小二乘法回归

    介绍 定义 偏最小二乘回归 多元线性回归分析 43 典型相关分析 43 主成分分析 输入 xff1a n m 的预测矩阵 X n p 的响应矩阵 Y 输出 X 和 Y 的投影 分数 矩阵 T U R n l 目标 xff1a 最大化 cor
  • 唐诗生成器

    使用唐诗语料库 xff0c 经过去噪预处理 分词 生成搭配 生成主题等过程 xff0c 生成唐诗 csdn下载地址 xff1a http download csdn net detail lijiancheng0614 9840952 gi
  • 使用TensorFlow-Slim进行图像分类

    参考 https github com tensorflow models tree master slim 使用TensorFlow Slim进行图像分类 准备 安装TensorFlow 参考 https www tensorflow o
  • 使用TensorFlow Object Detection API进行图像物体检测

    参考 https github com tensorflow models tree master object detection 使用TensorFlow Object Detection API进行图像物体检测 准备 安装Tensor
  • 双网卡下使用udp带来的问题

    今天在工程人员现场布置程序时 xff0c 出了一个疑难问题 xff0c 客户端发送的UDP包服务程序能收到 xff0c 但是服务程序收到的包的ip地址很随机 xff0c 造成在生成唯一ID的时候出现问题 xff0c 经过仔细排查 xff0c
  • 帧融合的功能(慢镜头的制作)

    转自 xff1a http mc2109 blog 163 com blog static 253694620087217213706 帧融合的功能 xff08 慢镜头的制作 xff09 2008 08 21 19 02 13 分类 xff
  • 无人驾驶二 卡尔曼滤波与PID控制

    链接 xff1a https pan baidu com s 108cN2yyKOiouiABXTYtGOw pwd 61 1234 提取码 xff1a 1234 卡尔曼滤波形象的描述见 xff1a 卡尔曼滤波原理及实现 曦爷的博客 CSD
  • JetsonTX2和TX2I的镜像备份与恢复及内核、DTB更新

    为了HDMI转CSI的图像采集模块能被识别 xff0c 可以成功采集HDMI视频图像 xff0c 最近在研究JetsonTX2和TX2I的刷机 镜像备份与恢复 xff0c 以及内核和DTB的刷入 按照https elinux org Jet
  • Dockerfile详解超全

    Dockerfile详解 环境介绍指令介绍FROMMAINTAINERLABELADDCOPYEXPOSEENV在Dockerfile中使用变量的方式 RUNCMDRUN amp amp CMDENTRYPOINTVOLUMEUSERWOR
  • c/c++调用libcurl库发送http请求的两种基本用法

    libcurl主要提供了两种发送http请求的方式 xff0c 分别是Easy interface方式和multi interface方式 xff0c 前者是采用阻塞的方式发送单条数据 xff0c 后者采用组合的方式可以一次性发送多条数据
  • ROS(二):读取摄像头图像节点并发布topic以及订阅

    读取树莓派摄像头信息发布到ROS话题中 摄像头为树莓派第二代摄像头 ros为kinetic版本 ubuntu系统 参考文档链接 http www ncnynl com archives 201611 1067 html http blog
  • 如何查看/确认linux是否能上网

    很多linux系统没有可视化界面 xff0c 无法通过界面访问一个外网的地址 xff08 比如 www baidu com 来确认是否能上网 在这种情况下 xff0c 确认linux服务器是不是能联网的方法很简单 xff0c 只需要ping
  • Ubuntu从源码编译LGSVL搭建环境

    上一周借助校园里面的教育网终于git clone成功了Apollo5 5的官方master repository xff0c 并build其gpu版本的模拟器 xff0c 根据最新的Apollo5 5 master文件描述 xff0c 桥接
  • #移动开发者大会#总结

    移动开发者大会 总结 xff08 有限的发言者 xff09 xff1a 李开复 xff1a 1 Android将在中国一骑绝尘 今年底中国将有4000万台Android手机 xff0c 2000万台iPhone 明年底总数会翻一倍 xff0
  • 河北金融学院赴京参加2011移动开发者大会有感

    记从被邀请到参加移动开发者大会的全过程 10月底 xff0c 突然接到潘永强老师的邀请 参加2011移动开发者大会 xff0c 当时我们真的很兴奋 xff0c 因为对于我们来说 xff0c 去北京是第一次 xff0c 去参加如此大型的会议更
  • 2011河北金融学院CSDN高校俱乐部动员大会

    2011年11月24日下午二点 xff0c 我校CSDN高校俱乐部动员大会在教学楼B123举行 该次大会主要针对大一学生召开 xff0c 号召大家了解并加入CSDN高校俱乐部 俱乐部指导老师王洪涛老师 计算机协会指导老师杜光辉老师 以及优秀
  • “激情与梦想 我的程序员之路”—2012高校巡讲

    2012年3月29日下午2点半 xff0c CSDN高校俱乐部项目主管潘永强老师在我校进行了一场以 激情与梦想 xff0c 我的程序员之路 为主题的演讲 信息管理与工程系团总支书记陈春燕 指导老师王洪涛以及杜光辉 刘冲等7位老师出席了该次讲

随机推荐

  • TX2下编译qt程序步骤

    1 将 aarch64 qt 5 15 1 tar bz2 解压到 opt 2 在 bashrc 添加qt的库和路进 art 64 art desktop opt cat bashrc tail n 2 export LD LIBRARY
  • 电子政务三网架构

    国家电子政务网络架构由政务内网 政务专网 政务外网组成 政务内网是涉密网络 xff0c 在上面传输涉密公文 xff0c 属高度机密的网络 xff0c 覆盖范围尽可能小 xff0c 它与国际互联网物理隔离 政务专网是党政机关非涉密办公网 xf
  • SDN介绍(什么是SDN)

    SDN介绍 一 xff0e 什么是SDN 二 xff0e SDN解决什么问题 xff1f 三 xff0e 传统网络概念和结构体系传统网络数据控制与转发 xff1a 传统网络架构 xff1a 四 xff0e SDN概述SDN xff08 So
  • 我的2011--快乐最重要

    呵呵 xff0c 听着郭德纲和于谦老师的相声 xff0c 开始写这篇文章 xff0c 刚毕业不到六个月 xff0c 就换了一份工作 xff0c 很多事情都在意料之外 xff0c 很多事情又在意料之中 xff0c 总之 xff0c 以后回忆到
  • 朱金灿:韧性、悟性、具备快速学习能力是我喜欢的特质

    英雄会是CSDN旗下针对国内IT技术领域专家展示和交流的平台 通过线下线上的互动形式 xff0c 为CSDN社区专家提供更多学习 合作 宣传的机会 英雄会后续将在北上广深等国内一二线城市建立分会 xff0c 各个分会后期将组织技术交流活动
  • 本地vnc(TigerVNC)远程linux server,提示拒绝连接

    可能原因 amp 分析 xff1a 可确认下初始的系统环境变量是否被改动 xff0c 如新安装的anaconda自动添加到环境变量 xff0c 且放置在系统的原有环境变量的前面 xff0c 可尝试将后加的环境变量编辑到后面 xff0c 再重
  • 高质量嵌入式Linux C编程第一次博客作业

    1 xff1a linux 与 Unix的关系 xff1f 某些PC机的Unix和Linux在实现方面相类似 几乎所有的商业Unix版本都基本支持同样的软件 程序设计环境和网络特性 然而 xff0c Linux和Unix的商业版本依然存在许
  • java enum(枚举)使用详解 + 总结

    enum 的全称为 enumeration xff0c 是 JDK 1 5 中引入的新特性 xff0c 存放在 java lang 包中 下面是我在使用 enum 过程中的一些经验和总结 xff0c 主要包括如下内容 xff1a 1 原始的
  • RBAC用户、角色、权限、组设计方案

    设计一个灵活 通用 方便的权限管理系统 在这个系统中 xff0c 我们需要对系统的所有资源进行权限控制 xff0c 那么系统中的资源包括哪些呢 xff1f 我们可以把这些资源简单概括为静态资源 xff08 功能操作 数据列 xff09 和动
  • ssh 怎样以root用户登录

    sudo vim etc ssh sshd config 找到并用 注释掉这行 xff1a PermitRootLogin prohibit password 新建一行 添加 xff1a PermitRootLogin yes 重启服务 s
  • python 函数内部修改外部变量

    如果内部修改外部变量需要nonlocal xff0c global def f1 print 34 in f1 34 num 61 111 def f2 nonlocal num num 61 222 print num f2 print
  • python 列表生成式将两个列表组合

    l1 61 1 2 3 4 5 l2 61 10 20 30 40 50 l3 61 x y for x in l1 for y in l2 if y x 61 61 10 l4 61 x y for x in l1 for y in l2
  • python monkey脚本

    import wx import wx xrc import os import threading import thread import logging import re import time import csv import
  • tiny210 ubuntu下sd卡分区

    1 ubuntu实现SD Flasher exe原理 友善官方给出的烧录uboot的工具是SD Flasher exe xff0c 这个工具只能在windows下使用 由于本人电脑无法打开这个工具 xff0c 所以在windows下无法制作
  • MonkeyScript API 文档

    一 前言 本文档记录了和 MonkeyScript 相关的 API 文档 xff0c 由承香墨影整理 所有 API 描述均来自 MonkeySourceScript java 也可以自行查看源码 xff0c 在线阅读地址 xff1a htt
  • mysql教程01

    常用数据类型如下 xff1a 整数 xff1a int xff0c bit小数 xff1a decimal字符串 xff1a varchar char日期时间 date time datetime枚举类型 enum decimal表示浮点数
  • mysql02

    查看版本 xff1a select version 查看所有数据库 xff1a show databases xff1b 创建数据数据库 xff1a create database test01 charset 61 utf8 使用数据库
  • 类linux驱动模块框架module_init(init_fun)在STM32上的实现

    原文 xff1a https zhuanlan zhihu com p 81309285 设计思想 利用编译器的特性 xff0c 在程序编译时将各模块初始化函数顺序存放到内存的指定地址 xff0c 然后在程序运行时main函数从这块内存区域
  • 国内如何快速下载keil的pack文件包(干货)

    想要在国内如何快速下载keil的pack文件包 xff0c 真的是有点麻烦的 xff0c 不过网上找了一个好方法 xff0c 可以记录下 在keil的pack 官网 MDK5 Software Packs keil com 查找自己想要的p
  • 使用KEIL C51实现的简单合作式多任务操作系统内核(单片机实现版本)

    基于网上网友的代码 xff0c 自己在单片机上实现 xff0c 特此记录分享之 基于https blog csdn net yyx112358 article details 78877523 使用KEIL C51实现的简单合作式多任务操作