📄 micrium support bug fixes - improvements.htm
字号:
<P> <FONT color=#ff0000> ptcb->OSTCBStkPtr = (OS_STK *)0;
/* Show that TCB is 'unused' */</FONT><BR><BR></P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_CORE.C (V2.61-004)</TD></TR></TBODY></TABLE>
<P>OS_TaskStatStkChk() has an error computing the stack bottom. The new
code for this function can be downloaded by clicking <A
href="http://www.ucos-ii.com/contents/support/downloads/OS_TaskStatStkChk.ZIP">HERE</A>!
This code also contains the fix for Bug <B>V2.61-003</B>.<BR><BR></P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_CORE.C (V2.61-003)</TD></TR></TBODY></TABLE>
<P>OS_TaskStatStkChk() didn't check for a task that was assigned to a
MUTEX and thus attempted to compute the stack size of an invalid task. The
following code corrects this problem:</P>
<P><B><FONT color=#ff0000>if (ptcb != (OS_TCB *)0) {</FONT></B><BR>
<B><FONT color=#ff0000>if (ptcb != (OS_TCB *)1)</FONT></B> {<BR>#if
OS_TASK_CREATE_EXT_EN > 0<BR> stk_size =
ptcb->OSTCBStkSize * sizeof(OS_STK);<BR>#endif<BR>#if
OS_TASK_PROFILE_EN > 0<BR>#if OS_STK_GROWTH == 1<BR>
ptcb->OSTCBStkBase = ptcb->OSTCBStkBottom +
stk_size;<BR>#else<BR> ptcb->OSTCBStkBase =
ptcb->OSTCBStkBottom - stk_size;<BR>#endif<BR>
ptcb->OSTCBStkUsed = (INT32U)stk_data.OSUsed;<BR>#endif<BR>
}<BR>}</P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_MEM.C (V2.61-002)</TD></TR></TBODY></TABLE>
<P>Line #242 is:<BR><BR>if (len > (OS_EVENT_NAME_SIZE - 1)) {<BR></P>
<P><B><FONT color=#ff0000>and should be:</FONT></B></P>
<P>if (len > (<FONT color=#ff0000><B>OS_MEM_NAME_SIZE</B></FONT> - 1))
{<BR></P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_FLAG.C (V2.61-001)</TD></TR></TBODY></TABLE>
<P>The second <FONT
face="Courier New, Courier, mono">OS_ENTER_CRITICAL()</FONT> in <FONT
face="Courier New, Courier, mono">OSFlagPendGetFlagsRdy()</FONT> needs to
be changed to <FONT
face="Courier New, Courier, mono">OS_EXIT_CRITICAL()</FONT><BR>The BAD
code is:</P>
<P>OS_FLAGS OSFlagPendGetFlagsRdy (void)<BR>{</P>
<BLOCKQUOTE>
<P>#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status
register */<BR>OS_CPU_SR cpu_sr;<BR>#endif<BR>OS_FLAGS flags;</P>
<P><BR>OS_ENTER_CRITICAL();<BR>flags =
OSTCBCur->OSTCBFlagsRdy;<BR><FONT
color=#ff0000>OS_ENTER_CRITICAL();</FONT><BR>return
(flags);</P></BLOCKQUOTE>
<P>}<BR></P>
<P><B><FONT color=#ff0000>and should be:</FONT></B></P>
<P>OS_FLAGS OSFlagPendGetFlagsRdy (void)<BR>{</P>
<BLOCKQUOTE>
<P>#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status
register */<BR>OS_CPU_SR cpu_sr;<BR>#endif<BR>OS_FLAGS flags;</P>
<P><BR>OS_ENTER_CRITICAL();<BR>flags =
OSTCBCur->OSTCBFlagsRdy;<BR><FONT
color=#ff0000><B>OS_EXIT_CRITICAL();</B></FONT><BR>return
(flags);</P></BLOCKQUOTE>
<P>}<BR></P>
<HR noShade>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: uCOS_II.H (V2.51-003)</TD></TR></TBODY></TABLE>
<P class=subtitle>Line 889</P>
<P class=codewiew>#ifndef OS_FLAG_QUERY_EN<BR>#error "OS_CFG.H, Missing
OS_FLAG_DEL_EN: Include code for OSFlagQuery()"</P>
<P>needs to be:</P>
<P><SPAN class=codewiew>#ifndef OS_FLAG_QUERY_EN<BR></SPAN><SPAN
class=codewiew_red>#error "OS_CFG.H, Missing OS_FLAG_QUERY_EN: Include
code for OSFlagQuery()"</SPAN></P>
<P></P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_Q.C (V2.51-002)</TD></TR></TBODY></TABLE>
<P>The function<SPAN class=codewiew> OSQQuery()</SPAN> contains a BUG in
the following code which is towards the end of the function.</P>
<P><SPAN class=codewiew>pq = (OS_Q *)pevent->OSEventPtr;<BR>if
(pq->OSQEntries > 0) {<BR> pdata->OSMsg = pq->OSQOut; /*
Get next message to return if available */<BR>} else {<BR>
pdata->OSMsg = (void *)0;<BR>}</SPAN><BR></P>
<P>The <B>CORRECT</B> code is shown below. Note that<SPAN
class=codewiew_red> pq->OSQOut</SPAN> was missing the <SPAN
class=codewiew_red>*</SPAN>.<BR></P>
<P><SPAN class=codewiew>pq = (OS_Q *)pevent->OSEventPtr;<BR>if
(pq->OSQEntries > 0) {<BR> pdata->OSMsg = </SPAN><SPAN
class=codewiew_red>*</SPAN><SPAN class=codewiew>pq->OSQOut; /* Get next
message to return if available */<BR>} else {<BR> pdata->OSMsg =
(void *)0;<BR>}</SPAN><BR></P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: uCOS_II.H (V2.51-001)</TD></TR></TBODY></TABLE>
<P>The function prototype for <SPAN class=codewiew>OSSchedLock()</SPAN>
was changed by mistake to <SPAN class=codewiew>OS_SchedLock()</SPAN>.
Simply REMOVE the underscore since the <B>CORRECT</B> name is <SPAN
class=codewiew>OSSchedLock()</SPAN>. </P>
<HR noShade>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD><SPAN class=title>礐/OS-II: OS_CPU_A.ASM (V2.05-001)
</SPAN><B>(For both Ix86L and Ix86L-FP)</B></TD></TR></TBODY></TABLE>
<P>The <I>NEW</I> ISRs MUST check to see if <SPAN
class=codewiew>OSIntNesting </SPAN>==<SPAN class=codewiew> 1</SPAN>
<I>BEFORE</I> you save the <SPAN class=codewiew>SP</SPAN> in the current
task's <SPAN class=codewiew>OS_TCB</SPAN>. The incorrect 'pseudo' code
is:</P>
<P class=codewiew>OSTCBCur->OSTCBStkPtr = SP /* Save SP onto current
task's stack */</P>
<P><B><FONT color=#ff0000>and should be:</FONT></B></P>
<P><SPAN class=codewiew_red>if (OSIntNesting == 1) {</SPAN><BR>
<SPAN class=codewiew>OSTCBCur->OSTCBStkPtr = SP /* Save SP onto current
task's stack */</SPAN><BR><SPAN class=codewiew_red>}</SPAN> </P>
<P>The reason we need this change is that we don't want to save the
current value of <SPAN class=codewiew>SP</SPAN> if the ISR is for a nested
ISR!</P>
<P><B>IMPORTANT</B>: If you have the release notes version <B>V2.05a</B>
then you have the CORRECT code.</P>
<HR noShade>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_CORE.C (V2.04-001)</TD></TR></TBODY></TABLE>
<P>The wrong argument is being passed to the call to <SPAN
class=codewiew>OSTaskCreateHook()</SPAN> in <SPAN
class=codewiew>OSTCBInit()</SPAN>.<BR>The BAD code is:</P>
<P class=codewiew>OSTaskCreateHook(<SPAN
class=codewiew_red>OSTCBPrioTbl[prio]</SPAN>); /* Call user defined hook
*/</P>
<P><B><FONT color=#ff0000>and should be:</FONT></B></P>
<P class=codewiew>OSTaskCreateHook(<SPAN class=codewiew_red>ptcb</SPAN>);
/* Call user defined hook */</P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_MUTEX.C (V2.04-002)</TD></TR></TBODY></TABLE>
<P>The test in <SPAN class=codewiew>OSMutexPost()</SPAN> to see if the
posting task owns the MUTEX is incorrect. The correct test needs to have
<SPAN class=codewiew_red>&&</SPAN> instead of <SPAN
class=codewiew_red>||</SPAN> as follows:</P>
<P><SPAN class=codewiew>if (OSTCBCur->OSTCBPrio != pip </SPAN><SPAN
class=codewiew_red>&&</SPAN><SPAN class=codewiew><BR>
OSTCBCur->OSTCBPrio != prio) { /* See if posting task owns the MUTEX
*/<BR> OS_EXIT_CRITICAL();<BR> return
(OS_ERR_NOT_MUTEX_OWNER);<BR>}</SPAN></P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_MUTEX.C (V2.04-003)</TD></TR></TBODY></TABLE>
<P>The function <SPAN class=codewiew>OSMutexDel()</SPAN> needs to release
the priority of the PIP. The correct code for <SPAN
class=codewiew>OSMutexDel()</SPAN> can be downloaded from: <BR><A
href="http://www.ucos-ii.com/contents/support/downloads/os_mutex_del.c">Download
new OSMutexDel()</A>.<BR></P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: uCOS_II.H (V2.04-004)</TD></TR></TBODY></TABLE>
<P>The function <SPAN class=codewiew>OSMutexDel()</SPAN> needs to be added
in the prototype list for MUTEXes as follows:</P>
<P><SPAN class=codewiew>#if OS_MUTEX_EN<BR>INT8U OSMutexAccept(OS_EVENT
*pevent, INT8U *err);<BR>OS_EVENT *OSMutexCreate(INT8U prio, INT8U
*err);<BR></SPAN><SPAN class=codewiew_red>OS_EVENT *OSMutexDel (OS_EVENT
*pevent, INT8U opt, INT8U *err);</SPAN><SPAN class=codewiew><BR>void
OSMutexPend(OS_EVENT *pevent, INT16U timeout, INT8U *err);<BR>INT8U
OSMutexPost(OS_EVENT *pevent);<BR>INT8U OSMutexQuery(OS_EVENT *pevent,
OS_MUTEX_DATA *pdata);<BR>#endif</SPAN><BR></P>
<HR noShade>
<P class=titleBIGGESTBIG>Improvements</P>
<TABLE cellSpacing=0 cellPadding=3 width="100%" bgColor=#ced6f0
border=0><TBODY>
<TR>
<TD class=title>礐/OS-II: OS_CPU_A.ASM and ISRs</TD></TR></TBODY></TABLE>
<P>As you probably know, <B>礐/OS-II</B> has a function that is dependent
on compiler options <SPAN class=codewiew>(OSIntCtxSw())</SPAN> and, the
port designer <B><FONT color=#ff0000>HAS</FONT></B> to adjust the Stack
Pointer based on the code generation of the compiler.</P>
<P>On certain processors (e.g. 80x86) you can simply write ISRs so that
you <B>save</B> the Stack Pointer (<SPAN class=codewiew>SS:SP</SPAN> for
the 80x86) into the current task's <SPAN class=codewiew>OS_TCB</SPAN>
after incrementing <SPAN class=codewiew>OSIntNesting</SPAN>. This way, we
save the proper pointer to the ISR stack frame in case we don't actually
return to the interrupted task. If we DO return to the interrupted task
then, there is no harm and all we did was waste a little bit of CPU time!
Of course, we <B>eliminate</B> the code at the beginning of <SPAN
class=codewiew>OSIntCtxSw()</SPAN> to adjust the Stack Pointer (<SPAN
class=codewiew>SP</SPAN> for the 80x86) and the code to save the Stack
Pointer into the <SPAN class=codewiew>OS_TCB</SPAN>!</P>
<P>The new pseudo code for an ISR and <SPAN
class=codewiew>OSIntCtxSw()</SPAN> is now:</P>
<P class=codewiew>MyISR:<BR> Save ALL registers;<BR>
OSIntNesting++;<BR> OSTCBCur->OSTCBStkPtr = SP; /*
<<<< NEW */<BR> /* Handle ISR */<BR>
OSIntExit();<BR> Restore ALL registers;<BR> Return from
Interrupt;<BR> OSIntCtxSw:<BR> OSTaskSwHook();<BR>
OSTCBCur = OSTCBHighRdy;<BR> SP =
OSTCBHighRdy->OSTCBStkPtr;<BR> Restore ALL registers;<BR>
Return from Interrupt;</P>
<P>In assembly language for the 80x86 (Large model), this becomes:</P>
<P class=codewiew>_MyISR PROC FAR<BR>;<BR> PUSHA ; Save interrupted
task's context<BR> PUSH ES<BR> PUSH DS<BR>;<BR> MOV AX,
SEG(_OSIntNesting) ; Reload DS<BR> MOV DS, AX<BR> INC BYTE PTR
_OSIntNesting ; Notify uC/OS-II of ISR<BR>;<BR> LES BX, DWORD PTR
DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP<BR> MOV ES:[BX+2],
SS<BR> MOV ES:[BX+0], SP<BR> CALL FAR PTR _MyISRHandler ;
Process the Interrupt<BR>;<BR> CALL FAR PTR _OSIntExit ; Notify
uC/OS-II of end of ISR<BR>;<BR> POP DS ; Restore interrupted task's
context<BR> POP ES<BR> POPA<BR>;<BR> IRET ; Return to
interrupted task<BR>;<BR>_MyISR ENDP<BR><BR>_OSIntCtxSw PROC
FAR<BR>;<BR> CALL FAR PTR _OSTaskSwHook ; Call user defined task
switch hook<BR>;<BR> MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur
= OSTCBHighRdy<BR> MOV DX, WORD PTR DS:_OSTCBHighRdy <BR> MOV
WORD PTR DS:_OSTCBCur+2, AX<BR> MOV WORD PTR DS:_OSTCBCur, DX
<BR>;<BR> MOV AL, BYTE PTR DS:_OSPrioHighRdy ; OSPrioCur =
OSPrioHighRdy<BR> MOV BYTE PTR DS:_OSPrioCur, AL<BR>;<BR> LES
BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP =
OSTCBHighRdy->OSTCBStkPtr<BR> MOV SS, ES:[BX+2]<BR> MOV SP,
ES:[BX]<BR>;<BR> POP DS ; Load new task's context<BR> POP
ES<BR> POPA<BR>;<BR> IRET ; Return to new
task<BR>;<BR>_OSIntCtxSw ENDP</P>
<P class=codewiew> </P>
<P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -