中断引入了一个问题:程序需要一种方法来执行代码片段并使代码片段不会被抢占。nesC语言通过atomic语句提供了这种功能。
例4.5:
atomic程序块允许变量可以在原子状态下进行读和写。实际上,在当前所有的mote平台上,atomic语句是通过禁止中断来实现原子性的。理论上,一个nesC的执行允许incrementA和incrementC在代码片段中互相抢占对方,这是因为它们访问不同的变量。
例4.6:
1)
2)
然而,在实际执行时nesC是棘手的,因为它开销大、与I/O设备交互困难。因此,应假设atomic语句禁止中断。(www.xing528.com)
nesC中atomic语句用于检查变量是否有合适的保护,并在没有合适保护的情况下发出警告。例如,在例4.6中若b和c没有在atomic语句中,nesC将会因为可能的自我抢占而发出警告。如果一个变量是由异步函数访问的,那这个变量必须受atomic语句保护。如果一个不包含atomic语句的函数经常被有atomic语句的函数调用,则编译器不会发出警告。
虽然可以通过在代码中使用atomic语句使数据竞争不被发出警告,但这么做时应考虑以下两个方面。一方面,围绕atomic语句禁止中断和使能中断会带来CPU开销,因此应最小化禁止和使能中断的次数。另一方面,较短的atomic语句使中断有更少的时延,这样可改善系统的并发性。确定atomic语句的运行时间是一个棘手的问题,特别是在一个组件不得不调用另一个组件时。
例4.7:
ATmege128 SPI总线的实现有一个资源仲裁器对总线访问进行管理。仲裁器允许不同的用户请求资源(总线)并在所请求的资源被授予时通知它们。然而,SPI总线不希望明确仲裁策略(如先到先服务或者基于优先级),所以它必须绑定一个仲裁器。这种分解涉及能量管理。SPI在没有用户时自行关闭,不需要调用仲裁器。这意味着SPI必须用atomic语句来查看是否调用仲裁器,若没有,则自行关闭。
这种情况下,调用inUse所需时间应该非常短(实际上它可能只是读一个状态变量)。如果某一个应用绑定了仲裁器,它的inUse命令耗时1ms,那么就可能带来一些问题。实现过程中,通常假定调用inUse命令几乎不耗时,在例4.7中就做了这样的假定。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。