任务创建之后,只是完成系统编程的一小部分,更为重要的是任务键的通信,在ucos里任务通信可以采用以下几种方式
1.共享全局变量,这是最快捷有效的方式,实现这种通信可以采用以下两种方式,一是利用宏OS_ENTER_CRITICAL和
OS_EXIT_CRITICAL来关中断和打开中断,二是利用函数OSSchedLock和OSSchedUnLock对UCOS的任务调度上锁和开锁
2. 使用信号量
3.使用邮箱
4.使用消息队列
下面介绍共享全局变量的而实现过程
1.宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL是在移植ucos过程中游用户定义的,在OS_CPU.h这个文件汇总,代码如下
这部分代码的作用是关,开中断,具体和CPU有关,当我们调用OS_ENTER_CRITICAL()时,系统中断被关,我们知道,任务切换时基于定时器中断,
当系统中断没关闭是,任务切换也不可能发生,所以确保在访问变量的时候,不会有其它的任务或中断也在同时访问这个变量,
尤其在中断函数里,因为现在很多CPU是支持中断嵌套的,为了防止中断执行上的时候不被其它的中断打断,就可以调用这两个宏。
2.第二种方法是给任务调度函数上锁开锁,这种方法和使用宏OS_ENTER_CRITICAL和OS_EIXT_CRITICAL最大区别是:中断可以执行的,尽管不执行任务切换,变量依然可以被中断函数访问
给任务调度器上锁函数如下:
void OSSchedLock(void)
{
if(OSRunnign==TRUE)
{
OS_ENTER_CRITICAL();
OSLockNesting++;
OS_EXIT_CRITICAL();
}
}
给任务调度器解锁的函数如下
void OSSchedUnLokc(void)
{
if(OSRunning==TRUE)
{
OS_ENTER_CRITICAL();
if(OSLockNesting>0)
{
OSLockNesting--;
if((OSLockNesting|OSIntNesting)==0)
{
OS_EXIT_CTITICAL();
OSSched();
}
else
{
OS_EXIT_CRITICAL();
}
}
else
{
OS_EXIT_CRITICAL();
}
}
}
它实现的原理大致是这样的.
调度一次OSSchedLock(),就会对全局变量OSLockNesting加1,调用OSSchedUnLock一次就对全局变量OSLockNesting减1
当OSLockNesting是零的时候,系统才能进行任务调度