起因:由于最近需要对嵌入式操作系统进行一个学习,直接上手freertos等等有点困难,因此对黑马这个简单的手搓操作系统进行学习,有一定的收获,主要包含以下几个部分:
- 操作系统的基础概念
- 操作系统的目的与功能
参考资源:
闲言少叙,将代码记录如下:
#include <STC8C.h>
#define MAX_TASKS 2
#define MAX_TASK_DEP 32
unsigned char idata task_sp[MAX_TASKS]; //任务的堆栈指针,简化方面我们当前操作系统有max_task
unsigned char idata task_stack[MAX_TASKS][MAX_TASK_DEP]; //每一个task任务的堆栈
unsigned char task_id; //当前任务号,从0开始
//定义一个任务切换的函数(任务调度器)
void task_switch(void){
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号任务,代表第0个小朋友做的事情
static unsigned int a=3;
while(1){
a=a+3;
task_switch();
}
}
void task1(){
//第1号任务,代表第1个小朋友做的事情
static 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;
}
void main(){
task_load(task1,1);
task_load(task0,0);
task_id=1;
SP = task_sp[1]; //一个小技巧,可以通过切换SP来进行一个任务切换,其实就是函数切换
}
仅关注几个重点学习到的知识点:
1,将函数导入内存区,我理解为就是在main里面调用一下我们编写的c函数,即带死循环的函数就是任务,这样后续就可以通过SP来启动任务
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;
}
2,任务切换,这里的情景比较简单,仅仅是任务的转换罢了,一个简单的Switch,但是由此可以进行拓展的是,复杂嵌入式系统也仅仅只是起到一个资源调度器的作用
void task_switch(void){
task_sp[task_id]=SP;
task_id=task_id+1;
if(task_id==MAX_TASKS){
task_id=0;
}
SP=task_sp[task_id];
}
3,上下文保护,其实就是在任务切换时要对一些数据进行保护,汇编需要堆栈,而这里用了static进行内存分配
static unsigned int a=3;
4,启动任务调度,非常巧妙,先保存任务地址,然后将任务地址进行堆栈相当于,在main函数最后其实有个ret,再出栈给pc,小巧思
SP = task_sp[1]; //一个小技巧,可以通过切换SP来进行一个任务切换,其实就是函数切换
然后到这里就完成结束了,黑马程序员的这个视频资源并不是说一个完备的嵌入式系统,但是确实使我对嵌入式系统要干什么,要完成什么目标有了一个较为基础的认识,接下来要对FREERTOS进行一个学习了,希望自己能够继续努力,有所收获。