用操作系统的好处,我现在总结一下:就是所有的线程同时执行。比如在单片机里,delay(100);这个函数,就是延时100或者毫秒或微秒或多少不确定。它是决对不能干别的工作的。而操作系统则不然,它的延时等待是在调别的就绪的函数来运行,所以,所有的函数是并发执行地。
我们平常意义上的操作系统指的是是一组控制和管理计算机硬件和软件资源,合理地对各类作业进行调度,以及方便用户的程序的集合,如windows 、linux等,对于这类操作系统而言,用户编写的各类程序都在操作系统之上运行,并不会直接操作硬件,而且用户程序的崩溃一般情况下也不会导致整个系统的崩溃,所以整体安全性较好。但由于受到嵌入式系统资源的限制,尤其是像mbed这样的单片机系统,计算机操作系统的理念并不能直接应用到嵌入式操作系统中(linux虽然也可以应用到嵌入式系统中,但同样也需要较多的硬件资源,它们和mbed并不是同一级别的,所以不在本文讨论之列),我们需要新的操作系统类型,这就是嵌入式实时操作系统。
嵌入式实时操作系统定义如下:运行在嵌入式系统(用于控制、监视或者辅助操作机器和设备的装置)之上,当外界事件或数据产生时,能够接受并以足够快的速度予以处理,其处理的结果又能在规定的时间之内来控制生产过程或对处理系统作出快速响应,并控制所有实时任务协调一致的软件系统,常见的有eCos、uCos、FreeRTOS等。对于这类操作系统而言,用户代码和操作系统代码一般情况下是编译在一起的,当然也没有虚拟机的概念,所以在编写基于此类操作系统的应用时一定要小心,否则就有可能引起整体系统的崩溃。
对于同样操作系统而言,它需要完成进程(线程)管理、存储管理、设备管理、作业管理、安全管理等功能,但受到嵌入式系统资源及用途的闲置,嵌入式实时操作系统的主要功能就是线程管理,具体包括:
l 线程控制及调度:线程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配的单位。线程控制的主要任务就是创建线程、撤销线程和控制线程运行时候的各种状态转换,而线程调度的任务是从线程的就绪队列中按照一定的算法挑选出一个线程,把处理器资源分配给它,并准备好特定的执行环境让它执行起来。
l 线程同步:多个线程的执行是并发的,它们以异步的方式运行,它们的执行进度也是不可预知的;为了使多个线程可以有条不紊地运行,操作系统要提供线程同步机制,以协调线程的执行。一般有两种协调方式:互斥和同步。互斥指多个线程对临界资源访问时采用互斥的形式;同步则是在相互协作共同完成任务的线程之间,用同步机制协调它们之间的执行顺序。
l 线程间通信:线程间通信主要发生在相互协作的线程之间,由操作系统提供的线程间通信机制是它们之间相互交换数据和消息的手段。
l 线程调度:
在这里,我们有必要了解一下线程在系统中的状态及不同状态之间的切换原则,一个线程可能是以下状态中的一种:
l 运行态:线程正在运行当中,一个时刻只能有一个线程处于运行态;
l 就绪态:线程已经获得必要的资源,一旦正在运行的线程终止或这进入等待状态,队列中具有最高优先级的线程将变成运行态;
l 等待态:线程正在等待相关的事件发生;
l 停止态:此时线程并没有创建,也没有消耗任何系统资源。
下图显示了线程各个状态之间的切换关系:
mbed自带了mbed-rtos实时操作系统,实现了线程控制、线程同步、线程间通讯、线程调度等功能。mbed-rtos的实现建立在CMSIS-RTOS基础之上, CMSIS-RTOS是ARM公司提供的用于线程控制、资源和时间管理的实时操作系统的标准化编程接口,可以方便各类实时操作系统地开发。
- #include "mbed.h"
- #include "rtos.h"
- DigitalOut led1(LED1);
-
- DigitalOut led2(LED2);
-
- DigitalOut led3(LED3);
-
- DigitalOut led4(LED4);
-
- Serial pc(USBTX,USBRX);
-
- uint8_t ledvalue=0;
-
- Ticker tick;
-
- void setLed(uint8_t val)
-
- {
-
- led1=val % 2;
-
- led2=(val /2 ) % 2;
-
- led3=(val /4 ) % 2;
-
- led4=(val /5 ) % 2;
-
- }
-
- void printstr(void const *args)
-
- {
-
- while (true) {
-
- pc.printf("Hello World,Now value is %d.\n",ledvalue);
-
- // pc.printf("Hello World,Now value is %d.\n",*(uint8_t *)args);
-
- Thread::wait(1000);
-
- }
-
- }
-
- int main()
-
- {
-
- //Thread thread(printstr);
-
- Thread thread(printstr,&ledvalue);
-
- while (1)
-
- {
-
- setLed(++ledvalue);
-
- Thread::wait(100);
-
- }
-
- }
上边的代码,对有板子的坛友幸福了,可直接考到mbed上运行啦!要注意的是一定要导入mbed_rtos库见下图:
如果,导入了rtos库那么一定在error.h上报错。别怪兄弟没有提醒撒!!!
运行时的串口数据截图:
本帖最后由 ddllxxrr 于 2014-9-8 16:12 编辑