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

这篇具有很好参考价值的文章主要介绍了手写嵌入式操作系统(基于stm8单片机)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

#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];
}




文章来源地址https://www.toymoban.com/news/detail-708112.html

到了这里,关于手写嵌入式操作系统(基于stm8单片机)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【小黑嵌入式系统第二课】嵌入式系统的概述(二)——外围设备、处理器、ARM、操作系统

    上一课: 【小黑嵌入式系统第一课】嵌入式系统的概述(一)——概念、特点、发展、应用 下一课: 【小黑嵌入式系统第三课】嵌入式系统硬件平台(一)——概述、总线、存储设备(RAMROMFLASH) 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享

    2024年02月08日
    浏览(35)
  • 嵌入式实时操作系统的设计与开发

    在RTOS中,时钟具有非常重要的作用,通过时钟可实现延时任务、周期性触发任务执行、任务有限等待的计时。 大多数嵌入式系统有两种时钟源,分别为实时时钟RTC(Real-Time Clock)和定时器/计数器。 实时时钟一般是靠电池供电,即使系统断电,也可以维持日期和时间。由于实

    2024年02月11日
    浏览(28)
  • 嵌入式实时操作系统的设计与开发(一)

    以一款简单、易学的嵌入式开发平台ARM Mini2440(CPU是三星ARM 9系列的ARM S3C2440)为例,通过具体代码实现,介绍如何从裸板入手设计简单的轮询系统、前后台系统,以及如何一步一步在ARM Mini2440上编写RTOS内核,到如何让RTOS内核支持多核嵌入式处理器。 aCoral是2009年创建的开源

    2024年02月12日
    浏览(27)
  • 嵌入式实时操作系统的设计与开发(十)

    RTOS的引导是指将操作系统装入内存并开始执行的过程。在嵌入式系统的实际应用中,针对不同应用环境,对时间效率和空间效率有不同的要求。因此,操作系统启动时应充分考虑这两种限制。 时间限制主要包括两种情况:系统要求快速启动和系统启动后要求程序能实时运行

    2024年02月07日
    浏览(57)
  • 【嵌入式操作系统】实验2:GPIO编程及应用

    熟悉STM32 模块的GPIO硬件连接; 掌握GPIO初始化配置; 掌握GPIO控制板上LED灯编程; 熟练KEIL 工程的配置,编译,调试,下载。 操作系统:WINDOWS 10 开发工具:Keil 4,UartAssists 实验设备:125K RFID读写器模块、JLink在线调试器、电源、PC   运行程序后,LED灯D7、D8按照全熄灭、亮

    2024年02月09日
    浏览(30)
  • 嵌入式系统设计师考试笔记之操作系统基础复习笔记二

    目录 3、任务管理 (1)嵌入式操作系统的任务管理可以分为 (2)进程 (3)线程 (4)任务 (5)任务的创建与中止 (6)任务的状态任务有三中基本状态: (7)任务控制块 TCB (8)任务的切换 (9)任务的调度 (10)实时系统调度 (11)任务互斥 (12)信号量 (13)任务同

    2024年02月08日
    浏览(35)
  • 嵌入式实时操作系统的设计与开发(信号量学习)

    除了临界点机制、互斥量机制可实现临界资源的互斥访问外,信号量(Semaphore)是另一选择。 信号量与互斥量的区别 对于互斥量来说,主要应用于临界资源的互斥访问,并且能够有效地避免优先级反转问题。 对于信号量而言,它虽然也能用于临界资源的互斥访问,但是不能

    2024年02月08日
    浏览(44)
  • C语言嵌入式系统编程注意事项之内存操作

    在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能力 数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应的MOV指令,而除C/C++以外的其它编程语言

    2024年02月09日
    浏览(53)
  • 从何着手OpenHarmony?从这里开始认识嵌入式开源鸿蒙操作系统

    首先,我们需要知道HarmonyOS与OpenHarmony是不同的概念,我们需要知道它们的区别:         HarmonyOS是华为独家开发的,但华为在2020、2021年分两次 将HarmonyOS的基础能力全部捐献给了开放原子开源基金会,形成了OpenHarmony开源项目 ,华为对开源鸿蒙没有控制权,当然华为仍将

    2024年02月04日
    浏览(43)
  • STM32嵌入式系统:将数据保存到SD卡的操作

    STM32嵌入式系统:将数据保存到SD卡的操作 嵌入式系统在现代科技中扮演着重要角色,而STM32单片机是一种常用的嵌入式系统解决方案。本文将介绍如何使用STM32单片机将采集到的数据以TXT文件的格式保存到SD卡中,并且能够方便地读取这些本地数据。 硬件准备 为了实现数据保

    2024年02月01日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包