uCOS-II任务间通信之全局变量 [转载]
2016-12-02 23:14
260 查看
uCOS-II任务间通信之全局变量
任务创建好了之后,只是完成了系统编程的一小步,更为重要的是任务间的通信。比如在mcu21的项目里,有通信任务,有液晶显示任务,有控制任务。控制任务需要用到通信任务接受到的数据,液晶显示任务也显示控制任务的数据。这就需要用到任务间的通信了。
Mcu21总结了一下,在ucos II 里任务间通信可以采用以下几种方式。
1、共享全局变量,这是最快捷有效的方式,实现这种通信可以采用以下两种方式:一是利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来关闭中断和打开中断,二是利用函数OSSchedLock()和OSSchedUnlock()对μC/OS-II中的任务调度函数上锁和开锁。
2、使用信号量
3、使用邮箱
4、使用消息队列
下面介绍下共享全局变量的实现过程。
(1)宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()是在移植ucos II过程中由用户定义的。在os_cpu.h这个文件中。代码如下,这部分代码的作用是关,开中断,具体和CPU有关。当我们调用OS_ENTER_CRITICAL()时,系统中断被关闭,我们知道,任务切换时基于定时器中断的,当系统中断别关闭时,其它中断,包括定时器中断也就被关闭,任务切换也不可能发生,所以确保在访问变量的时候,不会有其它的任务或中断也在同时访问这个变量。
这两个宏非常好用,在mcu21的项目里经常用到。尤其在中断处理函数里面。
因为现在的很多CPU是支持中断嵌套的,为了防止中断执行的时候不被其它的中断打断,就可以调用这两个宏。
(2)第二种方法是给任务调度函数上锁,开锁。这种方法和使用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()最大的区别是:中断是可以执行的。尽管不执行任务切换,变量依然有可以被中断函数访问。
任务调度器上锁的函数如下:
给任务调度器解锁的函数如下:
它实现的原理大致是这样的。调用一次OSSchedLock(),就会对全局变量OSLockNesting加1,调用OSSchedUnlock ()一次就对全局变量OSLockNesting减1。当OSLockNesting是零的时候,系统才能进行任务调度。
任务创建好了之后,只是完成了系统编程的一小步,更为重要的是任务间的通信。比如在mcu21的项目里,有通信任务,有液晶显示任务,有控制任务。控制任务需要用到通信任务接受到的数据,液晶显示任务也显示控制任务的数据。这就需要用到任务间的通信了。
Mcu21总结了一下,在ucos II 里任务间通信可以采用以下几种方式。
1、共享全局变量,这是最快捷有效的方式,实现这种通信可以采用以下两种方式:一是利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来关闭中断和打开中断,二是利用函数OSSchedLock()和OSSchedUnlock()对μC/OS-II中的任务调度函数上锁和开锁。
2、使用信号量
3、使用邮箱
4、使用消息队列
下面介绍下共享全局变量的实现过程。
(1)宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()是在移植ucos II过程中由用户定义的。在os_cpu.h这个文件中。代码如下,这部分代码的作用是关,开中断,具体和CPU有关。当我们调用OS_ENTER_CRITICAL()时,系统中断被关闭,我们知道,任务切换时基于定时器中断的,当系统中断别关闭时,其它中断,包括定时器中断也就被关闭,任务切换也不可能发生,所以确保在访问变量的时候,不会有其它的任务或中断也在同时访问这个变量。
这两个宏非常好用,在mcu21的项目里经常用到。尤其在中断处理函数里面。
因为现在的很多CPU是支持中断嵌套的,为了防止中断执行的时候不被其它的中断打断,就可以调用这两个宏。
(2)第二种方法是给任务调度函数上锁,开锁。这种方法和使用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()最大的区别是:中断是可以执行的。尽管不执行任务切换,变量依然有可以被中断函数访问。
任务调度器上锁的函数如下:
void OSSchedLock (void) { if (OSRunning == TRUE) { OS_ENTER_CRITICAL(); OSLockNesting++; OS_EXIT_CRITICAL(); } }
给任务调度器解锁的函数如下:
void OSSchedUnlock (void) { if (OSRunning == TRUE) { OS_ENTER_CRITICAL(); if (OSLockNesting > 0) { OSLockNesting--; if ((OSLockNesting | OSIntNesting) == 0) { //(1) OS_EXIT_CRITICAL(); OSSched(); //(2) } else { OS_EXIT_CRITICAL(); } } else { OS_EXIT_CRITICAL(); } } }
它实现的原理大致是这样的。调用一次OSSchedLock(),就会对全局变量OSLockNesting加1,调用OSSchedUnlock ()一次就对全局变量OSLockNesting减1。当OSLockNesting是零的时候,系统才能进行任务调度。
相关文章推荐
- uCOS-II任务间通信之信号量 [转载]
- uCOS-II任务间通信之事件控制块 [转载]
- uCOS-II任务间通信之邮箱 [转载]
- ucos II 任务间 通信之三:信号量
- ucos II 任务间 通信之一:全局变量
- UCOS-II任务间通信:邮箱
- uCOS-II整理之任务的同步与通信
- uCOS-II内核之任务控制块 [转载]
- ucos-II 任务间通信源码分析
- uCOS-II任务间通信之事件控制块
- uCOS-II任务间通信之信号量
- uCOS-II任务间通信之邮箱
- (转载)uCOS-II的嵌入式串口通信模块设计
- uCOS-II内核之任务调度 [转载]
- uCOS-II任务管理之改变任务优先级 [转载]
- ucos II 任务间 通信之三:信号量
- ucos II 任务间 通信之一:全局变量
- UCOS-II任务间通信(信号量、邮箱、消息队列)
- 全局变量和局部变量在内存里的区别?堆和栈(转载-无法确定作者与出处) 收藏
- 转载:关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题