mirror of
https://github.com/FreeRTOS/FreeRTOS.git
synced 2026-09-20 17:45:01 +08: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:
File diff suppressed because one or more lines are too long
@@ -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>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
FreeRTOS V8.1.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||
FreeRTOS V8.1.0 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
@@ -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 )
|
||||
|
||||
@@ -162,7 +162,7 @@ static void prvTestTask( void *pvParameters );
|
||||
static void prvDemonstrateTaskStateAndHandleGetFunctions( void );
|
||||
|
||||
/*
|
||||
* Called from the idle task hook function to demonstrate the use of
|
||||
* Called from the idle task hook function to demonstrate the use of
|
||||
* xTimerPendFunctionCall() as xTimerPendFunctionCall() is not demonstrated by
|
||||
* any of the standard demo tasks.
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
+6
-15
@@ -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
|
||||
@@ -702,7 +699,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
the mutexes were given back in an order that is
|
||||
different to that in which they were taken. */
|
||||
queueYIELD_IF_USING_PREEMPTION();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
+8
-18
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user