<SLE66AMisc></SLE66AMisc>
<SLE66LinkerMisc></SLE66LinkerMisc>
<SFDFile></SFDFile>
+ <bCustSvd>0</bCustSvd>
<UseEnv>0</UseEnv>
<BinPath></BinPath>
<IncludePath></IncludePath>
<UserProg2Name></UserProg2Name>
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
+ <nStopB1X>0</nStopB1X>
+ <nStopB2X>0</nStopB2X>
</BeforeMake>
<AfterMake>
<RunUserProg1>1</RunUserProg1>
<StopOnExitCode>3</StopOnExitCode>
<CustomArgument></CustomArgument>
<IncludeLibraryModules></IncludeLibraryModules>
+ <ComprImg>1</ComprImg>
</CommonProperty>
<DllOption>
<SimDllName>SARMCM3.DLL</SimDllName>
<Oh166RecLen>16</Oh166RecLen>
</OPTHX>
<Simulator>
- <UseSimulator>0</UseSimulator>
+ <UseSimulator>1</UseSimulator>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
<RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreFunctions>1</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<LimitSpeedToRealTime>0</LimitSpeedToRealTime>
+ <RestoreSysVw>1</RestoreSysVw>
</Simulator>
<Target>
- <UseTarget>1</UseTarget>
+ <UseTarget>0</UseTarget>
<LoadApplicationAtStartup>1</LoadApplicationAtStartup>
- <RunToMain>0</RunToMain>
+ <RunToMain>1</RunToMain>
<RestoreBreakpoints>1</RestoreBreakpoints>
<RestoreWatchpoints>1</RestoreWatchpoints>
<RestoreMemoryDisplay>1</RestoreMemoryDisplay>
<RestoreFunctions>0</RestoreFunctions>
<RestoreToolbox>1</RestoreToolbox>
<RestoreTracepoints>0</RestoreTracepoints>
+ <RestoreSysVw>1</RestoreSysVw>
</Target>
<RunDebugAfterBuild>0</RunDebugAfterBuild>
- <TargetSelection>4</TargetSelection>
+ <TargetSelection>2</TargetSelection>
<SimDlls>
<CpuDll></CpuDll>
<CpuDllArguments></CpuDllArguments>
<UseTargetDll>1</UseTargetDll>
<UseExternalTool>0</UseExternalTool>
<RunIndependent>0</RunIndependent>
- <UpdateFlashBeforeDebugging>0</UpdateFlashBeforeDebugging>
+ <UpdateFlashBeforeDebugging>1</UpdateFlashBeforeDebugging>
<Capability>1</Capability>
<DriverSelection>4099</DriverSelection>
</Flash1>
+ <bUseTDR>1</bUseTDR>
<Flash2>BIN\lmidk-agdi.dll</Flash2>
<Flash3>"" ()</Flash3>
<Flash4></Flash4>
+ <pFcarmOut></pFcarmOut>
+ <pFcarmGrp></pFcarmGrp>
+ <pFcArmRoot></pFcArmRoot>
+ <FcArmLst>0</FcArmLst>
</Utilities>
<TargetArmAds>
<ArmAdsMisc>
<wLevel>0</wLevel>
<uThumb>0</uThumb>
<uSurpInc>0</uSurpInc>
+ <uC99>0</uC99>
+ <useXO>0</useXO>
<VariousControls>
<MiscControls>--diag_suppress 191,550,513,167,177,144</MiscControls>
<Define>RVDS_ARMCM3_LM3S102, "PACK_STRUCT_END=","ALIGN_STRUCT_END="</Define>
<SwStkChk>0</SwStkChk>
<NoWarn>0</NoWarn>
<uSurpInc>0</uSurpInc>
+ <useXO>0</useXO>
<VariousControls>
<MiscControls></MiscControls>
<Define></Define>
<useFile>0</useFile>
<TextAddressRange>0x00000000</TextAddressRange>
<DataAddressRange>0x20000000</DataAddressRange>
+ <pXoBase></pXoBase>
<ScatterFile></ScatterFile>
<IncludeLibs></IncludeLibs>
<IncludeLibsPath></IncludeLibsPath>
<FileType>1</FileType>
<FilePath>..\Common\Minimal\QueueSet.c</FilePath>
</File>
+ <File>
+ <FileName>EventGroupsDemo.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\Common\Minimal\EventGroupsDemo.c</FilePath>
+ </File>
</Files>
</Group>
<Group>
<FileType>1</FileType>
<FilePath>..\..\Source\portable\RVDS\ARM_CM3\port.c</FilePath>
</File>
+ <File>
+ <FileName>timers.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\Source\timers.c</FilePath>
+ </File>
+ <File>
+ <FileName>event_groups.c</FileName>
+ <FileType>1</FileType>
+ <FilePath>..\..\Source\event_groups.c</FilePath>
+ </File>
<File>
<FileName>heap_2.c</FileName>
<FileType>1</FileType>
HTTPD_CGI_CALL(io, "led-io", led_io );\r
\r
\r
-static const struct httpd_cgi_call * const calls[] = { &file, &tcp, &net, &rtos, &io, NULL };\r
+static const struct httpd_cgi_call * calls[] = { &file, &tcp, &net, &rtos, &io, NULL };\r
\r
/*---------------------------------------------------------------------------*/\r
static\r
#endif\r
\r
#if portBYTE_ALIGNMENT == 8\r
- #define portBYTE_ALIGNMENT_MASK ( 0x0007U )\r
+ #define portBYTE_ALIGNMENT_MASK ( 0x0007 )\r
#endif\r
\r
#if portBYTE_ALIGNMENT == 4\r
BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION;\r
\r
/*\r
- * Reset a queue back to its original empty state. pdPASS is returned if the\r
- * queue is successfully reset. pdFAIL is returned if the queue could not be\r
- * reset because there are tasks blocked on the queue waiting to either\r
- * receive from the queue or send to the queue.\r
+ * Reset a queue back to its original empty state. The return value is now\r
+ * obsolete and is always set to pdPASS.\r
*/\r
#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE )\r
\r
* Returns the ID assigned to the timer.\r
*\r
* IDs are assigned to timers using the pvTimerID parameter of the call to\r
- * xTimerCreated() that was used to create the timer.\r
+ * xTimerCreated() that was used to create the timer, and by calling the\r
+ * vTimerSetTimerID() API function.\r
*\r
* If the same callback function is assigned to multiple timers then the timer\r
- * ID can be used within the callback function to identify which timer actually\r
- * expired.\r
+ * ID can be used as time specific (timer local) storage.\r
*\r
* @param xTimer The timer being queried.\r
*\r
*/\r
void *pvTimerGetTimerID( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION;\r
\r
+/**\r
+ * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID );\r
+ *\r
+ * Sets the ID assigned to the timer.\r
+ *\r
+ * IDs are assigned to timers using the pvTimerID parameter of the call to\r
+ * xTimerCreated() that was used to create the timer.\r
+ *\r
+ * If the same callback function is assigned to multiple timers then the timer\r
+ * ID can be used as time specific (timer local) storage.\r
+ *\r
+ * @param xTimer The timer being updated.\r
+ *\r
+ * @param pvNewID The ID to assign to the timer.\r
+ *\r
+ * Example usage:\r
+ *\r
+ * See the xTimerCreate() API function example usage scenario.\r
+ */\r
+void vTimerSetTimerID( const TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION;\r
+\r
/**\r
* BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer );\r
*\r
/* Critical section management. */\r
#define portINTERRUPT_BITS ( ( uint16_t ) configKERNEL_INTERRUPT_PRIORITY << ( uint16_t ) 5 )\r
\r
-#define portDISABLE_INTERRUPTS() SR |= portINTERRUPT_BITS\r
+#define portDISABLE_INTERRUPTS() SR |= portINTERRUPT_BITS; __asm volatile ( "NOP" )\r
#define portENABLE_INTERRUPTS() SR &= ~portINTERRUPT_BITS\r
\r
/* Note that exiting a critical sectino will set the IPL bits to 0, nomatter\r
\r
/* Start the highest priority task by obtaining its associated thread\r
state structure, in which is stored the thread handle. */\r
- pxThreadState = ( xThreadState * ) *( ( uint32_t * ) pxCurrentTCB );\r
+ pxThreadState = ( xThreadState * ) *( ( size_t * ) pxCurrentTCB );\r
ulCriticalNesting = portNO_CRITICAL_NESTING;\r
\r
/* Bump up the priority of the thread that is going to run, in the\r
if( pvOldCurrentTCB != pxCurrentTCB )\r
{\r
/* Suspend the old thread. */\r
- pxThreadState = ( xThreadState *) *( ( uint32_t * ) pvOldCurrentTCB );\r
+ pxThreadState = ( xThreadState *) *( ( size_t * ) pvOldCurrentTCB );\r
SuspendThread( pxThreadState->pvThread );\r
\r
/* Obtain the state of the task now selected to enter the\r
Running state. */\r
- pxThreadState = ( xThreadState * ) ( *( uint32_t *) pxCurrentTCB );\r
+ pxThreadState = ( xThreadState * ) ( *( size_t *) pxCurrentTCB );\r
ResumeThread( pxThreadState->pvThread );\r
}\r
}\r
( void ) ulErrorCode;\r
\r
/* Find the handle of the thread being deleted. */\r
- pxThreadState = ( xThreadState * ) ( *( uint32_t *) pvTaskToDelete );\r
+ pxThreadState = ( xThreadState * ) ( *( size_t *) pvTaskToDelete );\r
\r
/* Check that the thread is still valid, it might have been closed by\r
vPortCloseRunningThread() - which will be the case if the task associated\r
( void ) ulErrorCode;\r
\r
/* Find the handle of the thread being deleted. */\r
- pxThreadState = ( xThreadState * ) ( *( uint32_t *) pvTaskToDelete );\r
+ pxThreadState = ( xThreadState * ) ( *( size_t *) pvTaskToDelete );\r
pvThread = pxThreadState->pvThread;\r
\r
/* Raise the Windows priority of the thread to ensure the FreeRTOS scheduler\r
#define portDOUBLE double\r
#define portLONG long\r
#define portSHORT short\r
-#define portSTACK_TYPE uint32_t\r
+#define portSTACK_TYPE size_t\r
#define portBASE_TYPE long\r
+#define portPOINTER_SIZE_TYPE size_t\r
\r
typedef portSTACK_TYPE StackType_t;\r
typedef long BaseType_t;\r
typedef uint32_t TickType_t;\r
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL\r
\r
- /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do\r
- not need to be guarded with a critical section. */\r
+ /* 32/64-bit tick type on a 32/64-bit architecture, so reads of the tick\r
+ count do not need to be guarded with a critical section. */\r
#define portTICK_TYPE_IS_ATOMIC 1\r
#endif\r
\r
/* Hardware specifics. */\r
#define portSTACK_GROWTH ( -1 )\r
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )\r
-#define portBYTE_ALIGNMENT 4\r
+\r
+\r
+#if defined( __x86_64_ _) || defined( _M_X64 )\r
+ #define portBYTE_ALIGNMENT 8\r
+#else\r
+ #define portBYTE_ALIGNMENT 4\r
+#endif\r
\r
#define portYIELD() vPortGenerateSimulatedInterrupt( portINTERRUPT_YIELD )\r
\r
void vPortSetInterruptHandler( uint32_t ulInterruptNumber, uint32_t (*pvHandler)( void ) );\r
\r
#endif\r
+\r
if( pucAlignedHeap == NULL )\r
{\r
/* Ensure the heap starts on a correctly aligned boundary. */\r
- pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );\r
+ pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );\r
}\r
\r
/* Check there is enough room left for the allocation. */\r
uint8_t *pucAlignedHeap;\r
\r
/* Ensure the heap starts on a correctly aligned boundary. */\r
- pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );\r
+ pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );\r
\r
/* xStart is used to hold a pointer to the first item in the list of free\r
blocks. The void cast is used to prevent compiler warnings. */\r
{\r
taskENTER_CRITICAL();\r
{\r
- /* Is there room on the queue now? The running task must be\r
- the highest priority task wanting to access the queue. If\r
- the head item in the queue is to be overwritten then it does\r
- not matter if the queue is full. */\r
+ /* Is there room on the queue now? The running task must be the\r
+ highest priority task wanting to access the queue. If the head item\r
+ in the queue is to be overwritten then it does not matter if the\r
+ queue is full. */\r
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )\r
{\r
traceQUEUE_SEND( pxQueue );\r
{\r
traceQUEUE_SEND_FROM_ISR( pxQueue );\r
\r
- /* A task can only have an inherited priority if it is a mutex\r
- holder - and if there is a mutex holder then the mutex cannot be\r
- given from an ISR. Therefore, unlike the xQueueGenericGive()\r
- function, there is no need to determine the need for priority\r
- disinheritance here or to clear the mutex holder TCB member. */\r
+ /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a\r
+ semaphore or mutex. That means prvCopyDataToQueue() cannot result\r
+ in a task disinheriting a priority and prvCopyDataToQueue() can be\r
+ called here even though the disinherit function does not check if\r
+ the scheduler is suspended before accessing the ready lists. */\r
( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );\r
\r
/* The event list is not altered if the queue is locked. This will\r
UBaseType_t uxSavedInterruptStatus;\r
Queue_t * const pxQueue = ( Queue_t * ) xQueue;\r
\r
+ /* Similar to xQueueGenericSendFromISR() but used with semaphores where the\r
+ item size is 0. Don't directly wake a task that was blocked on a queue\r
+ read, instead return a flag to say whether a context switch is required or\r
+ not (i.e. has a task with a higher priority than us been woken by this\r
+ post). */\r
+\r
configASSERT( pxQueue );\r
\r
- /* xQueueGenericSendFromISR() should be used in the item size is not 0. */\r
+ /* xQueueGenericSendFromISR() should be used instead of xQueueGiveFromISR()\r
+ if the item size is not 0. */\r
configASSERT( pxQueue->uxItemSize == 0 );\r
\r
+ /* Normally a mutex would not be given from an interrupt, and doing so is\r
+ definitely wrong if there is a mutex holder as priority inheritance makes no\r
+ sense for an interrupts, only tasks. */\r
+ configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->pxMutexHolder != NULL ) ) );\r
+\r
/* RTOS ports that support interrupt nesting have the concept of a maximum\r
system call (or maximum API call) interrupt priority. Interrupts that are\r
above the maximum system call priority are kept permanently enabled, even\r
link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */\r
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();\r
\r
- /* Similar to xQueueGenericSendFromISR() but used with semaphores where the\r
- item size is 0. Don't directly wake a task that was blocked on a queue\r
- read, instead return a flag to say whether a context switch is required or\r
- not (i.e. has a task with a higher priority than us been woken by this\r
- post). */\r
uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
{\r
/* When the queue is used to implement a semaphore no data is ever\r
\r
/* A task can only have an inherited priority if it is a mutex\r
holder - and if there is a mutex holder then the mutex cannot be\r
- given from an ISR. Therefore, unlike the xQueueGenericGive()\r
- function, there is no need to determine the need for priority\r
- disinheritance here or to clear the mutex holder TCB member. */\r
-\r
+ given from an ISR. As this is the ISR version of the function it\r
+ can be assumed there is no mutex holder and no need to determine if\r
+ priority disinheritance is needed. Simply increase the count of\r
+ messages (semaphores) available. */\r
++( pxQueue->uxMessagesWaiting );\r
\r
/* The event list is not altered if the queue is locked. This will\r
any other tasks waiting for the data. */\r
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )\r
{\r
- /* Tasks that are removed from the event list will get added to\r
- the pending ready list as the scheduler is still suspended. */\r
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )\r
{\r
/* The task waiting has a higher priority than this task. */\r
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )\r
{\r
traceQUEUE_SEND( pxQueueSetContainer );\r
+\r
/* The data copied is the handle of the queue that contains data. */\r
xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );\r
\r
* the task. It is inserted at the end of the list.\r
*/\r
#define prvAddTaskToReadyList( pxTCB ) \\r
- traceMOVED_TASK_TO_READY_STATE( pxTCB ) \\r
+ traceMOVED_TASK_TO_READY_STATE( pxTCB ); \\r
taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \\r
vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xGenericListItem ) )\r
/*-----------------------------------------------------------*/\r
#if( portSTACK_GROWTH < 0 )\r
{\r
pxTopOfStack = pxNewTCB->pxStack + ( usStackDepth - ( uint16_t ) 1 );\r
- 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. */\r
+ 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. */\r
\r
/* Check the alignment of the calculated top of stack is correct. */\r
configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) );\r
/* This function should not be called by application code hence the\r
'Restricted' in its name. It is not part of the public API. It is\r
designed for use by kernel code, and has special calling requirements -\r
- it should be called from a critical section. */\r
+ it should be called with the scheduler suspended. */\r
\r
\r
/* Place the event list item of the TCB in the appropriate event list.\r
\r
/* We must remove this task from the ready list before adding it to the\r
blocked list as the same list item is used for both lists. This\r
- function is called form a critical section. */\r
+ function is called with the scheduler locked so interrupts will not\r
+ access the lists at the same time. */\r
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r
{\r
/* The current task must be in a ready list, so there is no need to\r
locked then the mutex holder might now be NULL. */\r
if( pxMutexHolder != NULL )\r
{\r
+ /* If the holder of the mutex has a priority below the priority of\r
+ the task attempting to obtain the mutex then it will temporarily\r
+ inherit the priority of the task attempting to obtain the mutex. */\r
if( pxTCB->uxPriority < pxCurrentTCB->uxPriority )\r
{\r
/* Adjust the mutex holder state to account for its new\r
mtCOVERAGE_TEST_MARKER();\r
}\r
\r
- /* If the task being modified is in the ready state it will need to\r
- be moved into a new list. */\r
+ /* If the task being modified is in the ready state it will need\r
+ to be moved into a new list. */\r
if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxTCB->uxPriority ] ), &( pxTCB->xGenericListItem ) ) != pdFALSE )\r
{\r
if( uxListRemove( &( pxTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )\r
\r
if( pxMutexHolder != NULL )\r
{\r
+ /* A task can only have an inherited priority if it holds the mutex.\r
+ If the mutex is held by a task then it cannot be given from an\r
+ interrupt, and if a mutex is given by the holding task then it must\r
+ be the running state task. */\r
+ configASSERT( pxTCB == pxCurrentTCB );\r
+\r
configASSERT( pxTCB->uxMutexesHeld );\r
( pxTCB->uxMutexesHeld )--;\r
\r
+ /* Has the holder of the mutex inherited the priority of another\r
+ task? */\r
if( pxTCB->uxPriority != pxTCB->uxBasePriority )\r
{\r
/* Only disinherit if no other mutexes are held. */\r
if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 )\r
{\r
- /* A task can only have an inhertied priority if it holds\r
+ /* A task can only have an inherited priority if it holds\r
the mutex. If the mutex is held by a task then it cannot be\r
given from an interrupt, and if a mutex is given by the\r
holding task then it must be the running state task. Remove\r
void *pvTimerGetTimerID( const TimerHandle_t xTimer )\r
{\r
Timer_t * const pxTimer = ( Timer_t * ) xTimer;\r
+void *pvReturn;\r
\r
- return pxTimer->pvTimerID;\r
+ configASSERT( xTimer );\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ pvReturn = pxTimer->pvTimerID;\r
+ }\r
+ taskEXIT_CRITICAL();\r
+\r
+ return pvReturn;\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vTimerSetTimerID( const TimerHandle_t xTimer, void *pvNewID )\r
+{\r
+Timer_t * const pxTimer = ( Timer_t * ) xTimer;\r
+\r
+ configASSERT( xTimer );\r
+\r
+ taskENTER_CRITICAL();\r
+ {\r
+ pxTimer->pvTimerID = pvNewID;\r
+ }\r
+ taskEXIT_CRITICAL();\r
}\r
/*-----------------------------------------------------------*/\r
\r