手写嵌入式操作系统(基于stm8单片机)

2023-11-16

#include <stc8h.h>
#include <intrins.h>
#define MAX_TASKS 2 //简化方面,我们当前操作系统只有2个task
#define MAX_TASK_DEP 32

unsigned 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_SUSPENDED  //挂起状态
} TaskStatus;


typedef struct{
	  unsigned char id; //任务id
	  TaskStatus status; //任务状态
	  unsigned int delay_count; // 延迟计数器
	  unsigned int delay_duration;//延迟时间
}Task ;

Task idata tasks[MAX_TASKS] = {
	{0, TASK_RUNNING,0,0},
	{1, TASK_RUNNING,0,0},   //两个任务,都是默认运行状态,不延时,
};

void Timer0_init(void); //原型函数 
void sleep(unsigned int , unsigned int );// tid, delay_ms

void sleep(unsigned int task_id , unsigned int delay_ms){
   	tasks[task_id].status = TASK_SUSPENDED;
	  tasks[task_id].delay_count = 0;
	  tasks[task_id].delay_duration = delay_ms;
	
}

void Timer0_init(){
   AUXR |= 0x80;		//定时器时钟1T模式
		TMOD &= 0xF0;		//设置定时器模式
    EA = 1; // 全局中断允许
    ET0 = 1; // 定时器0中断允许
	  TR0 = 1;		//定时器0开始计时
	TL0 = 0x40;		//设置定时初始值
		TH0 = 0xA2;		//设置定时初始值
	
}


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_sp里面。
	
	 task_id = task_id + 1; //任务加1
	 if(task_id == MAX_TASKS){	 
		 task_id = 0;
	 } 
	 SP = task_sp[task_id];
}



void task0(){
	//第0号任务, 代表第0个小朋友做的事情。
	//static unsigned int a = 3;
	P5M0 = 0x00;
  P5M1 = 0x00;
	
  P53 = 1;
	while(1){
		//a = a + 3;
		//Delay1000ms();
		//检查自己的状态。如果自己是睡眠状态,就应该交给别的task去执行
		if(tasks[0].status == TASK_SUSPENDED){
			task_switch();
			continue;
		}
		
		sleep(0,1000);
		P53 = ~P53;
		task_switch();
	}
}

void task1(){
	//第1号任务, 代表第1个小朋友做的事情。
	//static unsigned int b = 5;
	P4M1 = 0x00;
	P4M0 = 0x00;
	P2M1 = 0x00;
	P2M0 = 0x00;
	P27 = 0;
	
	
	while(1){
				//检查自己的状态。如果自己是睡眠状态,就应该交给别的task去执行
		if(tasks[1].status == TASK_SUSPENDED){
			task_switch();
			continue;
		}
		//b = b + 5;
		//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_SUSPENDED){
				tasks[i].delay_count++;
			}
		  
			if(tasks[i].delay_count >= tasks[i].delay_duration){
				tasks[i].status = TASK_RUNNING; //睡眠结束		 
				tasks[i].delay_count = 0;
			}
		 
	 }
	   
}

void Timer1_Init(void)		//100微秒@24.000MHz
{
	AUXR |= 0x40;			//定时器时钟1T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0xA0;				//设置定时初始值
	TH1 = 0xF6;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
}

void Timer1_ISR(void) interrupt 3{
	task_switch();// 在timer1中的中断,进行任务切换。
}



//幼儿园老师(操作系统,加载任务的函数)
//fn fn是一个函数的指针,注意数据类型是int 16位的。
//tid task id, 是8位的, 0,1 
//下面函数的作用就是把一个task的函数指针放入对应的堆栈空间里面。
void task_load(unsigned int fn, unsigned char tid){
	task_sp[tid] =  task_stack[tid] + 1; // 把任务的指针往下一个空间挪一格,两个char了
	task_stack[tid][0] = fn& 0xff;
	task_stack[tid][1] = fn>>8;	
}


void main(){
	   Timer0_init();
		 Timer1_Init();
	   task_load(task0,0);// 把task0 装载到内存中。
	   task_load(task1,1);// 把task1 装载到内存中。
	   task_id = 0;   
	   SP = task_sp[0];
}




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

手写嵌入式操作系统(基于stm8单片机) 的相关文章

随机推荐

  • typora+阿里云OSS+PicGO进行图床设置

    typora 阿里云OSS PicGO进行图床设置 文章目录 typora 阿里云OSS PicGO进行图床设置 前言 crystal ball 一 阿里云OSS设置 satellite 1 进入 阿里云OSS官网 https www al
  • 解决刷新tagsview首页消失问题和引入path报错问题

    我的tagsview功能是用nuoyi源码 如果你的代码有tagsview功能直接找这个文件 如果没有这个功能可以参考nuoyi源码 重点参考以下文件 或者参考 通俗易懂 vue实现tagsview标签导航栏切换菜单功能 详细注释 都能看的
  • 原型聚类&&密度聚类&&层次聚类

    1 原型聚类 原型聚类算法假设聚类结构可以通过一组原型刻画 通常算法先会对原型进行初始化 然后对原型进行迭代更新求解 不同的原型表示和不同的求解方式会产生不同的算法 下面主要介绍三种典型的原型聚类算法 k 均值 学习向量量化 和 高斯混合聚
  • mybatis和spring的集成方法

    集成mybatis和spring 需要的步骤 1 新建maven项目 2 加入maven依赖 在pom xml加依赖 1 加入spring依赖
  • vscode 无法远程调试 xdebug

    launch json version 0 2 0 configurations name Listen for XDebug type php request launch port 9001 该端口不要和php fpm端口相同 path
  • Redis Streams做股票行情MQ?

    redis作为内存数据库 大多时候都是作为缓存来使用 但是因为有pub sub的存在 所以也可以做MQ来使用 做为MQ 它有两个严重的问题 1 无法持久化 2 没有ack机制 redis pub sub是一个要即时消费的MQ 如果消费晚了
  • 序列式容器

    容器的概观与分类 常用的数据结构不外乎array 数组 list 链表 tree 树 stack 堆栈 queue 队列 hash table 散列表 set 集合 map 映射 等等 根据 数据再容器中的排列 特性 这些数据结构分为序列式
  • 华为云云耀云服务器L实例评测

    大家好 我是雄雄 欢迎关注微信公众号 雄雄的小课堂 目录 前言 效果图 购买云耀云服务器L实例 重置密码 放开端口 远程连接 安装云监控面板 进入监控面板 前言 有幸参与了华为云云耀云服务器L实例的评测名额 借着评测 顺便教给大家一项技能
  • 多视图聚类(multi-view clustering)简介

    多视图聚类 目前大概有以下几种 多视图k means聚类 多视图谱聚类 多视图图聚类 多视图子空间聚类 multi view subspace clustering 深度学习多视图聚类 deep multi view clustering
  • Vector迭代器实现

    实现数组的迭代器 实现内容 1 使用C 语言实现一个长度可扩充的数组结构 要求使用class实现 不能直接使用vector等现成的数据结构 2 要求实现为可以用于不同数据类型的数组结构 并不是说同一个对象需要存储多种类型的数据 建议使用te
  • 【满分】【华为OD机试真题2023 JAVA&JS】租车骑绿道

    华为OD机试真题 2023年度机试题库全覆盖 刷题指南点这里 租车骑绿道 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 部门组织绿道骑行团建活动 租用公共双人自行车骑行 每辆自行车最多坐两人 做大载重M 给出部门每个人的体
  • 毕业设计 单片机与OpenMV机器视觉目标跟踪系统

    文章目录 0 前言 课题简介 设计框架 3 openMV实现舵机定位色块STM32 3 硬件设计 4 软件设计 4 1 硬件连接 4 2 软件代码 OpenMV端 4 3 软件代码 STM32端 4 4 利用PC端测试数据数据是否发送接收正
  • 《银行法律法规》一、经济金融基础知识——3、金融市场

    第三章 金融市场 第一节 金融市场概述 考点1 金融市场功能 概念 金融市场是指货币资金融通和金融工具交易的场所 金融市场的融资行为既包括以银行等金融机构为信用媒介的间接融资行为 也包括各类交易主体之间的直接融资行为 主体 是各类融资活动的
  • 运维企业实战Shell脚本合集+万能工具箱

    文章目录 系统维护篇 服务器日常巡检脚本 下线登录用户 企业级Linux日常自动抓取服务器巡检 登录 执行命令记录 备份脚本 终端对话 广播消息 批量查询IP归属地 手机号归属地信息 Linux开机后自动执行命令或脚本 一键自动格式化输出S
  • Anaconda中安装指定版本的tensorflow1.14.0/tensorflow-gpu1.14.0

    在运行github中一个项目时 由于其使用的tensorflow的版本是1 14 0 而我的版本是2 6 0的版本 因为版本过高导致运行失败 所以需要安装tensorflow1 14 0 首先在anaconda的命令行中输入如下命令 pip
  • 【Qt】【CMake】【CMakeLists.txt】-PROJECT_NAME 和 CMAKE_PROJECT_NAME 的区别

    Qt CMake CMakeLists txt PROJECT NAME 和 CMAKE PROJECT NAME 的区别 原帖 https stackoverflow com questions 38938315 difference b
  • 2000+Docker镜像,Kolla是如何管理的

    根据 DockerHub 上的数据 整个 Kolla 项目管理的 镜像有 2000 多个 这么多的镜像 是怎么定义 又是如何构建的呢 简介 我们一直在说的 Kolla 通常情况下泛指 包括了 Kolla 和 Kolla Ansible 两个
  • 二进制部署K8s

    一 环境需求 节点IP 节点名称 所需组件 192 168 248 11 k8s master docker etcd apiserver controller manager scheduler kube proxy flannel 19
  • cobra库:基于cobra-cli命令行生成项目结构

    cobra库 基于cobra cli命令行生成项目结构 一 新建go项目 在F盘创建文件夹cobra started 1 使用mod对go项目进行管理 go mod init cobra started 二 使用cobra cli代码生成
  • 手写嵌入式操作系统(基于stm8单片机)

    include