中国信息化培训中心

7x24小时咨询热线

400-660-3310

当前位置 : 好学校 中国信息化培训中心 学习资讯 资讯详情

物联网操作系统

2013-09-10

无线传感器网络中的操作系统是一个位于节点硬件和应用程序之间的软件层,它给应用程序开发者提供了基本的编程理念。操作系统的主要作用是确保应用程序能与硬件资源进行交互、执行和优化任务,在多种应用程序和服务程序之间做选择,并试图获取资源。

其他功能还包括:

内存管理。

电源管理。

文档管理。

建立关系网络。

一套编程环境和工具——命令、命令解释器、命令编辑器、编译器、调试器等,确保用户能开发、调试和执行用户的程序。

??进入操作系统访问敏感资源的合法入口,如输入组件。

传统上,操作系统可分为单任务、多任务、单用户和多用户操作系统。一个单任务操作系统一次只能执行一个任务,然而一个多任务操作系统能同时执行多个任务。多任务操作系统需要大量的内存来管理多个任务的状态,并使具有不同复杂性的任务并行执行。例如,在一个无线传感器节点中,处理器子系统与通信子系统相互作用的同时也可以与传感器子系统相互作用。一个多任务操作系统是这种类型环境的佳选择。然而,由于有限的资源,并行处理对资源的开销可能无法承担。在单任务操作系统中一次只能执行一个任务,因此目标任务执行持续时间短。在单用户操作系统中,在同一时间只有一个用户能使用系统里的资源,然而一个多用户操作系统允许多个用户同时共享系统里的资源。

一个特定操作系统的选择取决于很多因素,在接下来的内容中,将会讨论典型的功能性和非功能性方面。

1.功能性方面

1)数据类型

在无线传感器网络中,不同子系统之间的通信是至关重要的。由于各种原因这些子系

统相互通信,例如交换数据、托管功能和信号。相互作用通过精心制定的协议和数据类型

而产生,并且它们都是由操作系统来支持的。复杂的数据结构具有较强的表达能力但消耗

资源,然而简单的数据结构能节约资源但表达能力有限。在无线传感器网络中几乎所有现

有的操作系统或运行环境都支持C语言编程和一些复杂的数据类型,如结构体和枚举的原

始数据类型。

2)调度

任务调度是操作系统中的一个基本功能,任务如何有效地组织、确定优先级并执行,这些决定了操作系统的效率。

从广义上讲,有两种调度机制:基于排队和循环调度。在排队调度中,来自各予系统的任务是暂时存储在队列中,并根据预定义的规则串行执行。有些操作系统对任务指定优先级,使它们可以优先被考虑。

基于队列调度,可进一步分为先出和排序队列。在一个先入先出的系统中任务是按照它们抵达的时间来执行的:先到达的任务将会先被执行,确保处理器是闲置的。一个非抢占的操作系统在另一个任务没有完成前是不能执行其他任务的,然而在优先级的操作系统中,一个更高优先级的任务可能中断低优先级任务。在一个有序的队列计划中,队列中的任务是根据预定的准则进行排序。一种方法是根据它们的预估时间来排序任务,这种方法能防止持续时间长的任务中断持续时间短的任务,该方法也被称为短工作优先规则( SJF)。在SJF计划中,排序会带来系统开销,因为每个队列中的任务必须进行评估,估计执行期限,并据此进行排序任务。

先入先出的系统( FIFO)是简单和经济的,因为它会带来低的系统开销。然而,先入先出的系统可能对待任务不公平,因为持续时间长的任务可能会在很长一段时间内阻碍持续时间短的任务。

循环调度是一种分时调度技术,它可以并发处理多个任务。调度程序通过把时间分解成时间片来定义时间框架,并以多路复用方式把任务分配给各个时间片。这样所有的任务都朝着完成的方向运行。

不管任务如何执行,一个调度器可以是一个非抢占式或抢占式调度。严格意义上的非抢占式调度,任务从执行一直到结束不会被另一个任务中断。相反,严格意义上的抢占式调度决定任务之间的时间优先顺序,允许更高优先级的任务中断低优先级的任务。也有所谓的“礼貌先发制人( politely-preemptive)”的调度,即使任务可以被中断,但如果它是在一个关键部分,调度程序也不会中断这个操作。

3)栈

栈是一种数据结构,在内存中它通过将一个数据输入到另一个数据来暂时存储数据结构,访问对象遵循后进先出的原则。当它开始执行子程序前,处理器内核使用栈来存储系统状态信息,运用这个方法可以记住当子程序完成后程序返回的地址。通过存储当前子程序栈顶的状态,子程序可以再一次调用其他子程序。当该子程序完成后,处理器弹出栈顶地址,跳回到调用入口。

在一个多线程的操作系统中,每个线程都需要它自己的栈管理状态信息,这就是为什么在无线传感器网络中多线程操作系统如此昂贵的一个原因。

4)系统调用

操作系统提供了一些确保关注分离的基本功能,即需要访问硬件资源和额外的底层服务的访问机制的实施细节。用户调用这些操作,他们希望在访问硬件资源如传感器、看门狗定时器或者进行无线收发时,不需要考虑硬件是如何进行访问的。

5)中断处理

一个中断是由硬件设备产生的异步信号,使处理器中断执行当前的指令,并调用相应的中断处理程序。处理器把进程被中断的状态存储在堆栈中,并将执行中断处理子程序。例如,当一个通信子系统收到一个需要立即处理的数据包时可能会产生一个中断信号。该处理器子系统必须暂停当前通信进程的执行,在操作系统中调用适当的模块来处理数据包,处理完数据包后再返回执行通信进程。

另外,硬件设备在操作系统中可以定义多个中断标志。在某些情况下,操作系统本身可以产生周期性中断,用处理器来监控硬件资源的状态,发现硬件中断标志,并处理相应的中断事件。

任务可以有不同的优先级,同样,中断信号也可以有不同的优先级,一个高优先级的中断可以中断低优先级的中断。在这样的系统中,程序可以选择设置中断屏蔽来避免被中断。中断屏蔽可以防止程序被一些不相关的低级别中断所中断。但屏蔽中断可能存在破坏数据的危险。而一些操作系统在关键的操作中必须屏蔽中断。

6)多线程

一个线程是一个处理器或一个程序在执行过程中所采取的路径。在一个不可中断操作系统的单一任务中,任务是单一的,并且只有一个执行线程。在多线程环境中,一个任务可以被分为多个逻辑块,可相互独立的并发执行。同样,不同来源的多个任务也可并发执行。如果有必要,线程的相同任务可以共享一个共同的数据和地址空间来互相沟通。

一个多线程的操作系统主要有两个优势:

(1)任务之间互不阻止,这一点对于处理与任务有关的输入/输出系统特别重要。

(2)短期任务可以与长期任务一起执行。

因为线程具有占有资源的性质,它们不能被无休止地创建。创建线程能降低处理器的执行速度,可能没有足够的资源来分配大量的线程。因此,一些操作系统只能支持有限数量的线程,并把它们置入缓冲区中。缓冲区中的每一线程都等待分配任务,一旦得到请求,缓冲区就会分配一个可用的线程,直到任务完成,线程就会返回到缓冲区,并且等待下一次分配。如果缓冲区里所有的线程都被使用了,在下一个线程返回缓冲区之前,系统将会在队列中等待即将到来的请求。以这种方式,操作系统能将线程数量控制在一定规模。

7)基于线程与基于事件的编程

无线传感器网络,支持并发任务。其中涉及输入/输出系统的任务特别重要,应选择基于线程或基于事件的执行模式。

根据分散的堆栈和建立上下文信息的大规模,选择基于线程或基于事件的执行模式。在一个单一的程序和单一的地址空间中,基于线程的程序使用多线程控制。这样,当其他任务在不同的线程中执行时,被输入/输出设备阻止的线程可以被挂起。然而,程序员必须小心用锁(lock)保护共享数据结构,并使用条件变量来协调执行线程。在处理所有这些问题时,操作系统需要同步执行程序。一般情况下,多线程环境编写的程序代码是复杂的、可能产生错误,并可能导致死锁和恶性竞争。

在基于事件的编程中有事件和事件处理者。在操作系统调度中,当~个指定的事件发生时,事件处理程序会被命名。通常内核实现一个循环功能,当事件发生时,会以轮询的方式调用相应的事件处理程序。一般情况下一个事件会被一次处理完,但如果碰到一个阻塞操作,它会寄存一个新的回调,并向调度程序返回控制。

8)内存分配

内存单元是一种宝贵的资源,这是操作系统的关键所在,此外,数据和应用程序代码被暂时存储在内存单元中。内存怎样分配以及分配多长时间,决定任务执行的速度。内存可被分配到一个静态或动态的程序中,静态内存分配可以节省使用内存,但它只能用于程序内存的使用是预先知道的。程序启动时分配静态内存,作为执行操作的一部分,不会被释放。因为程序的内存是在编译时分配的,所以内存的使用率很高。另一方面,静态内存分配不允许在运行时进行。

当程序编译不知道所需内存的大小和被占用时间时,就采用动态内存分配。在使用动态数据结构的情况下,编译时无法知道内存的大小,这样的程序通常只是短暂使用内存。当它们不再需要特定的内存区时,它们会占用并短暂使用一部分内存。因为内存的资源是有限的,不再使用的内存可以被释放或分配给不同的所有者。动态内存分配确保了编程的灵活性,但产生了相当大的管理开销。

把增加节点的内存容量作为一项策略,大多数体系结构使用EEPROM或闪存来存储程序代码。因此,它可能用来部署相对复杂的应用程序和通信协议。然而,读写闪存的过程是耗能很大的。

2.非功能方面的问题

1)关注点分离

因为可用的资源极度紧张,被设计用来支持资源受限的设备以及由这些设备所建立的网络的操作系统不同于通用的操作系统。在通用操作系统中,操作系统和在它上面运行的应用程序之间有一个清晰的分离,它们通过定义良好的接口和系统调用来互相交流。操作系统本身有几个不同的服务可以独立地进行升级、调试或删除。在无线传感器网络中,这种方式是很难实现的。

在大多数情况下,操作系统由一个轻量级的模块编排”( wired)在一起,创造一个单块的程序模块代码,负责传感、处理和通信任务。“编排”需要在编译时产生一个单一的系统映像,并可以在单个节点上安装。一些操作系统提供了一个不可分割的系统内核以及一套库组件来构建一个应用程序。也有其他的操作系统,提供了一个内核和一些可重构的底层服务,将其虚拟成节点的硬件组件。该服务可以在“编排”后构成应用程序,因为这些服务的核心功能相对独立,即使它的功能是有限的,在一定程度上也是一个关注点分离,关注点分离确保了灵活和高效的重新编程和重新配置。更新或升级,可根据需要作为一个整体或部分。在软件升级中,重新配置确保了通信带宽和存储空间的有效利用。

2)系统开销

操作系统执行程序代码,需要自己的资源共享。消耗多少资源取决于它提供的更高服务级别和应用时的规模和服务类型,操作系统所消耗的资源称为系统的开销( overhead)

目前可用的无线传感器节点拥有的资源是以几千字节和几百兆字节为单位来计量的,这些资源会在程序进行检测、数据融合、自组织、网络化管理和通信等方面被共享,鉴于这些任务,操作系统的开销应该被理解。

3)可移植性

前面已经阐述了不同的硬件架构能被用于开发无线传感器节点,在理想情况下,异构体系结构和操作系统的节点能够共存和互相协作。然而目前现有的操作系统不提供这种类型的支持。

对于利用操作系统的可移植性来处理硬件架构的快速演变的问题,无线传感器网络仍然是一门新兴技术。在过去的十年中,架构设计经历了显著的变化,越来越多领域的应用程序开始被研究。为了适应无法预料的要求,这种演变的趋势将会继续下去。而操作系统应该是便携的和可扩展的。

4)动态编程

一旦无线传感器网络被部署,一部分应用程序或操作系统可能需要重新编程,原因如下:

??在初的部署设置时,无法获取完整部署所需的条件参数,因此,网络可能无法达到佳性能。

??应用需求和网络操作中物理环境的属性会随着时间变化。当网络正在运行时检测和修复错误可能是必要的。

因为节点数量庞大,人工更换软件是行不通的。另一种方法是开发一个操作系统,提供支持动态编程的功能。基于这样的考虑,要求应用程序和操作系统之间有明显的分离界限,才可能实现动态重编程的功能。另一方面,如果两者之间有界限,在原则上可以实现动态编程,但其实际执行取决于几个因素:首先,操作系统应该能接收“一片接一片的(pieceby piece)”软件更新,将它组合并存储在临时内存中;其次,操作系统要确保这确实是一个更新版本;后,它应该能删去旧的软件,并安装和配置新的升级版本。所有这些资源的消耗可能导致自身错误。

软件重新编程需要多种传输协议代码、压缩和解压缩代码;并确保代码的一致性和版本控制;以无线传输代码的方式来提供可靠稳定抗干扰的( robust)传输策略。

当前发展中的编程工具和环境将在以后的章节中介绍。

3.原型

1TinyOS (微操作系统.)

在无线传感器网络中微操作系统应用广泛、可选范围丰富并且运行环境有辅助工具。此外,它经历了一个漫长的设计和演进过程,使其工作原理更容易理解。

微操作系统具有紧凑的结构,这使它能够支持很多应用程序,概念上的架构包括一个调度器和一套组件,可通过定义良好的接口相互连接。组件可分为配置组件和模块。配置组件是由两个以上的模块相互连接而被“编排”( wiring)组成,而模块是微操作系统程序的基本构建块。多种配置组成一个单一的可执行代码,并产生一个微操作系统应用程序,微操作系统在应用和操作系统之间并没有提供一个明确的关注点分离。

一个组件由一个框架、命令处理程序、事件处理程序和一套不可中断的任务组成。组件是类似于面向对象编程语言中的对象,它封装了状态,并通过定义良好的接口进行交互。一个接口可以定义命令、事件处理程序和任务,并以它们自己的状态在一定框架范围内运行。因此,组什需明确其命令的用途和发出信号的事什,这种方式可以满足在这个应用程序被编译时确定所需的资源。

组件是分层结构,并通过命令和事件互相通信:高级别的组件给低级别的组件广播发送命令,低级别的组件给高级别的组件发送响应事件信号。因此,高级别的组件实现事件处理程序,而低级别的组件控制处理器(或功能子程序)。物理硬件的组成是以层次结构为基础的,图3.1说明了应用程序和操作系统之间的逻辑边界。

在图3.1中可以看到,有两个组件处于高级别,即路由组件和传感器中的应用组件。路由组件是负责建立和维护网络的,而传感器的应用组件是负责传感和处理的。通过动态交互信息,两个组件互相通信,并与较低级别的组件异步。此外,通过发出无阻塞指令和表示对指定的事件的关注,一个高级别组件能与低级别组件相互通信。

3.2-3.4显示了逻辑结构部件和组件配置,在图3.2中组件A显示了它服务接口C的功能,反过来又提供给命令Dl和信号事件D2。在图3.3中,组件B表示宣布调用命令Dl和提供一个事件处理程序来处理事件D2的界面。

在图3.4中,组件A和组件B之间的绑定是通过配置E来约束的。

?

低级别组件和高级别组件的逻辑边界

3.1??低级别组件和高级别组件的逻辑边界

?

微操作系统中定义的任务、指令和事件作为微操作系统运行环境的基本构建块,是为单一的框架组件之间能进行有效通信。任务是从执行直到完成的单一过程。换句话说,虽然它们可以被事件中断,但它们不能被其他任务抢占,这就是为什么微操作系统能支持并发( concurrency),并确保任务互不干扰或破坏对方的数据的原因。

因为任务要被完整执行,它可以分配一个单一的堆栈来存储上下文消息。任务可以调用低级别的指令,发送信号给更高级别的事件,并调用其他任务,包括它们自己。例如,负责从通信子系统读取数据包的任务可以重复调用自己,直到它已经完成读取所有的数据包。在微操作系统中调用任务是以FIFO规则为基础的,微操作系统架构对持续时间短的任务是有效的。

指令是由高级别组件到低级别组件的非阻塞请求,为了处理潜在的长期执行操作,微操作系统引入了分时操作的概念。在一个分时系统中,当任务完成后,函数调用会立即返回,并且调用的函数会通知调用者。它被称为分时是因为它将调用和执行分割成两个时间段来完成,一个典型的例子是数据包的传输任务。数据包传输可以阻塞任务,因为接收器在数据包重发之前要等待一个超时事件( ttim。。ut)。然而,在超时信号出现之前如果收到一个ACK数据包,接收器会放弃等待ttime。。。的控制。在微操作系统中,这个任务被分解成两个事件:超时事件和数据包接收事件。

每一个对己被命名事件感兴趣的组件都应该提供一个事件处理程序来处理它,硬件事件发生时将会调用事件处理程序。低级别的组件也能直接连接到硬件中断的处理程序,如外部中断、定时器事件、计数器事件。事件处理器会以不同的方式来处理可能发生的事件。它可以将后期高级别事件信息存入其结构中,或者调用低级别指令。

在微操作系统中资源分配是采用静态内存分配来进行优化的,因为应用的内存需求是在其组成时就明确了,它避免了与动态分配有关的额外开销。由于微操作系统缺乏明确的关注点分离,限制了它的适应性。此外,没有额外支持的微操作系统和任何机制来动态加载和删除组件。

作为一个基于事件的系统,微操作系统不支持直接执行上下文,因此一个复杂的程序通常需要一个状态机。因为许多程序员认为状态机难以管理,所以状态机出现较少,文献中提到一个典型的例子是处理与加密操作。这些操作需要几秒钟的时间来完成,占用了处理器的宝贵时间,使系统无法响应外部事件。基于线程的操作系统用时间先决( time critical)或短周期的任务抢占来处理这种类型的情况。

2SOS

SOS尝试在灵活性和资源效率之间建寺平衡,与微操作系统有所不同,它支持运行程序代码重新配置和重新编程。操作系统包括内核和一组模块,可以装载和卸载。在功能上模块类似于微操作系统的组件,它实现了特定的任务或功能。此外,微操作系统组件能以同样的方式“编排”建立一个应用程序,SOS应用程序由一个或多个互动模块组成。不像微操作系统的组件,它在内存中有一个固定存储区,在SOS模块中是一个状态独立的二进制代码,这种典型的特征确保了SOS能与其他模块动态链接。

SOS内核提供底层硬件接口,此外,它提供一个基于优先级的调度机制,并支持动态内存分配。

(1).交互

交互模块通过异步通信和直接调用注册函数(registered function),源于模块A到模块B的消息要先经过位于优先级队列排列的调度器。然后内核会调用模块B中合适的消息处理程序,并把消息传送给它。

模块执行特定目的存在的消息处理程序。一个模块可以通过直接调用它的注册函数与另一个模块进行交互。通过函数调用的交互作用比基于消息通信的速度要快,这种方法需要模块来明确记录其在内核中的公用函数,所有关注这些函数的模块需要“订阅”( subscribe)这些函数。在模块初始化时,注册函数通过调用一个名为ker_register_fn的系统函数来产生,调用确保模块通知内核二进制映像函数被执行了。内核通过创建一个函数控制块(FCB)来存储函数的关键信息,这个信息是用来处理函数订阅,并支持动态内存管理和运行时的模块更新。图3.5说明了两个基本类型模块之间的交互作用。

?

SOS系统中模块间的交互

??????????????????3.5??SOS系统中模块间的交互

模块通过调用名为ker_get_handle的系统函数来订阅一个命名函数,这样做它们提供了带有模块的内核和函数的ID,这将用于定位关注的函数控制块。如果查找成功,内核返回一个指向订阅函数的函数指针的指针。订阅者通过取消指针来访问订阅函数,这确保了内核通过FCB改变函数指针来重置新版本的功能,这个过程对用户是透明的。

(2).动态重编程

以下5个基本特征确保了SOS支持动态编程。第一,模块都是独立的二进制文件,它们使用相对地址而不是绝对地址,因此它们可重定位。第二,模块实现了两种处理,初始化和终的消息处理程序。当首次加载模块时,初始化消息处理器将调用内核。其目的是设置模块的初始状态,包括初始化定时器、函数注册以及函数订阅。在卸载模块前,内核会调用终的消息处理器。其目的是释放模块拥有的所有资源,包括定时器、内存和注册函数,使该模块能正常退出系统。在终消息后,内核会进行垃圾回收。第三,编译过程中,在已知的偏移二进制中,SOS使用一个链接脚本放置初始化处理模块,脚本在模块插入时可轻松地连接。第四,SOS保留外部的模块状态,这使新插入的模块继承了它所替换模块的状态信息。第五,当模块插入时,SOS生成和保存含有相关模块的初始化处理程序的绝对地址的原数据包,以及指针指向保持模块状态的动态内存。

SOS中,动态模块替换发生需3个步骤。

(1)当一个新的模块使用时,代码分发协议在网络中发布公告,公告中包含了模块的身份(ID)、版本号和所需内存的大小。当本地分发协议接收公告时,它评估数据包,决定模块是否是已经在本地存在更新的版本或节点对新的模块是关注的。在这两种情况下,它也可以确保有足够的空间在程序存储器中下载模块。

(2)?一旦决定下载模块,该协议进行下载模块并审查第一个数据包中的元数据。元数据包含了存储该模块所需本地内存的大小。如果SOS内核决定了它不具有足够的随机存储空间来满足运行该模块所需的本地空间,模块插入将会立即停止。

(3)换句话说,如果任何事情都很正常,那么模块插入将会发生。在模块插入时,内核创建的元数据用来存储处理器的绝对地址,指向动态内存控制模块的状态和信息。SOS内核通过调度模块的初始信息来调用模块的处理器。

3Contiki

Contiki是一种混合的操作系统,系统程序被分为内核服务和装载程序。默认情况下,它的核心功能是作为一个事件驱动的内核,并作为应用程序库支持多线程操作。有一个动态链接策略是用来匹配多线程库和具有明确要求的应用。

SOS -样,Contiki实现了把由内核支持的基本系统与动态可装载和可重编程服务的剩余部分分离。通过内核发布公告,服务程序之间相互通信。内核本身不提供任何硬件抽象,相反,它允许设备驱动程序和应用程序直接与硬件通信。这个内核的范围有限,很容易重新编程和更换服务。

每一个Contiki通过一个私有内存来管理自己的状态,保留一个指针来运行状态。然而,服务与服务之间共享相同的地址空间,它还实现了一个事件处理程序和一个可选的轮询处理器。图3.6说明了ROMRAM的内存分配。

?

Contiki操作系统的内存分配

3.6??Contiki操作系统的内存分配

如图3.6所示,Contiki在编译时被分成两个主要部分:一部分是虚线内的服务,包括核心服务;另一部分是这些虚线外的可动态装载服务。核心由内核、程序加载器、驱动通信硬件设备的通信协议栈和其他经常使用的服务组成。这些服务被编译成一个二进制映像,并运行在无线传感器节点上。这种操作系统只能被特殊的启动引导加载器(boot loader)覆盖或修改,其他情况下是不能被动态修改的。

该程序加载器负责将驱动程序下载到活动内存(active memory),它可以通过远程数据的通信服务或直接从本地存储来得到二进制文件。通常程序二进制文件存储在EEPROM中。

内核是操作系统的核心要素,其基本任务是调度事件和定期轮询处理。随后,Contiki的程序执行由内核或通过轮询机制调度事件来触发。在没有被中断或被其他机制所抢占的情况下,事件处理程序完成一个完整的事件处理。当Contiki在多线程环境中运行时,可能会出现一个线程抢占另一个线程的情况。

内核支持同步和异步事件,同步事件被尽可能快地派遣到目标进程,一旦事件的进程结束,控制返回到张贴过程(posting process)。另一方面,异步事件在合适的时候被派遣。除了这些事件外,内核提供了一种轮询机制,定期对硬件组件的状态进行采样。在这段时间内,调查处理器通过硬件设备的优先级来确定目标。

(1).服务架构

Contiki操作系统一个很有趣的特征是其支持动态加载和重新配置的服务,这是通过定义服务、服务接口、服务存根和服务层来实现的。Contiki服务模块是针对微操作系统的。?Contiki服务包括服务接口及其实现,也就是所谓的过程。服务接口包括一个版本号,以及实现该接口的功能的指针函数的列表。服务存根通过服务接口与服务的动态通信来完成一个应用程序,服务层类似于查询服务或注册表服务。主动服务通过提供服务接口、地址信息和版本号来对服务进行描述,这样一来,服务层保持跟踪所有进行的服务。图3.7.说明了应用程序与Contiki服务是如何进行交互的。

?

 Contiki服务交互架构

3.7??Contiki服务交互架构

因为程序是通过服务接口存根调用服务的,所以这种操作没必要知道有关的实施细节或服务在内存中的地址。当服务接口被调用时,服务接口存根查询服务层,并获得一个服务接口的指针。一旦获得服务的接口描述与服务的存根版本号配对,那么该接口存根就会调用执行所请求的功能。服务与使用该服务的程序的松散耦合使操作系统可以更新服务,而不需要修改应用程序。

(2).协议线程( Proto Thread)

Contiki通过结合一些事件和线程的功能来介绍协议线程的概念,协议线程可以视为轻量级(无堆栈的)线程,但它们也可以作为基于事件编程的中断任务。一个协议线程提供有条件的阻塞等待声明,PT__ WAIT_UNTILQ需要一个条件语句块实例,直到该语句评估正确为止。当协议线程到达PT WAIT_UNTIL()声明时,如果条件声明是正确的,那么它不中断地继续执行。PT—WAIT_UNTIL()指令不需要任何条件声明,包括复杂的布尔表达式。

因为协议线程是无堆栈的,只有明确的PT WAIT_UNTIL()声明能阻塞这个线程,所以从调度的角度来看,系统中的所有协议线程在相同的堆栈中运行,上下文切换是通过堆栈弹出来实现的。通过分别使用PT__ BEGINPT END声明来明确宣告协议线程的开始和结束,协议线程可以通过PT EXIT语句提前结束。

协议线程概念并没有明确指明它什么时候或以什么方式来被调用或调度,在Contiki的实施中,运行在事件驱动内核顶层的过程被当作一个协议线程来执行,因此,当过程收到一个事件时协议线程被调用,例如,在过程从其他过程或计时器事件收到消息的时候。同样,协议线程概念不预先确定内存是如何划拨给管理协议线程状态的。与调度一样,这也是在特定条件下实现的。例如,只有预先知道操作系统是由基于一组固定的协议线程组成,才能通过提前静态分配内存来进行状态管理。如果协议线程的数量没有提前知道,内存也可以以一种动态方式来分配。在Contiki执行中,静态内存分配是一种典型的设置,并且协议线程状态保存在进程控制块中。

因为协议线程减少了明确的状态机和状态转换,所以简化了事件驱动的编程状态机的设计。协议线程的成本是与内存开销和几个处理器的开销有关的,为了说明协议线程的实用性,考虑一个MAC协议,定期关闭无线收发子系统,但要确保无线收发子系统在进入休眠状态前完成通信。这种行为归纳如下:

(1)此时无线收发子系统打开。

(2)无线收发子系统周期性地保持收发状态。

(3)?一旦超过,无线收发子系统就会关闭,但是它已完成一项正在进行的通信。

(4)如果通信没有完成,那么MAC协议就要等待twait max时刻到达,相当于一个完整的通信周期。

(5)如果通信完成或超过大等待时间,无线收发子系统就会关闭,并且会保持休眠一个周期。

(6)这个过程(通信一休眠)不断重复。

3.8和图3.9分别显示了基于事件与基于协议线程实现的通信子系统的睡眠调度。状态机的实现需要一个明确的状态变量,可以采用开启、等待和关闭。有条件的if语句是用来执行不同的动态变量的值,代码可以放置在事件处理函数中,无论什么时候事件发生都可以被调用。在这种情况下可能发生的事件是定时时间到时和通信结束。在图3.8中可以看出,控制状态机的代码量超过总代码量的三分之一,此外,该机制的6个步骤的结构不能直接从代码中显现出来。

协议线程实施休眠的时间安排显然是更短、更直观的。

?

4LiteOS

LiteOS是一种基于多线程的操作系统,并且支持多个应用程序。它是基于一个操作系统和在它上面运行的应用程序之间完全分离的原则,不同于所有其他的操作系统,LiteOS并没有提供用来“编排”起来建立应用程序的组件或模块。就LiteOS而言,开发建立阻塞和确定它们彼此交互的方式,完全是应用程序开发人员的任务。

LiteOS提供几种系统调用的方式:来自用户的分离系统的壳调用,分层文件管理系统,动态重编程技术。

整个系统仿照分布式文件系统,在基站端的用户可以使用安装在资源丰富的计算机上的壳调用来实现对已命名节点的识别、交互,以及重编程。网络中的每个节点运行一个多线程的内核,其中有3个主要组件:一个调度器、一套系统调用和二进制安装器。内核的系统调用,使远程用户可以访问和管理本地文件和目录。本地文件分为传感器数据、设备驱动程序和应用程序二进制文件。在系统内的层次结构中,一个节点是一个无指定的组件。

3.10说明了LiteOS的系统架构。

?

LiteOS操作系统架构

3.10??LiteOS操作系统架构

1).壳和系统调用

壳继承了Linux操作系统的几个特点。壳向一个距其有一跳距离的无线节点提供了一种安装机制,使整个网络可被视为一个分布式和分层文件系统。用户可以像使用本地资源那样访问一个指定节点的资源。壳支持大量的可以在分布式文件系统上执行的Linux指令。

这样,LiteOSLinux用户提供了一个熟悉的界面。

命令被分为五大类:文件命令、处理命令、调试命令、环境命令和设备命令。文件中的命令用于浏览分层文件系统,以及移动、复制、删除文件和目录。下面给出一个使用文件命令操作的例子。

$ pwd

Current directory is /snOl/node101/apps

$ cp /c/Blink.lhex Blink.lhex

Copy complete

$ exec Blink.lhex

File Blink.‘lhex successfully started

$ ps

Name State

Blink Sleep

在这个例子中,pwd命令在sn01节点中打印了工作目录,这就是node101/apps。接下来,使用cp指令,Blink.lhex文件从资源丰富的计算机的根日录被复制到指定节点的sn01目录。然后,通过使用exec指令,文件就会被执行。ps指令报告进程状态,在这种情况下表示一个休眠的线程。

该过程命令对管理、创建、暂停、终止线程是非常有用的。在LiteOS中可以同时使用多达8个线程,调适指令确保能建立调适环境来调适程序代码。环境指令给管理操作系统环境提供了支持、显示交互的历史记录,并提供命令手册。后,设备命令提供对硬件设备(如传感器和无线收发子系统)的直接访问。

2.LiteFS

LiteFS是一种分布式文件系统,它是LiteOS的本质特征。通过LiteFS,用户可以直接访问传感器网络,可以规划和管理各个节点。类似于Linux中的文件,LiteOS中的文件代表数据、应用程序二进制和设各驱动程序。本地文件系统的组织结构如下:RAM包含被开放( opened)文件的列表以及内存分配和闪存EEPROM中的有关信息。文件系统的结构被存储在EEPROM存储器中,实际文件被存储在闪存中,如图3.11所示。

?

LiteFS的文件系统结构

3.11??LiteFS的文件系统结构

RAM中可同时打开多达8个文件,LiteFS使用两位向量来跟踪EEPROM和闪存分配。8B用于前者,32B用于后者,这相当于RAM104B。在EEPROM中每个文件代表一个32B的控制块,控制块的可用空问被划分为65块。第一块是根块,它在文件系统格式化时都被初始化,其余的区块是目录块(图中的D)或文件块(图中的F)。文件控制块多可寻址10个逻辑FLASH页,每一页包含2KB的数据(或8个物理FLASH页)。当一个文件占用超过20KB时,LiteFS为这个文件分配另一个控制块,并且在以前的控制块中存储一个新的控制块的地址。

3).动态重编程

LiteOS支持用户应用程序的动态更换和重新编程,无论是否提供源代码都可以完成。如果源代码是提供给操作系统的,它将被一个新的内存设置重新编译,同时所有引用和指向旧版本的指针将被重新定向。如果源代码不是提供给操作系统的,LiteOS采用差别修补( differential patching)”机制,以取代旧版本的二进制代码。该方法是通过插入差别修补程序,并将差别修补程序连同二迸制映像文件一起分发,来直接将重定位信息编码到二进制应用程序代码中。

有一种描述差别修补的数学模型已经被提出,该模型具有3个参数。该模型的参数是闪存的二进制可执行文件的起始地址、RAM中已分配内存的起始地址、栈顶。堆栈属于内存的一部分,只是在实际执行的过程中内存的某个区域被指定作为堆栈。当这些参数已知时,就有可能将更新的程序插入到旧的二进制映像中。模型参数是凭借经验和节点架构的知识来获得的,这限制了修补计划的实用性。

4.评价

与所有的排名一样,对操作系统的性能进行排名是一个困难的任务,排名需要从一个合适的角度进行。在无线传感器网络中,有关于开发、部署、运行性能和代码更新的若干问题。如果以设计为主题,可能存在以下的问题:由操作系统提供的用来访问硬件设备的接口有多丰富?由操作系统支持的编程环境有多灵活和富有表现性?由操作系统支持的并有利于构建应用程序的模块、组件和库文件是否有多样的选择?操作系统便携到什么程度?应用程序代码的可管理性如何?

如果以部署为主题,主要的方面是动态代码的安装和动态代码的传送。在大量的节点上对代码进行安装和测试是一个繁重的任务。同样,如果就代码的更新而言,动态代码的传送和重编程是重要的因素。

如果以运行方式为主题,主要的方面是操作系统的效率,特别是紧凑性和功耗。

在这些方面,TinyOS在规模上是紧凑的,在资源利用上是高效的,因为管理分散体的开销成为单一管理纯二进制数,但更换或重新编程成本高。SOSContikiLiteOS灵活地支持了动态重编程,因此非常适合应用程序可能进行频繁的更新和升级过程。然而,图像传送的成本比较高。LiteOS被视为一个分布式文件系统网络的方式很有趣,因为它为用户提供了一个直观的网络浏览方式。然而,因为节点是无状态的,所有的更新记录应存储在用户触手可及的地方,它会导致网络上额外的流量被用于传送命令和状态信息。

通常,无线传感器网络是一种新的技术领域。操作环境以及应用要求可能变得更加紧凑和精致,但还存在一些后续的问题,如动态编程和代码更换之间的平衡,另外还有代码的执行效率与其他诸多因素的平衡。

????3.1和表3.2提供了本章提出的4个操作系统的功能和非功能方面的摘要。

?

当前操作系统非功能方面的比较

3.2当前操作系统非功能方面的比较

操作系统
小系统开销
关注分离
动态重编程
可移植性
?
TinyOs
?
332字节
操作系统和应用程序之间没有明显的区别,在编译过程中,一个特定的配置生成了一个单片的可执行代码
?
要求软件支持

?
?
SOS
?
Ca116字节
可替代模块被编译生成一个可执行代码,这在操作系统和应用程序之间没有明显的区别
?
支持
?
中等到低
?
Contiki
?
Ca810字节
模块被编译生成一个可重编程和可执行的代码,但这并不是应用程序和操作系统的分离
?
支持
?
?
中等
?
?
LiteOS
?
不可用
应用程序被分割成若干实体:它们是独立于操作系统开发的
?
支持

?
收藏
分享到:

相关课程

中国信息化培训中心

中国信息化培训中心

认证等级

信誉良好,可安心报读

中国信息化培训中心

已获好学校V2信誉等级认证

信誉值

  • (60-80)基础信誉积累,可放心报读
  • (81-90)良好信誉积累,可持续信赖
  • (91-100)充分信誉积累,推荐报读

与好学校签订读书保障协议:

  • 100%
  • 15
  • 13811
在线咨询
;