手写嵌入式操作系统

news/2025/1/15 23:06:19/

学习之前需要安装keil
参照Keil uvision5安装

#include<stc8h.h>
#include<intrins.h>
#define MAX_TASKS 2    //假设当前系统只有2个task
#define MAX_TASK_DEP 32unsigned char idata task_sp[MAX_TASKS];  //任务的堆栈指针
unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP];//每个task任务的堆栈
unsigned char task_id;//当前任务号,从0开始
//当前任务状态
typedef enum{TASK_RUNNING,//运行状态TASK_SUSPENED  //挂起状态
}TaskStatus;typedef struct{unsigned char id;//任务idTaskStatus status;//任务状态unsigned int delay_count;//延迟计数器unsigned int delay_duration;//延迟时间
}Task;Task idata tasks[MAX_TASKS]={{0,TASK_RUNNING,0,0},//两个任务都是默认运行状态,不延迟{0,TASK_RUNNING,0,0},};void Timer0_init(void);
void sleep(unsigned int,unsigned int);//tid  delay_msvoid sleep(unsigned int tid,unsigned int delay_ms)
{tasks[task_id].status=TASK_SUSPENED;tasks[task_id].delay_count=0;tasks[task_id].delay_duration=delay_ms;
}void Timer0_init()
{AUXR |= 0x80;		//定时器时钟1T模式TMOD &= 0xF0;		//设置定时器模式TL0 = 0x40;		//设置定时初始值TH0 = 0xA2;		//设置定时初始值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时}void Delay1000ms()		//@24.000MHz
{unsigned char i, j, k;_nop_();_nop_();i = 122;j = 193;k = 128;do{do{while (--k);} while (--j);} while (--i);
}//定义一个任务切换的函数(任务调度器)
void task_switch(){task_sp[task_id]=SP;task_id=task_id+1;if(task_id==MAX_TASKS)task_id=0;SP=task_sp[task_id];}void task0(){//第0号任务//static unsigned int a=3;//避免两个变量分配到相同的寄存器P5M0=0x00;P5M1=0x00;P53=1;while(1) {//a=a+3;//检查自己的状态,如果自己是睡眠,就应该交给其他任务去执行if(tasks[0].status==TASK_SUSPENED){task_switch();continue;}//Delay1000ms();sleep(0,1000);P53=~P53;task_switch();}
}void task1(){//第1号任务//static unsigned int b=5;P4M1=0x00;P4M0=0x00;P2M0=0x00;P2M1=0x00;P27=0;while(1) {//b=b+5;//检查自己的状态,如果自己是睡眠,就应该交给其他任务去执行if(tasks[1].status==TASK_SUSPENED){task_switch();continue;}//Delay1000ms();sleep(1,1000);P27=~P27;task_switch();}
}void Timer0_ISR(void) interrupt 1{//系统的定时器中断,每隔1毫秒执行一次中断函数unsigned char i;for(i=0;i<MAX_TASKS;i++){if(tasks[i].status==TASK_SUSPENED) tasks[i].delay_count++;if(tasks[i].delay_count>=tasks[i].delay_duration) tasks[i].delay_count=0;//睡眠结束}
}void Timer1_init()
{AUXR |= 0x40;		//定时器时钟1T模式TMOD &= 0x0F;		//设置定时器模式TL0 = 0xA0;		//设置定时初始值TH0 = 0xF6;		//设置定时初始值TF0 = 0;		//清除TF0标志TR0 = 1;		//定时器0开始计时}void Timer1_ISR(void) interrupt 3{task_switch();//在timer1中的中断,自动进行任务切换
}//加载任务的函数,把一个task的函数指针放入对应的堆栈空间里面
//fn是一个函数指针,数据类型是int 16位的
//tid task_id 是8位的0,1
void task_load(unsigned int fn,unsigned char tid){task_sp[tid]=task_stack[tid]+1; //加载一个任务进入栈task_stack[tid][0]=fn& 0xff;//取低8位task_stack[tid][1]=fn>> 8 ;//取高8位}void main(){Timer0_init();Timer1_init();task_load(task0,0);//把task0装到内存里task_load(task1,1);//把task1装到内存里task_id=0;SP=task_sp[0];}

http://www.ppmy.cn/news/1056048.html

相关文章

每日一学——认识路由器

路由器是一种网络设备&#xff0c;它用于在计算机网络中转发数据包。它能够在不同的网络之间选择最佳路径&#xff0c;将数据从源地址传输到目的地址。 路由器工作原理&#xff1a; 路由表&#xff1a;路由器内部有一个路由表&#xff0c;它记录了网络的连接关系和路径。路由器…

VUE id回写name的问题

起因 我们有部门&#xff0c;单位&#xff0c;传的是id&#xff0c;但是页面不管显示&#xff0c;还是回写&#xff0c;新增都要展示单位名/部门名。这个其实是前端的事情&#xff0c;但是我目前是前端也是我做&#xff0c;我们使用的是vue3&#xff0c;这个问题用List可能不好…

【GeoDa实用技巧100例】022:geoda生成空间权重矩阵(邻接矩阵、距离矩阵)

geoda生成空间权重矩阵(邻接矩阵、距离矩阵),车式矩阵、后式矩阵、K邻接矩阵。 文章目录 一、概述二、“车式”邻接的gal文档生成三、“后式”邻接gal文档生成四、k最近邻居gat文档生成五、查看gal和gat文档一、概述 空间权重矩阵(或相应的表格形式)一般需要用计算机软件生…

【Docker入门第一篇】

Docker简介 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。 容器是完全使…

使用Coding对java项目进行自动化的部署 (亲测有用)

Coding是啥嘞&#xff1f;看看百度百科把 https://baike.baidu.com/item/coding/8921246?fraladdin 普通部署和自动化部署比较 普通部署&#xff1a;打jar包->将jar包上传到服务器->执行java -jar命令&#xff0c;好像也不是很麻烦… coding自动化部署&#xff1a;提交…

在axios中获取文件上传进度

1.在axios 全局配置的文件中加入一个postFile 方法在上传文件时调用。 export function postFile(url, params,config) {return new Promise((resolve, reject) > {axios.post(url, params,config).then(res > {resolve(res);}).catch(err > {reject(err);})}) } 2.…

UnionTech OS(统信桌面操作系统)安装 g++ 和 cmake

文章目录 前言一、debian 10简介二、安装 g三、安装cmake参考资料 前言 统信桌面操作系统支持x86、龙芯、申威、鲲鹏、飞腾、兆芯等国产CPU平台&#xff0c;基于debian 10.x 的稳定版本&#xff0c;长期维护的统一内核版本(4.19)。 一、debian 10简介 Debian 10 是一款广泛使…