1、先解释一下,什么是操作系统。
操作系统最核心的功能,就是时分复用,甚至用单片机玩的流水灯,都可以认为是操作系统。
熄灭一个灯再点亮一个灯,被称为是一个任务。不过,流水灯不是所有灯同时亮,而是隔一段时间灭一个亮一个,这个时间间隔,被称为调度时间。而调度这个功能,可以使用定时器中断来实现。
当然,真实的操作系统可没这么简单。因为绝大多数的任务不是点灯,它们需要运算,需要用变量去记录任务的运行状态。
这样,需要一个仓库去存储这些变量,常用的仓库是先进先出的堆栈(跟51单片机里面切换中断一样,需要保护现场)。
再举个例子,按键消抖是一个任务,串口发数据是一个任务,你想让按键按下的时候串口发数据的话,怎么办?
你很容易想到使用全局变量,但是全局变量会增加代码的耦合度,为了解决这个问题,操作系统还必须带有任务间通信的机制,比如:信号量、互斥量等。
2、为什么需要操作系统。
一、正如上文所说的,可以降低代码的耦合度。
二、提高整机的稳定性。比如,飞行器上面的无线通信模块坏了,而这个通信的功能用了阻塞型的代码(如while(send_finished);),没有操作系统的话,飞行器将无法做姿态解算等其它任务,只能失速坠落。但是有操作系统的话,就可以使用调度算法跳过这些阻塞型的代码,去执行其它任务,来保证飞行器的稳定性。
3、CoOS跟uCOS ii差不多,也是个小型的操作系统,可以用在单片机上面。
而COIDE上面的CoOS已经给我们移植在Cortex M0、M3、M4,这三种内核上了,所以我们用起来很方便。
当然,使用之前需要添加CoOS组件,其中整个系统,也就只有OsConfig.h(裁剪用的)需要修改的,其它都不用改。
而OsConfig.h默认支持M3内核,所以本次示例不需要修改它。
下面介绍在M3内核下使用CoOS的最简单的工程。
相信用过uCOS ii的,都会发现这段代码跟uCOS ii的很相似。功能也很简单,就两个灯不停地闪烁。
具体开发流程:初始化内核->创建任务->调度,然后写上具体的任务函数,就可以了。
1、CoInitOS(),初始化CoOS内核
void CoInitOS(void);
2、CoCreateTask(),创建任务
CoCreateTask(task,argv,prio,stk,stkSz);
task是函数名,传入函数指针可以使内核调度该任务。
argv是传入任务的参数,对应于任务当中的pdata,一般不使用。
prio优先级,数值越小,优先级越高。
stk任务栈地址,写成【64-1】是因为C语言的数组是从0开始算的,0~63正好64个单元。
stkSz任务栈的大小。
3、CoStartOS(),启动CoOS以调度任务
void CoStartOS(void);
请注意,在此函数之后的语句都不执行。