+ New feature added: Task notifications.

+ Optimise Cortex-M4F ports by inlining some critical section macros.
+ Original ports used a #define to set the path to portmacro.h - that method has been obsolete for years and now all the old definitions have been moved into a separate header files called deprecated_definitions.h.
+ Cortex-M port now check the active vector bits against 0xff when determining if a function is called from an interrupt - previously only a subset of the bits (0x1f) were checked.
+ Add in new standard demo/test files TaskNotify.c/h and include the files in the simulator demos.
+ Update trace recorder code, and some demos to use the new version (more to do).
+ Introduce uxTaskPriorityGetFromISR().
+ Minor typo corrections.
+ Update MingW simulator demo to match the MSVC simulator demo.
This commit is contained in:
Richard Barry 2014-12-15 14:13:03 +00:00
parent ca22607d14
commit 85fb1cc024
65 changed files with 5524 additions and 4527 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Tracealyzer v2.6.0 Recorder Library
* Tracealyzer v2.7.0 Recorder Library
* Percepio AB, www.percepio.com
*
* trcHardwarePort.c
@ -32,7 +32,9 @@
* 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.
*
* Copyright Percepio AB, 2013.
* Tabs are used for indent in this file (1 tab = 4 spaces)
*
* Copyright Percepio AB, 2014.
* www.percepio.com
******************************************************************************/
@ -56,36 +58,37 @@ uint32_t last_timestamp = 0;
******************************************************************************/
uint32_t uiTraceTickCount = 0;
uint32_t DWT_CYCLES_ADDED = 0;
uint32_t DWT_CYCLES_ADDED = 0; /* Used on ARM Cortex-M only */
#if (SELECTED_PORT == PORT_ARM_CortexM)
void prvTraceEnableIRQ(void)
{
asm volatile ("cpsie i");
}
void prvTraceDisableIRQ(void)
{
asm volatile ("cpsid i");
}
void prvTraceSetIRQMask(uint32_t priMask)
{
asm volatile ("MSR primask, %0" : : "r" (priMask) );
}
uint32_t prvTraceGetIRQMask(void)
{
uint32_t result;
asm volatile ("MRS %0, primask" : "=r" (result) );
return result;
}
void prvTraceInitCortexM()
{
DWT_CTRL_REG |= 1; /* Enable the cycle counter */
DWT_CYCLE_COUNTER = 0;
/* Make sure DWT is enabled is enabled, if supported */
REG_DEMCR |= DEMCR_TRCENA;
do{
/* Verify that DWT is supported */
if (REG_DEMCR == 0)
{
vTraceError("DWT not supported by this chip!");
break;
}
/* Verify that DWT_CYCCNT is supported */
if (REG_DWT_CTRL & DWT_CTRL_NOCYCCNT)
{
vTraceError("DWT_CYCCNT not supported by this chip!");
break;
}
/* Reset the cycle counter */
REG_DWT_CYCCNT = 0;
/* Enable the cycle counter */
REG_DWT_CTRL |= DWT_CTRL_CYCCNTENA;
}while(0); /* breaks above jump here */
if (RecorderDataPtr->frequency == 0)
{
@ -109,10 +112,10 @@ void prvTraceInitCortexM()
void vTracePortGetTimeStamp(uint32_t *pTimestamp)
{
static uint32_t last_traceTickCount = 0;
static uint32_t last_hwtc_count = 0;
uint32_t traceTickCount = 0;
uint32_t hwtc_count = 0;
static uint32_t last_hwtc_count = 0;
uint32_t traceTickCount = 0;
uint32_t hwtc_count = 0;
if (trace_disable_timestamp == 1)
{
if (pTimestamp)
@ -120,51 +123,64 @@ void vTracePortGetTimeStamp(uint32_t *pTimestamp)
return;
}
/* Retrieve HWTC_COUNT only once since the same value should be used all throughout this function. */
/* Retrieve HWTC_COUNT only once since the same value should be used all throughout this function. */
#if (HWTC_COUNT_DIRECTION == DIRECTION_INCREMENTING)
hwtc_count = HWTC_COUNT;
hwtc_count = HWTC_COUNT;
#elif (HWTC_COUNT_DIRECTION == DIRECTION_DECREMENTING)
hwtc_count = HWTC_PERIOD - HWTC_COUNT;
hwtc_count = HWTC_PERIOD - HWTC_COUNT;
#else
Junk text to cause compiler error - HWTC_COUNT_DIRECTION is not set correctly!
Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING
Junk text to cause compiler error - HWTC_COUNT_DIRECTION is not set correctly!
Should be DIRECTION_INCREMENTING or DIRECTION_DECREMENTING
#endif
if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
{
/* This means last_traceTickCount is higher than uiTraceTickCount,
so we have previously compensated for a missed tick.
Therefore we use the last stored value because that is more accurate. */
traceTickCount = last_traceTickCount;
}
else
{
/* Business as usual */
traceTickCount = uiTraceTickCount;
}
/* Check for overflow. May occur if the update of uiTraceTickCount has been
delayed due to disabled interrupts. */
if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)
{
/* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */
traceTickCount++;
}
/* Check if the return address is OK, then we perform the calculation. */
if (pTimestamp)
{
/* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
*pTimestamp = traceTickCount * (HWTC_PERIOD / HWTC_DIVISOR);
/* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / HWTC_DIVISOR. */
*pTimestamp += (hwtc_count + traceTickCount * (HWTC_PERIOD % HWTC_DIVISOR)) / HWTC_DIVISOR;
#if (SELECTED_PORT == PORT_Win32)
/* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn
uses QueryPerformanceCounter. That function is not always reliable when used over
multiple threads. We must therefore handle rare cases where the timestamp is less
than the previous. In practice, the Win32 should "never" roll over since the
performance counter is 64 bit wide. */
if (last_hwtc_count > hwtc_count)
{
hwtc_count = last_hwtc_count;
}
#endif
if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000)
{
/* This means last_traceTickCount is higher than uiTraceTickCount,
so we have previously compensated for a missed tick.
Therefore we use the last stored value because that is more accurate. */
traceTickCount = last_traceTickCount;
}
else
{
/* Business as usual */
traceTickCount = uiTraceTickCount;
}
/* Check for overflow. May occur if the update of uiTraceTickCount has been
delayed due to disabled interrupts. */
if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count)
{
/* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */
traceTickCount++;
}
/* Check if the return address is OK, then we perform the calculation. */
if (pTimestamp)
{
/* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */
*pTimestamp = traceTickCount * (HWTC_PERIOD / HWTC_DIVISOR);
/* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / HWTC_DIVISOR. */
*pTimestamp += (hwtc_count + traceTickCount * (HWTC_PERIOD % HWTC_DIVISOR)) / HWTC_DIVISOR;
last_timestamp = *pTimestamp;
}
/* Store the previous values. */
last_traceTickCount = traceTickCount;
last_hwtc_count = hwtc_count;
}
/* Store the previous values. */
last_traceTickCount = traceTickCount;
last_hwtc_count = hwtc_count;
}
#endif
#endif