原创 多任务的共享数据操作

2011-2-25 14:16 1187 3 3 分类: MCU/ 嵌入式
来源:瑞萨单片机论坛

当共享地址空间进行数据交换时,为避免竞争,需要对内存进行互锁。
实现资源互斥访问的方法有很多,不同之处仅在于互斥的范围:禁止中断,禁止任务调度以及信号量对资源的上锁。
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条评论)

登录后参与讨论
我要评论
0
3
关闭 站长推荐上一条 /3 下一条