Initial mirror based on xmos/FreeRTOS feature/upstream-support branch

This commit is contained in:
David Chalco 2020-04-16 14:12:01 -07:00
parent 6199b72fbf
commit 6ccc4fe041
7 changed files with 602 additions and 0 deletions

View file

@ -654,6 +654,7 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
/* For internal use only - execute a 'set bits' command that was pended from
an interrupt. */
portTIMER_CALLBACK_ATTRIBUTE
void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
{
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */
@ -662,6 +663,7 @@ void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet
/* For internal use only - execute a 'clear bits' command that was pended from
an interrupt. */
portTIMER_CALLBACK_ATTRIBUTE
void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )
{
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */

View file

@ -276,6 +276,10 @@ hold explicit before calling the code. */
#error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined.
#endif /* configTIMER_TASK_STACK_DEPTH */
#ifndef portTIMER_CALLBACK_ATTRIBUTE
#define portTIMER_CALLBACK_ATTRIBUTE
#endif /* portTIMER_CALLBACK_ATTRIBUTE */
#endif /* configUSE_TIMERS */
#ifndef portSET_INTERRUPT_MASK_FROM_ISR

187
portable/ThirdParty/XMOS/XCORE200/port.c vendored Normal file
View file

@ -0,0 +1,187 @@
// Copyright (c) 2019, XMOS Ltd, All rights reserved
/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include <xs1.h>
static hwtimer_t xKernelTimer;
uint32_t ulPortYieldRequired = pdFALSE;
/*-----------------------------------------------------------*/
/***** TODO: These should be added to lib_xcore_c *****/
static void _hwtimer_get_trigger_time( hwtimer_t t, uint32_t *time )
{
asm volatile("getd %0, res[%1]" : "=r" (*time): "r" (t));
}
static xcore_c_error_t hwtimer_get_trigger_time( hwtimer_t t, uint32_t *time )
{
RETURN_EXCEPTION_OR_ERROR( _hwtimer_get_trigger_time( t, time ) );
}
/******************************************************/
DEFINE_RTOS_INTERRUPT_CALLBACK( pxKernelTimerISR, pvData )
{
uint32_t ulLastTrigger;
uint32_t ulNow;
/* Need the next interrupt to be scheduled relative to
* the current trigger time, rather than the current
* time. */
hwtimer_get_trigger_time( xKernelTimer, &ulLastTrigger );
/* Check to see if the ISR is late. If it is, we don't
* want to schedule the next interrupt to be in the past. */
hwtimer_get_time( xKernelTimer, &ulNow );
if( ulNow - ulLastTrigger >= configCPU_CLOCK_HZ / configTICK_RATE_HZ )
{
ulLastTrigger = ulNow;
}
ulLastTrigger += configCPU_CLOCK_HZ / configTICK_RATE_HZ;
hwtimer_change_trigger_time( xKernelTimer, ulLastTrigger );
#if configUPDATE_RTOS_TIME_FROM_TICK_ISR == 1
rtos_time_increment( RTOS_TICK_PERIOD( configTICK_RATE_HZ ) );
#endif
if( xTaskIncrementTick() != pdFALSE )
{
ulPortYieldRequired = pdTRUE;
}
}
/*-----------------------------------------------------------*/
static void prvCoreInit( void )
{
rtos_core_register();
asm volatile (
"ldap r11, kexcept\n\t"
"set kep, r11\n\t"
:
:
: "r11"
);
rtos_irq_enable( 1 );
uint32_t ulNow;
hwtimer_get_time( xKernelTimer, &ulNow );
// debug_printf( "The time is now (%u)\n", ulNow );
ulNow += configCPU_CLOCK_HZ / configTICK_RATE_HZ;
hwtimer_setup_interrupt_callback( xKernelTimer, ulNow, NULL, RTOS_INTERRUPT_CALLBACK( pxKernelTimerISR ) );
hwtimer_enable_trigger( xKernelTimer );
}
/*-----------------------------------------------------------*/
DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void )
{
prvCoreInit();
debug_printf( "FreeRTOS initialized\n" );
/*
* Restore the context of the first thread
* to run and jump into it.
*/
asm volatile (
"bu _freertos_restore_ctx\n\t"
: /* no outputs */
: /* no inputs */
: /* nothing is clobbered */
);
}
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/
/* Public functions required by all ports below: */
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
{
//debug_printf( "Top of stack was %p for task %p\n", pxTopOfStack, pxCode );
/*
* Grow the thread's stack by portTHREAD_CONTEXT_STACK_GROWTH
* so we can push the context onto it.
*/
pxTopOfStack -= portTHREAD_CONTEXT_STACK_GROWTH;
uint32_t dp;
uint32_t cp;
/*
* We need to get the current CP and DP pointers.
*/
asm volatile (
"ldaw r11, cp[0]\n\t" /* get CP into R11 */
"mov %0, r11\n\t" /* get R11 (CP) into cp */
"ldaw r11, dp[0]\n\t" /* get DP into R11 */
"mov %1, r11\n\t" /* get R11 (DP) into dp */
: "=r"(cp), "=r"(dp) /* output 0 is cp, output 1 is dp */
: /* there are no inputs */
: "r11" /* R11 gets clobbered */
);
/*
* Push the thread context onto the stack.
* Saved PC will point to the new thread's
* entry pointer.
* Interrupts will default to enabled.
* KEDI is also set to enable dual issue mode
* upon kernel entry.
*/
pxTopOfStack[ 1 ] = ( StackType_t ) pxCode; /* SP[1] := SPC */
pxTopOfStack[ 2 ] = (1<<9) | XS1_SR_IEBLE_MASK; /* SP[2] := SSR */
pxTopOfStack[ 3 ] = 0x00000000; /* SP[3] := SED */
pxTopOfStack[ 4 ] = 0x00000000; /* SP[4] := ET */
pxTopOfStack[ 5 ] = dp; /* SP[5] := DP */
pxTopOfStack[ 6 ] = cp; /* SP[6] := CP */
pxTopOfStack[ 7 ] = 0x00000000; /* SP[7] := LR */
pxTopOfStack[ 8 ] = ( StackType_t ) pvParameters; /* SP[8] := R0 */
pxTopOfStack[ 9 ] = 0x01010101; /* SP[9] := R1 */
pxTopOfStack[ 10 ] = 0x02020202; /* SP[10] := R2 */
pxTopOfStack[ 11 ] = 0x03030303; /* SP[11] := R3 */
pxTopOfStack[ 12 ] = 0x04040404; /* SP[12] := R4 */
pxTopOfStack[ 13 ] = 0x05050505; /* SP[13] := R5 */
pxTopOfStack[ 14 ] = 0x06060606; /* SP[14] := R6 */
pxTopOfStack[ 15 ] = 0x07070707; /* SP[15] := R7 */
pxTopOfStack[ 16 ] = 0x08080808; /* SP[16] := R8 */
pxTopOfStack[ 17 ] = 0x09090909; /* SP[17] := R9 */
pxTopOfStack[ 18 ] = 0x10101010; /* SP[18] := R10 */
pxTopOfStack[ 19 ] = 0x11111111; /* SP[19] := R11 */
//debug_printf( "Top of stack is now %p for task %p\n", pxTopOfStack, pxCode );
/*
* Returns the new top of the stack
*/
return pxTopOfStack;
}
/*-----------------------------------------------------------*/
/*
* See header file for description.
*/
BaseType_t xPortStartScheduler( void )
{
rtos_locks_initialize();
hwtimer_alloc( &xKernelTimer );
RTOS_KERNEL_ENTRY(vPortStartSchedulerOnCore)();
return pdPASS;
}
/*-----------------------------------------------------------*/
void vPortEndScheduler( void )
{
/* Do not implement. */
}
/*-----------------------------------------------------------*/

View file

@ -0,0 +1,150 @@
// Copyright (c) 2020, XMOS Ltd, All rights reserved
#include "rtos_support_rtos_config.h"
/* The FreeRTOS interrupt code calls vTaskSwitchContext.
Therfore it must be added to the rtos_isr group with the
rest of the ISR callback functions. */
.weak _fptrgroup.rtos_isr.nstackwords.group
.add_to_set _fptrgroup.rtos_isr.nstackwords.group, vTaskSwitchContext.nstackwords, vTaskSwitchContext
.globl kexcept
.align 128 /* align the kernel section to 128 bytes */
.type kexcept,@function
.issue_mode dual
.cc_top kexcept.function, kexcept
kexcept:
ldc r11, 0x0004
shl r11, r11, 16
ldc r9, 0x0080
or r11, r11, r9
bau r11 //_TrapHandler is at 0x00040080. TODO: Is it always? Why can't I access the symbol _TrapHandler?
_yield:
set sp, r4 /* Restore the task's SP to save the rest of its context. */
bu _yield_continue /* Skip the ulPortYieldRequired check and jump right to */
/* the context save and switch. Also skips saving SPC */
/* since the kcall handler has already saved it. */
.align 64
kcall:
/* start saving the thread's context */
extsp RTOS_SUPPORT_INTERRUPT_STACK_GROWTH
stw r1, sp[9]
stw r11, sp[19]
/* kcall sets SPC to the instruction of the kcall rather than the next instruction */
/* so we need to adjust the SPC value that we save to the stack: */
stw spc, sp[1] /* save the saved program counter onto the stack... */
ldw r1, sp[1] /* so that we can load it into r1 (which we have already saved). */
add r1, r1, 4 /* Add 4 to the spc to make it point to the instruction after the kcall. */
{stw r1, sp[1] /* Now save it to the stack. */
/* kcall uses the same common function as interrupt callbacks. */
/* tell it to call _yield above. */
ldap r11, _yield}
mov r1, r11
/* fall into rtos_interrupt_callback_common */
.globl rtos_interrupt_callback_common
rtos_interrupt_callback_common:
/* This is the body of the RTOS _xcore_c_interrupt_callback_XXX functions. */
/* r1 = interrupt_callback_t function */
/* Save the thread's context onto the thread's stack. */
/* The stack was extended for this by the wrapper function. */
/* Begin only by saving some registers. The rest will be saved */
/* later if vTaskSwitchContext() needs to be called. */
/* LR needs to be saved because it is clobbered when calling the callback. */
/* r0-r3, and r11 need to be saved because the callback may clobber them. */
/* r4 is saved because it is used here to hold the task SP. */
stw lr, sp[7]
stw r0, sp[8]
/*stw r1, sp[9] already saved by the wrapper function. */
stw r2, sp[10]
stw r3, sp[11]
{stw r4, sp[12]
/*stw r11, sp[19] already saved by the wrapper function. */
ldaw r4, sp[0]} /* Get value of current stackpointer into r4 */
{kentsp 0 /* switch to the kernel stack. */
/* The value 0 is safe to use since we don't need the SP */
/* that it saves to KSP[0]. We already have it in r4. */
get r11, ed} /* Get the event data... */
{mov r0, r11 /* into the first argument for the callback function... */
bla r1} /* and call the callback function. */
set sp, r4 /* Restore the task's SP now. */
ldw r0, dp[ulPortYieldRequired] /* Is a yield required? */
{bf r0, _freertos_restore_ctx_partial /* If not, restore the context now. */
ldc r0, 0}
stw r0, dp[ulPortYieldRequired] /* Otherwise, clear the yield required flag. */
/* Save the rest of the current task's context. */
stw spc, sp[1]
_yield_continue:
stw ssr, sp[2]
stw sed, sp[3]
stw et, sp[4]
stw dp, sp[5]
stw cp, sp[6]
stw r5, sp[13]
stw r6, sp[14]
stw r7, sp[15]
stw r8, sp[16]
stw r9, sp[17]
stw r10, sp[18]
ldw r0, dp[pxCurrentTCB] /* Save the current task's SP to the first */
stw r4, r0[0x0] /* word (top of stack) in the current TCB */
kentsp 0 /* switch back to the kernel stack. */
ldap r11, vTaskSwitchContext
bla r11 /* Finally call vTaskSwitchContext() now that the task's */
/* entire context is saved. */
//krestsp 0 /* unnecessary since KSP is already set and the SP */
/* is being restored next from the current TCB. */
.globl _freertos_restore_ctx
_freertos_restore_ctx:
ldw r0, dp[pxCurrentTCB]
ldw r0, r0[0x0] /* Get the top of the stack from the current TCB... */
set sp, r0; /* into the stack pointer register. */
/* Restore the state */
ldw spc, sp[1]
ldw ssr, sp[2]
ldw sed, sp[3]
ldw et, sp[4]
ldw dp, sp[5]
ldw cp, sp[6]
ldw r5, sp[13]
ldw r6, sp[14]
ldw r7, sp[15]
ldw r8, sp[16]
ldw r9, sp[17]
ldw r10, sp[18]
_freertos_restore_ctx_partial:
ldw lr, sp[7]
ldw r0, sp[8]
ldw r1, sp[9]
ldw r2, sp[10]
ldw r3, sp[11]
ldw r4, sp[12]
{ldw r11, sp[19]
/* shrink the stack by the size of the context just restored */
ldaw sp, sp[RTOS_SUPPORT_INTERRUPT_STACK_GROWTH]}
kret /* exit kernel mode and return to the thread */
.cc_bottom kexcept.function

View file

@ -0,0 +1,174 @@
// Copyright (c) 2020, XMOS Ltd, All rights reserved
#ifndef PORTMACRO_H
#define PORTMACRO_H
#ifndef __ASSEMBLER__
/* Inclusion of xc1.h will result in clock being defined as a type.
* By default, FreeRTOS will require standard time.h, where clock is a function.
*/
#ifndef USE_XCORE_CLOCK_TYPE
#define _clock_defined
#endif
#include <xs1.h>
#include "xcore_c.h"
#include "rtos_support.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Type definitions. */
#define portSTACK_TYPE uint32_t
typedef portSTACK_TYPE StackType_t;
typedef double portDOUBLE;
typedef int32_t BaseType_t;
typedef uint32_t UBaseType_t;
#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else
typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif
/*-----------------------------------------------------------*/
#endif /* __ASSEMBLER__ */
/* Architecture specifics. These can be used by assembly files as well. */
#define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8
#define portCRITICAL_NESTING_IN_TCB 1
#ifdef configNUM_CORES
#warning configNUM_CORES should not be defined when using the single core XCORE port
#undef configNUM_CORES
#endif
/* This may be set to zero in the config file if the rtos_time
functions are not needed or if it is incremented elsewhere. */
#ifndef configUPDATE_RTOS_TIME_FROM_TICK_ISR
#define configUPDATE_RTOS_TIME_FROM_TICK_ISR 1
#endif
/*
* When entering an ISR we need to grow the stack by one more word than
* we actually need to save the thread context. This is because there are
* some functions, written in assembly *cough* memcpy() *cough*, that think
* it is OK to store words at SP[0]. Therefore the ISR must leave SP[0] alone
* even though it is normally not necessary to do so.
*/
#define portTHREAD_CONTEXT_STACK_GROWTH RTOS_SUPPORT_INTERRUPT_STACK_GROWTH
#ifndef __ASSEMBLER__
#define portMEMORY_BARRIER() RTOS_MEMORY_BARRIER()
#define portTASK_STACK_DEPTH(pxTaskCode) RTOS_THREAD_STACK_SIZE(pxTaskCode)
/*-----------------------------------------------------------*/
/* Scheduler utilities. */
#define portYIELD() asm volatile( "KCALLI_lu6 0" ::: "memory" )
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
do \
{ \
if( xSwitchRequired != pdFALSE ) \
{ \
extern uint32_t ulPortYieldRequired; \
ulPortYieldRequired = pdTRUE; \
} \
} while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
/*-----------------------------------------------------------*/
/* Architecture specific optimisations. */
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#endif
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
/* Store/clear the ready priorities in a bit map. */
#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
/*-----------------------------------------------------------*/
#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __builtin_clz( uxReadyPriorities ) )
#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
/*-----------------------------------------------------------*/
/* Critical section management. */
#define portGET_INTERRUPT_STATE() rtos_interrupt_mask_get()
#define portDISABLE_INTERRUPTS() rtos_interrupt_mask_all()
#define portENABLE_INTERRUPTS() rtos_interrupt_unmask_all()
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x)
/*
* Will enable interrupts if ulState is non-zero.
*/
#define portRESTORE_INTERRUPTS(ulState) rtos_interrupt_mask_set(ulState)
/*
* Returns non-zero if currently running in an
* ISR or otherwise in kernel mode.
*/
#define portCHECK_IF_IN_ISR() rtos_isr_running()
#define portASSERT_IF_IN_ISR() configASSERT( portCHECK_IF_IN_ISR() == 0 )
void vTaskEnterCritical(void);
void vTaskExitCritical(void);
#define portENTER_CRITICAL() vTaskEnterCritical()
#define portEXIT_CRITICAL() vTaskExitCritical()
/*-----------------------------------------------------------*/
/* Runtime stats support */
#if ( configGENERATE_RUN_TIME_STATS == 1 )
int xscope_gettime( void );
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* nothing needed here */
#define portGET_RUN_TIME_COUNTER_VALUE() xscope_gettime()
#endif
/*-----------------------------------------------------------*/
/* Maps sprintf and snprintf to the lite version in lib_rtos_support */
#if ( configUSE_DEBUG_SPRINTF == 1 )
#define sprintf(...) rtos_sprintf(__VA_ARGS__)
#define snprintf(...) rtos_snprintf(__VA_ARGS__)
#endif
/* Attribute for the pxCallbackFunction member of the Timer_t struct.
Required by xcc to calculate stack usage. */
#define portTIMER_CALLBACK_ATTRIBUTE __attribute__((fptrgroup("timerCallbackGroup")))
/* Timer callback function macros. For xcc this ensures they get added to the timer callback
group so that stack usage for certain functions in timers.c can be calculated. */
#define portTIMER_CALLBACK_FUNCTION_PROTO( vFunction, xTimer ) void vFunction( TimerHandle_t xTimer )
#define portTIMER_CALLBACK_FUNCTION( vFunction, xTimer ) portTIMER_CALLBACK_ATTRIBUTE void vFunction( TimerHandle_t xTimer )
/*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/*-----------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
#endif /* __ASSEMBLER__ */
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,83 @@
// Copyright (c) 2020, XMOS Ltd, All rights reserved
#ifndef RTOS_SUPPORT_RTOS_CONFIG_H_
#define RTOS_SUPPORT_RTOS_CONFIG_H_
/**
* Lets the application know that the RTOS in use is FreeRTOS.
*/
#define RTOS_FREERTOS 1
/**
* The number of words to extend the stack by when entering an ISR.
*
* When entering an ISR we need to grow the stack by one more word than
* we actually need to save the thread context. This is because there are
* some functions, written in assembly *cough* memcpy() *cough*, that think
* it is OK to store words at SP[0]. Therefore the ISR must leave SP[0] alone
* even though it is normally not necessary to do so.
*/
#define RTOS_SUPPORT_INTERRUPT_STACK_GROWTH ( 19 + 1 )
/**
* The word offset into the stack where R1 is to be stored after it
* is extended when saving a thread's context.
*/
#define RTOS_SUPPORT_INTERRUPT_R1_STACK_OFFSET 9
/**
* The word offset into the stack where R11 is to be stored after it
* is extended when saving a thread's context.
*/
#define RTOS_SUPPORT_INTERRUPT_R11_STACK_OFFSET 19
/**
* The RTOS provided handler that should run when a
* core receives an intercore interrupt request.
*/
#define RTOS_INTERCORE_INTERRUPT_ISR()
/**
* The number of hardware locks that the RTOS
* requires. For a single core RTOS this could be
* zero. Locks are recursive.
*
* Note that the IRQ routines require a lock and
* will share the first one with the RTOS.
*/
#define RTOS_LOCK_COUNT 0
/**
* Remaps all calls to debug_printf() to rtos_printf().
* When this is on, files should not include both rtos_support.h
* and debug_print.h.
*/
#define RTOS_DEBUG_PRINTF_REMAP 1
#ifdef configENABLE_DEBUG_PRINTF
#if configENABLE_DEBUG_PRINTF
/* ensure that debug_printf is enabled */
#ifdef DEBUG_PRINT_ENABLE
#undef DEBUG_PRINT_ENABLE
#endif
#define DEBUG_PRINT_ENABLE 1
#else /* configENABLE_DEBUG_PRINTF */
/* ensure that debug_printf is disabled */
#ifdef DEBUG_UNIT
#undef DEBUG_UNIT
#endif
#ifdef DEBUG_PRINT_ENABLE
#undef DEBUG_PRINT_ENABLE
#endif
#define DEBUG_PRINT_ENABLE 0
#endif /* configENABLE_DEBUG_PRINTF */
#endif
#endif /* RTOS_SUPPORT_RTOS_CONFIG_H_ */

View file

@ -76,6 +76,7 @@ typedef struct tmrTimerControl /* The old naming convention is used to prevent b
ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */
TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */
void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */
portTIMER_CALLBACK_ATTRIBUTE
TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */
#if( configUSE_TRACE_FACILITY == 1 )
UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */
@ -101,6 +102,7 @@ typedef struct tmrTimerParameters
typedef struct tmrCallbackParameters
{
portTIMER_CALLBACK_ATTRIBUTE
PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */
void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */
uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */