mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-12 09:07:46 -04:00
Update kernel to support SMP
The XMOS XCore ports are also updated to support SMP.
This commit is contained in:
parent
bec63029ef
commit
596296fc73
16 changed files with 2043 additions and 807 deletions
|
@ -256,7 +256,7 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
|
|||
{
|
||||
if( xAlreadyYielded == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
vTaskYieldWithinAPI();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -408,7 +408,7 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
|
|||
{
|
||||
if( xAlreadyYielded == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
vTaskYieldWithinAPI();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -236,6 +236,14 @@
|
|||
#define configUSE_COUNTING_SEMAPHORES 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_TASK_PREEMPTION_DISABLE
|
||||
#define configUSE_TASK_PREEMPTION_DISABLE 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_CORE_EXCLUSION
|
||||
#define configUSE_CORE_EXCLUSION 0
|
||||
#endif
|
||||
|
||||
#ifndef configUSE_ALTERNATIVE_API
|
||||
#define configUSE_ALTERNATIVE_API 0
|
||||
#endif
|
||||
|
@ -283,6 +291,15 @@
|
|||
#define portSOFTWARE_BARRIER()
|
||||
#endif
|
||||
|
||||
#ifndef configNUM_CORES
|
||||
#define configNUM_CORES 1
|
||||
#endif
|
||||
|
||||
#ifndef configRUN_MULTIPLE_PRIORITIES
|
||||
#define configRUN_MULTIPLE_PRIORITIES 0
|
||||
#endif
|
||||
|
||||
|
||||
/* The timers module relies on xTaskGetSchedulerState(). */
|
||||
#if configUSE_TIMERS == 1
|
||||
|
||||
|
@ -782,10 +799,6 @@
|
|||
#define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 )
|
||||
#endif
|
||||
|
||||
#ifndef portYIELD_WITHIN_API
|
||||
#define portYIELD_WITHIN_API portYIELD
|
||||
#endif
|
||||
|
||||
#ifndef portSUPPRESS_TICKS_AND_SLEEP
|
||||
#define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )
|
||||
#endif
|
||||
|
@ -930,6 +943,18 @@
|
|||
#error configUSE_MUTEXES must be set to 1 to use recursive mutexes
|
||||
#endif
|
||||
|
||||
#if( ( configRUN_MULTIPLE_PRIORITIES == 0 ) && ( configUSE_CORE_EXCLUSION != 0 ) )
|
||||
#error configRUN_MULTIPLE_PRIORITIES must be set to 1 to use core exclusion
|
||||
#endif
|
||||
|
||||
#if( ( configRUN_MULTIPLE_PRIORITIES == 0 ) && ( configUSE_TASK_PREEMPTION_DISABLE != 0 ) )
|
||||
#error configRUN_MULTIPLE_PRIORITIES must be set to 1 to use task preemption disable
|
||||
#endif
|
||||
|
||||
#if( ( configUSE_PREEMPTION == 0 ) && ( configUSE_TASK_PREEMPTION_DISABLE != 0 ) )
|
||||
#error configUSE_PREEMPTION must be set to 1 to use task preemption disable
|
||||
#endif
|
||||
|
||||
#ifndef configINITIAL_TICK_COUNT
|
||||
#define configINITIAL_TICK_COUNT 0
|
||||
#endif
|
||||
|
@ -1174,7 +1199,14 @@ typedef struct xSTATIC_TCB
|
|||
StaticListItem_t xDummy3[ 2 ];
|
||||
UBaseType_t uxDummy5;
|
||||
void * pxDummy6;
|
||||
BaseType_t xDummy23[ 2 ];
|
||||
uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ];
|
||||
#if ( configUSE_TASK_PREEMPTION_DISABLE == 1 )
|
||||
BaseType_t xDummy24;
|
||||
#endif
|
||||
#if ( configUSE_CORE_EXCLUSION == 1 )
|
||||
UBaseType_t uxDummy25;
|
||||
#endif
|
||||
#if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
|
||||
void * pxDummy8;
|
||||
#endif
|
||||
|
|
|
@ -214,6 +214,9 @@ typedef enum
|
|||
* task. h
|
||||
*
|
||||
* Macro to disable all maskable interrupts.
|
||||
* This also returns what the interrupt state was
|
||||
* upon being called. This state may subsequently
|
||||
* be passed to taskRESTORE_INTERRUPTS().
|
||||
*
|
||||
* \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS
|
||||
* \ingroup SchedulerControl
|
||||
|
@ -230,6 +233,28 @@ typedef enum
|
|||
*/
|
||||
#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS()
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
* Macro to restore microcontroller interrupts to
|
||||
* a previous state.
|
||||
*
|
||||
* \defgroup taskRESTORE_INTERRUPTS taskRESTORE_INTERRUPTS
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
#define taskRESTORE_INTERRUPTS(ulState) portRESTORE_INTERRUPTS(ulState)
|
||||
|
||||
/**
|
||||
* task. h
|
||||
*
|
||||
* Macro that determines if it is being called from within an ISR
|
||||
* or a task. Returns non-zero if it is in an ISR.
|
||||
*
|
||||
* \defgroup taskCHECK_IF_IN_ISR taskCHECK_IF_IN_ISR
|
||||
* \ingroup SchedulerControl
|
||||
*/
|
||||
#define taskCHECK_IF_IN_ISR() portCHECK_IF_IN_ISR()
|
||||
|
||||
/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is
|
||||
* 0 to generate more optimal code when configASSERT() is defined as the constant
|
||||
* is used in assert() statements. */
|
||||
|
@ -237,6 +262,8 @@ typedef enum
|
|||
#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 )
|
||||
#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 )
|
||||
|
||||
/* Check if core value is valid */
|
||||
#define taskVALID_CORE_ID( xCoreID ) ( ( BaseType_t ) ( ( 0 <= xCoreID ) && ( xCoreID < configNUM_CORES ) ) )
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* TASK CREATION API
|
||||
|
@ -1208,6 +1235,12 @@ void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
|
|||
*/
|
||||
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
|
||||
|
||||
void vTaskCoreExclusionSet( const TaskHandle_t xTask, UBaseType_t uxCoreExclude );
|
||||
UBaseType_t vTaskCoreExclusionGet( const TaskHandle_t xTask );
|
||||
|
||||
void vTaskPreemptionDisable( const TaskHandle_t xTask );
|
||||
void vTaskPreemptionEnable( const TaskHandle_t xTask );
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* SCHEDULER CONTROL
|
||||
*----------------------------------------------------------*/
|
||||
|
@ -1666,10 +1699,10 @@ BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask,
|
|||
* xTaskGetIdleTaskHandle() is only available if
|
||||
* INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h.
|
||||
*
|
||||
* Simply returns the handle of the idle task. It is not valid to call
|
||||
* xTaskGetIdleTaskHandle() before the scheduler has been started.
|
||||
* Simply returns a pointer to the array of idle task handles.
|
||||
* It is not valid to call xTaskGetIdleTaskHandle() before the scheduler has been started.
|
||||
*/
|
||||
TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||
TaskHandle_t *xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/**
|
||||
* configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for
|
||||
|
@ -2946,7 +2979,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem,
|
|||
* Sets the pointer to the current TCB to the TCB of the highest priority task
|
||||
* that is ready to run.
|
||||
*/
|
||||
portDONT_DISCARD void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION;
|
||||
portDONT_DISCARD void vTaskSwitchContext( BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY
|
||||
|
@ -2959,6 +2992,11 @@ TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION;
|
|||
*/
|
||||
TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Return the handle of the task running on specified core.
|
||||
*/
|
||||
TaskHandle_t xTaskGetCurrentTaskHandleCPU( UBaseType_t xCoreID ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Shortcut used by the queue implementation to prevent unnecessary call to
|
||||
* taskYIELD();
|
||||
|
@ -3044,6 +3082,11 @@ TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION;
|
|||
*/
|
||||
void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* For internal use only. Same as portYIELD_WITHIN_API() in single core FreeRTOS.
|
||||
* For SMP this is not defined by the port.
|
||||
*/
|
||||
void vTaskYieldWithinAPI( void );
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -9,14 +9,29 @@
|
|||
|
||||
static hwtimer_t xKernelTimer;
|
||||
|
||||
uint32_t ulPortYieldRequired = pdFALSE;
|
||||
uint32_t ulPortYieldRequired[ portMAX_CORE_COUNT ] = { pdFALSE };
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vIntercoreInterruptISR( void )
|
||||
{
|
||||
int xCoreID;
|
||||
|
||||
// debug_printf( "In KCALL: %u\n", ulData );
|
||||
xCoreID = rtos_core_id_get();
|
||||
ulPortYieldRequired[ xCoreID ] = pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
DEFINE_RTOS_INTERRUPT_CALLBACK( pxKernelTimerISR, pvData )
|
||||
{
|
||||
uint32_t ulLastTrigger;
|
||||
uint32_t ulNow;
|
||||
int xCoreID;
|
||||
|
||||
xCoreID = 0;
|
||||
|
||||
configASSERT( xCoreID == rtos_core_id_get() );
|
||||
|
||||
/* Need the next interrupt to be scheduled relative to
|
||||
* the current trigger time, rather than the current
|
||||
|
@ -40,14 +55,36 @@ DEFINE_RTOS_INTERRUPT_CALLBACK( pxKernelTimerISR, pvData )
|
|||
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
ulPortYieldRequired = pdTRUE;
|
||||
ulPortYieldRequired[ xCoreID ] = pdTRUE;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCoreInit( void )
|
||||
void vPortYieldOtherCore( int xOtherCoreID )
|
||||
{
|
||||
rtos_core_register();
|
||||
int xCoreID;
|
||||
|
||||
/*
|
||||
* This function must be called from within a critical section.
|
||||
*/
|
||||
|
||||
xCoreID = rtos_core_id_get();
|
||||
|
||||
// debug_printf("%d->%d\n", xCoreID, xOtherCoreID);
|
||||
|
||||
// debug_printf("Yield core %d from %d\n", xOtherCoreID, xCoreID );
|
||||
|
||||
rtos_irq( xOtherCoreID, xCoreID );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static int prvCoreInit( void )
|
||||
{
|
||||
int xCoreID;
|
||||
|
||||
xCoreID = rtos_core_register();
|
||||
debug_printf( "Logical Core %d initializing as FreeRTOS Core %d\n", get_logical_core_id(), xCoreID );
|
||||
|
||||
asm volatile (
|
||||
"ldap r11, kexcept\n\t"
|
||||
"set kep, r11\n\t"
|
||||
|
@ -56,8 +93,15 @@ static void prvCoreInit( void )
|
|||
: "r11"
|
||||
);
|
||||
|
||||
rtos_irq_enable( 1 );
|
||||
rtos_irq_enable( configNUM_CORES );
|
||||
|
||||
/*
|
||||
* All threads wait here until all have enabled IRQs
|
||||
*/
|
||||
while( rtos_irq_ready() == pdFALSE );
|
||||
|
||||
if( xCoreID == 0 )
|
||||
{
|
||||
uint32_t ulNow;
|
||||
ulNow = hwtimer_get_time( xKernelTimer );
|
||||
// debug_printf( "The time is now (%u)\n", ulNow );
|
||||
|
@ -68,23 +112,30 @@ static void prvCoreInit( void )
|
|||
hwtimer_set_trigger_time( xKernelTimer, ulNow );
|
||||
triggerable_enable_trigger( xKernelTimer );
|
||||
}
|
||||
|
||||
return xCoreID;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void )
|
||||
{
|
||||
prvCoreInit();
|
||||
int xCoreID;
|
||||
|
||||
debug_printf( "FreeRTOS initialized\n" );
|
||||
xCoreID = prvCoreInit();
|
||||
|
||||
debug_printf( "FreeRTOS Core %d initialized\n", xCoreID );
|
||||
|
||||
/*
|
||||
* Restore the context of the first thread
|
||||
* to run and jump into it.
|
||||
*/
|
||||
asm volatile (
|
||||
"mov r6, %0\n\t" /* R6 must be the FreeRTOS core ID*/
|
||||
"ldaw r5, dp[pxCurrentTCBs]\n\t" /* R5 must be the TCB list which is indexed by R6 */
|
||||
"bu _freertos_restore_ctx\n\t"
|
||||
: /* no outputs */
|
||||
: /* no inputs */
|
||||
: /* nothing is clobbered */
|
||||
: "r"(xCoreID)
|
||||
: "r5", "r6"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -159,14 +210,22 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortStartSMPScheduler( void );
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
if( ( configNUM_CORES > portMAX_CORE_COUNT ) || ( configNUM_CORES <= 0 ) )
|
||||
{
|
||||
return pdFAIL;
|
||||
}
|
||||
|
||||
rtos_locks_initialize();
|
||||
xKernelTimer = hwtimer_alloc();
|
||||
RTOS_KERNEL_ENTRY(vPortStartSchedulerOnCore)();
|
||||
|
||||
vPortStartSMPScheduler();
|
||||
|
||||
return pdPASS;
|
||||
}
|
||||
|
|
26
portable/XCC/XCORE200/port.xc
Normal file
26
portable/XCC/XCORE200/port.xc
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* port.xc
|
||||
*
|
||||
* Created on: Jul 31, 2019
|
||||
* Author: mbruno
|
||||
*/
|
||||
|
||||
//#include "rtos_support.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "FreeRTOSConfig.h" /* to get configNUM_CORES */
|
||||
#ifndef configNUM_CORES
|
||||
#define configNUM_CORES 1
|
||||
#endif
|
||||
|
||||
void __xcore_interrupt_permitted_ugs_vPortStartSchedulerOnCore(void);
|
||||
|
||||
} /* extern "C" */
|
||||
|
||||
void vPortStartSMPScheduler( void )
|
||||
{
|
||||
par (int i = 0; i < configNUM_CORES; i++) {
|
||||
__xcore_interrupt_permitted_ugs_vPortStartSchedulerOnCore();
|
||||
}
|
||||
}
|
|
@ -21,7 +21,10 @@ kexcept:
|
|||
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. */
|
||||
{set sp, r4 /* Restore the task's SP to save the rest of its context. */
|
||||
get r11, id} /* Get the logical core ID into r11. */
|
||||
ldaw r0, dp[rtos_core_map]
|
||||
ldw r0, r0[r11] /* Translate to the RTOS core ID into r0 */
|
||||
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. */
|
||||
|
@ -68,7 +71,7 @@ rtos_interrupt_callback_common:
|
|||
{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 */
|
||||
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 */
|
||||
|
@ -78,12 +81,16 @@ rtos_interrupt_callback_common:
|
|||
{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. */
|
||||
{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. */
|
||||
get r11, id} /* Get the logical core ID into r11. */
|
||||
ldaw r0, dp[rtos_core_map]
|
||||
ldw r0, r0[r11] /* Translate to the RTOS core ID into r0. */
|
||||
ldaw r2, dp[ulPortYieldRequired] /* Get the yield required array into r2. */
|
||||
ldw r1, r2[r0] /* Is a yield required for this core? */
|
||||
{bf r1, _freertos_restore_ctx_partial /* If not, restore the context now. */
|
||||
ldc r1, 0}
|
||||
stw r1, r2[r0] /* Otherwise, clear the yield required flag. */
|
||||
|
||||
/* Save the rest of the current task's context. */
|
||||
stw spc, sp[1]
|
||||
|
@ -100,14 +107,17 @@ _yield_continue:
|
|||
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 */
|
||||
ldaw r5, dp[pxCurrentTCBs] /* Get the current TCB array into r5. */
|
||||
ldw r1, r5[r0] /* Get this core's current TCB pointer into r1. */
|
||||
stw r4, r1[0x0] /* Save the current task's SP to the first */
|
||||
/* word (top of stack) in the current TCB. */
|
||||
|
||||
kentsp 0 /* switch back to the kernel stack. */
|
||||
{kentsp 0 /* switch back to the kernel stack. */
|
||||
|
||||
mov r6, r0} /* copy the RTOS core ID into r6 so we don't lose it. */
|
||||
ldap r11, vTaskSwitchContext
|
||||
bla r11 /* Finally call vTaskSwitchContext() now that the task's */
|
||||
/* entire context is saved. */
|
||||
bla r11 /* Finally call vTaskSwitchContext(core_id) now that the task's */
|
||||
/* entire context is saved. Note the core id in r0 is the argument. */
|
||||
|
||||
//krestsp 0 /* unnecessary since KSP is already set and the SP */
|
||||
/* is being restored next from the current TCB. */
|
||||
|
@ -115,7 +125,7 @@ _yield_continue:
|
|||
.globl _freertos_restore_ctx
|
||||
_freertos_restore_ctx:
|
||||
|
||||
ldw r0, dp[pxCurrentTCB]
|
||||
ldw r0, r5[r6] /* get this core's current TCB pointer into r0 */
|
||||
ldw r0, r0[0x0] /* Get the top of the stack from the current TCB... */
|
||||
set sp, r0; /* into the stack pointer register. */
|
||||
|
||||
|
|
|
@ -46,9 +46,9 @@ typedef uint32_t UBaseType_t;
|
|||
#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
|
||||
#define portMAX_CORE_COUNT 8
|
||||
#ifndef configNUM_CORES
|
||||
#define configNUM_CORES 1
|
||||
#endif
|
||||
|
||||
/* This may be set to zero in the config file if the rtos_time
|
||||
|
@ -67,6 +67,12 @@ functions are not needed or if it is incremented elsewhere. */
|
|||
#define portTHREAD_CONTEXT_STACK_GROWTH RTOS_SUPPORT_INTERRUPT_STACK_GROWTH
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Check validity of number of cores specified in config */
|
||||
#if ( configNUM_CORES < 1 || portMAX_CORE_COUNT < configNUM_CORES )
|
||||
#error "Invalid number of cores specified in config!"
|
||||
#endif
|
||||
|
||||
#define portMEMORY_BARRIER() RTOS_MEMORY_BARRIER()
|
||||
#define portTASK_STACK_DEPTH(pxTaskCode) RTOS_THREAD_STACK_SIZE(pxTaskCode)
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -79,17 +85,24 @@ do \
|
|||
{ \
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
extern uint32_t ulPortYieldRequired; \
|
||||
ulPortYieldRequired = pdTRUE; \
|
||||
extern uint32_t ulPortYieldRequired[ portMAX_CORE_COUNT ]; \
|
||||
ulPortYieldRequired[ portGET_CORE_ID() ] = pdTRUE; \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* SMP utilities. */
|
||||
#define portGET_CORE_ID() rtos_core_id_get()
|
||||
|
||||
void vPortYieldOtherCore( int xOtherCoreID );
|
||||
#define portYIELD_CORE( x ) vPortYieldOtherCore( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
@ -108,10 +121,16 @@ do \
|
|||
/* Critical section management. */
|
||||
|
||||
#define portGET_INTERRUPT_STATE() rtos_interrupt_mask_get()
|
||||
|
||||
/*
|
||||
* This differs from the standard portDISABLE_INTERRUPTS()
|
||||
* in that it also returns what the interrupt state was
|
||||
* before it disabling interrupts.
|
||||
*/
|
||||
#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.
|
||||
*/
|
||||
|
@ -122,12 +141,43 @@ do \
|
|||
* 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 )
|
||||
|
||||
#define portGET_ISR_LOCK() rtos_lock_acquire(0)
|
||||
#define portRELEASE_ISR_LOCK() rtos_lock_release(0)
|
||||
#define portGET_TASK_LOCK() rtos_lock_acquire(1)
|
||||
#define portRELEASE_TASK_LOCK() rtos_lock_release(1)
|
||||
|
||||
void vTaskEnterCritical(void);
|
||||
void vTaskExitCritical(void);
|
||||
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||
|
||||
/*
|
||||
* vTaskEnterCritical() has been modified to be safe to use
|
||||
* from within ISRs. The previous mask does not need to be
|
||||
* returned since in the xCORE interrupts are always disabled
|
||||
* in ISRs. Effectively this call just grabs the kernel lock
|
||||
* when called from an ISR.
|
||||
*/
|
||||
static inline uint32_t portSET_INTERRUPT_MASK_FROM_ISR( void )
|
||||
{
|
||||
vTaskEnterCritical();
|
||||
return 0;
|
||||
}
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
|
||||
|
||||
/*
|
||||
* vTaskExitCritical() has been modified to be safe to use
|
||||
* from within ISRs. When the nesting level has reached zero
|
||||
* it releases the lock, but when called from within an ISR
|
||||
* it will *not* re-enable interrupts since it is assumed they
|
||||
* were previously disabled. Thus the previous state in x is
|
||||
* unused.
|
||||
*/
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vTaskExitCritical()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Runtime stats support */
|
||||
|
|
|
@ -35,7 +35,10 @@
|
|||
* The RTOS provided handler that should run when a
|
||||
* core receives an intercore interrupt request.
|
||||
*/
|
||||
#define RTOS_INTERCORE_INTERRUPT_ISR()
|
||||
#define RTOS_INTERCORE_INTERRUPT_ISR() do { \
|
||||
void vIntercoreInterruptISR( void ); \
|
||||
vIntercoreInterruptISR(); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* The number of hardware locks that the RTOS
|
||||
|
@ -45,7 +48,7 @@
|
|||
* Note that the IRQ routines require a lock and
|
||||
* will share the first one with the RTOS.
|
||||
*/
|
||||
#define RTOS_LOCK_COUNT 0
|
||||
#define RTOS_LOCK_COUNT 2
|
||||
|
||||
/**
|
||||
* Remaps all calls to debug_printf() to rtos_printf().
|
||||
|
@ -64,6 +67,15 @@
|
|||
#endif
|
||||
#define DEBUG_PRINT_ENABLE 1
|
||||
|
||||
#ifndef configTASKS_DEBUG
|
||||
#define configTASKS_DEBUG 0
|
||||
#endif
|
||||
#if configTASKS_DEBUG == 1
|
||||
#define DEBUG_PRINT_ENABLE_FREERTOS_TASKS 1
|
||||
#else
|
||||
#define DEBUG_PRINT_DISABLE_FREERTOS_TASKS 1
|
||||
#endif
|
||||
|
||||
#else /* configENABLE_DEBUG_PRINTF */
|
||||
|
||||
/* ensure that debug_printf is disabled */
|
||||
|
|
|
@ -10,14 +10,29 @@
|
|||
|
||||
static hwtimer_t xKernelTimer;
|
||||
|
||||
uint32_t ulPortYieldRequired = pdFALSE;
|
||||
uint32_t ulPortYieldRequired[ portMAX_CORE_COUNT ] = { pdFALSE };
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vIntercoreInterruptISR( void )
|
||||
{
|
||||
int xCoreID;
|
||||
|
||||
// debug_printf( "In KCALL: %u\n", ulData );
|
||||
xCoreID = rtos_core_id_get();
|
||||
ulPortYieldRequired[ xCoreID ] = pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
DEFINE_RTOS_INTERRUPT_CALLBACK( pxKernelTimerISR, pvData )
|
||||
{
|
||||
uint32_t ulLastTrigger;
|
||||
uint32_t ulNow;
|
||||
int xCoreID;
|
||||
|
||||
xCoreID = 0;
|
||||
|
||||
configASSERT( xCoreID == rtos_core_id_get() );
|
||||
|
||||
/* Need the next interrupt to be scheduled relative to
|
||||
* the current trigger time, rather than the current
|
||||
|
@ -41,14 +56,36 @@ DEFINE_RTOS_INTERRUPT_CALLBACK( pxKernelTimerISR, pvData )
|
|||
|
||||
if( xTaskIncrementTick() != pdFALSE )
|
||||
{
|
||||
ulPortYieldRequired = pdTRUE;
|
||||
ulPortYieldRequired[ xCoreID ] = pdTRUE;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvCoreInit( void )
|
||||
void vPortYieldOtherCore( int xOtherCoreID )
|
||||
{
|
||||
rtos_core_register();
|
||||
int xCoreID;
|
||||
|
||||
/*
|
||||
* This function must be called from within a critical section.
|
||||
*/
|
||||
|
||||
xCoreID = rtos_core_id_get();
|
||||
|
||||
// debug_printf("%d->%d\n", xCoreID, xOtherCoreID);
|
||||
|
||||
// debug_printf("Yield core %d from %d\n", xOtherCoreID, xCoreID );
|
||||
|
||||
rtos_irq( xOtherCoreID, xCoreID );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static int prvCoreInit( void )
|
||||
{
|
||||
int xCoreID;
|
||||
|
||||
xCoreID = rtos_core_register();
|
||||
debug_printf( "Logical Core %d initializing as FreeRTOS Core %d\n", get_logical_core_id(), xCoreID );
|
||||
|
||||
asm volatile (
|
||||
"ldap r11, kexcept\n\t"
|
||||
"set kep, r11\n\t"
|
||||
|
@ -57,8 +94,15 @@ static void prvCoreInit( void )
|
|||
: "r11"
|
||||
);
|
||||
|
||||
rtos_irq_enable( 1 );
|
||||
rtos_irq_enable( configNUM_CORES );
|
||||
|
||||
/*
|
||||
* All threads wait here until all have enabled IRQs
|
||||
*/
|
||||
while( rtos_irq_ready() == pdFALSE );
|
||||
|
||||
if( xCoreID == 0 )
|
||||
{
|
||||
uint32_t ulNow;
|
||||
ulNow = hwtimer_get_time( xKernelTimer );
|
||||
// debug_printf( "The time is now (%u)\n", ulNow );
|
||||
|
@ -69,23 +113,38 @@ static void prvCoreInit( void )
|
|||
hwtimer_set_trigger_time( xKernelTimer, ulNow );
|
||||
triggerable_enable_trigger( xKernelTimer );
|
||||
}
|
||||
|
||||
return xCoreID;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void )
|
||||
{
|
||||
prvCoreInit();
|
||||
int xCoreID;
|
||||
|
||||
debug_printf( "FreeRTOS initialized\n" );
|
||||
xCoreID = prvCoreInit();
|
||||
|
||||
#if( configUSE_CORE_INIT_HOOK == 1 )
|
||||
{
|
||||
extern void vApplicationCoreInitHook( BaseType_t xCoreID );
|
||||
|
||||
vApplicationCoreInitHook( xCoreID );
|
||||
}
|
||||
#endif
|
||||
|
||||
debug_printf( "FreeRTOS Core %d initialized\n", xCoreID );
|
||||
|
||||
/*
|
||||
* Restore the context of the first thread
|
||||
* to run and jump into it.
|
||||
*/
|
||||
asm volatile (
|
||||
"mov r6, %0\n\t" /* R6 must be the FreeRTOS core ID*/
|
||||
"ldaw r5, dp[pxCurrentTCBs]\n\t" /* R5 must be the TCB list which is indexed by R6 */
|
||||
"bu _freertos_restore_ctx\n\t"
|
||||
: /* no outputs */
|
||||
: /* no inputs */
|
||||
: /* nothing is clobbered */
|
||||
: "r"(xCoreID)
|
||||
: "r5", "r6"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -164,14 +223,22 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortStartSMPScheduler( void );
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
BaseType_t xPortStartScheduler( void )
|
||||
{
|
||||
if( ( configNUM_CORES > portMAX_CORE_COUNT ) || ( configNUM_CORES <= 0 ) )
|
||||
{
|
||||
return pdFAIL;
|
||||
}
|
||||
|
||||
rtos_locks_initialize();
|
||||
xKernelTimer = hwtimer_alloc();
|
||||
RTOS_KERNEL_ENTRY(vPortStartSchedulerOnCore)();
|
||||
|
||||
vPortStartSMPScheduler();
|
||||
|
||||
return pdPASS;
|
||||
}
|
||||
|
|
26
portable/XCC/XCOREAI/port.xc
Normal file
26
portable/XCC/XCOREAI/port.xc
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* port.xc
|
||||
*
|
||||
* Created on: Jul 31, 2019
|
||||
* Author: mbruno
|
||||
*/
|
||||
|
||||
//#include "rtos_support.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "FreeRTOSConfig.h" /* to get configNUM_CORES */
|
||||
#ifndef configNUM_CORES
|
||||
#define configNUM_CORES 1
|
||||
#endif
|
||||
|
||||
void __xcore_interrupt_permitted_ugs_vPortStartSchedulerOnCore(void);
|
||||
|
||||
} /* extern "C" */
|
||||
|
||||
void vPortStartSMPScheduler( void )
|
||||
{
|
||||
par (int i = 0; i < configNUM_CORES; i++) {
|
||||
__xcore_interrupt_permitted_ugs_vPortStartSchedulerOnCore();
|
||||
}
|
||||
}
|
|
@ -21,7 +21,10 @@ kexcept:
|
|||
bau r11 //_TrapHandler is at 0x00080080. 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. */
|
||||
{set sp, r4 /* Restore the task's SP to save the rest of its context. */
|
||||
get r11, id} /* Get the logical core ID into r11. */
|
||||
ldaw r0, dp[rtos_core_map]
|
||||
ldw r0, r0[r11] /* Translate to the RTOS core ID into r0 */
|
||||
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. */
|
||||
|
@ -68,7 +71,7 @@ rtos_interrupt_callback_common:
|
|||
{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 */
|
||||
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 */
|
||||
|
@ -78,12 +81,16 @@ rtos_interrupt_callback_common:
|
|||
{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. */
|
||||
{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. */
|
||||
get r11, id} /* Get the logical core ID into r11. */
|
||||
ldaw r0, dp[rtos_core_map]
|
||||
ldw r0, r0[r11] /* Translate to the RTOS core ID into r0. */
|
||||
ldaw r2, dp[ulPortYieldRequired] /* Get the yield required array into r2. */
|
||||
ldw r1, r2[r0] /* Is a yield required for this core? */
|
||||
{bf r1, _freertos_restore_ctx_partial /* If not, restore the context now. */
|
||||
ldc r1, 0}
|
||||
stw r1, r2[r0] /* Otherwise, clear the yield required flag. */
|
||||
|
||||
/* Save the rest of the current task's context. */
|
||||
|
||||
|
@ -113,14 +120,17 @@ _yield_continue:
|
|||
ldaw r11, sp[37]}
|
||||
vstc r11[0]
|
||||
#endif
|
||||
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 */
|
||||
ldaw r5, dp[pxCurrentTCBs] /* Get the current TCB array into r5. */
|
||||
ldw r1, r5[r0] /* Get this core's current TCB pointer into r1. */
|
||||
stw r4, r1[0x0] /* Save the current task's SP to the first */
|
||||
/* word (top of stack) in the current TCB. */
|
||||
|
||||
kentsp 0 /* switch back to the kernel stack. */
|
||||
{kentsp 0 /* switch back to the kernel stack. */
|
||||
|
||||
mov r6, r0} /* copy the RTOS core ID into r6 so we don't lose it. */
|
||||
ldap r11, vTaskSwitchContext
|
||||
bla r11 /* Finally call vTaskSwitchContext() now that the task's */
|
||||
/* entire context is saved. */
|
||||
bla r11 /* Finally call vTaskSwitchContext(core_id) now that the task's */
|
||||
/* entire context is saved. Note the core id in r0 is the argument. */
|
||||
|
||||
//krestsp 0 /* unnecessary since KSP is already set and the SP */
|
||||
/* is being restored next from the current TCB. */
|
||||
|
@ -128,7 +138,7 @@ _yield_continue:
|
|||
.globl _freertos_restore_ctx
|
||||
_freertos_restore_ctx:
|
||||
|
||||
ldw r0, dp[pxCurrentTCB]
|
||||
ldw r0, r5[r6] /* get this core's current TCB pointer into r0 */
|
||||
ldw r0, r0[0x0] /* Get the top of the stack from the current TCB... */
|
||||
set sp, r0 /* into the stack pointer register. */
|
||||
|
||||
|
|
|
@ -46,9 +46,9 @@ typedef uint32_t UBaseType_t;
|
|||
#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
|
||||
#define portMAX_CORE_COUNT 8
|
||||
#ifndef configNUM_CORES
|
||||
#define configNUM_CORES 1
|
||||
#endif
|
||||
|
||||
/* This may be set to zero in the config file if the rtos_time
|
||||
|
@ -67,6 +67,12 @@ functions are not needed or if it is incremented elsewhere. */
|
|||
#define portTHREAD_CONTEXT_STACK_GROWTH RTOS_SUPPORT_INTERRUPT_STACK_GROWTH
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
/* Check validity of number of cores specified in config */
|
||||
#if ( configNUM_CORES < 1 || portMAX_CORE_COUNT < configNUM_CORES )
|
||||
#error "Invalid number of cores specified in config!"
|
||||
#endif
|
||||
|
||||
#define portMEMORY_BARRIER() RTOS_MEMORY_BARRIER()
|
||||
#define portTASK_STACK_DEPTH(pxTaskCode) RTOS_THREAD_STACK_SIZE(pxTaskCode)
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -79,17 +85,24 @@ do \
|
|||
{ \
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
extern uint32_t ulPortYieldRequired; \
|
||||
ulPortYieldRequired = pdTRUE; \
|
||||
extern uint32_t ulPortYieldRequired[ portMAX_CORE_COUNT ]; \
|
||||
ulPortYieldRequired[ portGET_CORE_ID() ] = pdTRUE; \
|
||||
} \
|
||||
} while( 0 )
|
||||
|
||||
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* SMP utilities. */
|
||||
#define portGET_CORE_ID() rtos_core_id_get()
|
||||
|
||||
void vPortYieldOtherCore( int xOtherCoreID );
|
||||
#define portYIELD_CORE( x ) vPortYieldOtherCore( x )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specific optimisations. */
|
||||
#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
|
||||
#endif
|
||||
|
||||
#if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
|
||||
|
@ -108,10 +121,16 @@ do \
|
|||
/* Critical section management. */
|
||||
|
||||
#define portGET_INTERRUPT_STATE() rtos_interrupt_mask_get()
|
||||
|
||||
/*
|
||||
* This differs from the standard portDISABLE_INTERRUPTS()
|
||||
* in that it also returns what the interrupt state was
|
||||
* before it disabling interrupts.
|
||||
*/
|
||||
#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.
|
||||
*/
|
||||
|
@ -122,12 +141,43 @@ do \
|
|||
* 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 )
|
||||
|
||||
#define portGET_ISR_LOCK() rtos_lock_acquire(0)
|
||||
#define portRELEASE_ISR_LOCK() rtos_lock_release(0)
|
||||
#define portGET_TASK_LOCK() rtos_lock_acquire(1)
|
||||
#define portRELEASE_TASK_LOCK() rtos_lock_release(1)
|
||||
|
||||
void vTaskEnterCritical(void);
|
||||
void vTaskExitCritical(void);
|
||||
#define portENTER_CRITICAL() vTaskEnterCritical()
|
||||
#define portEXIT_CRITICAL() vTaskExitCritical()
|
||||
|
||||
/*
|
||||
* vTaskEnterCritical() has been modified to be safe to use
|
||||
* from within ISRs. The previous mask does not need to be
|
||||
* returned since in the xCORE interrupts are always disabled
|
||||
* in ISRs. Effectively this call just grabs the kernel lock
|
||||
* when called from an ISR.
|
||||
*/
|
||||
static inline uint32_t portSET_INTERRUPT_MASK_FROM_ISR( void )
|
||||
{
|
||||
vTaskEnterCritical();
|
||||
return 0;
|
||||
}
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
|
||||
|
||||
/*
|
||||
* vTaskExitCritical() has been modified to be safe to use
|
||||
* from within ISRs. When the nesting level has reached zero
|
||||
* it releases the lock, but when called from within an ISR
|
||||
* it will *not* re-enable interrupts since it is assumed they
|
||||
* were previously disabled. Thus the previous state in x is
|
||||
* unused.
|
||||
*/
|
||||
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vTaskExitCritical()
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Runtime stats support */
|
||||
|
|
|
@ -35,7 +35,10 @@
|
|||
* The RTOS provided handler that should run when a
|
||||
* core receives an intercore interrupt request.
|
||||
*/
|
||||
#define RTOS_INTERCORE_INTERRUPT_ISR()
|
||||
#define RTOS_INTERCORE_INTERRUPT_ISR() do { \
|
||||
void vIntercoreInterruptISR( void ); \
|
||||
vIntercoreInterruptISR(); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* The number of hardware locks that the RTOS
|
||||
|
@ -45,7 +48,7 @@
|
|||
* Note that the IRQ routines require a lock and
|
||||
* will share the first one with the RTOS.
|
||||
*/
|
||||
#define RTOS_LOCK_COUNT 0
|
||||
#define RTOS_LOCK_COUNT 2
|
||||
|
||||
/**
|
||||
* Remaps all calls to debug_printf() to rtos_printf().
|
||||
|
@ -64,6 +67,15 @@
|
|||
#endif
|
||||
#define DEBUG_PRINT_ENABLE 1
|
||||
|
||||
#ifndef configTASKS_DEBUG
|
||||
#define configTASKS_DEBUG 0
|
||||
#endif
|
||||
#if configTASKS_DEBUG == 1
|
||||
#define DEBUG_PRINT_ENABLE_FREERTOS_TASKS 1
|
||||
#else
|
||||
#define DEBUG_PRINT_DISABLE_FREERTOS_TASKS 1
|
||||
#endif
|
||||
|
||||
#else /* configENABLE_DEBUG_PRINTF */
|
||||
|
||||
/* ensure that debug_printf is disabled */
|
||||
|
|
10
queue.c
10
queue.c
|
@ -87,7 +87,7 @@ typedef struct SemaphoreData
|
|||
* performed just because a higher priority task has been woken. */
|
||||
#define queueYIELD_IF_USING_PREEMPTION()
|
||||
#else
|
||||
#define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API()
|
||||
#define queueYIELD_IF_USING_PREEMPTION() vTaskYieldWithinAPI()
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -957,7 +957,7 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue,
|
|||
* is also a higher priority task in the pending ready list. */
|
||||
if( xTaskResumeAll() == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
vTaskYieldWithinAPI();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1422,7 +1422,7 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue,
|
|||
|
||||
if( xTaskResumeAll() == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
vTaskYieldWithinAPI();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1614,7 +1614,7 @@ BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue,
|
|||
|
||||
if( xTaskResumeAll() == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
vTaskYieldWithinAPI();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1792,7 +1792,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue,
|
|||
|
||||
if( xTaskResumeAll() == pdFALSE )
|
||||
{
|
||||
portYIELD_WITHIN_API();
|
||||
vTaskYieldWithinAPI();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
3
timers.c
3
timers.c
|
@ -1,7 +1,6 @@
|
|||
/*
|
||||
* FreeRTOS Kernel V10.4.3
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -669,7 +668,7 @@
|
|||
* block time to expire. If a command arrived between the
|
||||
* critical section being exited and this yield then the yield
|
||||
* will not cause the task to block. */
|
||||
portYIELD_WITHIN_API();
|
||||
vTaskYieldWithinAPI();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue