mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Core kernel code:
- Re-introduce the ability to give a mutex from an ISR. Common demo code: - Add additional tests into the GenQTest files for priority inheritance and using a mutex from an ISR.
This commit is contained in:
parent
6507701fdf
commit
ff5d3512b3
|
@ -34,12 +34,12 @@
|
|||
|
||||
|
||||
<PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><ShowCodeCoverage>1</ShowCodeCoverage><ShowInstrProfiling>1</ShowInstrProfiling></Disassembly>
|
||||
<Register><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows></Register><WATCH_1><expressions><item></item></expressions><col-names><item>Expression</item><item>Location</item><item>Type</item><item>Value</item></col-names><col-widths><item>207</item><item>150</item><item>100</item><item>294</item></col-widths><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows></WATCH_1><CallStack><PreferedWindows><Position>1</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><col-names><item>Frame</item><item>_I0</item></col-names><col-widths><item>400</item><item>20</item></col-widths></CallStack><Breakpoints><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><col-names><item>Breakpoint</item><item>_I0</item></col-names><col-widths><item>500</item><item>35</item></col-widths></Breakpoints><Find-in-Files><ColumnWidth0>497</ColumnWidth0><ColumnWidth1>82</ColumnWidth1><ColumnWidth2>746</ColumnWidth2><ColumnWidth3>331</ColumnWidth3><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows><Window><Factory>Debug-Log</Factory></Window><Window><Factory>Build</Factory></Window></Windows></PreferedWindows></Find-in-Files><QuickWatch><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><col-names><item>Expression</item><item>Location</item><item>Type</item><item>Value</item></col-names><col-widths><item>100</item><item>150</item><item>100</item><item>100</item></col-widths><QWatchHistory><item>TC0</item><item>TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_RC</item></QWatchHistory></QuickWatch><Memory><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><FindDirection>1</FindDirection><FindAsHex>0</FindAsHex></Memory><TASKVIEW><Column0>200</Column0><Column1>100</Column1><Column2>100</Column2><Column3>100</Column3><Column4>100</Column4><Column5>100</Column5><Column6>100</Column6><Column7>100</Column7><Column8>150</Column8></TASKVIEW><QUEUEVIEW><Column0>200</Column0><Column1>100</Column1><Column2>100</Column2><Column3>100</Column3><Column4>100</Column4><Column5>100</Column5><Column6>100</Column6></QUEUEVIEW></Static>
|
||||
<Register><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows></Register><WATCH_1><expressions><item/></expressions><col-names><item>Expression</item><item>Location</item><item>Type</item><item>Value</item></col-names><col-widths><item>207</item><item>150</item><item>100</item><item>294</item></col-widths><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows></WATCH_1><CallStack><PreferedWindows><Position>1</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><col-names><item>Frame</item><item>_I0</item></col-names><col-widths><item>400</item><item>20</item></col-widths></CallStack><Breakpoints><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><col-names><item>Breakpoint</item><item>_I0</item></col-names><col-widths><item>500</item><item>35</item></col-widths></Breakpoints><Find-in-Files><ColumnWidth0>497</ColumnWidth0><ColumnWidth1>82</ColumnWidth1><ColumnWidth2>746</ColumnWidth2><ColumnWidth3>331</ColumnWidth3><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows><Window><Factory>Debug-Log</Factory></Window><Window><Factory>Build</Factory></Window></Windows></PreferedWindows></Find-in-Files><QuickWatch><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><col-names><item>Expression</item><item>Location</item><item>Type</item><item>Value</item></col-names><col-widths><item>100</item><item>150</item><item>100</item><item>100</item></col-widths><QWatchHistory><item>TC0</item><item>TC0->TC_CHANNEL[ tmrTC0_CHANNEL_0 ].TC_RC</item></QWatchHistory></QuickWatch><Memory><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><FindDirection>1</FindDirection><FindAsHex>0</FindAsHex></Memory><TASKVIEW><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><Column0>200</Column0><Column1>100</Column1><Column2>100</Column2><Column3>100</Column3><Column4>100</Column4><Column5>100</Column5><Column6>100</Column6><Column7>100</Column7><Column8>150</Column8></TASKVIEW><QUEUEVIEW><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><Column0>300</Column0><Column1>100</Column1><Column2>100</Column2><Column3>100</Column3><Column4>100</Column4><Column5>100</Column5><Column6>100</Column6></QUEUEVIEW></Static>
|
||||
<Windows>
|
||||
|
||||
|
||||
|
||||
<Wnd1>
|
||||
<Wnd0>
|
||||
<Tabs>
|
||||
<Tab>
|
||||
<Identity>TabID-24673-23877</Identity>
|
||||
|
@ -51,20 +51,20 @@
|
|||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<SelectedTab>0</SelectedTab></Wnd1><Wnd2><Tabs><Tab><Identity>TabID-22902-32031</Identity><TabName>Tasks</TabName><Factory>TASKVIEW</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd2><Wnd3><Tabs><Tab><Identity>TabID-22379-32041</Identity><TabName>Queues</TabName><Factory>QUEUEVIEW</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd3></Windows>
|
||||
<SelectedTab>0</SelectedTab></Wnd0><Wnd5><Tabs><Tab><Identity>TabID-31713-7906</Identity><TabName>Debug Log</TabName><Factory>Debug-Log</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd5></Windows>
|
||||
<Editor>
|
||||
|
||||
|
||||
|
||||
|
||||
<Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\main.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>140</YPos2><SelStart2>7249</SelStart2><SelEnd2>7249</SelEnd2></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\Full_Demo\main_full.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>0</SelStart2><SelEnd2>0</SelEnd2></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\blinky_demo\main_blinky.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>1373</SelStart2><SelEnd2>1373</SelEnd2></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\..\Source\portable\IAR\ARM_CA5_No_GIC\portASM.s</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>73</YPos2><SelStart2>3799</SelStart2><SelEnd2>3799</SelEnd2></Tab><ActiveTab>3</ActiveTab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>
|
||||
<Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\main.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>127</YPos2><SelStart2>6411</SelStart2><SelEnd2>6411</SelEnd2></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\Full_Demo\main_full.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>0</SelStart2><SelEnd2>0</SelEnd2></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\blinky_demo\main_blinky.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>1373</SelStart2><SelEnd2>1373</SelEnd2></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\..\Common\Minimal\GenQTest.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>796</YPos2><SelStart2>27238</SelStart2><SelEnd2>27238</SelEnd2></Tab><ActiveTab>3</ActiveTab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>
|
||||
<Positions>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Top><Row0><Sizes><Toolbar-0111A108><key>iaridepm.enu1</key></Toolbar-0111A108></Sizes></Row0><Row1><Sizes><Toolbar-222ED2A8><key>debuggergui.enu1</key></Toolbar-222ED2A8></Sizes></Row1></Top><Left><Row0><Sizes><Wnd1><Rect><Top>-2</Top><Left>-2</Left><Bottom>520</Bottom><Right>332</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>119048</sizeHorzCX><sizeHorzCY>203252</sizeHorzCY><sizeVertCX>198810</sizeVertCX><sizeVertCY>530488</sizeVertCY></Rect></Wnd1></Sizes></Row0></Left><Right><Row0><Sizes/></Row0></Right><Bottom><Row0><Sizes><Wnd2><Rect><Top>-2</Top><Left>-2</Left><Bottom>198</Bottom><Right>1682</Right><x>-2</x><y>-2</y><xscreen>1684</xscreen><yscreen>200</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>203252</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203252</sizeVertCY></Rect></Wnd2></Sizes></Row0><Row1><Sizes><Wnd3><Rect><Top>196</Top><Left>-2</Left><Bottom>396</Bottom><Right>1682</Right><x>-2</x><y>196</y><xscreen>1684</xscreen><yscreen>200</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>203252</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203252</sizeVertCY></Rect></Wnd3></Sizes></Row1></Bottom><Float><Sizes/></Float></Positions>
|
||||
<Top><Row0><Sizes><Toolbar-011172A8><key>iaridepm.enu1</key></Toolbar-011172A8></Sizes></Row0><Row1><Sizes><Toolbar-07251300><key>debuggergui.enu1</key></Toolbar-07251300></Sizes></Row1></Top><Left><Row0><Sizes><Wnd0><Rect><Top>-2</Top><Left>-2</Left><Bottom>718</Bottom><Right>332</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>119048</sizeHorzCX><sizeHorzCY>203252</sizeHorzCY><sizeVertCX>198810</sizeVertCX><sizeVertCY>731707</sizeVertCY></Rect></Wnd0></Sizes></Row0></Left><Right><Row0><Sizes/></Row0></Right><Bottom><Row0><Sizes><Wnd5><Rect><Top>-2</Top><Left>-2</Left><Bottom>198</Bottom><Right>1682</Right><x>-2</x><y>-2</y><xscreen>1684</xscreen><yscreen>200</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>203252</sizeHorzCY><sizeVertCX>119048</sizeVertCX><sizeVertCY>203252</sizeVertCY></Rect></Wnd5></Sizes></Row0></Bottom><Float><Sizes/></Float></Positions>
|
||||
</Desktop>
|
||||
</Project>
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ Watch0=_ 0 "" 0 "" 0 "" 0 "" 0 0 0 0
|
|||
Watch1=_ 0 "" 0 "" 0 "" 0 "" 0 0 0 0
|
||||
CStepIntDis=_ 0
|
||||
[DebugChecksum]
|
||||
Checksum=-666464609
|
||||
Checksum=-1280642381
|
||||
[Exceptions]
|
||||
StopOnUncaught=_ 0
|
||||
StopOnThrow=_ 0
|
||||
|
@ -42,7 +42,7 @@ Exclusions=
|
|||
[Disassemble mode]
|
||||
mode=0
|
||||
[Breakpoints2]
|
||||
Bp0=_ 1 "EMUL_CODE" "{$PROJ_DIR$\main.c}.218.24" 0 0 1 "" 0 "" 0
|
||||
Bp0=_ 1 "EMUL_CODE" "{$PROJ_DIR$\main.c}.221.2" 0 0 1 "" 0 "" 0
|
||||
Count=1
|
||||
[Aliases]
|
||||
Count=0
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<Windows>
|
||||
|
||||
|
||||
<Wnd1>
|
||||
<Wnd0>
|
||||
<Tabs>
|
||||
<Tab>
|
||||
<Identity>TabID-22351-19008</Identity>
|
||||
|
@ -48,7 +48,7 @@
|
|||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<SelectedTab>0</SelectedTab></Wnd1><Wnd4>
|
||||
<SelectedTab>0</SelectedTab></Wnd0><Wnd2>
|
||||
<Tabs>
|
||||
<Tab>
|
||||
<Identity>TabID-21076-19237</Identity>
|
||||
|
@ -58,20 +58,20 @@
|
|||
</Tab>
|
||||
<Tab><Identity>TabID-23502-23081</Identity><TabName>Debug Log</TabName><Factory>Debug-Log</Factory><Session/></Tab><Tab><Identity>TabID-24431-23894</Identity><TabName>Ambiguous Definitions</TabName><Factory>Select-Ambiguous-Definitions</Factory><Session/></Tab><Tab><Identity>TabID-9033-6116</Identity><TabName>Find in Files</TabName><Factory>Find-in-Files</Factory><Session/></Tab></Tabs>
|
||||
|
||||
<SelectedTab>0</SelectedTab></Wnd4></Windows>
|
||||
<SelectedTab>0</SelectedTab></Wnd2></Windows>
|
||||
<Editor>
|
||||
|
||||
|
||||
|
||||
|
||||
<Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\main.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>59</YPos2><SelStart2>7249</SelStart2><SelEnd2>7249</SelEnd2></Tab><ActiveTab>0</ActiveTab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\Full_Demo\main_full.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>0</SelStart2><SelEnd2>0</SelEnd2></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\blinky_demo\main_blinky.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>1373</SelStart2><SelEnd2>1373</SelEnd2></Tab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>
|
||||
<Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\main.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>5074</SelStart2><SelEnd2>5074</SelEnd2></Tab><ActiveTab>0</ActiveTab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\Full_Demo\main_full.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>0</SelStart2><SelEnd2>0</SelEnd2></Tab><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\blinky_demo\main_blinky.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>0</SelStart><SelEnd>0</SelEnd><XPos2>0</XPos2><YPos2>63</YPos2><SelStart2>1373</SelStart2><SelEnd2>1373</SelEnd2></Tab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>
|
||||
<Positions>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Top><Row0><Sizes><Toolbar-0111A108><key>iaridepm.enu1</key></Toolbar-0111A108></Sizes></Row0></Top><Left><Row0><Sizes><Wnd1><Rect><Top>-2</Top><Left>-2</Left><Bottom>668</Bottom><Right>352</Right><x>-2</x><y>-2</y><xscreen>190</xscreen><yscreen>170</yscreen><sizeHorzCX>113095</sizeHorzCX><sizeHorzCY>172764</sizeHorzCY><sizeVertCX>210714</sizeVertCX><sizeVertCY>680894</sizeVertCY></Rect></Wnd1></Sizes></Row0></Left><Right><Row0><Sizes/></Row0></Right><Bottom><Row0><Sizes><Wnd4><Rect><Top>-2</Top><Left>-2</Left><Bottom>272</Bottom><Right>1682</Right><x>-2</x><y>-2</y><xscreen>1684</xscreen><yscreen>274</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>278455</sizeHorzCY><sizeVertCX>113095</sizeVertCX><sizeVertCY>172764</sizeVertCY></Rect></Wnd4></Sizes></Row0></Bottom><Float><Sizes/></Float></Positions>
|
||||
<Top><Row0><Sizes><Toolbar-011172A8><key>iaridepm.enu1</key></Toolbar-011172A8></Sizes></Row0><Row1><Sizes/></Row1></Top><Left><Row0><Sizes><Wnd0><Rect><Top>-2</Top><Left>-2</Left><Bottom>668</Bottom><Right>352</Right><x>-2</x><y>-2</y><xscreen>190</xscreen><yscreen>170</yscreen><sizeHorzCX>113095</sizeHorzCX><sizeHorzCY>172764</sizeHorzCY><sizeVertCX>210714</sizeVertCX><sizeVertCY>680894</sizeVertCY></Rect></Wnd0></Sizes></Row0></Left><Right><Row0><Sizes/></Row0></Right><Bottom><Row0><Sizes><Wnd2><Rect><Top>-2</Top><Left>-2</Left><Bottom>272</Bottom><Right>1682</Right><x>-2</x><y>-2</y><xscreen>1684</xscreen><yscreen>274</yscreen><sizeHorzCX>1002381</sizeHorzCX><sizeHorzCY>278455</sizeHorzCY><sizeVertCX>113095</sizeVertCX><sizeVertCY>172764</sizeVertCY></Rect></Wnd2></Sizes></Row0></Bottom><Float><Sizes/></Float></Positions>
|
||||
</Desktop>
|
||||
</Workspace>
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
#define genqMUTEX_MEDIUM_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||
#define genqMUTEX_HIGH_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
||||
|
||||
#define genqINTERRUPT_MUTEX_GIVE_PERIOD_MS ( 100 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -121,6 +122,28 @@ static void prvLowPriorityMutexTask( void *pvParameters );
|
|||
static void prvMediumPriorityMutexTask( void *pvParameters );
|
||||
static void prvHighPriorityMutexTask( void *pvParameters );
|
||||
|
||||
/*
|
||||
* Exercises the priority inheritance when a task takes two mutexes, returning
|
||||
* them in a different order to which they were taken.
|
||||
*/
|
||||
static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex );
|
||||
|
||||
/*
|
||||
* Exercises the priority inheritance when a task takes two mutexes, returning
|
||||
* them in the same order in which they were taken.
|
||||
*/
|
||||
static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex );
|
||||
|
||||
/*
|
||||
* Task that receives an a mutex that is given from an interrupt - although
|
||||
* generally mutexes should not be used given in interrupts (and definitely
|
||||
* never taken in an interrupt) there are some circumstances when it may be
|
||||
* desirable. NOTE: This function is not declared static to prevent compiler
|
||||
* warnings being generated in demos where the function is declared but not
|
||||
* used.
|
||||
*/
|
||||
void vInterruptMutexTask( void *pvParameters );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Flag that will be latched to pdTRUE should any unexpected behaviour be
|
||||
|
@ -139,6 +162,11 @@ static volatile uint32_t ulGuardedVariable = 0;
|
|||
priority mutex test tasks. */
|
||||
static TaskHandle_t xHighPriorityMutexTask, xMediumPriorityMutexTask;
|
||||
|
||||
/* A mutex which is given from an interrupt - although generally mutexes should
|
||||
not be used given in interrupts (and definitely never taken in an interrupt)
|
||||
there are some circumstances when it may be desirable. */
|
||||
static SemaphoreHandle_t xISRMutex = NULL;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vStartGenericQueueTasks( UBaseType_t uxPriority )
|
||||
|
@ -146,6 +174,9 @@ void vStartGenericQueueTasks( UBaseType_t uxPriority )
|
|||
QueueHandle_t xQueue;
|
||||
SemaphoreHandle_t xMutex;
|
||||
|
||||
xISRMutex = xSemaphoreCreateMutex();
|
||||
configASSERT( xISRMutex );
|
||||
|
||||
/* Create the queue that we are going to use for the
|
||||
prvSendFrontAndBackTest demo. */
|
||||
xQueue = xQueueCreate( genqQUEUE_LENGTH, sizeof( uint32_t ) );
|
||||
|
@ -180,6 +211,14 @@ SemaphoreHandle_t xMutex;
|
|||
xTaskCreate( prvLowPriorityMutexTask, "MuLow", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_LOW_PRIORITY, NULL );
|
||||
xTaskCreate( prvMediumPriorityMutexTask, "MuMed", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, &xMediumPriorityMutexTask );
|
||||
xTaskCreate( prvHighPriorityMutexTask, "MuHigh", configMINIMAL_STACK_SIZE, ( void * ) xMutex, genqMUTEX_HIGH_PRIORITY, &xHighPriorityMutexTask );
|
||||
|
||||
/* Only when the windows simulator is being used - create the task that
|
||||
receives a mutex from an interrupt. */
|
||||
#ifdef _WINDOWS_
|
||||
{
|
||||
xTaskCreate( vInterruptMutexTask, "IntMu", configMINIMAL_STACK_SIZE, NULL, genqMUTEX_MEDIUM_PRIORITY, NULL );
|
||||
}
|
||||
#endif /* __WINDOWS__ */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -411,6 +450,252 @@ QueueHandle_t xQueue;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTakeTwoMutexesReturnInDifferentOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )
|
||||
{
|
||||
/* Take the mutex. It should be available now. */
|
||||
if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Set the guarded variable to a known start value. */
|
||||
ulGuardedVariable = 0;
|
||||
|
||||
/* This task's priority should be as per that assigned when the task was
|
||||
created. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now unsuspend the high priority task. This will attempt to take the
|
||||
mutex, and block when it finds it cannot obtain it. */
|
||||
vTaskResume( xHighPriorityMutexTask );
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* Ensure the task is reporting its priority as blocked and not
|
||||
suspended (as it would have done in versions up to V7.5.3). */
|
||||
#if( INCLUDE_eTaskGetState == 1 )
|
||||
{
|
||||
configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked );
|
||||
}
|
||||
#endif /* INCLUDE_eTaskGetState */
|
||||
|
||||
/* The priority of the high priority task should now have been inherited
|
||||
as by now it will have attempted to get the mutex. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Attempt to set the priority of this task to the test priority -
|
||||
between the idle priority and the medium/high test priorities, but the
|
||||
actual priority should remain at the high priority. */
|
||||
vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now unsuspend the medium priority task. This should not run as the
|
||||
inherited priority of this task is above that of the medium priority
|
||||
task. */
|
||||
vTaskResume( xMediumPriorityMutexTask );
|
||||
|
||||
/* If the medium priority task did run then it will have incremented the
|
||||
guarded variable. */
|
||||
if( ulGuardedVariable != 0 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Take the local mutex too, so two mutexes are now held. */
|
||||
if( xSemaphoreTake( xLocalMutex, genqNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* When the semaphore is given back the priority of this task should not
|
||||
yet be disinherited because the local mutex is still held. This is a
|
||||
simplification to allow FreeRTOS to be integrated with middleware that
|
||||
attempts to hold multiple mutexes without bloating the code with complex
|
||||
algorithms. It is possible that the high priority mutex task will
|
||||
execute as it shares a priority with this task. */
|
||||
if( xSemaphoreGive( xMutex ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* The guarded variable is only incremented by the medium priority task,
|
||||
which still should not have executed as this task should remain at the
|
||||
higher priority, ensure this is the case. */
|
||||
if( ulGuardedVariable != 0 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now also give back the local mutex, taking the held count back to 0.
|
||||
This time the priority of this task should be disinherited back to the
|
||||
priority to which it was set while the mutex was held. This means
|
||||
the medium priority task should execute and increment the guarded
|
||||
variable. When this task next runs both the high and medium priority
|
||||
tasks will have been suspended again. */
|
||||
if( xSemaphoreGive( xLocalMutex ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* Check the guarded variable did indeed increment... */
|
||||
if( ulGuardedVariable != 1 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* ... and that the priority of this task has been disinherited to
|
||||
genqMUTEX_TEST_PRIORITY. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Set the priority of this task back to its original value, ready for
|
||||
the next loop around this test. */
|
||||
vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvTakeTwoMutexesReturnInSameOrder( SemaphoreHandle_t xMutex, SemaphoreHandle_t xLocalMutex )
|
||||
{
|
||||
/* Take the mutex. It should be available now. */
|
||||
if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Set the guarded variable to a known start value. */
|
||||
ulGuardedVariable = 0;
|
||||
|
||||
/* This task's priority should be as per that assigned when the task was
|
||||
created. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now unsuspend the high priority task. This will attempt to take the
|
||||
mutex, and block when it finds it cannot obtain it. */
|
||||
vTaskResume( xHighPriorityMutexTask );
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* Ensure the task is reporting its priority as blocked and not
|
||||
suspended (as it would have done in versions up to V7.5.3). */
|
||||
#if( INCLUDE_eTaskGetState == 1 )
|
||||
{
|
||||
configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked );
|
||||
}
|
||||
#endif /* INCLUDE_eTaskGetState */
|
||||
|
||||
/* The priority of the high priority task should now have been inherited
|
||||
as by now it will have attempted to get the mutex. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now unsuspend the medium priority task. This should not run as the
|
||||
inherited priority of this task is above that of the medium priority
|
||||
task. */
|
||||
vTaskResume( xMediumPriorityMutexTask );
|
||||
|
||||
/* If the medium priority task did run then it will have incremented the
|
||||
guarded variable. */
|
||||
if( ulGuardedVariable != 0 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Take the local mutex too, so two mutexes are now held. */
|
||||
if( xSemaphoreTake( xLocalMutex, genqNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* When the local semaphore is given back the priority of this task should
|
||||
not yet be disinherited because the shared mutex is still held. This is a
|
||||
simplification to allow FreeRTOS to be integrated with middleware that
|
||||
attempts to hold multiple mutexes without bloating the code with complex
|
||||
algorithms. It is possible that the high priority mutex task will
|
||||
execute as it shares a priority with this task. */
|
||||
if( xSemaphoreGive( xLocalMutex ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* The guarded variable is only incremented by the medium priority task,
|
||||
which still should not have executed as this task should remain at the
|
||||
higher priority, ensure this is the case. */
|
||||
if( ulGuardedVariable != 0 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now also give back the shared mutex, taking the held count back to 0.
|
||||
This time the priority of this task should be disinherited back to the
|
||||
priority at which it was created. This means the medium priority task
|
||||
should execute and increment the guarded variable. When this task next runs
|
||||
both the high and medium priority tasks will have been suspended again. */
|
||||
if( xSemaphoreGive( xMutex ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* Check the guarded variable did indeed increment... */
|
||||
if( ulGuardedVariable != 1 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* ... and that the priority of this task has been disinherited to
|
||||
genqMUTEX_LOW_PRIORITY. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvLowPriorityMutexTask( void *pvParameters )
|
||||
{
|
||||
SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters, xLocalMutex;
|
||||
|
@ -430,131 +715,21 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters, xLocalMutex;
|
|||
|
||||
for( ;; )
|
||||
{
|
||||
/* Take the mutex. It should be available now. */
|
||||
if( xSemaphoreTake( xMutex, genqNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
/* The first tests exercise the priority inheritance when two mutexes
|
||||
are taken then returned in a different order to which they were
|
||||
taken. */
|
||||
prvTakeTwoMutexesReturnInDifferentOrder( xMutex, xLocalMutex );
|
||||
|
||||
/* Set the guarded variable to a known start value. */
|
||||
ulGuardedVariable = 0;
|
||||
|
||||
/* This task's priority should be as per that assigned when the task was
|
||||
created. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_LOW_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now unsuspend the high priority task. This will attempt to take the
|
||||
mutex, and block when it finds it cannot obtain it. */
|
||||
vTaskResume( xHighPriorityMutexTask );
|
||||
/* Just to show this task is still running. */
|
||||
ulLoopCounter2++;
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* Ensure the task is reporting its priority as blocked and not
|
||||
suspended (as it would have done in versions up to V7.5.3). */
|
||||
#if( INCLUDE_eTaskGetState == 1 )
|
||||
{
|
||||
configASSERT( eTaskGetState( xHighPriorityMutexTask ) == eBlocked );
|
||||
}
|
||||
#endif /* INCLUDE_eTaskGetState */
|
||||
|
||||
/* The priority of the high priority task should now have been inherited
|
||||
as by now it will have attempted to get the mutex. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Attempt to set the priority of this task to the test priority -
|
||||
between the idle priority and the medium/high test priorities, but the
|
||||
actual priority should remain at the high priority. */
|
||||
vTaskPrioritySet( NULL, genqMUTEX_TEST_PRIORITY );
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now unsuspend the medium priority task. This should not run as the
|
||||
inherited priority of this task is above that of the medium priority
|
||||
task. */
|
||||
vTaskResume( xMediumPriorityMutexTask );
|
||||
|
||||
/* If the medium priority task did run then it will have incremented the
|
||||
guarded variable. */
|
||||
if( ulGuardedVariable != 0 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Take the local mutex too, so two mutexes are now held. */
|
||||
if( xSemaphoreTake( xLocalMutex, genqNO_BLOCK ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* When the semaphore is given back the priority of this task should not
|
||||
yet be disinherited because the local mutex is still held. This is a
|
||||
simplification to allow FreeRTOS to be integrated with middleware that
|
||||
attempts to hold multiple mutexes without bloating the code with complex
|
||||
algorithms. It is possible that the high priority mutex task will
|
||||
execute as it shares a priority with this task. */
|
||||
if( xSemaphoreGive( xMutex ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* The guarded variable is only incremented by the medium priority task,
|
||||
which still should not have executed as this task should remain at the
|
||||
higher priority, ensure this is the case. */
|
||||
if( ulGuardedVariable != 0 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_HIGH_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Now also give back the local mutex, taking the held count back to 0.
|
||||
This time the priority of this task should be disinherited back to the
|
||||
priority to which it was set while the mutex was held. This means
|
||||
the medium priority task should execute and increment the guarded
|
||||
variable. When this task next runs both the high and medium priority
|
||||
tasks will have been suspended again. */
|
||||
if( xSemaphoreGive( xLocalMutex ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
taskYIELD();
|
||||
#endif
|
||||
|
||||
/* Check the guarded variable did indeed increment... */
|
||||
if( ulGuardedVariable != 1 )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* ... and that the priority of this task has been disinherited to
|
||||
genqMUTEX_TEST_PRIORITY. */
|
||||
if( uxTaskPriorityGet( NULL ) != genqMUTEX_TEST_PRIORITY )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
|
||||
/* Set the priority of this task back to its original value, ready for
|
||||
the next loop around this test. */
|
||||
vTaskPrioritySet( NULL, genqMUTEX_LOW_PRIORITY );
|
||||
/* The second tests exercise the priority inheritance when two mutexes
|
||||
are taken then returned in the same order in which they were taken. */
|
||||
prvTakeTwoMutexesReturnInSameOrder( xMutex, xLocalMutex );
|
||||
|
||||
/* Just to show this task is still running. */
|
||||
ulLoopCounter2++;
|
||||
|
@ -612,12 +787,53 @@ SemaphoreHandle_t xMutex = ( SemaphoreHandle_t ) pvParameters;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* NOTE: This function is not declared static to prevent compiler warnings in
|
||||
demos where the function is declared but not used. */
|
||||
void vInterruptMutexTask( void *pvParameters )
|
||||
{
|
||||
const TickType_t xInterruptGivePeriod = pdMS_TO_TICKS( genqINTERRUPT_MUTEX_GIVE_PERIOD_MS );
|
||||
volatile uint32_t ulLoops = 0;
|
||||
|
||||
/* Just to avoid compiler warnings. */
|
||||
( void ) pvParameters;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
/* Has to wait longer than the time between gives to make sure it
|
||||
should definitely have received the mutex. */
|
||||
if( xSemaphoreTake( xISRMutex, ( xInterruptGivePeriod * 2 ) ) != pdPASS )
|
||||
{
|
||||
xErrorDetected = pdTRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulLoops++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vMutexISRInteractionTest( void )
|
||||
{
|
||||
static TickType_t xLastGiveTime = 0;
|
||||
TickType_t xTimeNow;
|
||||
|
||||
xTimeNow = xTaskGetTickCountFromISR();
|
||||
if( ( xTimeNow - xLastGiveTime ) >= pdMS_TO_TICKS( genqINTERRUPT_MUTEX_GIVE_PERIOD_MS ) )
|
||||
{
|
||||
configASSERT( xISRMutex );
|
||||
xSemaphoreGiveFromISR( xISRMutex, NULL );
|
||||
xLastGiveTime = xTimeNow;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* This is called to check that all the created tasks are still running. */
|
||||
BaseType_t xAreGenericQueueTasksStillRunning( void )
|
||||
{
|
||||
static uint32_t ulLastLoopCounter = 0, ulLastLoopCounter2 = 0;
|
||||
|
||||
/* If the demo task is still running then we expect the loopcounters to
|
||||
/* If the demo task is still running then we expect the loop counters to
|
||||
have incremented since this function was last called. */
|
||||
if( ulLastLoopCounter == ulLoopCounter )
|
||||
{
|
||||
|
|
|
@ -741,7 +741,12 @@ static TickType_t uxTick = ( TickType_t ) -1;
|
|||
as well as late timer expiries. */
|
||||
const TickType_t xMargin = 6;
|
||||
#else
|
||||
const TickType_t xMargin = 3;
|
||||
#ifdef _WINDOWS_
|
||||
/* Windows is not real real time. */
|
||||
const TickType_t xMargin = 8;
|
||||
#else
|
||||
const TickType_t xMargin = 4;
|
||||
#endif /* _WINDOWS_ */
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
|
||||
void vStartGenericQueueTasks( UBaseType_t uxPriority );
|
||||
BaseType_t xAreGenericQueueTasksStillRunning( void );
|
||||
void vMutexISRInteractionTest( void );
|
||||
|
||||
#endif /* GEN_Q_TEST_H */
|
||||
|
||||
|
|
|
@ -297,7 +297,7 @@ volatile uint32_t ulSetToNonZeroInDebuggerToContinue = 0;
|
|||
( void ) ulLine;
|
||||
( void ) pcFileName;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
taskENTER_CRITICAL();
|
||||
{
|
||||
/* Stop the trace recording. */
|
||||
if( xPrinted == pdFALSE )
|
||||
|
|
|
@ -401,6 +401,9 @@ void vFullDemoTickHookFunction( void )
|
|||
|
||||
/* Exercise event groups from interrupts. */
|
||||
vPeriodicEventGroupsProcessing();
|
||||
|
||||
/* Exercise giving mutexes from an interrupt. */
|
||||
vMutexISRInteractionTest();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
typedef void (*TaskFunction_t)( void * );
|
||||
|
||||
/* Converts a time in milliseconds to a time in ticks. */
|
||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( ( TickType_t ) xTimeInMs * configTICK_RATE_HZ ) / ( TickType_t ) 1000 )
|
||||
#define pdMS_TO_TICKS( xTimeInMs ) ( ( ( TickType_t ) ( xTimeInMs ) * configTICK_RATE_HZ ) / ( TickType_t ) 1000 )
|
||||
|
||||
#define pdFALSE ( ( BaseType_t ) 0 )
|
||||
#define pdTRUE ( ( BaseType_t ) 1 )
|
||||
|
|
|
@ -1554,12 +1554,9 @@ eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION;
|
|||
|
||||
/*
|
||||
* For internal use only. Increment the mutex held count when a mutex is
|
||||
* taken and decrement the mutex held count when the mutex is given back
|
||||
* respectively. The mutex held count is used to know when it is safe to
|
||||
* disinherit a priority.
|
||||
* taken and return the handle of the task that has taken the mutex.
|
||||
*/
|
||||
void vTaskIncrementMutexHeldCount( void );
|
||||
void vTaskDecrementMutexHeldCount( void );
|
||||
void *pvTaskIncrementMutexHeldCount( void );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
|||
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
|
||||
2) Incorrect interrupt priority assignment, especially on Cortex-M3
|
||||
parts where numerically high priority values denote low actual
|
||||
interrupt priories, which can seem counter intuitive. See
|
||||
interrupt priorities, which can seem counter intuitive. See
|
||||
configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html
|
||||
3) Calling an API function from within a critical section or when
|
||||
the scheduler is suspended, or calling an API function that does
|
||||
|
|
|
@ -421,10 +421,7 @@ QueueHandle_t xReturn = NULL;
|
|||
|
||||
traceCREATE_MUTEX( pxNewQueue );
|
||||
|
||||
/* Start with the semaphore in the expected state. Preload the
|
||||
mutex held count as calling xQueueGenericSend() will decrement the
|
||||
count back to 0. */
|
||||
vTaskIncrementMutexHeldCount();
|
||||
/* Start with the semaphore in the expected state. */
|
||||
( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK );
|
||||
}
|
||||
else
|
||||
|
@ -1125,8 +1122,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||
{
|
||||
/* The task waiting has a higher priority so record that a
|
||||
context switch is required. */
|
||||
/* The task waiting has a higher priority so
|
||||
record that a context switch is required. */
|
||||
if( pxHigherPriorityTaskWoken != NULL )
|
||||
{
|
||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||
|
@ -1243,7 +1240,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
/* Record the information required to implement
|
||||
priority inheritance should it become necessary. */
|
||||
pxQueue->pxMutexHolder = ( int8_t * ) xTaskGetCurrentTaskHandle(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */
|
||||
pxQueue->pxMutexHolder = ( int8_t * ) pvTaskIncrementMutexHeldCount(); /*lint !e961 Cast is not redundant as TaskHandle_t is a typedef. */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1633,7 +1630,6 @@ BaseType_t xReturn = pdFALSE;
|
|||
if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX )
|
||||
{
|
||||
/* The mutex is no longer being held. */
|
||||
vTaskDecrementMutexHeldCount();
|
||||
xReturn = xTaskPriorityDisinherit( ( void * ) pxQueue->pxMutexHolder );
|
||||
pxQueue->pxMutexHolder = NULL;
|
||||
}
|
||||
|
@ -1699,7 +1695,7 @@ BaseType_t xReturn = pdFALSE;
|
|||
|
||||
static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer )
|
||||
{
|
||||
if( pxQueue->uxQueueType != queueQUEUE_IS_MUTEX )
|
||||
if( pxQueue->uxItemSize != 0 )
|
||||
{
|
||||
pxQueue->u.pcReadFrom += pxQueue->uxItemSize;
|
||||
if( pxQueue->u.pcReadFrom >= pxQueue->pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */
|
||||
|
@ -1712,11 +1708,6 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer
|
|||
}
|
||||
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A mutex was taken. */
|
||||
vTaskIncrementMutexHeldCount();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
|
|
@ -553,14 +553,14 @@ TCB_t * pxNewTCB;
|
|||
pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) ); /*lint !e923 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. */
|
||||
|
||||
/* Check the alignment of the calculated top of stack is correct. */
|
||||
configASSERT( ( ( ( uint32_t ) pxTopOfStack & ( uint32_t ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||
configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||
}
|
||||
#else /* portSTACK_GROWTH */
|
||||
{
|
||||
pxTopOfStack = pxNewTCB->pxStack;
|
||||
|
||||
/* Check the alignment of the stack buffer is correct. */
|
||||
configASSERT( ( ( ( uint32_t ) pxNewTCB->pxStack & ( uint32_t ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||
configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );
|
||||
|
||||
/* If we want to use stack checking on architectures that use
|
||||
a positive stack growth direction then we also need to store the
|
||||
|
@ -3246,6 +3246,9 @@ TCB_t *pxTCB;
|
|||
|
||||
if( pxMutexHolder != NULL )
|
||||
{
|
||||
configASSERT( pxTCB->uxMutexesHeld );
|
||||
( pxTCB->uxMutexesHeld )--;
|
||||
|
||||
if( pxTCB->uxPriority != pxTCB->uxBasePriority )
|
||||
{
|
||||
/* Only disinherit if no other mutexes are held. */
|
||||
|
@ -3584,7 +3587,7 @@ TickType_t uxReturn;
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTaskIncrementMutexHeldCount( void )
|
||||
void *pvTaskIncrementMutexHeldCount( void )
|
||||
{
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
{
|
||||
|
@ -3594,26 +3597,13 @@ void vTaskIncrementMutexHeldCount( void )
|
|||
{
|
||||
( pxCurrentTCB->uxMutexesHeld )++;
|
||||
}
|
||||
|
||||
return pxCurrentTCB;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vTaskDecrementMutexHeldCount( void )
|
||||
{
|
||||
#if ( configUSE_MUTEXES == 1 )
|
||||
{
|
||||
/* If xSemaphoreCreateMutex() is called before any tasks have been created
|
||||
then pxCurrentTCB will be NULL. */
|
||||
if( pxCurrentTCB != NULL )
|
||||
{
|
||||
configASSERT( pxCurrentTCB->uxMutexesHeld );
|
||||
( pxCurrentTCB->uxMutexesHeld )--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FREERTOS_MODULE_TEST
|
||||
#include "tasks_test_access_functions.h"
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue