mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-06 06:07:45 -04:00
moved XMOS ports to thirdparty
This commit is contained in:
parent
20576e8095
commit
0732461e70
10 changed files with 0 additions and 0 deletions
238
portable/ThirdParty/XCC/XCORE200/port.c
vendored
Normal file
238
portable/ThirdParty/XCC/XCORE200/port.c
vendored
Normal file
|
@ -0,0 +1,238 @@
|
|||
// Copyright (c) 2019, XMOS Ltd, All rights reserved
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <xs1.h>
|
||||
#include <xcore/hwtimer.h>
|
||||
#include <xcore/triggerable.h>
|
||||
|
||||
static hwtimer_t xKernelTimer;
|
||||
|
||||
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
|
||||
* time. */
|
||||
ulLastTrigger = hwtimer_get_trigger_time( xKernelTimer );
|
||||
|
||||
/* 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. */
|
||||
ulNow = hwtimer_get_time( xKernelTimer );
|
||||
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[ xCoreID ] = pdTRUE;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYieldOtherCore( int xOtherCoreID )
|
||||
{
|
||||
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"
|
||||
:
|
||||
:
|
||||
: "r11"
|
||||
);
|
||||
|
||||
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 );
|
||||
|
||||
ulNow += configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
triggerable_setup_interrupt_callback( xKernelTimer, NULL, RTOS_INTERRUPT_CALLBACK( pxKernelTimerISR ) );
|
||||
hwtimer_set_trigger_time( xKernelTimer, ulNow );
|
||||
triggerable_enable_trigger( xKernelTimer );
|
||||
}
|
||||
|
||||
return xCoreID;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void )
|
||||
{
|
||||
int xCoreID;
|
||||
|
||||
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 */
|
||||
: "r"(xCoreID)
|
||||
: "r5", "r6"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/* 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 ] = XS1_SR_IEBLE_MASK
|
||||
| XS1_SR_KEDI_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;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
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();
|
||||
|
||||
vPortStartSMPScheduler();
|
||||
|
||||
return pdPASS;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Do not implement. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
26
portable/ThirdParty/XCC/XCORE200/port.xc
vendored
Normal file
26
portable/ThirdParty/XCC/XCORE200/port.xc
vendored
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();
|
||||
}
|
||||
}
|
160
portable/ThirdParty/XCC/XCORE200/portasm.S
vendored
Normal file
160
portable/ThirdParty/XCC/XCORE200/portasm.S
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
// 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. */
|
||||
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. */
|
||||
|
||||
.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. */
|
||||
|
||||
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]
|
||||
_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]
|
||||
|
||||
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. */
|
||||
|
||||
mov r6, r0} /* copy the RTOS core ID into r6 so we don't lose it. */
|
||||
ldap r11, vTaskSwitchContext
|
||||
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. */
|
||||
|
||||
.globl _freertos_restore_ctx
|
||||
_freertos_restore_ctx:
|
||||
|
||||
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. */
|
||||
|
||||
/* 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
|
||||
|
218
portable/ThirdParty/XCC/XCORE200/portmacro.h
vendored
Normal file
218
portable/ThirdParty/XCC/XCORE200/portmacro.h
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
// 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 "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
|
||||
#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
|
||||
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__
|
||||
|
||||
/* 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)
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() asm volatile( "KCALLI_lu6 0" ::: "memory" )
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
do \
|
||||
{ \
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
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 0
|
||||
#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()
|
||||
|
||||
/*
|
||||
* 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()
|
||||
|
||||
/*
|
||||
* 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 )
|
||||
|
||||
#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.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() (vTaskEnterCritical(), 0)
|
||||
|
||||
/*
|
||||
* 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(), (void) x)
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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 */
|
||||
|
95
portable/ThirdParty/XCC/XCORE200/rtos_support_rtos_config.h
vendored
Normal file
95
portable/ThirdParty/XCC/XCORE200/rtos_support_rtos_config.h
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
// 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() do { \
|
||||
void vIntercoreInterruptISR( void ); \
|
||||
vIntercoreInterruptISR(); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* 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 2
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
#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 */
|
||||
#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_ */
|
||||
|
251
portable/ThirdParty/XCC/XCOREAI/port.c
vendored
Normal file
251
portable/ThirdParty/XCC/XCOREAI/port.c
vendored
Normal file
|
@ -0,0 +1,251 @@
|
|||
// Copyright (c) 2019, XMOS Ltd, All rights reserved
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include <string.h>
|
||||
#include <xs1.h>
|
||||
#include <xcore/hwtimer.h>
|
||||
#include <xcore/triggerable.h>
|
||||
|
||||
static hwtimer_t xKernelTimer;
|
||||
|
||||
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
|
||||
* time. */
|
||||
ulLastTrigger = hwtimer_get_trigger_time( xKernelTimer );
|
||||
|
||||
/* 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. */
|
||||
ulNow = hwtimer_get_time( xKernelTimer );
|
||||
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[ xCoreID ] = pdTRUE;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortYieldOtherCore( int xOtherCoreID )
|
||||
{
|
||||
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"
|
||||
:
|
||||
:
|
||||
: "r11"
|
||||
);
|
||||
|
||||
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 );
|
||||
|
||||
ulNow += configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
triggerable_setup_interrupt_callback( xKernelTimer, NULL, RTOS_INTERRUPT_CALLBACK( pxKernelTimerISR ) );
|
||||
hwtimer_set_trigger_time( xKernelTimer, ulNow );
|
||||
triggerable_enable_trigger( xKernelTimer );
|
||||
}
|
||||
|
||||
return xCoreID;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
DEFINE_RTOS_KERNEL_ENTRY( void, vPortStartSchedulerOnCore, void )
|
||||
{
|
||||
int xCoreID;
|
||||
|
||||
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 */
|
||||
: "r"(xCoreID)
|
||||
: "r5", "r6"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
/* 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 ] = XS1_SR_IEBLE_MASK
|
||||
| XS1_SR_KEDI_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 */
|
||||
pxTopOfStack[ 20 ] = 0x00000000; /* SP[20] := vH and vSR */
|
||||
memset(&pxTopOfStack[21], 0, 32); /* SP[21 - 28] := vR */
|
||||
memset(&pxTopOfStack[29], 1, 32); /* SP[29 - 36] := vD */
|
||||
memset(&pxTopOfStack[37], 2, 32); /* SP[37 - 44] := vC */
|
||||
|
||||
//debug_printf( "Top of stack is now %p for task %p\n", pxTopOfStack, pxCode );
|
||||
|
||||
/*
|
||||
* Returns the new top of the stack
|
||||
*/
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
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();
|
||||
|
||||
vPortStartSMPScheduler();
|
||||
|
||||
return pdPASS;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* Do not implement. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
26
portable/ThirdParty/XCC/XCOREAI/port.xc
vendored
Normal file
26
portable/ThirdParty/XCC/XCOREAI/port.xc
vendored
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();
|
||||
}
|
||||
}
|
186
portable/ThirdParty/XCC/XCOREAI/portasm.S
vendored
Normal file
186
portable/ThirdParty/XCC/XCOREAI/portasm.S
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
// 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, 0x0008
|
||||
shl r11, r11, 16
|
||||
ldc r9, 0x0080
|
||||
or r11, r11, r9
|
||||
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. */
|
||||
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. */
|
||||
|
||||
.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. */
|
||||
|
||||
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. */
|
||||
|
||||
/* Save standard xs2 regs */
|
||||
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]
|
||||
#if 1
|
||||
/* Save VPU status and headroom */
|
||||
vgetc r11
|
||||
{stw r11, sp[20]
|
||||
/* Save VPU regs */
|
||||
ldaw r11, sp[21]}
|
||||
{vstr r11[0]
|
||||
ldaw r11, sp[29]}
|
||||
{vstd r11[0]
|
||||
ldaw r11, sp[37]}
|
||||
vstc r11[0]
|
||||
#endif
|
||||
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. */
|
||||
|
||||
mov r6, r0} /* copy the RTOS core ID into r6 so we don't lose it. */
|
||||
ldap r11, vTaskSwitchContext
|
||||
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. */
|
||||
|
||||
.globl _freertos_restore_ctx
|
||||
_freertos_restore_ctx:
|
||||
|
||||
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. */
|
||||
|
||||
/* Restore the current task's context */
|
||||
#if 1
|
||||
/* Restore VPU regs */
|
||||
ldaw r11, sp[37]
|
||||
{vldc r11[0]
|
||||
ldaw r11, sp[29]}
|
||||
{vldd r11[0]
|
||||
ldaw r11, sp[21]}
|
||||
vldr r11[0]
|
||||
/* Restore VPU status and headroom */
|
||||
ldw r11, sp[20]
|
||||
vsetc r11
|
||||
#endif
|
||||
/* Restore standard xs2 regs */
|
||||
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
|
||||
|
218
portable/ThirdParty/XCC/XCOREAI/portmacro.h
vendored
Normal file
218
portable/ThirdParty/XCC/XCOREAI/portmacro.h
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
// 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 "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
|
||||
#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
|
||||
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__
|
||||
|
||||
/* 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)
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler utilities. */
|
||||
#define portYIELD() asm volatile( "KCALLI_lu6 0" ::: "memory" )
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
do \
|
||||
{ \
|
||||
if( xSwitchRequired != pdFALSE ) \
|
||||
{ \
|
||||
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 0
|
||||
#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()
|
||||
|
||||
/*
|
||||
* 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()
|
||||
|
||||
/*
|
||||
* 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 )
|
||||
|
||||
#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.
|
||||
*/
|
||||
#define portSET_INTERRUPT_MASK_FROM_ISR() (vTaskEnterCritical(), 0)
|
||||
|
||||
/*
|
||||
* 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(), (void) x)
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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 */
|
||||
|
95
portable/ThirdParty/XCC/XCOREAI/rtos_support_rtos_config.h
vendored
Normal file
95
portable/ThirdParty/XCC/XCOREAI/rtos_support_rtos_config.h
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
// 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 ( 44 + 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() do { \
|
||||
void vIntercoreInterruptISR( void ); \
|
||||
vIntercoreInterruptISR(); \
|
||||
} while ( 0 )
|
||||
|
||||
/**
|
||||
* 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 2
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
#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 */
|
||||
#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_ */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue