当前位置: 首页 > wzjs >正文

大连微信网站深圳宝安区邮编

大连微信网站,深圳宝安区邮编,wordpress 引号转义,设计师的网站这是B站【黑马程序员】的课程《黑马程序员嵌入式操作系统视频教程,嵌入式入门必学的操作系统教程,从理论到动手实践一套通关》,这套课程的前10节课介绍了一些理论知识,很简单生动,从第11节课开始写代码,从零…

这是B站【黑马程序员】的课程《黑马程序员嵌入式操作系统视频教程,嵌入式入门必学的操作系统教程,从理论到动手实践一套通关》,这套课程的前10节课介绍了一些理论知识,很简单生动,从第11节课开始写代码,从零开始手写嵌入式实时操作系统。这篇笔记主要针对嵌入式实时操作系统demo代码编写。


目录

1 声明两个任务的堆栈指针和任务堆栈

2 定义操作系统的loadtask函数

3 通过修改SP,来修改调用的函数

4 任务调度器的实现

5 任务切换的上下文混淆问题

6 多任务访问外设操作(LED)

7 为什么延时1秒会出现睡眠2秒的问题

8 改用硬件delay实现sleep函数

9 操作系统监管定期时间片轮转

10 最终代码


1 声明两个任务的堆栈指针和任务堆栈

#include <stc8h.h>#define MAX_TASKS 2    //为了简化,假设当前操作系统只有两个task
#define MAX_TASKS_DEP 32    //每个task任务的堆栈深度为32unsigned char task_sp[MAX_TASKS];    //任务的堆栈指针,即当前系统的两个堆栈指针
unsigned char task_stack[MAX_TASKS][MAX_TASKS_DEP];

2 定义操作系统的loadtask函数

#include <stc8h.h>#define MAX_TASKS 2 
#define MAX_TASKS_DEP 32 //idata关键字指明这两个变量在stc8单片机访问最快的内部内存中
unsigned char idata task_sp[MAX_TASKS];
unsigned char idata task_stack[MAX_TASKS][MAX_TASKS_DEP];unsigned char task_id;    //当前任务号,从0开始//第0号任务
void task0()
{unsigned int a = 3;while (1){a = a + 3;}
}//第1号任务
void task1()
{unsigned int b = 5;while (1){b = b + 5;}
}//操作系统加载任务的函数
//参数说明:
//    fn:是一个函数的指针,数据类型为int,stc8单片机中函数指针为16位
//    tid:表示task id
//函数作用:
//    把一个task的函数指针放入对应的堆栈空间里面
void task_load(unsigned int fn, unsigned char tid)
{task_sp[tid] = task_stack[tid] + 1;    //把任务的指针往下一个空间挪一格task_stack[tid][0] = fn & 0xff;    //task_stack[tid][0]放上fn函数指针的低8位task_stack[tid][1] = fn >> 8;    //task_stack[tid][1]放上fn函数指针的高8位
}

3 通过修改SP,来修改调用的函数

#include <stc8h.h>#define MAX_TASKS 2 
#define MAX_TASKS_DEP 32 unsigned char idata task_sp[MAX_TASKS];
unsigned char idata task_stack[MAX_TASKS][MAX_TASKS_DEP];unsigned char task_id; void task0()
{unsigned int a = 3;while (1){a = a + 3;}
}void task1()
{unsigned int b = 5;while (1){b = b + 5;}
}void task_load(unsigned int fn, unsigned char tid)
{task_sp[tid] = task_stack[tid] + 1;task_stack[tid][0] = fn & 0xff;task_stack[tid][1] = fn >> 8;
}int main()
{task_load(task0, 0);    //把task0装载到内存中task_id = 0;SP = task_sp[0];    //修改StackPointer寄存器的值为task_sp[0]的地址,执行task0函数
}

4 任务调度器的实现

#include <stc8h.h>#define MAX_TASKS 2 
#define MAX_TASKS_DEP 32 unsigned char idata task_sp[MAX_TASKS];
unsigned char idata task_stack[MAX_TASKS][MAX_TASKS_DEP];unsigned char task_id; //定义一个任务切换的函数(任务调度器)
void task_switch()
{task_sp[task_id] = SP;    //把当前系统的堆栈指针存放到某个任务的task_sp里task_id = task_id + 1;//防止task_id溢出if (task_id == MAX_TASKS){task_id = 0;}SP = task_sp[task_id];
}void task0()
{unsigned int a = 3;while (1){a = a + 3;task_switch();    //任务切换}
}void task1()
{unsigned int b = 5;while (1){b = b + 5;task_switch();    //任务切换}
}void task_load(unsigned int fn, unsigned char tid)
{task_sp[tid] = task_stack[tid] + 1;task_stack[tid][0] = fn & 0xff;task_stack[tid][1] = fn >> 8;
}int main()
{task_load(task0, 0);task_id = 0;SP = task_sp[0];
}

5 任务切换的上下文混淆问题

void task0()
{static unsigned int a = 3;    //编译器将其放在静态数据区域,这样不会出现数据脏读的现象while (1){a = a + 3;task_switch();}
}void task1()
{static unsigned int b = 5;    //编译器将其放在静态数据区域,这样不会出现数据脏读的现象while (1){b = b + 5;task_switch(); }
}

6 多任务访问外设操作(LED)

#include <intrins.h>//软件生成
//24MHZ的主频下,延时1s的函数
void Delay1000ms()
{unsigned char i, j, k;_nop_();_nop_();i = 122;j = 193;k = 128;do{do{    while(--k);}while (--j)} while (--i)
}void task0()
{//亮灯P5M0 = 0x00;P5M1 = 0x00;P53 = 1;while (1){//延迟1sDelay1000ms();//熄灯P53 = ~P53;task_switch();}
}void task1()
{//亮灯P4M1 = 0x00;P4M0 = 0x00;P2M1 = 0x00;P2M0 = 0x00;P27 = 1;while (1){//延迟1sDelay1000ms();//熄灯P27 = ~P27;task_switch(); }
}int main()
{task_load(task0, 0);task_load(task1, 1);task_id = 0;SP = task_sp[0];
}

7 为什么延时1秒会出现睡眠2秒的问题

因为软件实现的软delay占用了cpu的时间。

8 改用硬件delay实现sleep函数

#include <intrins.h>//枚举任务状态
typedef enum {TASK_RUNNING,    //运行状态TASK_SUSPENDED,  //挂起状态
} 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 sleep(unsigned int , unsigned int );//睡眠函数
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;
}//软件生成
//24MHZ主频下,硬件delay1ms
void Timer0_init()
{AUXR |= 0x80;TMOD &= 0xF0;TL0 = 0x40;TH0 = 0xA2;TF0 = 2;TR0 = 1;
}//系统的定时器中断,每隔1ms就执行一次中断函数
void Timer0_ISR(void) interrupt 1
{unsigned char i = 0;for (i = 0; i < MAX_TASKS; i++){//睡眠状态if (tasks[i].status == TASK_SUSPENDED){tasks[task_id].delay_count++;}//睡眠结束if (tasks[i].delay_count == tasks[task_id].delay_duration){//睡眠结束tasks[i].status = TASK_RUNNING;tasks[i].delay_count = 0;}}
}void task0()
{P5M0 = 0x00;P5M1 = 0x00;P53 = 1;while (1){//检查自己的状态,如果自己是睡眠状态,就应该交给别的task去做if (tasks[0].status == TASK_SUSPENDED){task_switch();continue();}//硬件延迟1ssleep(0, 1000);P53 = ~P53;task_switch();}
}void task1()
{P4M1 = 0x00;P4M0 = 0x00;P2M1 = 0x00;P2M0 = 0x00;P27 = 1;while (1){//检查自己的状态,如果自己是睡眠状态,就应该交给别的task去做if (tasks[1].status == TASK_SUSPENDED){task_switch();continue();}//硬件延迟1ssleep(1, 1000);P27 = ~P27;task_switch(); }
}int main()
{Timer0_init();task_load(task0, 0);task_load(task1, 1);task_id = 0;SP = task_sp[0];
}

9 操作系统监管定期时间片轮转

//在24Mhz下,设置定时器为100ms
void Timer1_Init(void)
{AUXR |= 0x40;TMOD &= 0x0F;TL1 = 0xA0;TH1 = 0xF6;TF1 = 0;TR1 = 1;
}//在timer1中的中断,每100ms进行任务切换
void Timer1_ISR(void) interrupt 1
{task_switch(); 
}int main()
{Timer0_init();Timer1_init();task_load(task0, 0);task_load(task1, 1);task_id = 0;SP = task_sp[0];
}

10 最终代码

#include <intrins.h>#include <stc8h.h>#define MAX_TASKS 2 
#define MAX_TASKS_DEP 32 unsigned char idata task_sp[MAX_TASKS];
unsigned char idata task_stack[MAX_TASKS][MAX_TASKS_DEP];unsigned char task_id; typedef enum {TASK_RUNNING,   TASK_SUSPENDED, 
} TaskStatus;typedef struct {unsigned char id;  TaskStatus 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 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 Timer0_init();
void sleep(unsigned int , unsigned int );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;TMOD &= 0xF0;TL0 = 0x40;TH0 = 0xA2;TF0 = 2;TR0 = 1;
}void Timer0_ISR(void) interrupt 1
{unsigned char i = 0;for (i = 0; i < MAX_TASKS; i++){if (tasks[i].status == TASK_SUSPENDED){tasks[task_id].delay_count++;}if (tasks[i].delay_count == tasks[task_id].delay_duration){tasks[i].status = TASK_RUNNING;tasks[i].delay_count = 0;}}
}void Timer1_Init(void)
{AUXR |= 0x40;TMOD &= 0x0F;TL1 = 0xA0;TH1 = 0xF6;TF1 = 0;TR1 = 1;
}void Timer1_ISR(void) interrupt 1
{task_switch(); 
}void task0()
{P5M0 = 0x00;P5M1 = 0x00;P53 = 1;while (1){if (tasks[0].status == TASK_SUSPENDED){task_switch();continue();}sleep(0, 1000);P53 = ~P53;task_switch();}
}void task1()
{P4M1 = 0x00;P4M0 = 0x00;P2M1 = 0x00;P2M0 = 0x00;P27 = 1;while (1){if (tasks[1].status == TASK_SUSPENDED){task_switch();continue();}sleep(1, 1000);P27 = ~P27;task_switch(); }
}int main()
{Timer0_init();Timer1_init();task_load(task0, 0);task_load(task1, 1);task_id = 0;SP = task_sp[0];
}

http://www.dtcms.com/wzjs/823128.html

相关文章:

  • 网站备案需要多久网站设计 网络推广的服务内容
  • 优酷wordpress建站教程在哪里推广自己的产品
  • 建免费的网站全国最缺工100个职业排行出炉
  • 网站设计建设公司教程广州网站手机建设公司
  • 做网站用什么字体字号微信制作小程序的软件
  • 百度微建站wordpress管理员账号
  • 网站首页为什么不收录施工企业负责人每月带班时间不少于
  • 做长图的网站羽毛球赛事2022直播
  • 成都品牌营销策划有限公司网站指定关键词优化
  • 网站淘宝客怎么做的wordpress视频下载
  • 网站建设可用性邵阳红网站
  • 彩票网站维护需要几天买程序的网站
  • 投票活动网站怎么做太原小程序制作
  • 自己做的网站怎么被搜录正规网站建设价格费用
  • 百度推广会帮你做网站不创意网红
  • 阿里云可以做电商网站吗设计展厅的公司
  • 建站时长是什么原因造成的图书拍卖网站开发遇到的问题
  • 河北做it的网站dede网站后缀乱码
  • 网站健设推广产品多少钱网站和服务器的关系
  • 盐城做网站推广电话小型局域网组建方案
  • 福建设计院网站哈尔滨公司网站
  • 怎样利用云盘做电影网站怎样制作企业的网站
  • 帮人盖章网站备案授权书网站建设培训证书
  • 东莞网站建设完整网上注册平台怎么注册
  • 博客网站做外贸可以吗手机网站设计公司皆选亿企邦
  • 2w网站建设发展环境镇江哪里做网站
  • 新网站怎么做才能可以在百度上搜索到原创文章网站
  • 织梦文章类网站模板外贸开发模板网站模板
  • 巴中住房建设部网站北京移动端网站价格
  • 沧州网站优化价格计算机科学与技术网站