diff options
| author | Marti Bolivar <mbolivar@leaflabs.com> | 2011-06-24 14:38:35 -0400 | 
|---|---|---|
| committer | Marti Bolivar <mbolivar@leaflabs.com> | 2011-06-24 14:38:35 -0400 | 
| commit | b08c0f74786fe871e7c64a77d19d2a66329f62a4 (patch) | |
| tree | ce8ba7985fd93ad8910f8c0313722815137cabbd /libraries/FreeRTOS/utility/port.c | |
| parent | 22b9ffc1a7b77cab2a55c4c9ebf9c9abdc6c790e (diff) | |
| parent | 1a825f8a475f0b10c5c528cedd6c930a2f248255 (diff) | |
| download | librambutan-b08c0f74786fe871e7c64a77d19d2a66329f62a4.tar.gz librambutan-b08c0f74786fe871e7c64a77d19d2a66329f62a4.zip  | |
Merge branch 'freertos'
Diffstat (limited to 'libraries/FreeRTOS/utility/port.c')
| -rwxr-xr-x | libraries/FreeRTOS/utility/port.c | 292 | 
1 files changed, 292 insertions, 0 deletions
diff --git a/libraries/FreeRTOS/utility/port.c b/libraries/FreeRTOS/utility/port.c new file mode 100755 index 0000000..dc01720 --- /dev/null +++ b/libraries/FreeRTOS/utility/port.c @@ -0,0 +1,292 @@ +/* +    FreeRTOS V7.0.1 - 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 CM3 port. + *----------------------------------------------------------*/ + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" + +/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is +defined.  The value should also ensure backward compatibility. +FreeRTOS.org versions prior to V4.4.0 did not include this definition. */ +#ifndef configKERNEL_INTERRUPT_PRIORITY +	#define configKERNEL_INTERRUPT_PRIORITY 255 +#endif + +/* 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 set up the initial stack. */ +#define portINITIAL_XPSR			( 0x01000000 ) + +/* 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 portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa; + +/* + * Setup the timer to generate the tick interrupts. + */ +static void prvSetupTimerInterrupt( void ); + +/* + * Exception handlers. + */ +void xPortPendSVHandler( void ) __attribute__ (( naked )); +void xPortSysTickHandler( void ); +void vPortSVCHandler( void ) __attribute__ (( naked )); + +/* + * Start first task is a separate function so it can be tested in isolation. + */ +void vPortStartFirstTask( void ) __attribute__ (( naked )); + +/*-----------------------------------------------------------*/ + +/* + * 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. */ +	pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ +	*pxTopOfStack = portINITIAL_XPSR;	/* xPSR */ +	pxTopOfStack--; +	*pxTopOfStack = ( portSTACK_TYPE ) pxCode;	/* PC */ +	pxTopOfStack--; +	*pxTopOfStack = 0;	/* LR */ +	pxTopOfStack -= 5;	/* R12, R3, R2 and R1. */ +	*pxTopOfStack = ( portSTACK_TYPE ) pvParameters;	/* R0 */ +	pxTopOfStack -= 8;	/* R11, R10, R9, R8, R7, R6, R5 and R4. */ + +	return pxTopOfStack; +} +/*-----------------------------------------------------------*/ + +// !!! Maple +// void vPortSVCHandler( void ) +void __exc_svc( void ) +// !!! Maple +{ +	__asm volatile ( +					"	ldr	r3, pxCurrentTCBConst2		\n" /* Restore the context. */ +					"	ldr r1, [r3]					\n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ +					"	ldr r0, [r1]					\n" /* The first item in pxCurrentTCB is the task top of stack. */ +					"	ldmia r0!, {r4-r11}				\n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */ +					"	msr psp, r0						\n" /* Restore the task stack pointer. */ +					"	mov r0, #0 						\n" +					"	msr	basepri, r0					\n" +					"	orr r14, #0xd					\n" +					"	bx r14							\n" +					"									\n" +					"	.align 2						\n" +					"pxCurrentTCBConst2: .word pxCurrentTCB				\n" +				); +} +/*-----------------------------------------------------------*/ + +void vPortStartFirstTask( void ) +{ +	__asm volatile( +					" ldr r0, =0xE000ED08 	\n" /* Use the NVIC offset register to locate the stack. */ +					" ldr r0, [r0] 			\n" +					" ldr r0, [r0] 			\n" +					" msr msp, r0			\n" /* Set the msp back to the start of the stack. */ +					" cpsie i				\n" /* Globally enable interrupts. */ +					" svc 0					\n" /* System call to start first task. */ +					" nop					\n" +				); +} +/*-----------------------------------------------------------*/ + +/* + * See header file for description. + */ +portBASE_TYPE xPortStartScheduler( void ) +{ +	/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */ +	*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI; +	*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI; + +// !!! Maple +	systick_attach_callback(&xPortSysTickHandler); +//	/* Start the timer that generates the tick ISR.  Interrupts are disabled +//	here already. */ +//	prvSetupTimerInterrupt(); +// !!! Maple + +	/* Initialise the critical nesting count ready for the first task. */ +	uxCriticalNesting = 0; + +	/* Start the first task. */ +	vPortStartFirstTask(); + +	/* Should not get here! */ +	return 0; +} +/*-----------------------------------------------------------*/ + +void vPortEndScheduler( void ) +{ +	/* It is unlikely that the CM3 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(); +	uxCriticalNesting++; +} +/*-----------------------------------------------------------*/ + +void vPortExitCritical( void ) +{ +	uxCriticalNesting--; +	if( uxCriticalNesting == 0 ) +	{ +		portENABLE_INTERRUPTS(); +	} +} +/*-----------------------------------------------------------*/ + +// !!! Maple +// void xPortPendSVHandler( void ) +void __exc_pendsv( void ) +// !!! Maple +{ +	/* This is a naked function. */ + +	__asm volatile +	( +	"	mrs r0, psp							\n" +	"										\n" +	"	ldr	r3, pxCurrentTCBConst			\n" /* Get the location of the current TCB. */ +	"	ldr	r2, [r3]						\n" +	"										\n" +	"	stmdb r0!, {r4-r11}					\n" /* Save the remaining registers. */ +	"	str r0, [r2]						\n" /* Save the new top of stack into the first member of the TCB. */ +	"										\n" +	"	stmdb sp!, {r3, r14}				\n" +	"	mov r0, %0							\n" +	"	msr basepri, r0						\n" +	"	bl vTaskSwitchContext				\n" +	"	mov r0, #0							\n" +	"	msr basepri, r0						\n" +	"	ldmia sp!, {r3, r14}				\n" +	"										\n"	/* Restore the context, including the critical nesting count. */ +	"	ldr r1, [r3]						\n" +	"	ldr r0, [r1]						\n" /* The first item in pxCurrentTCB is the task top of stack. */ +	"	ldmia r0!, {r4-r11}					\n" /* Pop the registers. */ +	"	msr psp, r0							\n" +	"	bx r14								\n" +	"										\n" +	"	.align 2							\n" +	"pxCurrentTCBConst: .word pxCurrentTCB	\n" +	::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) +	); +} +/*-----------------------------------------------------------*/ + +void xPortSysTickHandler( 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; +} +/*-----------------------------------------------------------*/ +  | 
