当共享地址空间进行数据交换时,为避免竞争,需要对内存进行互锁。
实现资源互斥访问的方法有很多,不同之处仅在于互斥的范围:禁止中断,禁止任务调度以及信号量对资源的上锁。
1.禁止中断
对于互斥使用最强有力的办法是禁止中断,这种方法保证了对CPU的单独访问。
uC/OS-II:
OS_ENTER_CRITICAL()
OS_EXIT_CRITICAL()
VxWorks:
intLock()
intUnlock()
对于大部分实时系统,禁止中断不能作为一种通用的互斥方法。因为若关中断的时间太长的话,会影响整个系统的中断相应时间,即中断延迟时间。
当改变或复制几个变量的值时,应想到用这种办法来做。
注意:在中断服务子程序ISR中,禁止中断是处理共享数据结构的唯一办法。
2.禁止任务调度
不允许其他任务抢占当前执行任务时,禁止抢占提供了一种较小限制性的互斥,此时,中断仍能响应。
uC/OS-II:
OSSchedLock()
OSSchedUnlock()
VxWorks:
taskLock()
taskUnlock()
使用这种办法也会使系统实时性得不到充分的保证,类似于第一种办法。
3.信号量
在大多数RTOS中,信号量被高度优化,可以提供最快的任务间通信机制。信号量是互斥和任务同步的最主要手段。
对于互斥,信号量可对共享资源访问进行互锁。
对于同步,信号量可协调外部事件与任务之间的执行。
二进制信号量
uC/OS-II:
OSSemCreate()
OSSemPost()
OSSemPend()
OSSemDel()
OSSemQuery()
VxWorks:
semBCreate() // 分配并初始化一个二进制信号量
semTake() // 获取一个信号量
semGive() // 提供一个信号量
semDelete() // 中止并释放一个信号量
semFlush() // 解锁所有正在等待信号量的任务
互斥信号量:
uC/OS-II:
OSMutexCreate()
OSMutexPost()
OSMutexPend()
OSMutexDel()
OSMutexQuery()
VxWorks:
semMCreate() // 分配并初始化一个互斥信号量
semTake() // 获取一个信号量
semGive() // 提供一个信号量
semDelete() // 中止并释放一个信号量
semFlush() // 解锁所有正在等待信号量的任务
总结:
使用实时系统时,访问共享资源或数据结构,一般使用信号量的方法。
值得注意的是,在ISR中,只能使用禁止中断的办法。
文章评论(0条评论)
登录后参与讨论