📄 嵌入式系统vxworks介绍及编程.htm
字号:
face="Courier New">/* Release semaphore */ <BR><A name=BM84245>taskUnsafe
();</A></FONT></P></B></DIR></DIR>
<UL>
<LI><BIG><BIG><STRONG><FONT lang=ZH-CN>任务间的同步和进程间协调</FONT></STRONG>
</BIG></BIG></LI></UL><FONT lang=ZH-CN face=System>
<BLOCKQUOTE>
<P>信号量作为任务间同步和互斥的机制。在</FONT> <FONT lang=ZH-CN face=System>wind
核中有几种类型的信号量,它们分别针对不同的应用需求:二进制信号量、计数信号量、互斥信号量和</FONT> <FONT lang=ZH-CN
face=System>POSIX 信号量。所有的这些信号量是快速和高效的,它们除了被应用在开发设计过程中外,还被广泛地应用在VxWorks
高层应用系统中。对于进程间通信,wind 核也提供了诸如消息队列、管道、套接字和信号等机制。</FONT> </P></BLOCKQUOTE><FONT
lang=ZH-CN face=System>
<BLOCKQUOTE>
<P>任务间的同步和进程间协调的几种方式:</P></BLOCKQUOTE>
<OL>
<OL>
<LI>内存共享(Shared Memory),对简单的数据共享而言.
<LI>信号量(Semaphore),基本的互斥和同步.
<LI>消息队列(Message queues)和管道(Pipe),单个CPU中,任务间的信息传递.
<LI>套结字(Socket)和远程调用(Remote procedure calls),相对于网络任务间的通信.
<LI>信号(Signals),出错处理(Exception handling). </LI></OL></OL></FONT>
<P><FONT lang=ZH-CN face=宋体 size=4><STRONG>互斥</STRONG></FONT><FONT lang=ZH-CN
face=System size=4><B>(Mutual Exclusion)</B></FONT></P>
<BLOCKQUOTE>
<P><FONT lang=ZH-CN
face=System>互斥是用来控制多任务对共享数据进行串行访问的同步机制。在多任务应用中,当两个或多个任务同时访问共享数据时,可能会造成数据破坏。互斥使它们串行地访问数据,从而达到保护数据的目的.</FONT></P></BLOCKQUOTE>
<BLOCKQUOTE>
<P><FONT lang=ZH-CN face=System>解决互斥的几种方法:</FONT></P>
<P><FONT lang=ZH-CN face=System>1. 关闭中断的方法(intLock): 能解决任务和中断ISR之间产生的互斥.
</FONT></P>
<BLOCKQUOTE><PRE class=Code><BIG><A name=84963><B><EM>f</EM>uncA () </B></A></BIG></PRE><PRE class=Code><BIG><B><A name=84963>{ int lock = intLock();</A></B></BIG></PRE><PRE class=Code><BIG><B><A name=84963>. . <I class=i>critical region that cannot be interrupted</I> .</A></B></BIG></PRE><PRE class=Code><BIG><A name=84963><B>intUnlock (lock); }</B></A></BIG></PRE>
<P><FONT lang=ZH-CN
face=System>但在实时系统中采取这个办法会影响系统对外部中断及时响应和处理的能力.</FONT></P></BLOCKQUOTE>
<P><FONT lang=ZH-CN face=System>2. 关闭系统优先级(taskLock):
关闭系统优先级,这样在当前任务执行时,除了中断外,不会有其他优先级高的任务来抢占CPU,影响当前程序运行. </FONT></P>
<BLOCKQUOTE><B><A name=84977>
<P>funcA () </A></B></P>
<P><B><A name=84977>{ taskLock ();</A></B></P>
<P><B><A name=84977>. . <I class=i>critical region that cannot be
interrupted </I>.</A></B></P>
<P><B><A name=84977>taskUnlock (); }</A></B></P></BLOCKQUOTE>
<P><FONT lang=ZH-CN
face=System>这种方法阻止了高优先级的任务抢先运行,在实时系统中也是不适合的,除非关闭优先级的时间特别短.</FONT></P>
<P><FONT lang=ZH-CN face=System>3. <STRONG>信号量(Semaphore):</STRONG>
信号量是</FONT><FONT lang=ZH-CN>解决<STRONG>互斥</STRONG></FONT><FONT lang=ZH-CN
face=System>和</FONT><STRONG><FONT lang=ZH-CN>同步协调进程</FONT></STRONG><FONT
lang=ZH-CN face=System>最好的方法</FONT>
<UL>
<LI><FONT lang=ZH-CN face=System>当一个Semaphore创建时,指定了任务队列的种类</FONT> </LI></UL>
<BLOCKQUOTE>
<OL type=A>
<LI><FONT lang=ZH-CN face=System>semBCreat( SEM_Q_PRIORITY, SEM_FULL),
SEM_Q_PRIORITY 指明处于等待状态的任务在等待队列中以优先级的顺序排列</FONT>
<LI><FONT lang=ZH-CN
face=System>semBCreat(SEM_Q_FIFO,SEM_FULL), SEM_Q_FIFO指明
处于等待状态的任务在等待队列中以先进先出的顺序排列</FONT> </LI></OL></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
<UL>
<LI><FONT lang=ZH-CN
face=System>当一个Semaphore创建时,指定了这个semaphore是用在解决互斥还是用来同步任务</FONT>
</LI></UL></BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<OL type=A>
<LI><FONT lang=ZH-CN face=System>semBCreat( SEM_Q_FIFO, SEM_FULL) ,
SEM_FULL 指明用于任务间互斥.</FONT> </LI></OL></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE><A name=85183><B>
<P>SEM_ID semMutex;</B></A></P>
<P><A name=85183><B>semMutex = semBCreate (SEM_Q_PRIORITY,
SEM_FULL);</B></A></P>
<P><B>.........</B></P><B><A name=85194>
<P>semTake (semMutex, WAIT_FOREVER);</A></B></P>
<P><B><A name=85194>. . <I class=i>critical region, only
accessible by a single task at a time</I> . </A></B></P>
<P><B><A name=85194>semGive
(semMutex);</A></B></P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<OL type=A start=2>
<LI><FONT lang=ZH-CN face=System>semBCreat(SEM_Q_FIFO,SEM_EMPTY),
SEM_EMPTY 指明用于任务间同步.</FONT> </LI></OL></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN>/* includes */</FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN>#include "vxWorks.h" </FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN>#include "semLib.h" </FONT></SPAN></STRONG></EM></BIG></PRE><A
name=85208><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN>SEM_ID syncSem;</FONT></SPAN></STRONG></EM></BIG></A></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>/* ID of sync semaphore */</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>init ( int someIntNum )</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>{ /* connect interrupt service routine */ </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>intConnect (INUM_TO_IVEC (someIntNum), eventInterruptSvcRout, 0); </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>/* create semaphore */ </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>syncSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY);</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>/* spawn task used for synchronization. */</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>taskSpawn ("sample", 100, 0, 20000, task1, 0,0,0,0,0,0,0,0,0,0);</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>} </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>task1 (void) </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>{ ... </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>semTake (syncSem, WAIT_FOREVER);</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>/* wait for event to occur */</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>printf ("task 1 got the semaphore\n");</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>... </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>/* process event */</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>} </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>eventInterruptSvcRout (void)</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>{ ... </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>semGive (syncSem); </A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>/* let task 1 process event */</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>...</A></FONT></SPAN></STRONG></EM></BIG></PRE><PRE class=Code><BIG><EM><STRONG><SPAN class=Code><FONT lang=ZH-CN><A name=85208>}</A></FONT></SPAN></STRONG></EM></BIG></PRE></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE><FONT
lang=ZH-CN face=System>
<P> 函数介绍:</FONT></P>
<P><FONT lang=ZH-CN
face=System> semTake(semID,time
out)--------有Semaphore空闲,就Take, 如果没有,由time out 定,超时则向下执行</FONT></P><FONT
lang=ZH-CN face=System>
<P>
</FONT></P><FONT lang=ZH-CN face=System>
<P><STRONG><FONT lang=ZH-CN face=宋体 size=4>优先级反转</FONT>(Priority Inversion)
</STRONG></P>
<BLOCKQUOTE>
<P>优先级反转是指一个任务等待比它优先级低的任务释放资源而被阻塞,如果这时有中等优先级的就绪任务,阻塞会进一步恶化。优先级继承技术可用来解决优先级反转问题。
</P></BLOCKQUOTE>
<P> </P>
<BLOCKQUOTE>
<P>Priority inversion arises when a higher-priority task is forced to wait an
indefinite period of time for a lower-priority task to
complete.</P></BLOCKQUOTE></FONT>
<P><STRONG><FONT lang=ZH-CN face=宋体 size=4>优先级继承</FONT><FONT lang=ZH-CN
face=System>(Priority Inheritance) </STRONG></P>
<BLOCKQUOTE>
<P>优先级继承可用来解决优先级反转问题。当优先级反转发生时,优先级较低的任务被暂时地提高它的优先级,使得该任务能尽快执行,释放出优先级较高的任务所需要的资源。</P></BLOCKQUOTE>
<BLOCKQUOTE>
<P>The mutual-exclusion semaphore has the option SEM_INVERSION_SAFE, which
enables a priority-inheritance algorithm. The priority-inheritance protocol
assures that a task that owns a resource executes at the priority of the
highest-priority task blocked on that resource. Once the task priority has
been elevated, it remains at the higher level until all mutual-exclusion
semaphores that the task owns are released; then the task returns to its
normal, or standard, priority. Hence, the "inheriting" task is protected from
preemption by any intermediate-priority tasks. This option must be used in
conjunction with a priority queue (SEM_Q_PRIORITY).</P></BLOCKQUOTE>
<P> </P></FONT></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -