Hu Zhenyu's Blog


访客计数:
net traffic statistics

about

FreeRTOS系列[一] 什么是操作系统?

最近在看FreeRTOS,于是就将学习过程中看到的一些知识记录下来。

引言

首先,什么是操作系统? 可能随便一个用过几年电脑的人都会知道Windows XP、Windows 7这些操作系统。也有人知道,没有操作系统,电脑就没法用。不仅仅是Winodows,还有Mac OS、Linux、DOS这些都是操作系统。这些一般都是通用操作系统,对于嵌入式的学习者来说,他们可能更熟悉WinCE、uC/OS-II、VxWorks之类的嵌入式操作系统,我学习的FreeRTOS就是一个嵌入式实时操作系统。

嵌入式的发展其实也是和计算机的发展密切相关的,让我们回到几十年前,看看为什么会有操作系统这样的东西诞生吧。

计算机的历史

第一台数字计算机与第一个程序员

在很多的计算机的书上,都会说第一台电子数字计算机是美国的ENIAC,其实他不是第一台,第一台数字计算机的时间可能会让你惊讶。第一台真正的数字计算机是英国数学家Charles Babbage (1792-1871)设计的。不过它是一台纯机械设计的,而且最终也没有成功运行起来。现在,有的人可能有种偏见,认为程序员是男人的世界,可是你知道么?世界上第一个程序员却是一个女人。她是英国著名诗人拜伦的女儿Ada Lovelace,她被Charles雇佣来为第一台数字计算机写程序。

第一代计算机

随着电子技术的发展,人们也改变了想法,从使用机械设计数字计算机到电子器件设计计算机。ENIAC就是这个时候诞生的。这个时候的计算机使用的程序完全是0和1的二进制语言,也就是机器语言(这时连汇编语言都没有)。程序员通过在插板上连线来编程,后来出现了穿孔卡片。这是第一代的电子管计算机。

第二代计算机

50年代发明了晶体管,晶体管让计算的可靠性大大提高了。这个时候也出现了汇编语言和第一个高级编程语言——FORTRAN。这个时候的计算机是如何使用的呢?

计算机因为很昂贵,被放在专门的空调房内,有专人进行操作。程序员首先将程序写在纸上,然后用穿孔机器制成卡片,将卡片交给操作员。

这样的效率肯定不高,于是批处理系统就诞生了。首先是有一个专门的廉价的计算机(它的性能比较低,不适合做数值计算,但适合处理卡片、磁带之类的),收集程序员的程序,处理成卡片或磁带,然后将这些程序依次输入到比较昂贵的计算机进行真正的计算。

第三代计算机

看过一些介绍计算的书的人都知道,第三代计算机就是集成电路计算机了。这个时候的计算机厂商一般有两条生产线,一条生产比较廉价的计算机,这些计算机计算能力比较差,不过适合处理磁带、打印等事务。另一条生产比较昂贵的计算机,这些计算机主要用来做复杂科学计算和工程计算。这两种计算机互相不兼容。

于是IBM公司决定开发360系统(这个可不是现在中国互联网上的那个360公司,不过也许那个公司名字就来源于此呢??)。这个系统目的就是开发一种兼容不同计算机的操作系统,它既能用于科学计算又能用于商业计算。但是为了让这个系统在不同的硬件系统上运行,他的程序写的越来越复杂,BUG也越来越多。

这个时候的操作系统,例如IBM 360系统实际上也还是一种批处理系统。一次只能运行一个程序,程序员从提交程序到得到程序结果要好几个小时,如果程序中间出错了,又要花上很长时间调试。于是有人提出了分时操作系统的概念。

分时操作系统提供了许多终端,不同的程序员从不同的终端提交他们的程序让计算机执行,CPU轮流执行这些程序。分时操作系统给了程序员一个错觉,那就是计算机是由他一个人独占使用的。最早的分时操作系统开发成功之后,MIT、贝尔实验室和通用电气公司决定开发一种“公共计算服务系统”(MULTICS)——一种支持数百名分时用户的机器,因为当时的计算机很昂贵,他们想着用一台计算机满足很多人的计算需求(其实这个想法还是很不错的,而且目前很火的“云计算”、“云服务”之类的也有些类似这种思想)。不过后来发现研制这个系统的难度出乎很多人的预料,于是贝尔实验室和通用电气都退出了它的研制。

MULTICS的失败,却促成了另一个伟大的操作系统的诞生,那就是UNIX。贝尔实验室一位曾经参加过MULTICS研制的科学家Ken Thompson,在一个无人使用的PDP-7机器上开发了一个简化的单用户版的MULTICS,这就是后来UNIX的雏形。为了发展UNIX,Dennis Ritchie 发明了C语言,C语言是世界上最流行、使用最广泛的编程语言之一。现在我们可以在很多不同的机器上使用C语言编程,都得感谢他。不要看UNIX系统的历史很古老了,它其实现在也还在很多机器上使用着,很多大型机上跑的是UNIX,目前最著名的开源操作系统Linux也是根据UNIX的思想写的,苹果公司的产品上使用的iOS和MAC OS都是基于UNIX内核写的。

UNIX 就有很多现代操作系统的拥有的东西了——任务调度算法、文件系统、权限管理、进程间通信…………Windows其实也有很多借鉴了UNIX的东西。

操作系统的功能

为什么我要花很大的篇幅来讲计算机的历史?因为只有了解了历史,才知道为什么会出现操作系统这个东西。

其实嵌入式系统的开发和设计也和计算机早期的发展历史有些相似。我们一开始学习单片机的知识,单片机就类似早期的性能很差的计算机。现在我们可能都是从汇编语言开始学起,据说早些年代的人们学习单片机都是要学习机器语言的,我们现在可以说幸福很多。学了汇编,我们可能了解了单片机的体系结构,但是,现在一般的产品都是使用C语言开发了,C语言既具有类似汇编的直接操作底层的能力,又具有描述高级数据结构的能力。

没有操作系统的情况

我们学习了一种单片机,熟悉了它的寄存器之后,就可以开始写程序,实现我们自己想要的功能了。一般,我们都是在主函数中写一个死循环,然后在其中实现我们的程序。

这种开发的程序结构又叫做“前后台”的结构。什么是前后台呢?应用程序是一个无限循环,在无限循环中调用相关的函数实现功能,这部分被看作是后台行为。前台程序通过中断来处理事件,后台程序掌控整个嵌入式系统软、硬件资源的分配、管理和任务的调度,是一个系统调度程序。

下面是一个前后台系统的程序结构:

int
main(void)
{
    prvHadwareSetup();  //硬件初始化和软件初始化代码
    
    for(;;)
    {
        do_first_things();    //后台程序依次执行
        do_second_things();
        ...
        do_something();
    }

    return 0;           //永远不会执行到这一行
}

void ISR(void)          //中断服务程序
{
    do_something_urgent();   //中断函数处理某个事件
}

大部分使用单片机的初学者,或者是对于一些简单的应用,可能都是使用这样的程序架构。这个架构使用起来简单,不要太复杂的任务调度,各个任务都是依次执行。

不过这样也带来了一些缺点,那就是各个任务的执行时间,有时候是不确定的,如果一个任务执行的时候占用了太多的CPU时间,就可能影响到其他的任务的执行。每个任务的优先级都是相同的,如果有一个任务什么也没做,但是却堵塞了CPU执行,其他的任务也得不到执行的机会,这样会造成整个系统的崩溃。

使用操作系统

嵌入式实时操作系统,和早期的操作系统类似,是为了解决多任务、实时性等等问题的。

一般的操作系统,为了实现多任务,都会使用时间片的方法。也就是将时间分成很小很小的块,每个块执行一个任务,时间片用完了就切换到另一个任务。这样,给人的感觉就是好几个任务同时在执行,但是实际上某一个时刻还是只有一个任务能够占用CPU时间。还有抢占式多任务,就是给不同的任务分配不同的优先级,高优先级的能够获得更多的CPU时间。

实时操作系统在切换任务的时候,会保存下现在的寄存器状态,然后跳到下一个任务处理函数中执行,当再次执行到这个任务的时候,又需要将寄存器状态恢复过来,继续从上次打断的地方执行。这就是上下文(CONTEXT)的保存和恢复。

实时操作系统还要处理中断的问题,和任务切换一样需要保存上下文,还要处理中断嵌套的问题。什么是中断嵌套? 就是你正在执行中断处理函数里面的程序,这时如果又来了中断,怎么办? 有的做法是先执行完当前的中断函数,再执行后来的中断程序。还有的做法就是,新的中断会打断现有的中断的执行,这就是中断的嵌套。用一个图形来表示可能会更加形象:

管理任务是一个操作系统最最基本的任务。除了任务管理,还有内存管理,进程间通信,设备管理,文件管理等等功能。

操作系统也可以说是一种虚拟机,它将硬件抽象成了各种API,甚至不同的硬件可以使用同样的API去访问,这大大地方便的上层的程序员,他们不用去关心底层的硬件到底是如何运作。

上面一段是针对通用操作系统的说法,嵌入式操作系统当然也有这样,但是大部分开发者可能是即要给操作系统写驱动(这需要了解底层硬件是如何工作的),也要写上层的功能实现代码。有人可能说,用了操作系统太麻烦了,要多做许多工作。错!一开始看起来,使用操作系统,一开始可能要写什么驱动,但是写好之后,以后升级维护的时候,这些都不用修改,而且以后移植到其他平台也可以通用。 而不使用操作系统,升级维护和移植可能就比较麻烦。

最后,我们的题目是什么是操作系统嘛。还是给操作系统下个定义作为结束吧。

操作系统是管理计算机硬件资源,控制其他程序运行并为用户提供交互操作界面的系统软件的集合。操作系统的主要任务有 任务管理与调度、管理和分配内存、硬件抽象与控制、操作网络与文件系统等等。操作系统为其他应用软件提供支持,使计算机系统所有资源最大限度地发挥作用,提供各种形式的用户界面,使用户有一个好的工作环境。

参考文献

《操作系统设计与实现(第二版)》 Andrew S. Tanenbaum / Albert S. Woodhull

百度百科

上一篇: FreeRTOS介绍与移植
下一篇: FreeRTOS系列[二]源代码分析 FreeRTOS.h


知识共享许可协议

本站采用 知识共享署名-非商业性使用-相同方式共享3.0 中国大陆许可协议 进行许可,转载请注明出处。

推荐使用 chrome 浏览器浏览本站。