上一节通过一个具体的RT-Thread工程探索了RT-Thread是如何启动的,这节还是以应用为目的学习,通过实现BlinkLED学习RTOS如何编程应用。
1.单片机中的两种系统在实现BlinkLED之前,先插一段题外话,讲讲单片机中的两种系统及其区别,为实现BlinkLED作以铺垫。
1.1.裸机系统裸机系统就是我们大多数人所写的程序,直接运行在单片机上,并没有操作系统。
1.1.1.轮询系统最简单的裸机系统就是一个main函数,单片机重复不断的执行while(1)中的程序,这种模式很像单片机不断的进行查询判断,然后执行相应程序,比如在流水灯程序中查询判断延时时长是否满足设定值,在键盘程序中查询判断按键是否按下,这样的系统称为轮询系统,伪代码如下所示;这种轮询系统很简单,如果项目中只是一些简单的应用,并不需要实时响应用户,那么选用这种系统是再好不过的;
int main(void){
/* 初始化相关硬件 */
HardWareInit();
/* 无限循环 */
while(1)
{
/* 处理任务1 */
handle_task1();
/* 处理任务2 */
handle_task2();
/* 处理任务3 */
handle_task3();
......
}
}
这种系统有个致命的缺点——实时响应性差!在处理任务1的时候,任务2中的按键被按下,这个时候就无法响应到这个操作,所以有了第二种裸机系统用来解决这个问题;
1.1.2.前后台系统这种系统加入了中断服务程序,比如之前所出现的情况——在处理任务1的时候,任务2中的按键被按下,这个时候如果按键可以触发中断,那么CPU就会跑去执行相应的中断服务程序,执行完成后再接着之前的程序开始执行,这样系统的实时响应性就有个进一步的提高,这种系统称为前后台系统,中断服务程序称为前台,main函数中的无限循环称为后台,伪代码如下:
int main(void){
/* 初始化相关硬件 */
HardWareInit();
/* 无限循环 */
while(1)
{
/* 处理任务1 */
handle_task1();
/* 处理任务2 */
handle_task2();
/* 处理任务3 */
handle_task3();
......
}
}
//中断服务程序1
void ISR1(void)
{
//中断处理程序
}
这种系统提高了实时响应性能,但是如果在执行中断的时候再发生了一个优先级高的突发事件,发生中断嵌套,CPU转去处理新的中断程序,然后依次返回;
1.2.多线程系统由上面可以看出,裸机系统的效率并不高,CPU一直在顺序的执行某一段程序,这个时候操作系统的优势就体现出来了,操作系统都是多线程操作系统,虽然只有一个CPU,但是通过操作系统的安排和调度,可以在外接看来并行的执行很多个线程,系统的实时响应处理能力大大提升;
在多线程系统中将整个程序主体分为一个个独立的,无限循环且不能返回的小程序,这一个个小程序就称为线程,每个线程都是独立的,互不干扰的,且具备自身的优先级,由操作系统进行调度和管理,称为多线程系统,伪代码如下:
{
/* 初始化相关硬件 */
HardWareInit();
/* 无限循环 */
while(1)
{
/* 处理任务1 */
handle_task1();
/* 处理任务2 */
handle_task2();
/* 处理任务3 */
handle_task3();
......
}
}
//中断服务程序1
void ISR1(void)
{
/* 中断处理程序 */
}
//一个个独立的线程
void handle_task1()
{
/* 无限循环,不返回 */
while(1)
{
/* 线程实体 */
}
}