From 31b2f2b712149e5f39feacabc191db43e720c1f7 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Fri, 6 Apr 2012 16:36:52 +0000 Subject: [PATCH] Starting point for Tasking XMC4500 demo. Compiling only, not executed yet. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1724 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../.cproject | 119 ++++ .../.project | 20 + .../FreeRTOSConfig.h | 143 ++++ .../portable/Tasking/ARM_CM4F/port.c | 234 ++++++ .../portable/Tasking/ARM_CM4F/port_asm.asm | 169 +++++ .../portable/Tasking/ARM_CM4F/portmacro.h | 144 ++++ .../RTOSDemo.lsl | 8 + .../Startup/Infineon/XMC4500/cstart_XMC4500.c | 104 +++ .../Startup/Infineon/XMC4500/system_XMC4500.c | 419 +++++++++++ .../main.c | 223 ++++++ .../main_blinky.c | 233 ++++++ .../main_full.c | 664 ++++++++++++++++++ 12 files changed, 2480 insertions(+) create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/.cproject create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/.project create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOSConfig.h create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/port.c create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/port_asm.asm create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/portmacro.h create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/RTOSDemo.lsl create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/Startup/Infineon/XMC4500/cstart_XMC4500.c create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/Startup/Infineon/XMC4500/system_XMC4500.c create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main.c create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main_blinky.c create mode 100644 Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main_full.c diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/.cproject b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/.cproject new file mode 100644 index 000000000..ca51e565a --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/.cproject @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + TASKING VX-toolset for ARM Cortex: object linker v4.2r1 Build 135 SN 00521976 + TASKING VX-toolset for ARM Cortex: control program v4.2r1 Build 118 + TASKING VX-toolset for ARM Cortex: assembler v4.2r1 Build 141 + TASKING program builder v4.2r1 Build 063 + TASKING VX-toolset for ARM Cortex: C compiler v4.2r1 Build 652 SN 00521976 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/.project b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/.project new file mode 100644 index 000000000..34056f957 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/.project @@ -0,0 +1,20 @@ + + + RTOSDemo + + + + + + com.tasking.arm.TskManagedBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.tasking.arm.target + + diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOSConfig.h b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOSConfig.h new file mode 100644 index 000000000..4c1d32df8 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOSConfig.h @@ -0,0 +1,143 @@ +/* + FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +#include +extern uint32_t SystemCoreClock; + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 5 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 40960 ) ) +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configGENERATE_RUN_TIME_STATS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( 2 ) +#define configTIMER_QUEUE_LENGTH 5 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS + /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 6 /* 63 priority levels */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x3f + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/port.c b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/port.c new file mode 100644 index 000000000..2e34b8737 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/port.c @@ -0,0 +1,234 @@ +/* + FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/*----------------------------------------------------------- + * Implementation of functions defined in portable.h for the ARM CM4F port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Constants required to manipulate the NVIC. */ +#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long * ) 0xe000e010 ) +#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long * ) 0xe000e014 ) +#define portNVIC_INT_CTRL ( ( volatile unsigned long * ) 0xe000ed04 ) +#define portNVIC_SYSPRI2 ( ( volatile unsigned long * ) 0xe000ed20 ) +#define portNVIC_SYSTICK_CLK 0x00000004 +#define portNVIC_SYSTICK_INT 0x00000002 +#define portNVIC_SYSTICK_ENABLE 0x00000001 +#define portNVIC_PENDSVSET 0x10000000 +#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16 ) +#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24 ) + +/* Constants required to manipulate the VFP. */ +#define portFPCCR ( ( volatile unsigned long * ) 0xe000ef34 ) /* Floating point context control register. */ +#define portASPEN_AND_LSPEN_BITS ( 0x3UL << 30UL ) + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR ( 0x01000000 ) +#define portINITIAL_EXEC_RETURN ( 0xfffffffd ) + +/* The priority used by the kernel is assigned to a variable to make access +from inline assembler easier. */ +const unsigned long ulKernelPriority = configKERNEL_INTERRUPT_PRIORITY; + +/* Each task maintains its own interrupt status in the critical nesting +variable. */ +static unsigned long ulCriticalNesting = 0xaaaaaaaaUL; + +/* + * Setup the timer to generate the tick interrupts. + */ +static void prvSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void SysTick_Handler( void ); + +/* + * Functions defined in port_asm.asm. + */ +extern void vPortEnableVFP( void ); +extern void vPortStartFirstTask( void ); + +/* This exists purely to allow the const to be used from within the +port_asm.asm assembly file. */ +const unsigned long ulMaxSyscallInterruptPriorityConst = configMAX_SYSCALL_INTERRUPT_PRIORITY; + +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters ) +{ + /* Simulate the stack frame as it would be created by a context switch + interrupt. */ + + /* Offset added to account for the way the MCU uses the stack on entry/exit + of interrupts, and to ensure alignment. */ + pxTopOfStack -= 2; + + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; + *pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */ + pxTopOfStack--; + *pxTopOfStack = 0; /* LR */ + + /* Save code space by skipping register initialisation. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */ + + /* A save method is being used that requiers each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; + + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ + + return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portBASE_TYPE xPortStartScheduler( void ) +{ + /* Make PendSV and SysTick the lowest priority interrupts. */ + *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI; + *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI; + + /* Start the timer that generates the tick ISR. Interrupts are disabled + here already. */ + prvSetupTimerInterrupt(); + + /* Initialise the critical nesting count ready for the first task. */ + ulCriticalNesting = 0; + + /* Ensure the VFP is enabled - it should be anyway. */ + vPortEnableVFP(); + + /* Lazy save always. */ + *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; + + /* Start the first task. */ + vPortStartFirstTask(); + + /* Should not get here! */ + return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ + /* It is unlikely that the CM4F port will require this function as there + is nothing to return to. */ +} +/*-----------------------------------------------------------*/ + +void vPortYieldFromISR( void ) +{ + /* Set a PendSV to request a context switch. */ + *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; +} +/*-----------------------------------------------------------*/ + +void vPortEnterCritical( void ) +{ + portDISABLE_INTERRUPTS(); + ulCriticalNesting++; +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ + ulCriticalNesting--; + if( ulCriticalNesting == 0 ) + { + portENABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ + +void SysTick_Handler( void ) +{ +unsigned long ulDummy; + + /* If using preemption, also force a context switch. */ + #if configUSE_PREEMPTION == 1 + *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET; + #endif + + ulDummy = portSET_INTERRUPT_MASK_FROM_ISR(); + { + vTaskIncrementTick(); + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy ); +} +/*-----------------------------------------------------------*/ + +/* + * Setup the systick timer to generate the tick interrupts at the required + * frequency. + */ +void prvSetupTimerInterrupt( void ) +{ + /* Configure SysTick to interrupt at the requested rate. */ + *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL; + *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE; +} +/*-----------------------------------------------------------*/ + diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/port_asm.asm b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/port_asm.asm new file mode 100644 index 000000000..2cb513f74 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/port_asm.asm @@ -0,0 +1,169 @@ +;/* +; FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. +; +; +; *************************************************************************** +; * * +; * FreeRTOS tutorial books are available in pdf and paperback. * +; * Complete, revised, and edited pdf reference manuals are also * +; * available. * +; * * +; * Purchasing FreeRTOS documentation will not only help you, by * +; * ensuring you get running as quickly as possible and with an * +; * in-depth knowledge of how to use FreeRTOS, it will also help * +; * the FreeRTOS project to continue with its mission of providing * +; * professional grade, cross platform, de facto standard solutions * +; * for microcontrollers - completely free of charge! * +; * * +; * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * +; * * +; * Thank you for using FreeRTOS, and thank you for your support! * +; * * +; *************************************************************************** +; +; +; This file is part of the FreeRTOS distribution. +; +; FreeRTOS is free software; you can redistribute it and/or modify it under +; the terms of the GNU General Public License (version 2) as published by the +; Free Software Foundation AND MODIFIED BY the FreeRTOS exception. +; >>>NOTE<<< The modification to the GPL is included to allow you to +; distribute a combined work that includes FreeRTOS without being obliged to +; provide the source code for proprietary components outside of the FreeRTOS +; kernel. FreeRTOS is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +; more details. You should have received a copy of the GNU General Public +; License and the FreeRTOS license exception along with FreeRTOS; if not it +; can be viewed here: http://www.freertos.org/a00114.html and also obtained +; by writing to Richard Barry, contact details for whom are available on the +; FreeRTOS WEB site. +; +; 1 tab == 4 spaces! +; +; http://www.FreeRTOS.org - Documentation, latest information, license and +; contact details. +; +; http://www.SafeRTOS.com - A version that is certified for use in safety +; critical systems. +; +; http://www.OpenRTOS.com - Commercial support, development, porting, +; licensing and training services. +;*/ + + .extern pxCurrentTCB + .extern vTaskSwitchContext + .extern ulMaxSyscallInterruptPriorityConst + + .global PendSV_Handler + .global SVC_Handler + .global vPortStartFirstTask + .global vPortEnableVFP + +;----------------------------------------------------------- + + .section .text + .thumb + .align 4 +PendSV_Handler: .type func + mrs r0, psp + + ;Get the location of the current TCB. + ldr r3, =pxCurrentTCB + ldr r2, [r3] + + ;Is the task using the FPU context? If so, push high vfp registers. + tst r14, #0x10 + it eq + vstmdbeq r0!, {s16-s31} + + ;Save the core registers. + stmdb r0!, {r4-r11, r14} + + ;Save the new top of stack into the first member of the TCB. + str r0, [r2] + + stmdb sp!, {r3, r14} + ldr r0, ulMaxSyscallInterruptPriorityConst + ldr r0, [r0] + msr basepri, r0 +; bl vTaskSwitchContext + mov r0, #0 + msr basepri, r0 + ldmia sp!, {r3, r14} + + ;The first item in pxCurrentTCB is the task top of stack. + ldr r1, [r3] + ldr r0, [r1] + + ;Pop the core registers. + ldmia r0!, {r4-r11, r14} + + ;Is the task using the FPU context? If so, pop the high vfp registers too. + tst r14, #0x10 + it eq + vldmiaeq r0!, {s16-s31} + + msr psp, r0 + bx r14 + + .size PendSV_Handler, $-PendSV_Handler + .endsec + +;----------------------------------------------------------- + + .section .text + .thumb + .align 4 +SVC_Handler: .type func + ;Get the location of the current TCB. + ldr r3, =pxCurrentTCB + ldr r1, [r3] + ldr r0, [r1] + ;Pop the core registers. + ldmia r0!, {r4-r11, r14} + msr psp, r0 + mov r0, #0 + msr basepri, r0 + bx r14 + .size SVC_Handler, $-SVC_Handler + .endsec + +;----------------------------------------------------------- + + .section .text + .thumb + .align 4 +vPortStartFirstTask .type func + ;Use the NVIC offset register to locate the stack. + ldr r0, =0xE000ED08 + ldr r0, [r0] + ldr r0, [r0] + ;Set the msp back to the start of the stack. + msr msp, r0 + ;Call SVC to start the first task. + cpsie i + svc 0 + .size vPortStartFirstTask, $-vPortStartFirstTask + .endsec + +;----------------------------------------------------------- + + .section .text + .thumb + .align 4 +vPortEnableVFP .type func + ;The FPU enable bits are in the CPACR. + ldr r0, =0xE000ED88 + ldr r1, [r0] + + ;Enable CP10 and CP11 coprocessors, then save back. + orr r1, r1, #( 0xf << 20 ) + str r1, [r0] + bx r14 + .size vPortEnableVFP, $-vPortEnableVFP + .endsec + + + .end + diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/portmacro.h b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/portmacro.h new file mode 100644 index 000000000..2f671fba1 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/FreeRTOS_Source/portable/Tasking/ARM_CM4F/portmacro.h @@ -0,0 +1,144 @@ +/* + FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE unsigned portLONG +#define portBASE_TYPE long + +#if( configUSE_16_BIT_TICKS == 1 ) + typedef unsigned portSHORT portTickType; + #define portMAX_DELAY ( portTickType ) 0xffff +#else + typedef unsigned portLONG portTickType; + #define portMAX_DELAY ( portTickType ) 0xffffffff +#endif +/*-----------------------------------------------------------*/ + +/* Architecture specifics. */ +#define portSTACK_GROWTH ( -1 ) +#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +/*-----------------------------------------------------------*/ + + +/* Scheduler utilities. */ +extern void vPortYieldFromISR( void ); + +#define portYIELD() vPortYieldFromISR() + +#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR() +/*-----------------------------------------------------------*/ + + +/* Critical section management. */ + +/* + * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other + * registers. r0 is clobbered. + */ +#define portSET_INTERRUPT_MASK() __set_BASEPRI( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + +/* + * Set basepri back to 0 without effective other registers. + * r0 is clobbered. + */ +#define portCLEAR_INTERRUPT_MASK() __set_BASEPRI( 0 ) + +#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x + + +extern void vPortEnterCritical( void ); +extern void vPortExitCritical( void ); + +#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK() +#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +/*-----------------------------------------------------------*/ + +/* Task function macros as described on the FreeRTOS.org WEB site. */ +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters ) +#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters ) + +#define portNOP() + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/RTOSDemo.lsl b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/RTOSDemo.lsl new file mode 100644 index 000000000..3fc7fd708 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/RTOSDemo.lsl @@ -0,0 +1,8 @@ +// TASKING VX-toolset for ARM +// Project linker script file +// +#if defined(__PROC_XMC4500X1024__) +#include "xmc45xx.lsl" +#else +#include +#endif diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/Startup/Infineon/XMC4500/cstart_XMC4500.c b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/Startup/Infineon/XMC4500/cstart_XMC4500.c new file mode 100644 index 000000000..c5a285ad0 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/Startup/Infineon/XMC4500/cstart_XMC4500.c @@ -0,0 +1,104 @@ +/* +** @(#)cstart.c 1.8 $E% +** +** Copyright 1997-2012 Altium BV * +** +** DESCRIPTION: +** +** The system startup code initializes the processor's registers +** and the application C variables. +** +*/ + +#pragma nomisrac +#pragma profiling off /* prevent profiling information on cstart */ +#pragma optimize abcefgIJKlopRsUy /* preset optimization level */ +#pragma tradeoff 4 /* preset tradeoff level */ +#pragma runtime BCMSZ /* disable runtime error checking for cstart */ +#pragma warning 750 /* do not warn about unsaved registers */ +#pragma section .text=cstart /* use: .text.cstart as the section name */ +#pragma alias Reset_Handler = _START /* requirement for CMSIS */ +#pragma extern Reset_Handler /* required for mil-linking with CMSIS */ + +#include +#include + +#define VTOR (*(volatile unsigned int *)0xE000ED08) +#define PREF_PCON (*(volatile unsigned int *)0x58004000) +#define SCU_GCU_PEEN (*(volatile unsigned int *)0x5000413C) +#define SCU_GCU_PEFLAG (*(volatile unsigned int *)0x50004150) + + +extern unsigned char _lc_ub_stack[]; +extern unsigned char _lc_vtor_value[]; + +#pragma weak exit +#pragma extern _Exit +#pragma extern main +extern int main( int argc, char *argv[] ); +extern void SystemInit( void ); +extern void __init( void ); +#if __PROF_ENABLE__ +extern void __prof_init( void ); +#endif + +#ifdef __POSIX__ +extern void * _posix_boot_stack_top; +extern int posix_main( void ); +#endif + +#ifdef __USE_ARGC_ARGV +#ifndef __ARGCV_BUFSIZE +#define __ARGCV_BUFSIZE 256 +#endif +static char argcv[__ARGCV_BUFSIZE]; +#endif + +void __interrupt() __frame() _START( void ) +{ + PREF_PCON |= 0x00010000; /* Disable Branch prediction */ + SCU_GCU_PEFLAG =0xFFFFFFFF; /* Clear existing parity errors if any */ + SCU_GCU_PEEN = 0; /* Disable parity */ + + /* + * Anticipate possible ROM/RAM remapping + * by loading the 'real' program address. + */ + __remap_pc(); + /* + * Initialize stack pointer. + */ + __setsp( _lc_ub_stack ); + /* + * Call a user function which initializes hardware, + * such as ROM/RAM re-mapping or MMU configuration. + */ + SystemInit(); + /* + * Copy initialized sections from ROM to RAM + * and clear uninitialized data sections in RAM. + */ + __init(); + __asm( "_cptable_handled:" ); /* symbol may be used by debugger */ + + /* + * Load VTOR register with the actual vector table + * start address + */ + VTOR = (unsigned int)_lc_vtor_value; + +#ifdef __POSIX__ + __setsp( _posix_boot_stack_top ); +#endif +#if __PROF_ENABLE__ + __prof_init(); +#endif +#ifdef __POSIX__ + exit( posix_main() ); +#elif defined __USE_ARGC_ARGV + exit( main( _argcv( argcv, __ARGCV_BUFSIZE ), (char **)argcv ) ); +#else + exit( main( 0, NULL ) ); +#endif + return; +} diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/Startup/Infineon/XMC4500/system_XMC4500.c b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/Startup/Infineon/XMC4500/system_XMC4500.c new file mode 100644 index 000000000..fc9b4840e --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/Startup/Infineon/XMC4500/system_XMC4500.c @@ -0,0 +1,419 @@ +/****************************************************************************** + * @file system_XMC4500.c + * @brief Device specific initialization for the XMC4500-Series according to CMSIS + * @version V2.2 + * @date 20. January 2012 + * + * @note + * Copyright (C) 2011 Infineon Technologies AG. All rights reserved. + + * + * @par + * Infineon Technologies AG (Infineon) is supplying this software for use with Infineon’s microcontrollers. + * This file can be freely distributed within development tools that are supporting such microcontrollers. + + * + * @par + * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED + * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. + * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + * + * + ******************************************************************************/ + +#include "system_XMC4500.h" +#include + +/*---------------------------------------------------------------------------- + Define clocks is located in System_XMC4500.h + *----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +/*!< System Clock Frequency (Core Clock)*/ +uint32_t SystemCoreClock = CLOCK_OSC_HP; + +/*---------------------------------------------------------------------------- + Keil pragma to prevent warnings + *----------------------------------------------------------------------------*/ +#if defined(__ARMCC_VERSION) +#pragma diag_suppress 177 +#endif + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------ +*/ + + + +/*--------------------- Watchdog Configuration ------------------------------- +// +// Watchdog Configuration +// Disable Watchdog +// +// +*/ +#define WDT_SETUP 1 +#define WDTENB_nVal 0x00000001 + +/*--------------------- CLOCK Configuration ------------------------------- +// +// Main Clock Configuration +// CPU clock divider +// <0=> fCPU = fSYS +// <1=> fCPU = fSYS / 2 +// Peripheral Bus clock divider +// <0=> fPB = fCPU +// <1=> fPB = fCPU / 2 +// CCU Bus clock divider +// <0=> fCCU = fCPU +// <1=> fCCU = fCPU / 2 +// +// +// +*/ + +#define SCU_CLOCK_SETUP 1 +#define SCU_CPUCLKCR_DIV 0x00000000 +#define SCU_PBCLKCR_DIV 0x00000000 +#define SCU_CCUCLKCR_DIV 0x00000000 + + + +/*--------------------- USB CLOCK Configuration --------------------------- +// +// USB Clock Configuration +// +// +// +*/ + +#define SCU_USB_CLOCK_SETUP 0 + + +/*--------------------- CLOCKOUT Configuration ------------------------------- +// +// Clock OUT Configuration +// Clockout Source Selection +// <0=> System Clock +// <2=> USB Clock +// <3=> Divided value of PLL Clock +// Clockout Pin Selection +// <0=> P1.15 +// <1=> P0.8 +// +// +// +// +*/ + +#define SCU_CLOCKOUT_SETUP 0 // recommended to keep disabled +#define SCU_CLOCKOUT_SOURCE 0x00000000 +#define SCU_CLOCKOUT_PIN 0x00000000 + +/*---------------------------------------------------------------------------- + static functions declarations + *----------------------------------------------------------------------------*/ +#if (SCU_CLOCK_SETUP == 1) +static int SystemClockSetup(void); +#endif + +#if (SCU_USB_CLOCK_SETUP == 1) +static void USBClockSetup(void); +#endif + +/** + * @brief Setup the microcontroller system. + * Initialize the PLL and update the + * SystemCoreClock variable. + * @param None + * @retval None + */ +void SystemInit(void) +{ +/* Setup the WDT */ +#if (WDT_SETUP == 1) +WDT->CTR &= ~WDTENB_nVal; +#endif + +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) +SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */ + (3UL << 11*2) ); /* set CP11 Full Access */ +#endif + +/* Disable branch prediction - PCON.PBS = 1 */ +PREF->PCON |= (PREF_PCON_PBS_Msk); + +/* Enable unaligned memory access - SCB_CCR.UNALIGN_TRP = 0 */ +SCB->CCR &= ~(SCB_CCR_UNALIGN_TRP_Msk); + +/* Setup the clockout */ +/* README README README README README README README README README README */ +/* + * Please use the CLOCKOUT feature with diligence. Use this only if you know + * what you are doing. + * + * You must be aware that the settings below can potentially be in conflict + * with DAVE code generation engine preferences. + * + * Even worse, the setting below configures the ports as output ports while in + * reality, the board on which this chip is mounted may have a source driving + * the ports. + * + * So use this feature only when you are absolutely sure that the port must + * indeed be configured as an output AND you are NOT linking this startup code + * with code that was generated by DAVE code engine. + */ +#if (SCU_CLOCKOUT_SETUP == 1) +SCU_CLK->EXTCLKCR |= SCU_CLOCKOUT_SOURCE; + +if (SCU_CLOCKOUT_PIN) { + PORT0->IOCR8 = 0x00000088; /*P0.8 --> ALT1 select + HWSEL */ + PORT0->HWSEL &= (~PORT0_HWSEL_HW8_Msk); + } +else PORT1->IOCR12 = 0x88000000; /*P1.15--> ALT1 select */ +#endif + +/* Setup the System clock */ +#if (SCU_CLOCK_SETUP == 1) +SystemClockSetup(); +#endif + +/* Setup the USB PL */ +#if (SCU_USB_CLOCK_SETUP == 1) +USBClockSetup(); +#endif + +} + + +/** + * @brief Update SystemCoreClock according to Clock Register Values + * @note - + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + +/*---------------------------------------------------------------------------- + Clock Variable definitions + *----------------------------------------------------------------------------*/ +SystemCoreClock = SYSTEM_FREQUENCY;/*!< System Clock Frequency (Core Clock)*/ + +} + + +/** + * @brief - + * @note - + * @param None + * @retval None + */ +#if (SCU_CLOCK_SETUP == 1) +static int SystemClockSetup(void) +{ +/* enable PLL first */ + SCU_PLL->PLLCON0 &= ~(SCU_PLL_PLLCON0_VCOPWD_Msk | + SCU_PLL_PLLCON0_PLLPWD_Msk); + +/* Enable OSC_HP */ + if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL) + { + /* Enable the OSC_HP*/ + SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4); + /* Setup OSC WDG devider */ + SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16); + /* Select external OSC as PLL input */ + SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk; + /* Restart OSC Watchdog */ + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk; + + do + { + ; /* here a timeout need to be added */ + }while(!( (SCU_PLL->PLLSTAT) & + (SCU_PLL_PLLSTAT_PLLHV_Msk | SCU_PLL_PLLSTAT_PLLLV_Msk | + SCU_PLL_PLLSTAT_PLLSP_Msk) + ) + ); + + } + +/* Setup Main PLL */ + /* Select FOFI as system clock */ + if(SCU_CLK->SYSCLKCR != 0X000000) + SCU_CLK->SYSCLKCR = 0x00000000; /*Select FOFI*/ + + /* Go to bypass the Main PLL */ + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_VCOBYP_Msk; + + /* disconnect OSC_HP to PLL */ + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_FINDIS_Msk; + + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | + (PLL_K2DIV_STEP_1<<16) | (PLL_PDIV<<24)); + + /* we may have to set OSCDISCDIS */ + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_OSCDISCDIS_Msk; + + /* connect OSC_HP to PLL */ + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_FINDIS_Msk; + + /* restart PLL Lock detection */ + SCU_PLL->PLLCON0 |= SCU_PLL_PLLCON0_RESLD_Msk; + + /* wait for PLL Lock */ + while (!(SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk)); + + /* Go back to the Main PLL */ + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_VCOBYP_Msk; + + /********************************************************* + here we need to setup the system clock divider + *********************************************************/ + + SCU_CLK->CPUCLKCR = SCU_CPUCLKCR_DIV; + SCU_CLK->PBCLKCR = SCU_PBCLKCR_DIV; + SCU_CLK->CCUCLKCR = SCU_CCUCLKCR_DIV; + + /* Switch system clock to PLL */ + SCU_CLK->SYSCLKCR |= 0x00010000; + + /********************************************************* + here the ramp up of the system clock starts + *********************************************************/ + /* Delay for next K2 step ~50µs */ + /********************************/ + /* Set reload register */ + SysTick->LOAD = ((1250+100) & SysTick_LOAD_RELOAD_Msk) - 1; + + /* Load the SysTick Counter Value */ + SysTick->VAL = 0; + + /* Enable SysTick IRQ and SysTick Timer */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_ENABLE_Msk; + + /* wait for ~50µs */ + while (SysTick->VAL >= 100); + + /* Stop SysTick Timer */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + /********************************/ + + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | + (PLL_K2DIV_STEP_2<<16) | (PLL_PDIV<<24)); + + /* Delay for next K2 step ~50µs */ + /********************************/ + SysTick->LOAD = ((3000+100) & SysTick_LOAD_RELOAD_Msk) - 1; + + /* Load the SysTick Counter Value */ + SysTick->VAL = 0; + + /* Enable SysTick IRQ and SysTick Timer */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; + + /* Wait for ~50µs */ + while (SysTick->VAL >= 100); + + /* Stop SysTick Timer */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + /********************************/ + + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | + (PLL_K2DIV_STEP_3<<16) | (PLL_PDIV<<24)); + + /* Delay for next K2 step ~50µs */ + /********************************/ + SysTick->LOAD = ((4800+100) & SysTick_LOAD_RELOAD_Msk) - 1; + + /* Load the SysTick Counter Value */ + SysTick->VAL = 0; + + /* Enable SysTick IRQ and SysTick Timer */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; + + /* Wait for ~50µs */ + while (SysTick->VAL >= 100); + + /* Stop SysTick Timer */ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; + /********************************/ + + /* Setup devider settings for main PLL */ + SCU_PLL->PLLCON1 = ((PLL_K1DIV) | (PLL_NDIV<<8) | (PLL_K2DIV<<16) | + (PLL_PDIV<<24)); + + /* clear request for System OCS Watchdog Trap and System VCO Lock Trap */ + SCU_TRAP->TRAPCLR = SCU_TRAP_TRAPCLR_SOSCWDGT_Msk | + SCU_TRAP_TRAPCLR_SVCOLCKT_Msk; + + return(1); + +} +#endif + +/** + * @brief - + * @note - + * @param None + * @retval None + */ +#if(SCU_USB_CLOCK_SETUP == 1) +static void USBClockSetup(void) +{ +/* enable PLL first */ + SCU_PLL->USBPLLCON &= ~(SCU_PLL_USBPLLCON_VCOPWD_Msk | + SCU_PLL_USBPLLCON_PLLPWD_Msk); + +/* check and if not already running enable OSC_HP */ + if(!((SCU_PLL->PLLSTAT) & + (SCU_PLL_PLLSTAT_PLLHV_Msk | + SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk))) + { + if (SCU_PLL_CLOCK_INPUT == SCU_CLOCK_CRYSTAL) + { + + SCU_OSC->OSCHPCTRL = (OSC_HP_MODE<<4); /*enable the OSC_HP*/ + /* setup OSC WDG devider */ + SCU_OSC->OSCHPCTRL |= (OSCHPWDGDIV<<16); + /* select external OSC as PLL input */ + SCU_PLL->PLLCON2 &= ~SCU_PLL_PLLCON2_PINSEL_Msk; + /* restart OSC Watchdog */ + SCU_PLL->PLLCON0 &= ~SCU_PLL_PLLCON0_OSCRES_Msk; + + do + { + ; /* here a timeout need to be added */ + }while(!((SCU_PLL->PLLSTAT) & (SCU_PLL_PLLSTAT_PLLHV_Msk | + SCU_PLL_PLLSTAT_PLLLV_Msk |SCU_PLL_PLLSTAT_PLLSP_Msk))); + + } + } + + +/* Setup USB PLL */ + /* Go to bypass the Main PLL */ + SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_VCOBYP_Msk; + /* disconnect OSC_FI to PLL */ + SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_FINDIS_Msk; + /* Setup devider settings for main PLL */ + SCU_PLL->USBPLLCON = ((USBPLL_NDIV<<8) | (USBPLL_PDIV<<24)); + /* we may have to set OSCDISCDIS */ + SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_OSCDISCDIS_Msk; + /* connect OSC_FI to PLL */ + SCU_PLL->USBPLLCON &= ~SCU_PLL_USBPLLCON_FINDIS_Msk; + /* restart PLL Lock detection */ + SCU_PLL->USBPLLCON |= SCU_PLL_USBPLLCON_RESLD_Msk; + /* wait for PLL Lock */ + while (!(SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk)); + } +#endif diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main.c b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main.c new file mode 100644 index 000000000..d443e5a6a --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main.c @@ -0,0 +1,223 @@ +/* + FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/****************************************************************************** + * This project provides two demo applications. A simple blinky style project, + * and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to + * select between the two. The simply blinky demo is implemented and described + * in main_blinky.c. The more comprehensive test and demo application is + * implemented and described in main_full.c. + * + * This file implements the code that is not demo specific, including the + * hardware setup and FreeRTOS hook functions. + * + * + * Additional code: + * + * This demo does not contain a non-kernel interrupt service routine that + * can be used as an example for application writers to use as a reference. + * Therefore, the framework of a dummy (not installed) handler is provided + * in this file. The dummy function is called Dummy_IRQHandler(). Please + * ensure to read the comments in the function itself, but more importantly, + * the notes on the function contained on the documentation page for this demo + * that is found on the FreeRTOS.org web site. + */ + +/* Standard includes. */ +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* Hardware includes. */ +#include "XMC4500.h" +#include "System_XMC4500.h" + +/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, +or 0 to run the more comprehensive test and demo application. */ +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 + +/*-----------------------------------------------------------*/ + +/* + * Set up the hardware ready to run this demo. + */ +static void prvSetupHardware( void ); + +/* + * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +extern void main_blinky( void ); +extern void main_full( void ); + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + /* Prepare the hardware to run this demo. */ + prvSetupHardware(); + + /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top + of this file. */ + #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 + { + main_blinky(); + } + #else + { + main_full(); + } + #endif + + return 0; +} +/*-----------------------------------------------------------*/ + +static void prvSetupHardware( void ) +{ +extern void SystemCoreClockUpdate( void ); + + /* Ensure SystemCoreClock variable is set. */ + SystemCoreClockUpdate(); + + /* Configure pin P3.9 for the LED. */ + PORT3->IOCR8 = 0x00008000; + + /* Ensure all priority bits are assigned as preemption priority bits. */ + NVIC_SetPriorityGrouping( 0 ); +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + /* vApplicationMallocFailedHook() will only be called if + configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook + function that will get called if a call to pvPortMalloc() fails. + pvPortMalloc() is called internally by the kernel whenever a task, queue, + timer or semaphore is created. It is also called by various parts of the + demo application. If heap_1.c or heap_2.c are used, then the size of the + heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in + FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used + to query the size of free heap space that remains (although it does not + provide information on how the remaining heap might be fragmented). */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set + to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle + task. It is essential that code added to this hook function never attempts + to block in any way (for example, call xQueueReceive() with a block time + specified, or call vTaskDelay()). If the application makes use of the + vTaskDelete() API function (as this demo application does) then it is also + important that vApplicationIdleHook() is permitted to return to its calling + function, because it is the responsibility of the idle task to clean up + memory allocated by the kernel to any task that has since been deleted. */ +} +/*-----------------------------------------------------------*/ + +void vApplicationStackOverflowHook( xTaskHandle pxTask, signed char *pcTaskName ) +{ + ( void ) pcTaskName; + ( void ) pxTask; + + /* Run time stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + function is called if a stack overflow is detected. */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ + /* This function will be called by each tick interrupt if + configUSE_TICK_HOOK is set to 1 in FreeRTOSConfig.h. User code can be + added here, but the tick hook is called from an interrupt context, so + code must not attempt to block, and only the interrupt safe FreeRTOS API + functions can be used (those that end in FromISR()). */ +} +/*-----------------------------------------------------------*/ + +#ifdef JUST_AN_EXAMPLE_ISR + +void Dummy_IRQHandler(void) +{ +long lHigherPriorityTaskWoken = pdFALSE; + + /* Clear the interrupt if necessary. */ + Dummy_ClearITPendingBit(); + + /* This interrupt does nothing more than demonstrate how to synchronise a + task with an interrupt. A semaphore is used for this purpose. Note + lHigherPriorityTaskWoken is initialised to zero. */ + xSemaphoreGiveFromISR( xTestSemaphore, &lHigherPriorityTaskWoken ); + + /* If there was a task that was blocked on the semaphore, and giving the + semaphore caused the task to unblock, and the unblocked task has a priority + higher than the current Running state task (the task that this interrupt + interrupted), then lHigherPriorityTaskWoken will have been set to pdTRUE + internally within xSemaphoreGiveFromISR(). Passing pdTRUE into the + portEND_SWITCHING_ISR() macro will result in a context switch being pended to + ensure this interrupt returns directly to the unblocked, higher priority, + task. Passing pdFALSE into portEND_SWITCHING_ISR() has no effect. */ + portEND_SWITCHING_ISR( lHigherPriorityTaskWoken ); +} + +#endif /* JUST_AN_EXAMPLE_ISR */ diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main_blinky.c b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main_blinky.c new file mode 100644 index 000000000..be344d5e9 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main_blinky.c @@ -0,0 +1,233 @@ +/* + FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the simply blinky style version. + * + * NOTE 2: This file only contains the source code that is specific to the + * basic demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + ****************************************************************************** + * + * main_blinky() creates one queue, and two tasks. It then starts the + * scheduler. + * + * The Queue Send Task: + * The queue send task is implemented by the prvQueueSendTask() function in + * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly + * block for 200 milliseconds, before sending the value 100 to the queue that + * was created within main_blinky(). Once the value is sent, the task loops + * back around to block for another 200 milliseconds. + * + * The Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly + * blocks on attempts to read data from the queue that was created within + * main_blinky(). When data is received, the task checks the value of the + * data, and if the value equals the expected 100, toggles the LED. The 'block + * time' parameter passed to the queue receive function specifies that the + * task should be held in the Blocked state indefinitely to wait for data to + * be available on the queue. The queue receive task will only leave the + * Blocked state when the queue send task writes to the queue. As the queue + * send task writes to the queue every 200 milliseconds, the queue receive + * task leaves the Blocked state every 200 milliseconds, and therefore toggles + * the LED every 200 milliseconds. + */ + +/* Standard includes. */ +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + +/* Hardware includes. */ +#include "XMC4500.h" +#include "System_XMC4500.h" + +/* Priorities at which the tasks are created. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which data is sent to the queue. The 200ms value is converted +to ticks using the portTICK_RATE_MS constant. */ +#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_RATE_MS ) + +/* The number of items the queue can hold. This is 1 as the receive task +will remove items as they are added, meaning the send task should always find +the queue empty. */ +#define mainQUEUE_LENGTH ( 1 ) + +/* Values passed to the two tasks just to check the task parameter +functionality. */ +#define mainQUEUE_SEND_PARAMETER ( 0x1111UL ) +#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL ) + +/* To toggle the single LED */ +#define mainTOGGLE_LED() ( PORT3->OMR = 0x02000200 ) + +/*-----------------------------------------------------------*/ + +/* + * The tasks as described in the comments at the top of this file. + */ +static void prvQueueReceiveTask( void *pvParameters ); +static void prvQueueSendTask( void *pvParameters ); + +/* + * Called by main() to create the simply blinky style application if + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + */ +void main_blinky( void ); + +/* + * The hardware only has a single LED. Simply toggle it. + */ +extern void vMainToggleLED( void ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static xQueueHandle xQueue = NULL; + +/*-----------------------------------------------------------*/ + +void main_blinky( void ) +{ + /* Create the queue. */ + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); + + if( xQueue != NULL ) + { + /* Start the two tasks as described in the comments at the top of this + file. */ + xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ + ( signed char * ) "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ + configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ + ( void * ) mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */ + mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ + NULL ); /* The task handle is not required, so NULL is passed. */ + + xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* Start the tasks and timer running. */ + vTaskStartScheduler(); + } + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was insufficient FreeRTOS heap memory available for the idle and/or + timer tasks to be created. See the memory management section on the + FreeRTOS web site for more details. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void *pvParameters ) +{ +portTickType xNextWakeTime; +const unsigned long ulValueToSend = 100UL; + + /* Check the task parameter is as expected. */ + configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_SEND_PARAMETER ); + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Place this task in the blocked state until it is time to run again. + The block time is specified in ticks, the constant used converts ticks + to ms. While in the Blocked state this task will not consume any CPU + time. */ + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + /* Send to the queue - causing the queue receive task to unblock and + toggle the LED. 0 is used as the block time so the sending operation + will not block - it shouldn't need to block as the queue should always + be empty at this point in the code. */ + xQueueSend( xQueue, &ulValueToSend, 0U ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void *pvParameters ) +{ +unsigned long ulReceivedValue; + + /* Check the task parameter is as expected. */ + configASSERT( ( ( unsigned long ) pvParameters ) == mainQUEUE_RECEIVE_PARAMETER ); + + for( ;; ) + { + /* Wait until something arrives in the queue - this task will block + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + FreeRTOSConfig.h. */ + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + /* To get here something must have been received from the queue, but + is it the expected value? If it is, toggle the LED. */ + if( ulReceivedValue == 100UL ) + { + mainTOGGLE_LED(); + ulReceivedValue = 0U; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main_full.c b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main_full.c new file mode 100644 index 000000000..cc188f440 --- /dev/null +++ b/Demo/CORTEX_M4F_Infineon_XMC4500_Tasking/main_full.c @@ -0,0 +1,664 @@ +/* + FreeRTOS V7.1.0 - Copyright (C) 2011 Real Time Engineers Ltd. + + + *************************************************************************** + * * + * FreeRTOS tutorial books are available in pdf and paperback. * + * Complete, revised, and edited pdf reference manuals are also * + * available. * + * * + * Purchasing FreeRTOS documentation will not only help you, by * + * ensuring you get running as quickly as possible and with an * + * in-depth knowledge of how to use FreeRTOS, it will also help * + * the FreeRTOS project to continue with its mission of providing * + * professional grade, cross platform, de facto standard solutions * + * for microcontrollers - completely free of charge! * + * * + * >>> See http://www.FreeRTOS.org/Documentation for details. <<< * + * * + * Thank you for using FreeRTOS, and thank you for your support! * + * * + *************************************************************************** + + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation AND MODIFIED BY the FreeRTOS exception. + >>>NOTE<<< The modification to the GPL is included to allow you to + distribute a combined work that includes FreeRTOS without being obliged to + provide the source code for proprietary components outside of the FreeRTOS + kernel. FreeRTOS is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. You should have received a copy of the GNU General Public + License and the FreeRTOS license exception along with FreeRTOS; if not it + can be viewed here: http://www.freertos.org/a00114.html and also obtained + by writing to Richard Barry, contact details for whom are available on the + FreeRTOS WEB site. + + 1 tab == 4 spaces! + + http://www.FreeRTOS.org - Documentation, latest information, license and + contact details. + + http://www.SafeRTOS.com - A version that is certified for use in safety + critical systems. + + http://www.OpenRTOS.com - Commercial support, development, porting, + licensing and training services. +*/ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the comprehensive test and demo version. + * + * NOTE 2: This file only contains the source code that is specific to the + * full demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + ****************************************************************************** + * + * main_full() creates all the demo application tasks and a software timer, then + * starts the scheduler. The web documentation provides more details of the + * standard demo application tasks, which provide no particular functionality, + * but do provide a good example of how to use the FreeRTOS API. + * + * In addition to the standard demo tasks, the following tasks and tests are + * defined and/or created within this file: + * + * "Reg test" tasks - These fill both the core and floating point registers with + * known values, then check that each register maintains its expected value for + * the lifetime of the task. Each task uses a different set of values. The reg + * test tasks execute with a very low priority, so get preempted very + * frequently. A register containing an unexpected value is indicative of an + * error in the context switching mechanism. + * + * "Check" timer - The check software timer period is initially set to three + * seconds. The callback function associated with the check software timer + * checks that all the standard demo tasks, and the register check tasks, are + * not only still executing, but are executing without reporting any errors. If + * the check software timer discovers that a task has either stalled, or + * reported an error, then it changes its own execution period from the initial + * three seconds, to just 200ms. The check software timer callback function + * also toggles the single LED each time it is called. This provides a visual + * indication of the system status: If the LED toggles every three seconds, + * then no issues have been discovered. If the LED toggles every 200ms, then + * an issue has been discovered with at least one task. + */ + +/* Standard includes. */ +#include + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "semphr.h" + +/* Standard demo application includes. */ +#include "flop.h" +#include "integer.h" +#include "PollQ.h" +#include "semtest.h" +#include "dynamic.h" +#include "BlockQ.h" +#include "blocktim.h" +#include "countsem.h" +#include "GenQTest.h" +#include "recmutex.h" +#include "death.h" + +/* Hardware includes. */ +#include "XMC4500.h" +#include "System_XMC4500.h" + +/* Priorities for the demo application tasks. */ +#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2UL ) +#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1UL ) +#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2UL ) +#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3UL ) +#define mainFLOP_TASK_PRIORITY ( tskIDLE_PRIORITY ) + +/* To toggle the single LED */ +#define mainTOGGLE_LED() ( PORT3->OMR = 0x02000200 ) + +/* A block time of zero simply means "don't block". */ +#define mainDONT_BLOCK ( 0UL ) + +/* The period after which the check timer will expire, in ms, provided no errors +have been reported by any of the standard demo tasks. ms are converted to the +equivalent in ticks using the portTICK_RATE_MS constant. */ +#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS ) + +/* The period at which the check timer will expire, in ms, if an error has been +reported in one of the standard demo tasks. ms are converted to the equivalent +in ticks using the portTICK_RATE_MS constant. */ +#define mainERROR_CHECK_TIMER_PERIOD_MS ( 200UL / portTICK_RATE_MS ) + +/*-----------------------------------------------------------*/ + +/* + * The check timer callback function, as described at the top of this file. + */ +static void prvCheckTimerCallback( xTimerHandle xTimer ); + +/* + * Register check tasks, and the tasks used to write over and check the contents + * of the FPU registers, as described at the top of this file. The nature of + * these files necessitates that they are written in an assembly file. + */ +static void vRegTest1Task( void *pvParameters ); +static void vRegTest2Task( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* The following two variables are used to communicate the status of the +register check tasks to the check software timer. If the variables keep +incrementing, then the register check tasks has not discovered any errors. If +a variable stops incrementing, then an error has been found. */ +volatile unsigned long ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; + +/*-----------------------------------------------------------*/ + +void main_full( void ) +{ +xTimerHandle xCheckTimer = NULL; + + /* Start all the other standard demo/test tasks. The have not particular + functionality, but do demonstrate how to use the FreeRTOS API and test the + kernel port. */ + vStartIntegerMathTasks( tskIDLE_PRIORITY ); + vStartDynamicPriorityTasks(); + vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); + vCreateBlockTimeTasks(); + vStartCountingSemaphoreTasks(); + vStartGenericQueueTasks( tskIDLE_PRIORITY ); + vStartRecursiveMutexTasks(); + vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); + vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); + vStartMathTasks( mainFLOP_TASK_PRIORITY ); + + /* Create the register check tasks, as described at the top of this + file */ + xTaskCreate( vRegTest1Task, ( signed char * ) "Reg1", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); + xTaskCreate( vRegTest2Task, ( signed char * ) "Reg2", configMINIMAL_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, NULL ); + + /* Create the software timer that performs the 'check' functionality, + as described at the top of this file. */ + xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */ + ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ + pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ + ( void * ) 0, /* The ID is not used, so can be set to anything. */ + prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ + ); + + if( xCheckTimer != NULL ) + { + xTimerStart( xCheckTimer, mainDONT_BLOCK ); + } + + /* The set of tasks created by the following function call have to be + created last as they keep account of the number of tasks they expect to see + running. */ + vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); + + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following line + will never be reached. If the following line does execute, then there was + insufficient FreeRTOS heap memory available for the idle and/or timer tasks + to be created. See the memory management section on the FreeRTOS web site + for more details. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvCheckTimerCallback( xTimerHandle xTimer ) +{ +static long lChangedTimerPeriodAlready = pdFALSE; +static unsigned long ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; +unsigned long ulErrorFound = pdFALSE; + + /* Check all the demo tasks (other than the flash tasks) to ensure + that they are all still running, and that none have detected an error. */ + + if( xAreMathsTaskStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreBlockingQueuesStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if ( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if ( xAreGenericQueueTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if ( xAreRecursiveMutexTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xIsCreateTaskStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xArePollingQueuesStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + ulErrorFound = pdTRUE; + } + + /* Check that the register test 1 task is still running. */ + if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + { + ulErrorFound = pdTRUE; + } + ulLastRegTest1Value = ulRegTest1LoopCounter; + + /* Check that the register test 2 task is still running. */ + if( ulLastRegTest2Value == ulRegTest2LoopCounter ) + { + ulErrorFound = pdTRUE; + } + ulLastRegTest2Value = ulRegTest2LoopCounter; + + /* Toggle the check LED to give an indication of the system status. If + the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then + everything is ok. A faster toggle indicates an error. */ + mainTOGGLE_LED(); + + /* Have any errors been latch in ulErrorFound? If so, shorten the + period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds. + This will result in an increase in the rate at which mainCHECK_LED + toggles. */ + if( ulErrorFound != pdFALSE ) + { + if( lChangedTimerPeriodAlready == pdFALSE ) + { + lChangedTimerPeriodAlready = pdTRUE; + + /* This call to xTimerChangePeriod() uses a zero block time. + Functions called from inside of a timer callback function must + *never* attempt to block. */ + xTimerChangePeriod( xTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK ); + } + } +} +/*-----------------------------------------------------------*/ + +/* This is a naked function. */ +static void vRegTest1Task( void *pvParameters ) +{ + __asm volatile + ( + " \n" /* Fill the core registers with known values. */ + " mov r0, #100 \n" + " mov r1, #101 \n" + " mov r2, #102 \n" + " mov r3, #103 \n" + " mov r4, #104 \n" + " mov r5, #105 \n" + " mov r6, #106 \n" + " mov r7, #107 \n" + " mov r8, #108 \n" + " mov r9, #109 \n" + " mov r10, #110 \n" + " mov r11, #111 \n" + " mov r12, #112 \n" + " \n" + " vmov d0, r0, r1 \n" /* Fill the VFP registers with known values. */ + " vmov d1, r2, r3 \n" + " vmov d2, r4, r5 \n" + " vmov d3, r6, r7 \n" + " vmov d4, r8, r9 \n" + " vmov d5, r10, r11 \n" + " vmov d6, r0, r1 \n" + " vmov d7, r2, r3 \n" + " vmov d8, r4, r5 \n" + " vmov d9, r6, r7 \n" + " vmov d10, r8, r9 \n" + " vmov d11, r10, r11 \n" + " vmov d12, r0, r1 \n" + " vmov d13, r2, r3 \n" + " vmov d14, r4, r5 \n" + " vmov d15, r6, r7 \n" + " \n" + "reg1_loop: \n" /* Check all the VFP registers still contain the values set above." */ + " push { r0-r1 } \n" /* First save registers that are clobbered by the test. */ + " \n" + " vmov r0, r1, d0 \n" + " cmp r0, #100 \n" + " bne reg1_error_loopf \n" + " cmp r1, #101 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d1 \n" + " cmp r0, #102 \n" + " bne reg1_error_loopf \n" + " cmp r1, #103 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d2 \n" + " cmp r0, #104 \n" + " bne reg1_error_loopf \n" + " cmp r1, #105 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d3 \n" + " cmp r0, #106 \n" + " bne reg1_error_loopf \n" + " cmp r1, #107 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d4 \n" + " cmp r0, #108 \n" + " bne reg1_error_loopf \n" + " cmp r1, #109 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d5 \n" + " cmp r0, #110 \n" + " bne reg1_error_loopf \n" + " cmp r1, #111 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d6 \n" + " cmp r0, #100 \n" + " bne reg1_error_loopf \n" + " cmp r1, #101 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d7 \n" + " cmp r0, #102 \n" + " bne reg1_error_loopf \n" + " cmp r1, #103 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d8 \n" + " cmp r0, #104 \n" + " bne reg1_error_loopf \n" + " cmp r1, #105 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d9 \n" + " cmp r0, #106 \n" + " bne reg1_error_loopf \n" + " cmp r1, #107 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d10 \n" + " cmp r0, #108 \n" + " bne reg1_error_loopf \n" + " cmp r1, #109 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d11 \n" + " cmp r0, #110 \n" + " bne reg1_error_loopf \n" + " cmp r1, #111 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d12 \n" + " cmp r0, #100 \n" + " bne reg1_error_loopf \n" + " cmp r1, #101 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d13 \n" + " cmp r0, #102 \n" + " bne reg1_error_loopf \n" + " cmp r1, #103 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d14 \n" + " cmp r0, #104 \n" + " bne reg1_error_loopf \n" + " cmp r1, #105 \n" + " bne reg1_error_loopf \n" + " vmov r0, r1, d15 \n" + " cmp r0, #106 \n" + " bne reg1_error_loopf \n" + " cmp r1, #107 \n" + " bne reg1_error_loopf \n" + " \n" + " pop {r0-r1} \n" /* Restore the registers that were clobbered by the test. */ + " \n" + " b reg1_loopf_pass \n" /* VFP register test passed. Jump to the core register test. */ + " \n" + "reg1_error_loopf: \n" + " b reg1_error_loopf \n" /* If this line is hit then a VFP register value was found to be\n incorrect. */ + " \n" + "reg1_loopf_pass: \n" + " \n" + " cmp r0, #100 \n" + " bne reg1_error_loop \n" + " cmp r1, #101 \n" + " bne reg1_error_loop \n" + " cmp r2, #102 \n" + " bne reg1_error_loop \n" + " cmp r3, #103 \n" + " bne reg1_error_loop \n" + " cmp r4, #104 \n" + " bne reg1_error_loop \n" + " cmp r5, #105 \n" + " bne reg1_error_loop \n" + " cmp r6, #106 \n" + " bne reg1_error_loop \n" + " cmp r7, #107 \n" + " bne reg1_error_loop \n" + " cmp r8, #108 \n" + " bne reg1_error_loop \n" + " cmp r9, #109 \n" + " bne reg1_error_loop \n" + " cmp r10, #110 \n" + " bne reg1_error_loop \n" + " cmp r11, #111 \n" + " bne reg1_error_loop \n" + " cmp r12, #112 \n" + " bne reg1_error_loop \n" + " \n" + " push { r0-r1 } \n" /* Everything passed, increment the loop counter. */ + " ldr r0, =ulRegTest1LoopCounter \n" + " ldr r1, [r0] \n" + " adds r1, r1, #1 \n" + " str r1, [r0] \n" + " pop { r0-r1 } \n" + " \n" + " b reg1_loop \n" /* Start again. */ + " \n" + "reg1_error_loop: \n" /* If this line is hit then there was an error in a core register value. */ + " b reg1_error_loop \n" /* The loop ensures the loop counter stops incrementing. */ + " nop " + ); +} +/*-----------------------------------------------------------*/ + +/* This is a naked function. */ +static void vRegTest2Task( void *pvParameters ) +{ + __asm volatile + ( + " mov r0, #-1 \n" /* Set all the core registers to known values. */ + " mov r1, #1 \n" + " mov r2, #2 \n" + " mov r3, #3 \n" + " mov r4, #4 \n" + " mov r5, #5 \n" + " mov r6, #6 \n" + " mov r7, #7 \n" + " mov r8, #8 \n" + " mov r9, #9 \n" + " mov r10, #10 \n" + " mov r11, #11 \n" + " mov r12, #12 \n" + " \n" + " vmov d0, r0, r1 \n" /* Set all the VFP to known values. */ + " vmov d1, r2, r3 \n" + " vmov d2, r4, r5 \n" + " vmov d3, r6, r7 \n" + " vmov d4, r8, r9 \n" + " vmov d5, r10, r11 \n" + " vmov d6, r0, r1 \n" + " vmov d7, r2, r3 \n" + " vmov d8, r4, r5 \n" + " vmov d9, r6, r7 \n" + " vmov d10, r8, r9 \n" + " vmov d11, r10, r11 \n" + " vmov d12, r0, r1 \n" + " vmov d13, r2, r3 \n" + " vmov d14, r4, r5 \n" + " vmov d15, r6, r7 \n" + " \n" + "reg2_loop: \n" + " \n" + " push { r0-r1 } \n" /* Check all the VFP registers still contain the values set above. */ + " vmov r0, r1, d0 \n" /*First save registers that are clobbered by the test. */ + " cmp r0, #-1 \n" + " bne reg2_error_loopf \n" + " cmp r1, #1 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d1 \n" + " cmp r0, #2 \n" + " bne reg2_error_loopf \n" + " cmp r1, #3 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d2 \n" + " cmp r0, #4 \n" + " bne reg2_error_loopf \n" + " cmp r1, #5 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d3 \n" + " cmp r0, #6 \n" + " bne reg2_error_loopf \n" + " cmp r1, #7 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d4 \n" + " cmp r0, #8 \n" + " bne reg2_error_loopf \n" + " cmp r1, #9 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d5 \n" + " cmp r0, #10 \n" + " bne reg2_error_loopf \n" + " cmp r1, #11 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d6 \n" + " cmp r0, #-1 \n" + " bne reg2_error_loopf \n" + " cmp r1, #1 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d7 \n" + " cmp r0, #2 \n" + " bne reg2_error_loopf \n" + " cmp r1, #3 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d8 \n" + " cmp r0, #4 \n" + " bne reg2_error_loopf \n" + " cmp r1, #5 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d9 \n" + " cmp r0, #6 \n" + " bne reg2_error_loopf \n" + " cmp r1, #7 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d10 \n" + " cmp r0, #8 \n" + " bne reg2_error_loopf \n" + " cmp r1, #9 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d11 \n" + " cmp r0, #10 \n" + " bne reg2_error_loopf \n" + " cmp r1, #11 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d12 \n" + " cmp r0, #-1 \n" + " bne reg2_error_loopf \n" + " cmp r1, #1 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d13 \n" + " cmp r0, #2 \n" + " bne reg2_error_loopf \n" + " cmp r1, #3 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d14 \n" + " cmp r0, #4 \n" + " bne reg2_error_loopf \n" + " cmp r1, #5 \n" + " bne reg2_error_loopf \n" + " vmov r0, r1, d15 \n" + " cmp r0, #6 \n" + " bne reg2_error_loopf \n" + " cmp r1, #7 \n" + " bne reg2_error_loopf \n" + " \n" + " pop {r0-r1} \n" /* Restore the registers that were clobbered by the test. */ + " \n" + " b reg2_loopf_pass \n" /* VFP register test passed. Jump to the core register test. */ + " \n" + "reg2_error_loopf: \n" + " b reg2_error_loopf \n" /* If this line is hit then a VFP register value was found to be incorrect. */ + " \n" + "reg2_loopf_pass: \n" + " \n" + " cmp r0, #-1 \n" + " bne reg2_error_loop \n" + " cmp r1, #1 \n" + " bne reg2_error_loop \n" + " cmp r2, #2 \n" + " bne reg2_error_loop \n" + " cmp r3, #3 \n" + " bne reg2_error_loop \n" + " cmp r4, #4 \n" + " bne reg2_error_loop \n" + " cmp r5, #5 \n" + " bne reg2_error_loop \n" + " cmp r6, #6 \n" + " bne reg2_error_loop \n" + " cmp r7, #7 \n" + " bne reg2_error_loop \n" + " cmp r8, #8 \n" + " bne reg2_error_loop \n" + " cmp r9, #9 \n" + " bne reg2_error_loop \n" + " cmp r10, #10 \n" + " bne reg2_error_loop \n" + " cmp r11, #11 \n" + " bne reg2_error_loop \n" + " cmp r12, #12 \n" + " bne reg2_error_loop \n" + " \n" + " push { r0-r1 } \n" /* Increment the loop counter to indicate this test is still functioning correctly. */ + " ldr r0, =ulRegTest2LoopCounter \n" + " ldr r1, [r0] \n" + " adds r1, r1, #1 \n" + " str r1, [r0] \n" + " pop { r0-r1 } \n" + " \n" + " b reg2_loop \n" /* Start again. */ + " \n" + "reg2_error_loop: \n" /* If this line is hit then there was an error in a core register value. */ + " b reg2_error_loop \n" /* This loop ensures the loop counter variable stops incrementing. */ + " nop \n" + ); +} + + + -- 2.39.5