Improve QueueSet.c test coverage by reading the queue set from an ISR to force paths through the queue locking and unlocking.
Add the FreeRTOS+Trace recorder into the Win32 MSVC demo. Added more functions, including the queue set functions, to the MPU port.
This commit is contained in:
parent
26152204a4
commit
b671bf368a
@ -67,7 +67,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Demonstrates the creation an use of queue sets.
|
* Tests the use of queue sets.
|
||||||
*
|
*
|
||||||
* A receive task creates a number of queues and adds them to a queue set before
|
* A receive task creates a number of queues and adds them to a queue set before
|
||||||
* blocking on the queue set receive. A transmit task and (optionally) an
|
* blocking on the queue set receive. A transmit task and (optionally) an
|
||||||
@ -76,11 +76,12 @@
|
|||||||
* the queues and flags an error if the received message does not match that
|
* the queues and flags an error if the received message does not match that
|
||||||
* expected. The task sends values in the range 0 to
|
* expected. The task sends values in the range 0 to
|
||||||
* queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range
|
* queuesetINITIAL_ISR_TX_VALUE, and the ISR sends value in the range
|
||||||
* queuesetINITIAL_ISR_TX_VALUE to 0xffffffffUL;
|
* queuesetINITIAL_ISR_TX_VALUE to ULONG_MAX.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Standard includes. */
|
/* Standard includes. */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
/* Kernel includes. */
|
/* Kernel includes. */
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
@ -102,7 +103,7 @@
|
|||||||
|
|
||||||
/* Messages are sent in incrementing order from both a task and an interrupt.
|
/* Messages are sent in incrementing order from both a task and an interrupt.
|
||||||
The task sends values in the range 0 to 0xfffe, and the interrupt sends values
|
The task sends values in the range 0 to 0xfffe, and the interrupt sends values
|
||||||
in the range of 0xffff to 0xffffffff; */
|
in the range of 0xffff to ULONG_MAX. */
|
||||||
#define queuesetINITIAL_ISR_TX_VALUE 0xffffUL
|
#define queuesetINITIAL_ISR_TX_VALUE 0xffffUL
|
||||||
|
|
||||||
/* The priorities used in this demo. */
|
/* The priorities used in this demo. */
|
||||||
@ -115,8 +116,13 @@ queuesetPRIORITY_CHANGE_LOOPS number of values are sent to a queue. */
|
|||||||
#define queuesetPRIORITY_CHANGE_LOOPS 100UL
|
#define queuesetPRIORITY_CHANGE_LOOPS 100UL
|
||||||
|
|
||||||
/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */
|
/* The ISR sends to the queue every queuesetISR_TX_PERIOD ticks. */
|
||||||
#define queuesetISR_TX_PERIOD ( 100UL )
|
#define queuesetISR_TX_PERIOD 2//( 100UL )
|
||||||
|
|
||||||
|
/* The allowable maximum deviation between a received value and the expected
|
||||||
|
received value. A deviation will occur when data is received from a queue
|
||||||
|
inside an ISR in between a task receiving from a queue and the task checking
|
||||||
|
the received value. */
|
||||||
|
#define queuesetALLOWABLE_RX_DEVIATION 5
|
||||||
/*
|
/*
|
||||||
* The task that periodically sends to the queue set.
|
* The task that periodically sends to the queue set.
|
||||||
*/
|
*/
|
||||||
@ -127,6 +133,35 @@ static void prvQueueSetSendingTask( void *pvParameters );
|
|||||||
*/
|
*/
|
||||||
static void prvQueueSetReceivingTask( void *pvParameters );
|
static void prvQueueSetReceivingTask( void *pvParameters );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the value received from a queue is the expected value. Some values
|
||||||
|
* originate from the send task, some values originate from the ISR, with the
|
||||||
|
* range of the value being used to distinguish between the two message
|
||||||
|
* sources.
|
||||||
|
*/
|
||||||
|
static void prvCheckReceivedValue( unsigned long ulReceived );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For purposes of test coverage, functions that read from and write to a
|
||||||
|
* queue set from an ISR respectively.
|
||||||
|
*/
|
||||||
|
static void prvReceiveFromQueueInSetFromISR( void );
|
||||||
|
static void prvSendToQueueInSetFromISR( void );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the queues and add them to a queue set before resuming the Tx
|
||||||
|
* task.
|
||||||
|
*/
|
||||||
|
static void prvSetupTest( xTaskHandle xQueueSetSendingTask );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks a value received from a queue falls within the range of expected
|
||||||
|
* values.
|
||||||
|
*/
|
||||||
|
static portBASE_TYPE prvCheckReceivedValueWithinExpectedRange( unsigned long ulReceived, unsigned long ulExpectedReceived );
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
/* The queues that are added to the set. */
|
/* The queues that are added to the set. */
|
||||||
static xQueueHandle xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
static xQueueHandle xQueues[ queuesetNUM_QUEUES_IN_SET ] = { 0 };
|
||||||
|
|
||||||
@ -166,8 +201,8 @@ xTaskHandle xQueueSetSendingTask;
|
|||||||
/* Create the two queues. The handle of the sending task is passed into
|
/* Create the two queues. The handle of the sending task is passed into
|
||||||
the receiving task using the task parameter. The receiving task uses the
|
the receiving task using the task parameter. The receiving task uses the
|
||||||
handle to resume the sending task after it has created the queues. */
|
handle to resume the sending task after it has created the queues. */
|
||||||
xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask );
|
xTaskCreate( prvQueueSetSendingTask, ( signed char * ) "SetTx", configMINIMAL_STACK_SIZE, NULL, queuesetMEDIUM_PRIORITY, &xQueueSetSendingTask );
|
||||||
xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "Check", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, NULL );
|
xTaskCreate( prvQueueSetReceivingTask, ( signed char * ) "SetRx", configMINIMAL_STACK_SIZE, ( void * ) xQueueSetSendingTask, queuesetMEDIUM_PRIORITY, NULL );
|
||||||
|
|
||||||
/* It is important that the sending task does not attempt to write to a
|
/* It is important that the sending task does not attempt to write to a
|
||||||
queue before the queue has been created. It is therefore placed into the
|
queue before the queue has been created. It is therefore placed into the
|
||||||
@ -226,48 +261,6 @@ portBASE_TYPE xReturn = pdPASS, x;
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vQueueSetWriteToQueueFromISR( void )
|
|
||||||
{
|
|
||||||
portBASE_TYPE x = 0;
|
|
||||||
static unsigned long ulCallCount = 0;
|
|
||||||
|
|
||||||
/* xSetupComplete is set to pdTRUE when the queues have been created and
|
|
||||||
are available for use. */
|
|
||||||
if( xSetupComplete == pdTRUE )
|
|
||||||
{
|
|
||||||
/* It is intended that this function is called from the tick hook
|
|
||||||
function, so each call is one tick period apart. */
|
|
||||||
ulCallCount++;
|
|
||||||
if( ulCallCount > queuesetISR_TX_PERIOD )
|
|
||||||
{
|
|
||||||
ulCallCount = 0;
|
|
||||||
|
|
||||||
/* Look for a queue that can be written to. */
|
|
||||||
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
|
||||||
{
|
|
||||||
if( xQueues[ x ] != NULL )
|
|
||||||
{
|
|
||||||
/* xQueues[ x ] can be written to. Send the next value. */
|
|
||||||
if( xQueueSendFromISR( xQueues[ x ], ( void * ) &ulISRTxValue, NULL ) == pdPASS )
|
|
||||||
{
|
|
||||||
ulISRTxValue++;
|
|
||||||
|
|
||||||
/* If the Tx value has wrapped then set it back to its
|
|
||||||
initial value. */
|
|
||||||
if( ulISRTxValue == 0UL )
|
|
||||||
{
|
|
||||||
ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------*/
|
|
||||||
|
|
||||||
static void prvQueueSetSendingTask( void *pvParameters )
|
static void prvQueueSetSendingTask( void *pvParameters )
|
||||||
{
|
{
|
||||||
unsigned long ulTaskTxValue = 0;
|
unsigned long ulTaskTxValue = 0;
|
||||||
@ -299,41 +292,6 @@ unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0;
|
|||||||
xQueueSetTasksStatus = pdFAIL;
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to remove the queue from a queue set it does not belong
|
|
||||||
to (NULL being passed as the queue set in this case). */
|
|
||||||
if( xQueueRemoveFromQueueSet( xQueueInUse, NULL ) != pdFAIL )
|
|
||||||
{
|
|
||||||
/* It is not possible to successfully remove a queue from a queue
|
|
||||||
set it does not belong to. */
|
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Mark the space in the array of queues as being empty before actually
|
|
||||||
removing the queue from the queue set. This is to prevent the code
|
|
||||||
that accesses the queue set from an interrupt from attempting to access
|
|
||||||
a queue that is no longer in the set. */
|
|
||||||
xQueues[ xQueueToWriteTo ] = 0;
|
|
||||||
|
|
||||||
/* Attempt to remove the queue from the queue set it does belong to. */
|
|
||||||
if( xQueueRemoveFromQueueSet( xQueueInUse, xQueueSet ) != pdPASS )
|
|
||||||
{
|
|
||||||
/* It should be possible to remove the queue from the queue set it
|
|
||||||
does belong to. */
|
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add the queue back before cycling back to run again. */
|
|
||||||
if( xQueueAddToQueueSet( xQueueInUse, xQueueSet ) != pdPASS )
|
|
||||||
{
|
|
||||||
/* If the queue was successfully removed from the queue set then it
|
|
||||||
should be possible to add it back in again. */
|
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now the queue is back in the set it is ok for the interrupt that
|
|
||||||
writes to the queues to access it again. */
|
|
||||||
xQueues[ xQueueToWriteTo ] = xQueueInUse;
|
|
||||||
|
|
||||||
ulTaskTxValue++;
|
ulTaskTxValue++;
|
||||||
|
|
||||||
/* If the Tx value has reached the range used by the ISR then set it
|
/* If the Tx value has reached the range used by the ISR then set it
|
||||||
@ -363,56 +321,21 @@ unsigned portBASE_TYPE uxPriority = queuesetMEDIUM_PRIORITY, ulLoops = 0;
|
|||||||
|
|
||||||
static void prvQueueSetReceivingTask( void *pvParameters )
|
static void prvQueueSetReceivingTask( void *pvParameters )
|
||||||
{
|
{
|
||||||
unsigned long ulReceived, ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;
|
unsigned long ulReceived;
|
||||||
xQueueHandle xActivatedQueue;
|
xQueueHandle xActivatedQueue;
|
||||||
portBASE_TYPE x;
|
|
||||||
xTaskHandle xQueueSetSendingTask;
|
xTaskHandle xQueueSetSendingTask;
|
||||||
|
|
||||||
/* The handle to the sending task is passed in using the task parameter. */
|
/* The handle to the sending task is passed in using the task parameter. */
|
||||||
xQueueSetSendingTask = ( xTaskHandle ) pvParameters;
|
xQueueSetSendingTask = ( xTaskHandle ) pvParameters;
|
||||||
|
|
||||||
/* Ensure the queues are created and the queue set configured before the
|
/* Create the queues and add them to the queue set before resuming the Tx
|
||||||
sending task is unsuspended.
|
task. */
|
||||||
|
prvSetupTest( xQueueSetSendingTask );
|
||||||
First Create the queue set such that it will be able to hold a message for
|
|
||||||
every space in every queue in the set. */
|
|
||||||
xQueueSet = xQueueSetCreate( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH );
|
|
||||||
|
|
||||||
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
|
||||||
{
|
|
||||||
/* Create the queue and add it to the set. The queue is just holding
|
|
||||||
unsigned long value. */
|
|
||||||
xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( unsigned long ) );
|
|
||||||
configASSERT( xQueues[ x ] );
|
|
||||||
if( xQueueAddToQueueSet( xQueues[ x ], xQueueSet ) != pdPASS )
|
|
||||||
{
|
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The queue has now been added to the queue set and cannot be added to
|
|
||||||
another. */
|
|
||||||
if( xQueueAddToQueueSet( xQueues[ x ], xQueueSet ) != pdFAIL )
|
|
||||||
{
|
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The task that sends to the queues is not running yet, so attempting to
|
|
||||||
read from the queue set should fail, resulting in xActivatedQueue being set
|
|
||||||
to NULL. */
|
|
||||||
xActivatedQueue = xQueueBlockMultiple( xQueueSet, queuesetSHORT_DELAY );
|
|
||||||
configASSERT( xActivatedQueue == NULL );
|
|
||||||
|
|
||||||
/* Resume the task that writes to the queues. */
|
|
||||||
vTaskResume( xQueueSetSendingTask );
|
|
||||||
|
|
||||||
/* Let the ISR access the queues also. */
|
|
||||||
xSetupComplete = pdTRUE;
|
|
||||||
|
|
||||||
for( ;; )
|
for( ;; )
|
||||||
{
|
{
|
||||||
/* Wait for a message to arrive on one of the queues in the set. */
|
/* Wait for a message to arrive on one of the queues in the set. */
|
||||||
xActivatedQueue = xQueueBlockMultiple( xQueueSet, portMAX_DELAY );
|
xActivatedQueue = xQueueSelectFromSet( xQueueSet, portMAX_DELAY );
|
||||||
configASSERT( xActivatedQueue );
|
configASSERT( xActivatedQueue );
|
||||||
|
|
||||||
if( xActivatedQueue == NULL )
|
if( xActivatedQueue == NULL )
|
||||||
@ -430,52 +353,14 @@ xTaskHandle xQueueSetSendingTask;
|
|||||||
xQueueSetTasksStatus = pdFAIL;
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the received value is equal to or greater than
|
/* Ensure the value received was the value expected. This function
|
||||||
queuesetINITIAL_ISR_TX_VALUE then it was sent by an ISR. */
|
manipulates file scope data and is also called from an ISR, hence
|
||||||
if( ulReceived >= queuesetINITIAL_ISR_TX_VALUE )
|
the critical section. */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
/* The value was sent from the ISR. Check it against its
|
prvCheckReceivedValue( ulReceived );
|
||||||
expected value. */
|
|
||||||
configASSERT( ulReceived == ulExpectedReceivedFromISR );
|
|
||||||
if( ulReceived != ulExpectedReceivedFromISR )
|
|
||||||
{
|
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* It is expected to receive an incrementing value. */
|
|
||||||
ulExpectedReceivedFromISR++;
|
|
||||||
|
|
||||||
/* If the expected value has wrapped then set it back to
|
|
||||||
its initial value. */
|
|
||||||
if( ulExpectedReceivedFromISR == 0 )
|
|
||||||
{
|
|
||||||
ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The value was sent from the Tx task. Check it against its
|
|
||||||
expected value. */
|
|
||||||
configASSERT( ulReceived == ulExpectedReceivedFromTask );
|
|
||||||
if( ulReceived != ulExpectedReceivedFromTask )
|
|
||||||
{
|
|
||||||
xQueueSetTasksStatus = pdFAIL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* It is expected to receive an incrementing value. */
|
|
||||||
ulExpectedReceivedFromTask++;
|
|
||||||
|
|
||||||
/* If the expected value has reached the range of values
|
|
||||||
used by the ISR then set it back to 0. */
|
|
||||||
if( ulExpectedReceivedFromTask >= queuesetINITIAL_ISR_TX_VALUE )
|
|
||||||
{
|
|
||||||
ulExpectedReceivedFromTask = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( xQueueSetTasksStatus == pdPASS )
|
if( xQueueSetTasksStatus == pdPASS )
|
||||||
@ -484,4 +369,250 @@ xTaskHandle xQueueSetSendingTask;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vQueueSetAccessQueueSetFromISR( void )
|
||||||
|
{
|
||||||
|
static unsigned long ulCallCount = 0;
|
||||||
|
|
||||||
|
/* xSetupComplete is set to pdTRUE when the queues have been created and
|
||||||
|
are available for use. */
|
||||||
|
if( xSetupComplete == pdTRUE )
|
||||||
|
{
|
||||||
|
/* It is intended that this function is called from the tick hook
|
||||||
|
function, so each call is one tick period apart. */
|
||||||
|
ulCallCount++;
|
||||||
|
if( ulCallCount > queuesetISR_TX_PERIOD )
|
||||||
|
{
|
||||||
|
ulCallCount = 0;
|
||||||
|
|
||||||
|
/* First attempt to read from the queue set. */
|
||||||
|
prvReceiveFromQueueInSetFromISR();
|
||||||
|
|
||||||
|
/* Then write to the queue set. */
|
||||||
|
prvSendToQueueInSetFromISR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvCheckReceivedValue( unsigned long ulReceived )
|
||||||
|
{
|
||||||
|
static unsigned long ulExpectedReceivedFromTask = 0, ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
|
||||||
|
/* Values are received in tasks and interrupts. It is likely that the
|
||||||
|
receiving task will sometimes get preempted by the receiving interrupt
|
||||||
|
between reading a value from the queue and calling this function. When
|
||||||
|
that happens, if the receiving interrupt calls this function the values
|
||||||
|
will get passed into this function slightly out of order. For that
|
||||||
|
reason the value passed in is tested against a small range of expected
|
||||||
|
values, rather than a single absolute value. To make the range testing
|
||||||
|
easier values in the range limits are ignored. */
|
||||||
|
|
||||||
|
/* If the received value is equal to or greater than
|
||||||
|
queuesetINITIAL_ISR_TX_VALUE then it was sent by an ISR. */
|
||||||
|
if( ulReceived >= queuesetINITIAL_ISR_TX_VALUE )
|
||||||
|
{
|
||||||
|
/* The value was sent from the ISR. */
|
||||||
|
if( ( ulReceived - queuesetINITIAL_ISR_TX_VALUE ) < queuesetALLOWABLE_RX_DEVIATION )
|
||||||
|
{
|
||||||
|
/* The value received is at the lower limit of the expected range.
|
||||||
|
Don't test it and expect to receive one higher next time. */
|
||||||
|
ulExpectedReceivedFromISR++;
|
||||||
|
}
|
||||||
|
else if( ( ULONG_MAX - ulReceived ) <= queuesetALLOWABLE_RX_DEVIATION )
|
||||||
|
{
|
||||||
|
/* The value received is at the higher limit of the expected range.
|
||||||
|
Don't test it and expect to wrap soon. */
|
||||||
|
ulExpectedReceivedFromISR = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check the value against its expected value range. */
|
||||||
|
if( prvCheckReceivedValueWithinExpectedRange( ulReceived, ulExpectedReceivedFromISR ) != pdPASS )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It is expected to receive an incrementing value. */
|
||||||
|
ulExpectedReceivedFromISR++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The value was sent from the Tx task. */
|
||||||
|
if( ulReceived < queuesetALLOWABLE_RX_DEVIATION )
|
||||||
|
{
|
||||||
|
/* The value received is at the lower limit of the expected range.
|
||||||
|
Don't test it, and expect to receive one higher next time. */
|
||||||
|
ulExpectedReceivedFromTask++;
|
||||||
|
}
|
||||||
|
else if( ( ( queuesetINITIAL_ISR_TX_VALUE - 1 ) - ulReceived ) <= queuesetALLOWABLE_RX_DEVIATION )
|
||||||
|
{
|
||||||
|
/* The value received is at the higher limit of the expected range.
|
||||||
|
Don't test it and expect to wrap soon. */
|
||||||
|
ulExpectedReceivedFromTask = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check the value against its expected value range. */
|
||||||
|
if( prvCheckReceivedValueWithinExpectedRange( ulReceived, ulExpectedReceivedFromTask ) != pdPASS )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It is expected to receive an incrementing value. */
|
||||||
|
ulExpectedReceivedFromTask++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static portBASE_TYPE prvCheckReceivedValueWithinExpectedRange( unsigned long ulReceived, unsigned long ulExpectedReceived )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn = pdPASS;
|
||||||
|
|
||||||
|
if( ulReceived > ulExpectedReceived )
|
||||||
|
{
|
||||||
|
configASSERT( ( ulReceived - ulExpectedReceived ) <= queuesetALLOWABLE_RX_DEVIATION );
|
||||||
|
if( ( ulReceived - ulExpectedReceived ) > queuesetALLOWABLE_RX_DEVIATION )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
configASSERT( ( ulExpectedReceived - ulReceived ) <= queuesetALLOWABLE_RX_DEVIATION );
|
||||||
|
if( ( ulExpectedReceived - ulReceived ) > queuesetALLOWABLE_RX_DEVIATION )
|
||||||
|
{
|
||||||
|
xReturn = pdFALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvReceiveFromQueueInSetFromISR( void )
|
||||||
|
{
|
||||||
|
xQueueSetMemberHandle xActivatedQueue;
|
||||||
|
unsigned long ulReceived;
|
||||||
|
|
||||||
|
/* See if any of the queues in the set contain data. */
|
||||||
|
xActivatedQueue = xQueueSelectFromSetFromISR( xQueueSet );
|
||||||
|
|
||||||
|
if( xActivatedQueue != NULL )
|
||||||
|
{
|
||||||
|
/* Reading from the queue for test purposes only. */
|
||||||
|
if( xQueueReceiveFromISR( xActivatedQueue, &ulReceived, NULL ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* Data should have been available as the handle was returned from
|
||||||
|
xQueueSelectFromSetFromISR(). */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the value received was the value expected. */
|
||||||
|
prvCheckReceivedValue( ulReceived );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSendToQueueInSetFromISR( void )
|
||||||
|
{
|
||||||
|
static portBASE_TYPE xQueueToWriteTo = 0;
|
||||||
|
|
||||||
|
if( xQueueSendFromISR( xQueues[ xQueueToWriteTo ], ( void * ) &ulISRTxValue, NULL ) == pdPASS )
|
||||||
|
{
|
||||||
|
ulISRTxValue++;
|
||||||
|
|
||||||
|
/* If the Tx value has wrapped then set it back to its
|
||||||
|
initial value. */
|
||||||
|
if( ulISRTxValue == 0UL )
|
||||||
|
{
|
||||||
|
ulISRTxValue = queuesetINITIAL_ISR_TX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use a different queue next time. */
|
||||||
|
xQueueToWriteTo++;
|
||||||
|
if( xQueueToWriteTo >= queuesetNUM_QUEUES_IN_SET )
|
||||||
|
{
|
||||||
|
xQueueToWriteTo = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void prvSetupTest( xTaskHandle xQueueSetSendingTask )
|
||||||
|
{
|
||||||
|
portBASE_TYPE x;
|
||||||
|
xQueueSetMemberHandle xActivatedQueue;
|
||||||
|
|
||||||
|
/* Ensure the queues are created and the queue set configured before the
|
||||||
|
sending task is unsuspended.
|
||||||
|
|
||||||
|
First Create the queue set such that it will be able to hold a message for
|
||||||
|
every space in every queue in the set. */
|
||||||
|
xQueueSet = xQueueCreateSet( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH );
|
||||||
|
|
||||||
|
for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ )
|
||||||
|
{
|
||||||
|
/* Create the queue and add it to the set. The queue is just holding
|
||||||
|
unsigned long value. */
|
||||||
|
xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( unsigned long ) );
|
||||||
|
configASSERT( xQueues[ x ] );
|
||||||
|
if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdPASS )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The queue has now been added to the queue set and cannot be added to
|
||||||
|
another. */
|
||||||
|
if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdFAIL )
|
||||||
|
{
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to remove a queue from a queue set it does not belong
|
||||||
|
to (NULL being passed as the queue set in this case). */
|
||||||
|
if( xQueueRemoveFromSet( xQueues[ 0 ], NULL ) != pdFAIL )
|
||||||
|
{
|
||||||
|
/* It is not possible to successfully remove a queue from a queue
|
||||||
|
set it does not belong to. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to remove a queue from the queue set it does belong to. */
|
||||||
|
if( xQueueRemoveFromSet( xQueues[ 0 ], xQueueSet ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* It should be possible to remove the queue from the queue set it
|
||||||
|
does belong to. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the queue back again before starting the dynamic tests. */
|
||||||
|
if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdPASS )
|
||||||
|
{
|
||||||
|
/* If the queue was successfully removed from the queue set then it
|
||||||
|
should be possible to add it back in again. */
|
||||||
|
xQueueSetTasksStatus = pdFAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The task that sends to the queues is not running yet, so attempting to
|
||||||
|
read from the queue set should fail, resulting in xActivatedQueue being set
|
||||||
|
to NULL. */
|
||||||
|
xActivatedQueue = xQueueSelectFromSet( xQueueSet, queuesetSHORT_DELAY );
|
||||||
|
configASSERT( xActivatedQueue == NULL );
|
||||||
|
|
||||||
|
/* Resume the task that writes to the queues. */
|
||||||
|
vTaskResume( xQueueSetSendingTask );
|
||||||
|
|
||||||
|
/* Let the ISR access the queues also. */
|
||||||
|
xSetupComplete = pdTRUE;
|
||||||
|
}
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
|
|
||||||
void vStartQueueSetTasks( void );
|
void vStartQueueSetTasks( void );
|
||||||
portBASE_TYPE xAreQueueSetTasksStillRunning( void );
|
portBASE_TYPE xAreQueueSetTasksStillRunning( void );
|
||||||
void vQueueSetWriteToQueueFromISR( void );
|
void vQueueSetAccessQueueSetFromISR( void );
|
||||||
|
|
||||||
#endif /* QUEUE_WAIT_MULTIPLE_H */
|
#endif /* QUEUE_WAIT_MULTIPLE_H */
|
||||||
|
|
||||||
|
@ -92,7 +92,6 @@
|
|||||||
#define configIDLE_SHOULD_YIELD 1
|
#define configIDLE_SHOULD_YIELD 1
|
||||||
#define configUSE_CO_ROUTINES 0
|
#define configUSE_CO_ROUTINES 0
|
||||||
#define configUSE_MUTEXES 1
|
#define configUSE_MUTEXES 1
|
||||||
#define configGENERATE_RUN_TIME_STATS 0
|
|
||||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||||
#define configUSE_RECURSIVE_MUTEXES 1
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
#define configQUEUE_REGISTRY_SIZE 0
|
#define configQUEUE_REGISTRY_SIZE 0
|
||||||
@ -111,6 +110,13 @@
|
|||||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||||
|
|
||||||
|
|
||||||
|
/* Run time stats gathering definitions. */
|
||||||
|
unsigned long ulGetRunTimeCounterValue( void );
|
||||||
|
void vConfigureTimerForRunTimeStats( void );
|
||||||
|
#define configGENERATE_RUN_TIME_STATS 1
|
||||||
|
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats()
|
||||||
|
#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue()
|
||||||
|
|
||||||
/* Co-routine definitions. */
|
/* Co-routine definitions. */
|
||||||
#define configUSE_CO_ROUTINES 0
|
#define configUSE_CO_ROUTINES 0
|
||||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||||
@ -140,5 +146,7 @@ version of the Win32 simulator projects. It will be ignored in the GCC
|
|||||||
version. */
|
version. */
|
||||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||||
|
|
||||||
|
/* Include the FreeRTOS+Trace recorder hooks. */
|
||||||
|
#include "trcHooks.h"
|
||||||
|
|
||||||
#endif /* FREERTOS_CONFIG_H */
|
#endif /* FREERTOS_CONFIG_H */
|
||||||
|
143
FreeRTOS/Demo/WIN32-MSVC/Run-time-stats-utils.c
Normal file
143
FreeRTOS/Demo/WIN32-MSVC/Run-time-stats-utils.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.
|
||||||
|
|
||||||
|
FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME. PLEASE VISIT
|
||||||
|
http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* FreeRTOS tutorial books are available in pdf and paperback. *
|
||||||
|
* Complete, revised, and edited pdf reference manuals are also *
|
||||||
|
* available. *
|
||||||
|
* *
|
||||||
|
* Purchasing FreeRTOS documentation will not only help you, by *
|
||||||
|
* ensuring you get running as quickly as possible and with an *
|
||||||
|
* in-depth knowledge of how to use FreeRTOS, it will also help *
|
||||||
|
* the FreeRTOS project to continue with its mission of providing *
|
||||||
|
* professional grade, cross platform, de facto standard solutions *
|
||||||
|
* for microcontrollers - completely free of charge! *
|
||||||
|
* *
|
||||||
|
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
|
||||||
|
* *
|
||||||
|
* Thank you for using FreeRTOS, and thank you for your support! *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
This file is part of the FreeRTOS distribution.
|
||||||
|
|
||||||
|
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License (version 2) as published by the
|
||||||
|
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
|
||||||
|
>>>NOTE<<< The modification to the GPL is included to allow you to
|
||||||
|
distribute a combined work that includes FreeRTOS without being obliged to
|
||||||
|
provide the source code for proprietary components outside of the FreeRTOS
|
||||||
|
kernel. FreeRTOS is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||||
|
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
more details. You should have received a copy of the GNU General Public
|
||||||
|
License and the FreeRTOS license exception along with FreeRTOS; if not it
|
||||||
|
can be viewed here: http://www.freertos.org/a00114.html and also obtained
|
||||||
|
by writing to Richard Barry, contact details for whom are available on the
|
||||||
|
FreeRTOS WEB site.
|
||||||
|
|
||||||
|
1 tab == 4 spaces!
|
||||||
|
|
||||||
|
***************************************************************************
|
||||||
|
* *
|
||||||
|
* Having a problem? Start by reading the FAQ "My application does *
|
||||||
|
* not run, what could be wrong?" *
|
||||||
|
* *
|
||||||
|
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||||
|
* *
|
||||||
|
***************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org - Documentation, training, latest versions, license
|
||||||
|
and contact details.
|
||||||
|
|
||||||
|
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||||
|
including FreeRTOS+Trace - an indispensable productivity tool.
|
||||||
|
|
||||||
|
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
|
||||||
|
the code with commercial support, indemnification, and middleware, under
|
||||||
|
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
|
||||||
|
provide a safety engineered and independently SIL3 certified version under
|
||||||
|
the SafeRTOS brand: http://www.SafeRTOS.com.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Utility functions required to gather run time statistics. See:
|
||||||
|
* http://www.freertos.org/rtos-run-time-stats.html
|
||||||
|
*
|
||||||
|
* Note that this is a simulated port, where simulated time is a lot slower than
|
||||||
|
* real time, therefore the run time counter values have no real meaningful
|
||||||
|
* units.
|
||||||
|
*
|
||||||
|
* Also note that it is assumed this demo is going to be used for short periods
|
||||||
|
* of time only, and therefore timer overflows are not handled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FreeRTOS includes. */
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
|
||||||
|
/* FreeRTOS+Trace includes. */
|
||||||
|
#include "trcUser.h"
|
||||||
|
|
||||||
|
/* Variables used in the creation of the run time stats time base. Run time
|
||||||
|
stats record how much time each task spends in the Running state. */
|
||||||
|
static long long llInitialRunTimeCounterValue = 0LL, llTicksPerHundedthMillisecond = 0LL;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
void vConfigureTimerForRunTimeStats( void )
|
||||||
|
{
|
||||||
|
LARGE_INTEGER liPerformanceCounterFrequency, liInitialRunTimeValue;
|
||||||
|
|
||||||
|
/* Initialise the variables used to create the run time stats time base.
|
||||||
|
Run time stats record how much time each task spends in the Running
|
||||||
|
state. */
|
||||||
|
|
||||||
|
if( QueryPerformanceFrequency( &liPerformanceCounterFrequency ) == 0 )
|
||||||
|
{
|
||||||
|
llTicksPerHundedthMillisecond = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* How many times does the performance counter increment in 1/100th
|
||||||
|
millisecond. */
|
||||||
|
llTicksPerHundedthMillisecond = liPerformanceCounterFrequency.QuadPart / 100000LL;
|
||||||
|
|
||||||
|
/* What is the performance counter value now, this will be subtracted
|
||||||
|
from readings taken at run time. */
|
||||||
|
QueryPerformanceCounter( &liInitialRunTimeValue );
|
||||||
|
llInitialRunTimeCounterValue = liInitialRunTimeValue.QuadPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
unsigned long ulGetRunTimeCounterValue( void )
|
||||||
|
{
|
||||||
|
LARGE_INTEGER liCurrentCount;
|
||||||
|
unsigned long ulReturn;
|
||||||
|
|
||||||
|
/* What is the performance counter value now? */
|
||||||
|
QueryPerformanceCounter( &liCurrentCount );
|
||||||
|
|
||||||
|
/* Subtract the performance counter value reading taken when the
|
||||||
|
application started to get a count from that reference point, then
|
||||||
|
scale to (simulated) 1/100ths of a millisecond. */
|
||||||
|
if( llTicksPerHundedthMillisecond == 0 )
|
||||||
|
{
|
||||||
|
/* The trace macros are probably calling this function before the
|
||||||
|
scheduler has been started. */
|
||||||
|
ulReturn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulReturn = ( unsigned long ) ( ( liCurrentCount.QuadPart - llInitialRunTimeCounterValue ) / llTicksPerHundedthMillisecond );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ulReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
@ -0,0 +1,411 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* FreeRTOS+Trace v2.2.2 Recorder Library
|
||||||
|
* Percepio AB, www.percepio.se
|
||||||
|
*
|
||||||
|
* trcConfig.h
|
||||||
|
*
|
||||||
|
* Configuration parameters for the trace recorder library. Before using the
|
||||||
|
* trace recorder library, please check that the default settings are
|
||||||
|
* appropriate for your system, and if necessary adjust these. Most likely, you
|
||||||
|
* will need to adjust the NTask, NISR, NQueue, NMutex and NSemaphore values to
|
||||||
|
* reflect the number of such objects in your system. These may be
|
||||||
|
* overapproximated, although larger values values implies more RAM usage.
|
||||||
|
*
|
||||||
|
* Terms of Use
|
||||||
|
* This software is copyright Percepio AB. The recorder library is free for
|
||||||
|
* use together with Percepio products. You may distribute the recorder library
|
||||||
|
* in its original form, including modifications in trcPort.c and trcPort.h
|
||||||
|
* given that these modification are clearly marked as your own modifications
|
||||||
|
* and documented in the initial comment section of these source files.
|
||||||
|
* This software is the intellectual property of Percepio AB and may not be
|
||||||
|
* sold or in other ways commercially redistributed without explicit written
|
||||||
|
* permission by Percepio AB.
|
||||||
|
*
|
||||||
|
* Disclaimer
|
||||||
|
* The trace tool and recorder library is being delivered to you AS IS and
|
||||||
|
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
|
||||||
|
* not and cannot warrant the performance or results you may obtain by using the
|
||||||
|
* software or documentation. Percepio AB make no warranties, express or
|
||||||
|
* implied, as to noninfringement of third party rights, merchantability, or
|
||||||
|
* fitness for any particular purpose. In no event will Percepio AB, its
|
||||||
|
* technology partners, or distributors be liable to you for any consequential,
|
||||||
|
* incidental or special damages, including any lost profits or lost savings,
|
||||||
|
* even if a representative of Percepio AB has been advised of the possibility
|
||||||
|
* of such damages, or for any claim by any third party. Some jurisdictions do
|
||||||
|
* not allow the exclusion or limitation of incidental, consequential or special
|
||||||
|
* damages, or the exclusion of implied warranties or limitations on how long an
|
||||||
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
|
*
|
||||||
|
* FreeRTOS+Trace is available as Free Edition and in two premium editions.
|
||||||
|
* You may use the premium features during 30 days for evaluation.
|
||||||
|
* Download FreeRTOS+Trace at http://www.percepio.se/index.php?page=downloads
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2012.
|
||||||
|
* www.percepio.se
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TRCCONFIG_H
|
||||||
|
#define TRCCONFIG_H
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CONFIGURATION RELATED TO CAPACITY AND ALLOCATION
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* EVENT_BUFFER_SIZE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
*
|
||||||
|
* This defines the capacity of the event buffer, i.e., the number of records
|
||||||
|
* it may store. Each registered event typically use one record (4 byte), but
|
||||||
|
* vTracePrintF may use multiple records depending on the number of data args.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#if WIN32
|
||||||
|
#define EVENT_BUFFER_SIZE 3000
|
||||||
|
#else
|
||||||
|
#define EVENT_BUFFER_SIZE 1000 /* Adjust wrt. to available RAM */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* SYMBOL_TABLE_SIZE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value.
|
||||||
|
*
|
||||||
|
* This defines the capacity of the symbol table, in bytes. This symbol table
|
||||||
|
* stores User Events labels and names of deleted tasks, queues, or other kernel
|
||||||
|
* objects. Note that the names of active objects not stored here but in the
|
||||||
|
* Object Table. Thus, if you don't use User Events or delete any kernel
|
||||||
|
* objects you set this to zero (0) to minimize RAM usage.
|
||||||
|
******************************************************************************/
|
||||||
|
#define SYMBOL_TABLE_SIZE 1000
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* NTask, NISR, NQueue, NSemaphore, NMutex
|
||||||
|
*
|
||||||
|
* A group of Macros which should be defined as an integer value of zero (0)
|
||||||
|
* or larger.
|
||||||
|
*
|
||||||
|
* This defines the capacity of the Object Property Table - the maximum number
|
||||||
|
* of objects active at any given point within each object class.
|
||||||
|
*
|
||||||
|
* NOTE: In case objects are deleted and created during runtime, this setting
|
||||||
|
* does not limit the total amount of objects, only the number of concurrently
|
||||||
|
* active objects.
|
||||||
|
*
|
||||||
|
* Using too small values will give an error message through the vTraceError
|
||||||
|
* routine, which makes the error message appear when opening the trace data
|
||||||
|
* in FreeRTOS+Trace. If you are using the recorder status monitor task,
|
||||||
|
* any error messages are displayed in console prints, assuming that the
|
||||||
|
* print macro has been defined properly (vConsolePrintMessage).
|
||||||
|
*
|
||||||
|
* NOTE 2: If you include the monitor task (USE_TRACE_PROGRESS_MONITOR_TASK)
|
||||||
|
* make sure to dimension NTask with this task accounted for.
|
||||||
|
*
|
||||||
|
* Also remember to account for all tasks created by FreeRTOS, such as the
|
||||||
|
* IDLE task, the FreeRTOS timer task, and any tasks created by other 3rd party
|
||||||
|
* software components, such as communication stacks.
|
||||||
|
* Moreover, one task slot is used to indicate "(startup)", i.e., a "task" that
|
||||||
|
* represent the time before the first task starts. NTask should thus be at
|
||||||
|
* least 2-3 slots larger than your application task count.
|
||||||
|
*
|
||||||
|
* NOTE 3: The FreeRTOS timer task creates a Queue, that should be accounted
|
||||||
|
* for in NQueue.
|
||||||
|
******************************************************************************/
|
||||||
|
#define NTask 500
|
||||||
|
#define NISR 500
|
||||||
|
#define NQueue 500
|
||||||
|
#define NSemaphore 500
|
||||||
|
#define NMutex 500
|
||||||
|
|
||||||
|
/* Maximum object name length for each class (includes zero termination) */
|
||||||
|
#define NameLenTask configMAX_TASK_NAME_LEN
|
||||||
|
#define NameLenISR 10
|
||||||
|
#define NameLenQueue 15
|
||||||
|
#define NameLenSemaphore 15
|
||||||
|
#define NameLenMutex 15
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_DESCRIPTION
|
||||||
|
*
|
||||||
|
* Macro which should be defined as a string.
|
||||||
|
*
|
||||||
|
* This string is stored in the trace and displayed in FreeRTOS+Trace. Can be
|
||||||
|
* used to store, e.g., system version or build date. This is also used to store
|
||||||
|
* internal error messages from the recorder, which if occurs overwrites the
|
||||||
|
* value defined here. This may be maximum 256 chars.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRACE_DESCRIPTION "FreeRTOS+Trace Demo"
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_DESCRIPTION_MAX_LENGTH
|
||||||
|
*
|
||||||
|
* The maximum length (including zero termination) for the TRACE_DESCRIPTION
|
||||||
|
* string. Since this string also is used for internal error messages from the
|
||||||
|
* recorder do not make it too short, as this may truncate the error messages.
|
||||||
|
* Default is 80.
|
||||||
|
* Maximum allowed length is 256 - the trace will fail to load if longer.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRACE_DESCRIPTION_MAX_LENGTH 80
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_DATA_ALLOCATION
|
||||||
|
*
|
||||||
|
* This defines how to allocate the recorder data structure, i.e., using a
|
||||||
|
* static declaration or using a dynamic allocation in runtime (malloc).
|
||||||
|
*
|
||||||
|
* Should be one of these two options:
|
||||||
|
* - TRACE_DATA_ALLOCATION_STATIC (default)
|
||||||
|
* - TRACE_DATA_ALLOCATION_DYNAMIC
|
||||||
|
*
|
||||||
|
* Using static allocation has the benefits of compile-time errors if the buffer
|
||||||
|
* is too large (too large constants in trcConfig.h) and no need to call the
|
||||||
|
* initialization routine (xTraceInitTraceData).
|
||||||
|
*
|
||||||
|
* Using dynamic allocation may give more flexibility in some cases.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define TRACE_DATA_ALLOCATION TRACE_DATA_ALLOCATION_STATIC
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* CONFIGURATION REGARDING WHAT CODE/FEATURES TO INCLUDE
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_USER_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
* Default is 1.
|
||||||
|
*
|
||||||
|
* If this is zero (0) the code for creating User Events is excluded to
|
||||||
|
* reduce code size. User Events are application-generated events, like
|
||||||
|
* "printf" but for the trace log instead of console output. User Events are
|
||||||
|
* much faster than a printf and can therefore be used in timing critical code.
|
||||||
|
* See vTraceUserEvent() and vTracePrintF() in trcUser.h
|
||||||
|
*
|
||||||
|
* Note that FreeRTOS+Trace Standard Edition or Professional Edition is required
|
||||||
|
* for User Events, they are not displayed in FreeRTOS+Trace Free Edition.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_USER_EVENTS 1
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* INCLUDE_ISR_TRACING
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
* Default is 1.
|
||||||
|
*
|
||||||
|
* If this is zero (0), the code for recording Interrupt Service Routines is
|
||||||
|
* excluded to reduce code size. Note, recording ISRs require that you insert
|
||||||
|
* calls to vTraceStoreISRBegin and vTraceStoreISREnd in your interrupt handlers.
|
||||||
|
* There is no automatic recording of ISRs like for task scheduling, since
|
||||||
|
* FreeRTOS does not have a central interrupt dispatcher.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_ISR_TRACING 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_OBJECT_DELETE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
* Default is 1.
|
||||||
|
*
|
||||||
|
* This must be enabled (1) if tasks, queues or other
|
||||||
|
* traced kernel objects are deleted at runtime, e.g., using vTaskDelete or
|
||||||
|
* vQueueDelete. If no deletes are made, this can be set to 0 in order to
|
||||||
|
* exclude the delete-handling code.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define INCLUDE_OBJECT_DELETE 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* CONFIGURATION RELATED TO BEHAVIOR
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* RECORDER_STORE_MODE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as one of:
|
||||||
|
* - STORE_MODE_RING_BUFFER
|
||||||
|
* - STORE_MODE_STOP_WHEN_FULL
|
||||||
|
* Default is STORE_MODE_RING_BUFFER.
|
||||||
|
*
|
||||||
|
* With RECORDER_STORE_MODE set to STORE_MODE_RING_BUFFER, the events are stored
|
||||||
|
* in a ring buffer, i.e., where the oldest events are overwritten when the
|
||||||
|
* buffer becomes full. This allows you to get the last events leading up to an
|
||||||
|
* interesting state, e.g., an error, without having a large trace buffer for
|
||||||
|
* string the whole run since startup. In this mode, the recorder can run
|
||||||
|
* "forever" as the buffer never gets full, i.e., in the sense that it always
|
||||||
|
* has room for more events.
|
||||||
|
*
|
||||||
|
* To fetch the trace in mode STORE_MODE_RING_BUFFER, you need to first halt the
|
||||||
|
* system using your debugger and then do a RAM dump, or to explicitly stop the
|
||||||
|
* recorder using vTraceStop() and then store/upload the trace data using a
|
||||||
|
* FreeRTOS task that you need to provide yourself. The trace data is found in
|
||||||
|
* the struct RecorderData, initialized in trcBase.c.
|
||||||
|
*
|
||||||
|
* Note that, if you upload the trace using a RAM dump, i.e., when the system is
|
||||||
|
* halted on a breakpoint or by a debugger command, there is no need to stop the
|
||||||
|
* recorder first.
|
||||||
|
*
|
||||||
|
* When RECORDER_STORE_MODE is STORE_MODE_STOP_WHEN_FULL, the recording is
|
||||||
|
* stopped when the buffer becomes full. When the recorder stops itself this way
|
||||||
|
* vTracePortEnd() is called which allows for custom actions, such as triggering
|
||||||
|
* a task that stores the trace buffer, i.e., in case taking a RAM dump
|
||||||
|
* using an on-chip debugger is not possible. In the Windows port, vTracePortEnd
|
||||||
|
* saves the trace to file directly, but this is not recommended in a real-time
|
||||||
|
* system since the scheduler is blocked during the processing of vTracePortEnd.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define RECORDER_STORE_MODE STORE_MODE_RING_BUFFER
|
||||||
|
/*#define RECORDER_STORE_MODE STORE_MODE_STOP_WHEN_FULL*/
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* STOP_AFTER_N_EVENTS
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer value, or not defined.
|
||||||
|
* Default is -1
|
||||||
|
*
|
||||||
|
* STOP_AFTER_N_EVENTS is intended for tests of the ring buffer mode (when
|
||||||
|
* RECORDER_STORE_MODE is STORE_MODE_RING_BUFFER). It stops the recording when
|
||||||
|
* the specified number of events has been observed. This value can be larger
|
||||||
|
* than the buffer size, to allow for test of the "wrapping around" that occurs
|
||||||
|
* in ring buffer mode . A negative value (or no definition of this macro)
|
||||||
|
* disables this feature.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define STOP_AFTER_N_EVENTS -1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* USE_IMPLICIT_IFE_RULES
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
* Default is 1.
|
||||||
|
*
|
||||||
|
* ### Instance Finish Events (IFE) ###
|
||||||
|
*
|
||||||
|
* For tasks with "infinite" main loops (non-terminating tasks), the concept
|
||||||
|
* of a task instance has no clear definition, it is an application-specific
|
||||||
|
* thing. FreeRTOS+Trace allows you to define Instance Finish Events (IFEs),
|
||||||
|
* which marks the point in a cyclic task when the "task instance" ends.
|
||||||
|
* The IFE is a blocking kernel call, typically in the main loop of a task
|
||||||
|
* which typically reads a message queue, waits for a semaphore or performs
|
||||||
|
* an explicit delay.
|
||||||
|
*
|
||||||
|
* If USE_IMPLICIT_IFE_RULES is one (1), the following FreeRTOS kernel calls
|
||||||
|
* are considered by default to be IFEs (Implicit IFEs):
|
||||||
|
* - vTaskDelay
|
||||||
|
* - vTaskDelayUntil
|
||||||
|
* - vTaskSuspend
|
||||||
|
* - xQueueReceive (blocking cases only)
|
||||||
|
* - xSemaphoreTake (blocking cases only)
|
||||||
|
*
|
||||||
|
* However, Implicit IFEs only applies to blocking kernel calls. If an
|
||||||
|
* xQueueReceive reads a message without blocking, it does not create a new
|
||||||
|
* instance since no blocking occurred.
|
||||||
|
*
|
||||||
|
* Moreover, the actual IFE might sometimes be another blocking call such as
|
||||||
|
* xQueueSend or xSemaphoreGive. We therefore allow for user-defined
|
||||||
|
* Explicit IFEs by calling
|
||||||
|
*
|
||||||
|
* vTraceTaskInstanceIsFinished()
|
||||||
|
*
|
||||||
|
* right before the kernel call considered as IFE. This does not create an
|
||||||
|
* additional event but instead stores the service code and object handle
|
||||||
|
* of the IFE call as properties of the task.
|
||||||
|
*
|
||||||
|
* If using Explicit IFEs and the task also calls an Implicit IFE like
|
||||||
|
* vTaskDelay, this may result in additional incorrect task instances.
|
||||||
|
* This is solved by disabling the Implicit IFEs for the task, by adding
|
||||||
|
* a call to
|
||||||
|
*
|
||||||
|
* vTraceTaskSkipDefaultInstanceFinishedEvents()
|
||||||
|
*
|
||||||
|
* in the very beginning of that task. This allows you to combine Explicit IFEs
|
||||||
|
* for some tasks with Implicit IFEs for the rest of the tasks, if
|
||||||
|
* USE_IMPLICIT_IFE_RULES is 1.
|
||||||
|
*
|
||||||
|
* By setting USE_IMPLICIT_IFE_RULES to zero (0), the implicit IFEs are disabled
|
||||||
|
* for all tasks. Tasks will then be considered to have a single instance only,
|
||||||
|
* covering all execution fragments, unless you define an explicit IFE in each
|
||||||
|
* task by calling vTraceTaskInstanceIsFinished before the blocking call.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define USE_IMPLICIT_IFE_RULES 1
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* INCLUDE_SAVE_TO_FILE
|
||||||
|
*
|
||||||
|
* Macro which should be defined as either zero (0) or one (1).
|
||||||
|
* Default is 0.
|
||||||
|
*
|
||||||
|
* If enabled (1), the recorder will include code for saving the trace
|
||||||
|
* to a local file system.
|
||||||
|
******************************************************************************/
|
||||||
|
#ifdef WIN32
|
||||||
|
#define INCLUDE_SAVE_TO_FILE 1
|
||||||
|
#else
|
||||||
|
#define INCLUDE_SAVE_TO_FILE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_PROGRESS_MONITOR_TASK_PRIORITY
|
||||||
|
*
|
||||||
|
* Macro which sets the priority of the "recorder status monitor" task.
|
||||||
|
*
|
||||||
|
* This task, vTraceMonitorTask in trcUser.c, periodically writes
|
||||||
|
* the recorder status using the vTraceConsoleMessage macro, which is to
|
||||||
|
* be mapped to your console "printf" routine. The task is named TraceMon but
|
||||||
|
* is intentionally excluded from the demo trace.
|
||||||
|
*
|
||||||
|
* Default is tskIDLE_PRIORITY + 1
|
||||||
|
* Note that if your system constantly has a high CPU load from high-priority
|
||||||
|
* tasks, this might not be get a chance to execute.
|
||||||
|
*
|
||||||
|
* See vTraceMonitorTask in trcUser.c
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRACE_PROGRESS_MONITOR_TASK_PRIORITY (tskIDLE_PRIORITY + 3)
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_PROGRESS_MONITOR_TASK_STACKSIZE
|
||||||
|
*
|
||||||
|
* Macro which sets the stack size of the "recorder status monitor" task.
|
||||||
|
*
|
||||||
|
* This task, vTraceMonitorTask in trcUser.c, periodically writes
|
||||||
|
* the recorder status using the vTraceConsoleMessage macro, which is to
|
||||||
|
* be mapped to your console "printf" routine. The task is intentionally
|
||||||
|
* excluded from the demo trace.
|
||||||
|
*
|
||||||
|
* See vTraceMonitorTask in trcUser.c
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TRACE_PROGRESS_MONITOR_TASK_STACKSIZE 500
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TRACE_PROGRESS_MONITOR_TASK_PERIOD
|
||||||
|
*
|
||||||
|
* Macro which sets the period of the "recorder status monitor" task.
|
||||||
|
*
|
||||||
|
* This task, vTraceMonitorTask in trcUser.c, periodically writes
|
||||||
|
* the recorder status using the vTraceConsoleMessage macro, which is to
|
||||||
|
* be mapped to your console "printf" routine. The task is named TraceMon but
|
||||||
|
* is intentionally excluded from the demo trace.
|
||||||
|
*
|
||||||
|
* Default is 1000 FreeRTOS ticks (typically 1 second). On the Windows port, a
|
||||||
|
* lower value is suggested since the Windows port runs very slowly, often 20-40
|
||||||
|
* times slower than the simulated FreeRTOS time.
|
||||||
|
*
|
||||||
|
* See vTraceMonitorTask in trcUser.c
|
||||||
|
*****************************************************************************/
|
||||||
|
#if WIN32
|
||||||
|
#define TRACE_PROGRESS_MONITOR_TASK_PERIOD 100
|
||||||
|
#else
|
||||||
|
#define TRACE_PROGRESS_MONITOR_TASK_PERIOD 1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* TEAM_LICENSE_CODE
|
||||||
|
*
|
||||||
|
* Macro which defines a string - the team license code.
|
||||||
|
* If no team license is available, this should be an empty string "".
|
||||||
|
* This should be maximum 32 chars, including zero-termination.
|
||||||
|
*****************************************************************************/
|
||||||
|
#define TEAM_LICENSE_CODE ""
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
492
FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcPort.h
Normal file
492
FreeRTOS/Demo/WIN32-MSVC/Trace_Recorder_Configuration/trcPort.h
Normal file
@ -0,0 +1,492 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* FreeRTOS+Trace v2.3.0 Recorder Library
|
||||||
|
* Percepio AB, www.percepio.com
|
||||||
|
*
|
||||||
|
* trcPort.h
|
||||||
|
*
|
||||||
|
* Contains together with trcPort.c all portability issues of the trace recorder
|
||||||
|
* library.
|
||||||
|
*
|
||||||
|
* Terms of Use
|
||||||
|
* This software is copyright Percepio AB. The recorder library is free for
|
||||||
|
* use together with Percepio products. You may distribute the recorder library
|
||||||
|
* in its original form, including modifications in trcPort.c and trcPort.h
|
||||||
|
* given that these modification are clearly marked as your own modifications
|
||||||
|
* and documented in the initial comment section of these source files.
|
||||||
|
* This software is the intellectual property of Percepio AB and may not be
|
||||||
|
* sold or in other ways commercially redistributed without explicit written
|
||||||
|
* permission by Percepio AB.
|
||||||
|
*
|
||||||
|
* Disclaimer
|
||||||
|
* The trace tool and recorder library is being delivered to you AS IS and
|
||||||
|
* Percepio AB makes no warranty as to its use or performance. Percepio AB does
|
||||||
|
* not and cannot warrant the performance or results you may obtain by using the
|
||||||
|
* software or documentation. Percepio AB make no warranties, express or
|
||||||
|
* implied, as to noninfringement of third party rights, merchantability, or
|
||||||
|
* fitness for any particular purpose. In no event will Percepio AB, its
|
||||||
|
* technology partners, or distributors be liable to you for any consequential,
|
||||||
|
* incidental or special damages, including any lost profits or lost savings,
|
||||||
|
* even if a representative of Percepio AB has been advised of the possibility
|
||||||
|
* of such damages, or for any claim by any third party. Some jurisdictions do
|
||||||
|
* not allow the exclusion or limitation of incidental, consequential or special
|
||||||
|
* damages, or the exclusion of implied warranties or limitations on how long an
|
||||||
|
* implied warranty may last, so the above limitations may not apply to you.
|
||||||
|
*
|
||||||
|
* FreeRTOS+Trace is available as Free Edition and in two premium editions.
|
||||||
|
* You may use the premium features during 30 days for evaluation.
|
||||||
|
* Download FreeRTOS+Trace at http://www.percepio.com/products/downloads/
|
||||||
|
*
|
||||||
|
* Copyright Percepio AB, 2012.
|
||||||
|
* www.percepio.com
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#ifndef TRCPORT_H
|
||||||
|
#define TRCPORT_H
|
||||||
|
|
||||||
|
/* If FreeRTOS Win32 port */
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#define _WIN32_WINNT 0x0600
|
||||||
|
|
||||||
|
/* Standard includes. */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <windows.h>
|
||||||
|
#include <direct.h>
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* The Win32 port by default saves the trace to file and then kills the
|
||||||
|
* program when the recorder is stopped, to facilitate quick, simple tests
|
||||||
|
* of the recorder.
|
||||||
|
******************************************************************************/
|
||||||
|
#define WIN32_PORT_SAVE_WHEN_STOPPED 1
|
||||||
|
#define WIN32_PORT_EXIT_WHEN_STOPPED 1
|
||||||
|
#else
|
||||||
|
#define WIN32_PORT_SAVE_WHEN_STOPPED 0
|
||||||
|
#define WIN32_PORT_EXIT_WHEN_STOPPED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DIRECTION_INCREMENTING 1
|
||||||
|
#define DIRECTION_DECREMENTING 2
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Supported ports
|
||||||
|
*
|
||||||
|
* PORT_HWIndependent
|
||||||
|
* A hardware independent fallback option for event timestamping. Provides low
|
||||||
|
* resolution timestamps based on the OS tick.
|
||||||
|
* This may be used on the Win32 port, but may also be used on embedded hardware
|
||||||
|
* platforms. Note that this gives suboptimal display in FreeRTOS+Trace. All
|
||||||
|
* time durations will be truncated to the OS tick frequency, typically 1 KHz.
|
||||||
|
* This means that a task or ISR that executes in less than 1 ms get an exection
|
||||||
|
* time of zero. They are however still visible in FreeRTOS+Trace.
|
||||||
|
*
|
||||||
|
* PORT_Win32
|
||||||
|
* "Accurate" timestamping based on the Windows permance counter. Note that
|
||||||
|
* this gives the host machine time, not the simulated FreeRTOS time (tick
|
||||||
|
* count). The timing of the Win32 FreeRTOS build is not real-time, since it
|
||||||
|
* depends on the scheduling and tick rate of Windows, which is very slow.
|
||||||
|
*
|
||||||
|
* Officially supported hardware timer ports:
|
||||||
|
* - PORT_Atmel_AT91SAM7
|
||||||
|
* - PORT_Atmel_UC3A0
|
||||||
|
* - PORT_ARM_CortexM
|
||||||
|
* - PORT_Renesas_RX600
|
||||||
|
* - PORT_Microchip_dsPIC_AND_PIC24
|
||||||
|
*
|
||||||
|
* We also provide several "unofficial" hardware-specific ports. There have
|
||||||
|
* been developed by external contributors, and have not yet been verified
|
||||||
|
* by Percepio AB. Let us know if you have problems getting these to work.
|
||||||
|
*
|
||||||
|
* Unoffical hardware specific ports provided are:
|
||||||
|
* - PORT_TEXAS_INSTRUMENTS_TMS570
|
||||||
|
* - PORT_TEXAS_INSTRUMENTS_MSP430
|
||||||
|
* - PORT_MICROCHIP_PIC32
|
||||||
|
* - PORT_XILINX_PPC405
|
||||||
|
* - PORT_XILINX_PPC440
|
||||||
|
* - PORT_XILINX_MICROBLAZE
|
||||||
|
* - PORT_NXP_LPC210X
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define PORT_NOT_SET -1
|
||||||
|
|
||||||
|
/*** Officially supported hardware timer ports *******************************/
|
||||||
|
#define PORT_HWIndependent 0
|
||||||
|
#define PORT_Win32 1
|
||||||
|
#define PORT_Atmel_AT91SAM7 2
|
||||||
|
#define PORT_Atmel_UC3A0 3
|
||||||
|
#define PORT_ARM_CortexM 4
|
||||||
|
#define PORT_Renesas_RX600 5
|
||||||
|
#define PORT_Microchip_dsPIC_AND_PIC24 6
|
||||||
|
|
||||||
|
/*** Unofficial ports, provided by external developers, not yet verified *****/
|
||||||
|
#define PORT_TEXAS_INSTRUMENTS_TMS570 7
|
||||||
|
#define PORT_TEXAS_INSTRUMENTS_MSP430 8
|
||||||
|
#define PORT_MICROCHIP_PIC32 9
|
||||||
|
#define PORT_XILINX_PPC405 10
|
||||||
|
#define PORT_XILINX_PPC440 11
|
||||||
|
#define PORT_XILINX_MICROBLAZE 12
|
||||||
|
#define PORT_NXP_LPC210X 13
|
||||||
|
|
||||||
|
/*** Select your port here! **************************************************/
|
||||||
|
#define SELECTED_PORT PORT_Win32
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
#if (SELECTED_PORT == PORT_NOT_SET)
|
||||||
|
#error "You need to define SELECTED_PORT here!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* IRQ_PRIORITY_ORDER
|
||||||
|
*
|
||||||
|
* Macro which should be defined as an integer of 0 or 1.
|
||||||
|
*
|
||||||
|
* This should be 0 if lower irq priority values implies higher priority
|
||||||
|
* levels, such as on ARM Cortex M. If the opposite scheme is used, i.e.,
|
||||||
|
* if higher irq priority values means higher priority, this should be 1.
|
||||||
|
*
|
||||||
|
* This setting is not critical. It is used only to sort and colorize the
|
||||||
|
* interrupts in priority order, in case you record interrupts using
|
||||||
|
* the vTraceStoreISRBegin and vTraceStoreISREnd routines.
|
||||||
|
*
|
||||||
|
* We provide this setting for some hardware architectures below:
|
||||||
|
* - ARM Cortex M: 0 (lower irq priority values are more significant)
|
||||||
|
* - Atmel AT91SAM7x: 1 (higher irq priority values are more significant)
|
||||||
|
* - Atmel AVR32: 1 (higher irq priority values are more significant)
|
||||||
|
* - Renesas RX600: 1 (higher irq priority values are more significant)
|
||||||
|
* - Microchip PIC24: 0 (lower irq priority values are more significant)
|
||||||
|
* - Microchip dsPIC: 0 (lower irq priority values are more significant)
|
||||||
|
* - TI TMS570: 0 (lower irq priority values are more significant)
|
||||||
|
* - Freescale HCS08: 0 (lower irq priority values are more significant)
|
||||||
|
* - Freescale HCS12: 0 (lower irq priority values are more significant)
|
||||||
|
* - PowerPC 405: 0 (lower irq priority values are more significant)
|
||||||
|
* - PowerPC 440: 0 (lower irq priority values are more significant)
|
||||||
|
* - Freescale ColdFire: 1 (higher irq priority values are more significant)
|
||||||
|
* - NXP LPC210x: 0 (lower irq priority values are more significant)
|
||||||
|
* - MicroBlaze: 0 (lower irq priority values are more significant)
|
||||||
|
*
|
||||||
|
* If your chip is not on the above list, and you perhaps know this detail by
|
||||||
|
* heart, please inform us by e-mail to support@percepio.com.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*
|
||||||
|
* HWTC Macros
|
||||||
|
*
|
||||||
|
* These four HWTC macros provides a hardware isolation layer representing a
|
||||||
|
* generic hardware timer/counter used for driving the operating system tick,
|
||||||
|
* such as the SysTick feature of ARM Cortex M3/M4, or the PIT of the Atmel
|
||||||
|
* AT91SAM7X.
|
||||||
|
*
|
||||||
|
* HWTC_COUNT: The current value of the counter. This is expected to be reset
|
||||||
|
* a each tick interrupt. Thus, when the tick handler starts, the counter has
|
||||||
|
* already wrapped.
|
||||||
|
*
|
||||||
|
* HWTC_COUNT_DIRECTION: Should be one of:
|
||||||
|
* - DIRECTION_INCREMENTING - for hardware timer/counters of incrementing type
|
||||||
|
* such as the PIT on Atmel AT91SAM7X.
|
||||||
|
* When the counter value reach HWTC_PERIOD, it is reset to zero and the
|
||||||
|
* interrupt is signaled.
|
||||||
|
* - DIRECTION_DECREMENTING - for hardware timer/counters of decrementing type
|
||||||
|
* such as the SysTick on ARM Cortex M3/M4 chips.
|
||||||
|
* When the counter value reach 0, it is reset to HWTC_PERIOD and the
|
||||||
|
* interrupt is signaled.
|
||||||
|
*
|
||||||
|
* HWTC_PERIOD: The number of increments or decrements of HWTC_COUNT between
|
||||||
|
* two tick interrupts. This should preferably be mapped to the reload
|
||||||
|
* register of the hardware timer, to make it more portable between chips in the
|
||||||
|
* same family. The macro should in most cases be (reload register + 1).
|
||||||
|
*
|
||||||
|
* HWTC_DIVISOR: If the timer frequency is very high, like on the Cortex M chips
|
||||||
|
* (where the SysTick runs at the core clock frequency), the "differential
|
||||||
|
* timestamping" used in the recorder will more frequently insert extra XTS
|
||||||
|
* events to store the timestamps, which increases the event buffer usage.
|
||||||
|
* In such cases, to reduce the number of XTS events and thereby get longer
|
||||||
|
* traces, you use HWTC_DIVISOR to scale down the timestamps and frequency.
|
||||||
|
* Assuming a OS tick rate of 1 KHz, it is suggested to keep the effective timer
|
||||||
|
* frequency below 65 MHz to avoid an excessive amount of XTS events. Thus, a
|
||||||
|
* Cortex M chip running at 72 MHZ should use a HWTC_DIVISOR of 2, while a
|
||||||
|
* faster chip require a higher HWTC_DIVISOR value.
|
||||||
|
*
|
||||||
|
* The HWTC macros and uiTracePortGetTimeStamp is the main porting issue
|
||||||
|
* or the trace recorder library. Typically you should not need to change
|
||||||
|
* the code of uiTracePortGetTimeStamp if using the HWTC macros.
|
||||||
|
*
|
||||||
|
* FREE LICENSE OFFER FROM PERCEPIO
|
||||||
|
*
|
||||||
|
* For silicon companies and non-corporate FreeRTOS users (researchers, students,
|
||||||
|
* hobbyists or early-phase startups) we have the following offer:
|
||||||
|
* Provide a hardware port for our FreeRTOS recorder and get a FREE single-user
|
||||||
|
* license for FreeRTOS+Trace Professional Edition. Read more about this offer
|
||||||
|
* at www.percepio.com or contact us directly at support@percepio.com.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#if (SELECTED_PORT == PORT_Win32)
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT (ulGetRunTimeCounterValue())
|
||||||
|
#define HWTC_PERIOD 0
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 1 // Please update according to your hardware...
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_HWIndependent)
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT 0
|
||||||
|
#define HWTC_PERIOD 1
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 1 // Please update according to your hardware...
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_Atmel_AT91SAM7)
|
||||||
|
|
||||||
|
/* HWTC_PERIOD is hardcoded for AT91SAM7X256-EK Board (48 MHz)
|
||||||
|
A more generic solution is to get the period from pxPIT->PITC_PIMR */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT (AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF)
|
||||||
|
#define HWTC_PERIOD 2995
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_Atmel_UC3A0)
|
||||||
|
|
||||||
|
/* For Atmel AVR32 (AT32UC3A) */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT sysreg_read(AVR32_COUNT)
|
||||||
|
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_ARM_CortexM)
|
||||||
|
|
||||||
|
/* For all chips using ARM Cortex M cores */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
|
||||||
|
#define HWTC_COUNT (*((uint32_t*)0xE000E018))
|
||||||
|
#define HWTC_PERIOD ((*(uint32_t*)0xE000E014) + 1)
|
||||||
|
#define HWTC_DIVISOR 2
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_Renesas_RX600)
|
||||||
|
|
||||||
|
#include "iodefine.h"
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT (CMT0.CMCNT)
|
||||||
|
#define HWTC_PERIOD ((((configPERIPHERAL_CLOCK_HZ/configTICK_RATE_HZ)-1)/8))
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_Microchip_dsPIC_AND_PIC24)
|
||||||
|
|
||||||
|
/* For Microchip PIC24 and dsPIC (16 bit) */
|
||||||
|
|
||||||
|
/* Note: The trace library was originally designed for 32-bit MCUs, and is slower
|
||||||
|
than intended on 16-bit MCUs. Storing an event on a PIC24 takes about 70 µs.
|
||||||
|
In comparison, 32-bit MCUs are often 10-20 times faster. If recording overhead
|
||||||
|
becomes a problem on PIC24, use the filters to exclude less interresting tasks
|
||||||
|
or system calls. */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT (TMR1)
|
||||||
|
#define HWTC_PERIOD (PR1+1)
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_NXP_LPC210X)
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
/* Tested with LPC2106, but should work with most LPC21XX chips.
|
||||||
|
Assumption: prescaler is 1:1 (this setting is hardcoded in
|
||||||
|
FreeRTOS port for LPC21XX) */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT *((uint32_t *)0xE0004008 )
|
||||||
|
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_TEXAS_INSTRUMENTS_TMS570)
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
#define RTIFRC0 *((uint32_t *)0xFFFFFC10)
|
||||||
|
#define RTICOMP0 *((uint32_t *)0xFFFFFC50)
|
||||||
|
#define RTIUDCP0 *((uint32_t *)0xFFFFFC54)
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT (RTIFRC0 - (RTICOMP0 - RTIUDCP0))
|
||||||
|
#define HWTC_PERIOD (RTIUDCP0)
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_TEXAS_INSTRUMENTS_MSP430)
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT (TA0R)
|
||||||
|
#define HWTC_PERIOD configCPU_CLOCKS_PER_TICK
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 1 // higher irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_MICROCHIP_PIC32)
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING
|
||||||
|
#define HWTC_COUNT (ReadTimer1()) /* Should be available in BSP */
|
||||||
|
#define HWTC_PERIOD (ReadPeriod1()+1) /* Should be available in BSP */
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_XILINX_PPC405)
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
|
||||||
|
#define HWTC_COUNT mfspr( 0x3db)
|
||||||
|
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_XILINX_PPC440)
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
/* This should work with most PowerPC chips */
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
|
||||||
|
#define HWTC_COUNT mfspr( 0x016 )
|
||||||
|
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
|
||||||
|
#define HWTC_DIVISOR 1
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT == PORT_XILINX_MICROBLAZE)
|
||||||
|
/* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */
|
||||||
|
|
||||||
|
/* This should work with most Microblaze configurations
|
||||||
|
* This port is based on the official FreeRTOS Microlaze port and example application.
|
||||||
|
* It uses the AXI Timer 0 - the tick interrupt source.
|
||||||
|
* If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required.
|
||||||
|
*/
|
||||||
|
#include "xtmrctr_l.h"
|
||||||
|
|
||||||
|
#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING
|
||||||
|
#define HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 )
|
||||||
|
#define HWTC_PERIOD ( configCPU_CLOCK_HZ / configTICK_RATE_HZ )
|
||||||
|
#define HWTC_DIVISOR 16
|
||||||
|
|
||||||
|
#define IRQ_PRIORITY_ORDER 0 // lower irq priority values are more significant
|
||||||
|
|
||||||
|
#elif (SELECTED_PORT != PORT_NOT_SET)
|
||||||
|
|
||||||
|
#error "SELECTED_PORT had unsupported value!"
|
||||||
|
#define SELECTED_PORT PORT_NOT_SET
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SELECTED_PORT != PORT_NOT_SET)
|
||||||
|
|
||||||
|
#ifndef HWTC_COUNT_DIRECTION
|
||||||
|
#error "HWTC_COUNT_DIRECTION is not set!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HWTC_COUNT
|
||||||
|
#error "HWTC_COUNT is not set!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HWTC_PERIOD
|
||||||
|
#error "HWTC_PERIOD is not set!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HWTC_DIVISOR
|
||||||
|
#error "HWTC_DIVISOR is not set!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef IRQ_PRIORITY_ORDER
|
||||||
|
#error "IRQ_PRIORITY_ORDER is not set!"
|
||||||
|
#elif (IRQ_PRIORITY_ORDER != 0) && (IRQ_PRIORITY_ORDER != 1)
|
||||||
|
#error "IRQ_PRIORITY_ORDER has bad value!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (HWTC_DIVISOR < 1)
|
||||||
|
#error "HWTC_DIVISOR must be a non-zero positive value!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTraceConsoleMessage
|
||||||
|
*
|
||||||
|
* A wrapper for your system-specific console "printf" console output function.
|
||||||
|
* This needs to be correctly defined to see status reports from the trace
|
||||||
|
* status monitor task (this is defined in trcUser.c).
|
||||||
|
******************************************************************************/
|
||||||
|
#if (SELECTED_PORT == PORT_Atmel_AT91SAM7)
|
||||||
|
/* Port specific includes */
|
||||||
|
#include "console.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define vTraceConsoleMessage printf
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* uiTracePortGetTimeStamp
|
||||||
|
*
|
||||||
|
* Returns the current time based on the HWTC macros which provide a hardware
|
||||||
|
* isolation layer towards the hardware timer/counter.
|
||||||
|
*
|
||||||
|
* The HWTC macros and uiTracePortGetTimeStamp is the main porting issue
|
||||||
|
* or the trace recorder library. Typically you should not need to change
|
||||||
|
* the code of uiTracePortGetTimeStamp if using the HWTC macros.
|
||||||
|
*
|
||||||
|
* OFFER FROM PERCEPIO:
|
||||||
|
* For silicon companies and non-corporate FreeRTOS users (researchers,
|
||||||
|
* students, hobbyists or early-phase startups) we have an attractive offer:
|
||||||
|
* Provide a hardware timer port and get a FREE single-user licence for
|
||||||
|
* FreeRTOS+Trace Professional Edition. Read more about this offer at
|
||||||
|
* www.percepio.com or contact us directly at support@percepio.com.
|
||||||
|
******************************************************************************/
|
||||||
|
void uiTracePortGetTimeStamp(uint32_t *puiTimestamp);
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTracePortEnd
|
||||||
|
*
|
||||||
|
* This function is called when the recorder is stopped due to full buffer.
|
||||||
|
* Mainly intended to show a message in the console.
|
||||||
|
* This is used by the Win32 port to store the trace to a file. The file path is
|
||||||
|
* set using vTracePortSetFileName.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTracePortEnd(void);
|
||||||
|
|
||||||
|
#if (INCLUDE_SAVE_TO_FILE == 1)
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* vTracePortSetOutFile
|
||||||
|
*
|
||||||
|
* Sets the filename/path used in vTracePortSave.
|
||||||
|
* This is set in a separate function, since the Win32 port calls vTracePortSave
|
||||||
|
* in vTracePortEnd if WIN32_PORT_SAVE_WHEN_STOPPED is set.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTracePortSetOutFile(char* path);
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* vTracePortSave
|
||||||
|
*
|
||||||
|
* Saves the trace to a file on a target-side file system. The path is set in a
|
||||||
|
* separate function, vTracePortSetOutFile, since the Win32 port may call
|
||||||
|
* vTracePortSave in vTracePortEnd, if using WIN32_PORT_SAVE_WHEN_STOPPED.
|
||||||
|
******************************************************************************/
|
||||||
|
void vTracePortSave(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
@ -54,7 +54,7 @@
|
|||||||
</Midl>
|
</Midl>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\Include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..\Source\include;..\..\Source\portable\MSVC-MingW;..\Common\Include;..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\Include;.\Trace_Recorder_Configuration;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<MinimalRebuild>true</MinimalRebuild>
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
@ -125,6 +125,10 @@
|
|||||||
</Bscmake>
|
</Bscmake>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\trcBase.c" />
|
||||||
|
<ClCompile Include="..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\trcKernel.c" />
|
||||||
|
<ClCompile Include="..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\trcPort.c" />
|
||||||
|
<ClCompile Include="..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\trcUser.c" />
|
||||||
<ClCompile Include="..\..\Source\portable\MemMang\heap_3.c" />
|
<ClCompile Include="..\..\Source\portable\MemMang\heap_3.c" />
|
||||||
<ClCompile Include="..\..\Source\timers.c" />
|
<ClCompile Include="..\..\Source\timers.c" />
|
||||||
<ClCompile Include="..\Common\Minimal\BlockQ.c" />
|
<ClCompile Include="..\Common\Minimal\BlockQ.c" />
|
||||||
@ -166,6 +170,7 @@
|
|||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Run-time-stats-utils.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\Source\include\timers.h" />
|
<ClInclude Include="..\..\Source\include\timers.h" />
|
||||||
@ -180,6 +185,8 @@
|
|||||||
<ClInclude Include="..\..\Source\include\queue.h" />
|
<ClInclude Include="..\..\Source\include\queue.h" />
|
||||||
<ClInclude Include="..\..\Source\include\semphr.h" />
|
<ClInclude Include="..\..\Source\include\semphr.h" />
|
||||||
<ClInclude Include="..\..\Source\include\task.h" />
|
<ClInclude Include="..\..\Source\include\task.h" />
|
||||||
|
<ClInclude Include="Trace_Recorder_Configuration\trcConfig.h" />
|
||||||
|
<ClInclude Include="Trace_Recorder_Configuration\trcPort.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
@ -32,6 +32,9 @@
|
|||||||
<UniqueIdentifier>{19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4}</UniqueIdentifier>
|
<UniqueIdentifier>{19ff1a34-36de-4c48-9d10-3fb1fa0d1fa4}</UniqueIdentifier>
|
||||||
<Extensions>h;hpp;hxx;hm;inl</Extensions>
|
<Extensions>h;hpp;hxx;hm;inl</Extensions>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Demo App Source\FreeRTOS+Trace Recorder">
|
||||||
|
<UniqueIdentifier>{90b56567-bab6-4d92-b319-b514d378329d}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.c">
|
<ClCompile Include="main.c">
|
||||||
@ -97,6 +100,21 @@
|
|||||||
<ClCompile Include="..\Common\Minimal\QueueSet.c">
|
<ClCompile Include="..\Common\Minimal\QueueSet.c">
|
||||||
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
<Filter>Demo App Source\Common Demo Tasks</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\trcUser.c">
|
||||||
|
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\trcBase.c">
|
||||||
|
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\trcKernel.c">
|
||||||
|
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\..\FreeRTOS-Plus\FreeRTOS-Plus-Trace\trcPort.c">
|
||||||
|
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Run-time-stats-utils.c">
|
||||||
|
<Filter>Demo App Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="FreeRTOSConfig.h">
|
<ClInclude Include="FreeRTOSConfig.h">
|
||||||
@ -135,5 +153,11 @@
|
|||||||
<ClInclude Include="..\..\Source\include\timer_test.h">
|
<ClInclude Include="..\..\Source\include\timer_test.h">
|
||||||
<Filter>FreeRTOS Source\Include</Filter>
|
<Filter>FreeRTOS Source\Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Trace_Recorder_Configuration\trcConfig.h">
|
||||||
|
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Trace_Recorder_Configuration\trcPort.h">
|
||||||
|
<Filter>Demo App Source\FreeRTOS+Trace Recorder</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -178,6 +178,10 @@ int main( void )
|
|||||||
is done purely to test the use of vSemaphoreDelete(). */
|
is done purely to test the use of vSemaphoreDelete(). */
|
||||||
xMutexToDelete = xSemaphoreCreateMutex();
|
xMutexToDelete = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
|
/* Start the trace recording - the recording is written to a file if
|
||||||
|
configASSERT() is called. */
|
||||||
|
vTraceStart();
|
||||||
|
|
||||||
/* Start the scheduler itself. */
|
/* Start the scheduler itself. */
|
||||||
vTaskStartScheduler();
|
vTaskStartScheduler();
|
||||||
|
|
||||||
@ -381,7 +385,6 @@ extern unsigned portBASE_TYPE uxTaskGetTaskNumber( xTaskHandle xTask );
|
|||||||
pcStatusMessage = "Error: Returned test task state was incorrect 3";
|
pcStatusMessage = "Error: Returned test task state was incorrect 3";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
@ -408,13 +411,19 @@ void vApplicationTickHook( void )
|
|||||||
|
|
||||||
/* Write to a queue that is in use as part of the queue set demo to
|
/* Write to a queue that is in use as part of the queue set demo to
|
||||||
demonstrate using queue sets from an ISR. */
|
demonstrate using queue sets from an ISR. */
|
||||||
vQueueSetWriteToQueueFromISR();
|
vQueueSetAccessQueueSetFromISR();
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
void vAssertCalled( void )
|
void vAssertCalled( void )
|
||||||
{
|
{
|
||||||
taskDISABLE_INTERRUPTS();
|
taskDISABLE_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Stop the trace recording. */
|
||||||
|
vTraceStop();
|
||||||
|
vTracePortSave();
|
||||||
|
|
||||||
for( ;; );
|
for( ;; );
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
@ -101,6 +101,7 @@ only for ports that are using the MPU. */
|
|||||||
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
#define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark
|
||||||
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
#define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle
|
||||||
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
#define xTaskGetSchedulerState MPU_xTaskGetSchedulerState
|
||||||
|
#define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle
|
||||||
|
|
||||||
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
#define xQueueGenericCreate MPU_xQueueGenericCreate
|
||||||
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
#define xQueueCreateMutex MPU_xQueueCreateMutex
|
||||||
@ -113,6 +114,11 @@ only for ports that are using the MPU. */
|
|||||||
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
#define xQueueGenericReceive MPU_xQueueGenericReceive
|
||||||
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
#define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting
|
||||||
#define vQueueDelete MPU_vQueueDelete
|
#define vQueueDelete MPU_vQueueDelete
|
||||||
|
#define xQueueGenericReset MPU_xQueueGenericReset
|
||||||
|
#define xQueueCreateSet MPU_xQueueCreateSet
|
||||||
|
#define xQueueSelectFromSet MPU_xQueueSelectFromSet
|
||||||
|
#define xQueueAddToSet MPU_xQueueAddToSet
|
||||||
|
#define xQueueRemoveFromSet MPU_xQueueRemoveFromSet
|
||||||
|
|
||||||
#define pvPortMalloc MPU_pvPortMalloc
|
#define pvPortMalloc MPU_pvPortMalloc
|
||||||
#define vPortFree MPU_vPortFree
|
#define vPortFree MPU_vPortFree
|
||||||
|
@ -90,8 +90,8 @@ typedef void * xQueueHandle;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Type by which queue sets are referenced. For example, a call to
|
* Type by which queue sets are referenced. For example, a call to
|
||||||
* xQueueSetCreate() returns an xQueueSet variable that can then be used as a
|
* xQueueCreateSet() returns an xQueueSet variable that can then be used as a
|
||||||
* parameter to xQueueBlockMultiple(), xQueueAddToQueueSet(), etc.
|
* parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc.
|
||||||
*/
|
*/
|
||||||
typedef void * xQueueSetHandle;
|
typedef void * xQueueSetHandle;
|
||||||
|
|
||||||
@ -1309,10 +1309,10 @@ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned
|
|||||||
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
||||||
* function.
|
* function.
|
||||||
*
|
*
|
||||||
* A queue set must be explicitly created using a call to xQueueSetCreate()
|
* A queue set must be explicitly created using a call to xQueueCreateSet()
|
||||||
* before it can be used. Once created, standard FreeRTOS queues and semaphores
|
* before it can be used. Once created, standard FreeRTOS queues and semaphores
|
||||||
* can be added to the set using calls to xQueueAddToQueueSet().
|
* can be added to the set using calls to xQueueAddToSet().
|
||||||
* xQueueBlockMultiple() is then used to determine which, if any, of the queues
|
* xQueueSelectFromSet() is then used to determine which, if any, of the queues
|
||||||
* or semaphores contained in the set is in a state where a queue read or
|
* or semaphores contained in the set is in a state where a queue read or
|
||||||
* semaphore take operation would be successful.
|
* semaphore take operation would be successful.
|
||||||
*
|
*
|
||||||
@ -1328,6 +1328,10 @@ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned
|
|||||||
* queue added to a queue set. Therefore counting semaphores with large maximum
|
* queue added to a queue set. Therefore counting semaphores with large maximum
|
||||||
* counts should not be added to queue sets.
|
* counts should not be added to queue sets.
|
||||||
*
|
*
|
||||||
|
* Note 4: A received (in the case of a queue) or take (in the case of a
|
||||||
|
* semaphore) operation must not be performed on a member of a queue set unless
|
||||||
|
* a call to xQueueSelect() has first returned a handle to that set member.
|
||||||
|
*
|
||||||
* @param uxEventQueueLength Queue sets themselves queue events that occur on
|
* @param uxEventQueueLength Queue sets themselves queue events that occur on
|
||||||
* the queues and semaphores contained in the set. uxEventQueueLength specifies
|
* the queues and semaphores contained in the set. uxEventQueueLength specifies
|
||||||
* the maximum number of events that can be queued at once. To be absolutely
|
* the maximum number of events that can be queued at once. To be absolutely
|
||||||
@ -1347,15 +1351,19 @@ xQueueHandle xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned
|
|||||||
* @return If the queue set is created successfully then a handle to the created
|
* @return If the queue set is created successfully then a handle to the created
|
||||||
* queue set is returned. Otherwise NULL is returned.
|
* queue set is returned. Otherwise NULL is returned.
|
||||||
*/
|
*/
|
||||||
xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength );
|
xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds a queue or semaphore to a queue set that was previously created by a
|
* Adds a queue or semaphore to a queue set that was previously created by a
|
||||||
* call to xQueueSetCreate().
|
* call to xQueueCreateSet().
|
||||||
*
|
*
|
||||||
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
||||||
* function.
|
* function.
|
||||||
*
|
*
|
||||||
|
* Note 1: A received (in the case of a queue) or take (in the case of a
|
||||||
|
* semaphore) operation must not be performed on a member of a queue set unless
|
||||||
|
* a call to xQueueSelect() has first returned a handle to that set member.
|
||||||
|
*
|
||||||
* @param xQueueOrSemaphore The handle of the queue or semaphore being added to
|
* @param xQueueOrSemaphore The handle of the queue or semaphore being added to
|
||||||
* the queue set (cast to an xQueueSetMemberHandle type).
|
* the queue set (cast to an xQueueSetMemberHandle type).
|
||||||
*
|
*
|
||||||
@ -1367,10 +1375,11 @@ xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength );
|
|||||||
* queue set because it is already a member of a different queue set then pdFAIL
|
* queue set because it is already a member of a different queue set then pdFAIL
|
||||||
* is returned.
|
* is returned.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
|
portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Removes a queue or semaphore from a queue set.
|
* Removes a queue or semaphore from a queue set. A queue can only be removed
|
||||||
|
* from a set when it is empty.
|
||||||
*
|
*
|
||||||
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
||||||
* function.
|
* function.
|
||||||
@ -1385,11 +1394,14 @@ portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQue
|
|||||||
* then pdPASS is returned. If the queue was not in the queue set then pdFAIL
|
* then pdPASS is returned. If the queue was not in the queue set then pdFAIL
|
||||||
* is returned.
|
* is returned.
|
||||||
*/
|
*/
|
||||||
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
|
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xQueueBlockMultiple() allows a task to block (pend) on a read operation on
|
* xQueueSelectFromSet() selects from the members of a queue set a queue or
|
||||||
* all the queues and semaphores in a queue set simultaneously.
|
* semaphore that either contains data (in the case of a queue) or is available
|
||||||
|
* to take (in the case of a semaphore). xQueueSelectFromSet() effectively
|
||||||
|
* allows a task to block (pend) on a read operation on all the queues and
|
||||||
|
* semaphores in a queue set simultaneously.
|
||||||
*
|
*
|
||||||
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
* See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this
|
||||||
* function.
|
* function.
|
||||||
@ -1402,6 +1414,10 @@ portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore,
|
|||||||
* Note 2: Blocking on a queue set that contains a mutex will not cause the
|
* Note 2: Blocking on a queue set that contains a mutex will not cause the
|
||||||
* mutex holder to inherit the priority of the blocked task.
|
* mutex holder to inherit the priority of the blocked task.
|
||||||
*
|
*
|
||||||
|
* Note 3: A received (in the case of a queue) or take (in the case of a
|
||||||
|
* semaphore) operation must not be performed on a member of a queue set unless
|
||||||
|
* a call to xQueueSelect() has first returned a handle to that set member.
|
||||||
|
*
|
||||||
* @param xQueueSet The queue set on which the task will (potentially) block.
|
* @param xQueueSet The queue set on which the task will (potentially) block.
|
||||||
*
|
*
|
||||||
* @param xBlockTimeTicks The maximum time, in ticks, that the calling task will
|
* @param xBlockTimeTicks The maximum time, in ticks, that the calling task will
|
||||||
@ -1409,13 +1425,18 @@ portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore,
|
|||||||
* of the queue set to be ready for a successful queue read or semaphore take
|
* of the queue set to be ready for a successful queue read or semaphore take
|
||||||
* operation.
|
* operation.
|
||||||
*
|
*
|
||||||
* @return xQueueBlockMultiple() will return the handle of a queue (cast to
|
* @return xQueueSelectFromSet() will return the handle of a queue (cast to
|
||||||
* a xQueueSetMemberHandle type) contained in the queue set that contains data,
|
* a xQueueSetMemberHandle type) contained in the queue set that contains data,
|
||||||
* or the handle of a semaphore (cast to a xQueueSetMemberHandle type) contained
|
* or the handle of a semaphore (cast to a xQueueSetMemberHandle type) contained
|
||||||
* in the queue set that is available, or NULL if no such queue or semaphore
|
* in the queue set that is available, or NULL if no such queue or semaphore
|
||||||
* exists before before the specified block time expires.
|
* exists before before the specified block time expires.
|
||||||
*/
|
*/
|
||||||
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
|
xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A version of xQueueSelectFromSet() that can be used from an ISR.
|
||||||
|
*/
|
||||||
|
xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet );
|
||||||
|
|
||||||
/* Not public API functions. */
|
/* Not public API functions. */
|
||||||
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );
|
void vQueueWaitForMessageRestricted( xQueueHandle pxQueue, portTickType xTicksToWait );
|
||||||
|
@ -196,8 +196,10 @@ portBASE_TYPE MPU_xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParam
|
|||||||
unsigned portBASE_TYPE MPU_uxTaskGetStackHighWaterMark( xTaskHandle xTask );
|
unsigned portBASE_TYPE MPU_uxTaskGetStackHighWaterMark( xTaskHandle xTask );
|
||||||
xTaskHandle MPU_xTaskGetCurrentTaskHandle( void );
|
xTaskHandle MPU_xTaskGetCurrentTaskHandle( void );
|
||||||
portBASE_TYPE MPU_xTaskGetSchedulerState( void );
|
portBASE_TYPE MPU_xTaskGetSchedulerState( void );
|
||||||
|
xTaskHandle MPU_xTaskGetIdleTaskHandle( void );
|
||||||
xQueueHandle MPU_xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType );
|
xQueueHandle MPU_xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType );
|
||||||
signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
|
signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );
|
||||||
|
portBASE_TYPE MPU_xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue );
|
||||||
unsigned portBASE_TYPE MPU_uxQueueMessagesWaiting( const xQueueHandle pxQueue );
|
unsigned portBASE_TYPE MPU_uxQueueMessagesWaiting( const xQueueHandle pxQueue );
|
||||||
signed portBASE_TYPE MPU_xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
|
signed portBASE_TYPE MPU_xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );
|
||||||
xQueueHandle MPU_xQueueCreateMutex( void );
|
xQueueHandle MPU_xQueueCreateMutex( void );
|
||||||
@ -212,6 +214,10 @@ void *MPU_pvPortMalloc( size_t xSize );
|
|||||||
void MPU_vPortFree( void *pv );
|
void MPU_vPortFree( void *pv );
|
||||||
void MPU_vPortInitialiseBlocks( void );
|
void MPU_vPortInitialiseBlocks( void );
|
||||||
size_t MPU_xPortGetFreeHeapSize( void );
|
size_t MPU_xPortGetFreeHeapSize( void );
|
||||||
|
xQueueSetHandle MPU_xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength );
|
||||||
|
xQueueSetMemberHandle MPU_xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );
|
||||||
|
portBASE_TYPE MPU_xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
|
||||||
|
portBASE_TYPE MPU_xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );
|
||||||
|
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -749,6 +755,19 @@ portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
|
|||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )
|
||||||
|
xTaskHandle MPU_xTaskGetIdleTaskHandle( void )
|
||||||
|
{
|
||||||
|
xTaskHandle xReturn;
|
||||||
|
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
|
||||||
|
|
||||||
|
xReturn = xTaskGetIdleTaskHandle();
|
||||||
|
portRESET_PRIVILEGE( xRunningPrivileged );
|
||||||
|
return eReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( INCLUDE_vTaskSuspend == 1 )
|
#if ( INCLUDE_vTaskSuspend == 1 )
|
||||||
void MPU_vTaskSuspend( xTaskHandle pxTaskToSuspend )
|
void MPU_vTaskSuspend( xTaskHandle pxTaskToSuspend )
|
||||||
{
|
{
|
||||||
@ -935,6 +954,17 @@ portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
|
|||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
portBASE_TYPE MPU_xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn;
|
||||||
|
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
|
||||||
|
|
||||||
|
xReturn = xQueueGenericReset( pxQueue, xNewQueue );
|
||||||
|
portRESET_PRIVILEGE( xRunningPrivileged );
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
||||||
{
|
{
|
||||||
signed portBASE_TYPE xReturn;
|
signed portBASE_TYPE xReturn;
|
||||||
@ -1020,6 +1050,58 @@ signed portBASE_TYPE xReturn;
|
|||||||
#endif
|
#endif
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
xQueueSetHandle MPU_xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength )
|
||||||
|
{
|
||||||
|
xQueueSetHandle xReturn;
|
||||||
|
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
|
||||||
|
|
||||||
|
xReturn = xQueueCreateSet( uxEventQueueLength );
|
||||||
|
portRESET_PRIVILEGE( xRunningPrivileged );
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
xQueueSetMemberHandle MPU_xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
|
||||||
|
{
|
||||||
|
xQueueSetMemberHandle xReturn;
|
||||||
|
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
|
||||||
|
|
||||||
|
xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks );
|
||||||
|
portRESET_PRIVILEGE( xRunningPrivileged );
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
portBASE_TYPE MPU_xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn;
|
||||||
|
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
|
||||||
|
|
||||||
|
xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet );
|
||||||
|
portRESET_PRIVILEGE( xRunningPrivileged );
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
portBASE_TYPE MPU_xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
||||||
|
{
|
||||||
|
portBASE_TYPE xReturn;
|
||||||
|
portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();
|
||||||
|
|
||||||
|
xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet );
|
||||||
|
portRESET_PRIVILEGE( xRunningPrivileged );
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if configUSE_ALTERNATIVE_API == 1
|
#if configUSE_ALTERNATIVE_API == 1
|
||||||
signed portBASE_TYPE MPU_xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
signed portBASE_TYPE MPU_xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )
|
||||||
{
|
{
|
||||||
|
@ -111,7 +111,7 @@ zero. */
|
|||||||
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )
|
#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( 2U )
|
||||||
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )
|
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( 3U )
|
||||||
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )
|
#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( 4U )
|
||||||
#define queueQUEUE_TYPE_SET ( 5U )
|
#define queueQUEUE_TYPE_SET ( 0U )
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definition of the queue used by the scheduler.
|
* Definition of the queue used by the scheduler.
|
||||||
@ -191,10 +191,10 @@ void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ) P
|
|||||||
unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
|
unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ) PRIVILEGED_FUNCTION;
|
||||||
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;
|
portBASE_TYPE xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue ) PRIVILEGED_FUNCTION;
|
||||||
xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
|
xTaskHandle xQueueGetMutexHolder( xQueueHandle xSemaphore ) PRIVILEGED_FUNCTION;
|
||||||
xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
|
xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength ) PRIVILEGED_FUNCTION;
|
||||||
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
|
xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks ) PRIVILEGED_FUNCTION;
|
||||||
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
|
portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
|
||||||
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
|
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Co-routine queue functions differ from task queue functions. Co-routines are
|
* Co-routine queue functions differ from task queue functions. Co-routines are
|
||||||
@ -630,36 +630,52 @@ xTimeOutType xTimeOut;
|
|||||||
traceQUEUE_SEND( pxQueue );
|
traceQUEUE_SEND( pxQueue );
|
||||||
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||||
|
|
||||||
/* If there was a task waiting for data to arrive on the
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
queue then unblock it now. */
|
|
||||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
|
||||||
{
|
{
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
|
if( pxQueue->pxQueueSetContainer != NULL )
|
||||||
{
|
{
|
||||||
/* The unblocked task has a priority higher than
|
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
|
||||||
our own so yield immediately. Yes it is ok to do
|
|
||||||
this from within the critical section - the kernel
|
|
||||||
takes care of that. */
|
|
||||||
portYIELD_WITHIN_API();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
|
||||||
{
|
|
||||||
if( pxQueue->pxQueueSetContainer != NULL )
|
|
||||||
{
|
{
|
||||||
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
|
/* The queue is a member of a queue set, and posting
|
||||||
|
to the queue set caused a higher priority task to
|
||||||
|
unblock. A context switch is required. */
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If there was a task waiting for data to arrive on the
|
||||||
|
queue then unblock it now. */
|
||||||
|
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
|
{
|
||||||
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
|
||||||
{
|
{
|
||||||
/* The queue is a member of a queue set, and posting to
|
/* The unblocked task has a priority higher than
|
||||||
the queue set caused a higher priority task to unblock.
|
our own so yield immediately. Yes it is ok to
|
||||||
A context switch is required. */
|
do this from within the critical section - the
|
||||||
|
kernel takes care of that. */
|
||||||
portYIELD_WITHIN_API();
|
portYIELD_WITHIN_API();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* configUSE_QUEUE_SETS */
|
|
||||||
}
|
}
|
||||||
|
#else /* configUSE_QUEUE_SETS */
|
||||||
|
{
|
||||||
|
/* If there was a task waiting for data to arrive on the
|
||||||
|
queue then unblock it now. */
|
||||||
|
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
|
{
|
||||||
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) == pdTRUE )
|
||||||
|
{
|
||||||
|
/* The unblocked task has a priority higher than
|
||||||
|
our own so yield immediately. Yes it is ok to do
|
||||||
|
this from within the critical section - the kernel
|
||||||
|
takes care of that. */
|
||||||
|
portYIELD_WITHIN_API();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
|
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
@ -977,29 +993,29 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
|
|||||||
be done when the queue is unlocked later. */
|
be done when the queue is unlocked later. */
|
||||||
if( pxQueue->xTxLock == queueUNLOCKED )
|
if( pxQueue->xTxLock == queueUNLOCKED )
|
||||||
{
|
{
|
||||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
{
|
{
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
if( pxQueue->pxQueueSetContainer != NULL )
|
||||||
{
|
{
|
||||||
/* The task waiting has a higher priority so record that a
|
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
|
||||||
context switch is required. */
|
|
||||||
if( pxHigherPriorityTaskWoken != NULL )
|
|
||||||
{
|
{
|
||||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
/* The queue is a member of a queue set, and posting
|
||||||
|
to the queue set caused a higher priority task to
|
||||||
|
unblock. A context switch is required. */
|
||||||
|
if( pxHigherPriorityTaskWoken != NULL )
|
||||||
|
{
|
||||||
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
|
||||||
{
|
{
|
||||||
if( pxQueue->pxQueueSetContainer != NULL )
|
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
{
|
{
|
||||||
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) == pdTRUE )
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||||
{
|
{
|
||||||
/* The queue is a member of a queue set, and posting
|
/* The task waiting has a higher priority so record that a
|
||||||
to the queue set caused a higher priority task to
|
context switch is required. */
|
||||||
unblock. A context switch is required. */
|
|
||||||
if( pxHigherPriorityTaskWoken != NULL )
|
if( pxHigherPriorityTaskWoken != NULL )
|
||||||
{
|
{
|
||||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
@ -1007,8 +1023,23 @@ unsigned portBASE_TYPE uxSavedInterruptStatus;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* configUSE_QUEUE_SETS */
|
|
||||||
}
|
}
|
||||||
|
#else /* configUSE_QUEUE_SETS */
|
||||||
|
{
|
||||||
|
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
|
{
|
||||||
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||||
|
{
|
||||||
|
/* The task waiting has a higher priority so record that a
|
||||||
|
context switch is required. */
|
||||||
|
if( pxHigherPriorityTaskWoken != NULL )
|
||||||
|
{
|
||||||
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1371,52 +1402,58 @@ static void prvUnlockQueue( xQueueHandle pxQueue )
|
|||||||
{
|
{
|
||||||
/* Data was posted while the queue was locked. Are any tasks
|
/* Data was posted while the queue was locked. Are any tasks
|
||||||
blocked waiting for data to become available? */
|
blocked waiting for data to become available? */
|
||||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
{
|
{
|
||||||
/* Tasks that are removed from the event list will get added to
|
if( pxQueue->pxQueueSetContainer != NULL )
|
||||||
the pending ready list as the scheduler is still suspended. */
|
|
||||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
|
||||||
{
|
{
|
||||||
/* The task waiting has a higher priority so record that a
|
if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE )
|
||||||
context switch is required. */
|
{
|
||||||
vTaskMissedYield();
|
/* The queue is a member of a queue set, and posting to
|
||||||
|
the queue set caused a higher priority task to unblock.
|
||||||
|
A context switch is required. */
|
||||||
|
vTaskMissedYield();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
/* Tasks that are removed from the event list will get added to
|
||||||
|
the pending ready list as the scheduler is still suspended. */
|
||||||
|
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
{
|
{
|
||||||
/* It is highly unlikely that this code will ever run,
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||||
for the following reason:
|
|
||||||
+ A task will only lock a queue that is part of a
|
|
||||||
queue set when it is blocking on a write to the
|
|
||||||
queue.
|
|
||||||
+ An interrupt can only add something to a queue
|
|
||||||
while the queue is locked (resulting in the
|
|
||||||
following code executing when the queue is unlocked)
|
|
||||||
if the queue is not full, meaning a task will never
|
|
||||||
have blocked on a write in the first place.
|
|
||||||
The code could execute if an interrupt is also removing
|
|
||||||
items from a queue. */
|
|
||||||
if( pxQueue->pxQueueSetContainer != NULL )
|
|
||||||
{
|
{
|
||||||
if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE )
|
/* The task waiting has a higher priority so record that a
|
||||||
{
|
context switch is required. */
|
||||||
/* The queue is a member of a queue set, and posting to
|
vTaskMissedYield();
|
||||||
the queue set caused a higher priority task to unblock.
|
|
||||||
A context switch is required. */
|
|
||||||
vTaskMissedYield();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* configUSE_QUEUE_SETS */
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
--( pxQueue->xTxLock );
|
|
||||||
}
|
}
|
||||||
else
|
#else /* configUSE_QUEUE_SETS */
|
||||||
{
|
{
|
||||||
break;
|
/* Tasks that are removed from the event list will get added to
|
||||||
|
the pending ready list as the scheduler is still suspended. */
|
||||||
|
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
|
{
|
||||||
|
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||||
|
{
|
||||||
|
/* The task waiting has a higher priority so record that a
|
||||||
|
context switch is required. */
|
||||||
|
vTaskMissedYield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
|
|
||||||
|
--( pxQueue->xTxLock );
|
||||||
}
|
}
|
||||||
|
|
||||||
pxQueue->xTxLock = queueUNLOCKED;
|
pxQueue->xTxLock = queueUNLOCKED;
|
||||||
@ -1791,7 +1828,7 @@ signed portBASE_TYPE xReturn;
|
|||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
xQueueSetHandle xQueueSetCreate( unsigned portBASE_TYPE uxEventQueueLength )
|
xQueueSetHandle xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength )
|
||||||
{
|
{
|
||||||
xQUEUE *pxQueue;
|
xQUEUE *pxQueue;
|
||||||
|
|
||||||
@ -1805,7 +1842,7 @@ signed portBASE_TYPE xReturn;
|
|||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
portBASE_TYPE xQueueAddToQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
portBASE_TYPE xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xReturn;
|
portBASE_TYPE xReturn;
|
||||||
|
|
||||||
@ -1831,18 +1868,27 @@ signed portBASE_TYPE xReturn;
|
|||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
portBASE_TYPE xQueueRemoveFromQueueSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
portBASE_TYPE xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )
|
||||||
{
|
{
|
||||||
portBASE_TYPE xReturn;
|
portBASE_TYPE xReturn;
|
||||||
|
|
||||||
if( xQueueOrSemaphore->pxQueueSetContainer != xQueueSet )
|
if( xQueueOrSemaphore->pxQueueSetContainer != xQueueSet )
|
||||||
{
|
{
|
||||||
|
/* The queue was not a member of the set. */
|
||||||
|
xReturn = pdFAIL;
|
||||||
|
}
|
||||||
|
else if( xQueueOrSemaphore->uxMessagesWaiting != 0 )
|
||||||
|
{
|
||||||
|
/* It is dangerous to remove a queue from a set when the queue is
|
||||||
|
not empty because the queue set will still hold pending events for
|
||||||
|
the queue. */
|
||||||
xReturn = pdFAIL;
|
xReturn = pdFAIL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
{
|
{
|
||||||
|
/* The queue is no longer contained in the set. */
|
||||||
xQueueOrSemaphore->pxQueueSetContainer = NULL;
|
xQueueOrSemaphore->pxQueueSetContainer = NULL;
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
@ -1857,7 +1903,7 @@ signed portBASE_TYPE xReturn;
|
|||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
xQueueSetMemberHandle xQueueBlockMultiple( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
|
xQueueSetMemberHandle xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )
|
||||||
{
|
{
|
||||||
xQueueSetMemberHandle xReturn = NULL;
|
xQueueSetMemberHandle xReturn = NULL;
|
||||||
|
|
||||||
@ -1868,6 +1914,19 @@ signed portBASE_TYPE xReturn;
|
|||||||
#endif /* configUSE_QUEUE_SETS */
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
|
xQueueSetMemberHandle xQueueSelectFromSetFromISR( xQueueSetHandle xQueueSet )
|
||||||
|
{
|
||||||
|
xQueueSetMemberHandle xReturn = NULL;
|
||||||
|
|
||||||
|
xQueueReceiveFromISR( ( xQueueHandle ) xQueueSet, &xReturn, NULL );
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configUSE_QUEUE_SETS */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
|
|
||||||
static portBASE_TYPE prvNotifyQueueSetContainer( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )
|
static portBASE_TYPE prvNotifyQueueSetContainer( xQUEUE *pxQueue, portBASE_TYPE xCopyPosition )
|
||||||
@ -1880,6 +1939,8 @@ signed portBASE_TYPE xReturn;
|
|||||||
|
|
||||||
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
|
if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength )
|
||||||
{
|
{
|
||||||
|
traceQUEUE_SEND( pxQueueSetContainer );
|
||||||
|
/* The data copies is the handle of the queue that contains data. */
|
||||||
prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );
|
prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition );
|
||||||
if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
|
if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
{
|
{
|
||||||
|
@ -974,7 +974,11 @@ tskTCB * pxNewTCB;
|
|||||||
/* Remember the ready list the task might be referenced from
|
/* Remember the ready list the task might be referenced from
|
||||||
before its uxPriority member is changed so the
|
before its uxPriority member is changed so the
|
||||||
taskRESET_READY_PRIORITY() macro can function correctly. */
|
taskRESET_READY_PRIORITY() macro can function correctly. */
|
||||||
uxPriorityUsedOnEntry = pxTCB->uxPriority;
|
#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION != 0 )
|
||||||
|
{
|
||||||
|
uxPriorityUsedOnEntry = pxTCB->uxPriority;
|
||||||
|
}
|
||||||
|
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
|
||||||
|
|
||||||
#if ( configUSE_MUTEXES == 1 )
|
#if ( configUSE_MUTEXES == 1 )
|
||||||
{
|
{
|
||||||
@ -1274,11 +1278,13 @@ portBASE_TYPE xReturn;
|
|||||||
/* Should only reach here if a task calls xTaskEndScheduler(). */
|
/* Should only reach here if a task calls xTaskEndScheduler(). */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* This line will only be reached if the kernel could not be started, or
|
{
|
||||||
vTaskEndScheduler() was called (vTaskEndScheduler() is not implemented for
|
/* This line will only be reached if the kernel could not be started,
|
||||||
most ports). */
|
because there was not enough FreeRTOS heap to create the idle task
|
||||||
configASSERT( xReturn );
|
or the timer task. */
|
||||||
|
configASSERT( xReturn );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user