mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-01 11:53:53 -04:00
made a copy
This commit is contained in:
parent
bb7dc7c37f
commit
e20f132f48
2632 changed files with 751681 additions and 0 deletions
214
20080212/Source/portable/IAR/ARM_CM3/port.c
Normal file
214
20080212/Source/portable/IAR/ARM_CM3/port.c
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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.
|
||||
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
Change from V4.2.1:
|
||||
|
||||
+ Introduced usage of configKERNEL_INTERRUPT_PRIORITY macro to set the
|
||||
interrupt priority used by the kernel.
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM CM3 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to manipulate the NVIC. */
|
||||
#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned portLONG *) 0xe000e010 )
|
||||
#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned portLONG *) 0xe000e014 )
|
||||
#define portNVIC_INT_CTRL ( ( volatile unsigned portLONG *) 0xe000ed04 )
|
||||
#define portNVIC_SYSPRI2 ( ( volatile unsigned portLONG *) 0xe000ed20 )
|
||||
#define portNVIC_SYSPRI1 ( ( volatile unsigned portLONG *) 0xe000ed1c )
|
||||
#define portNVIC_SYSTICK_CLK 0x00000004
|
||||
#define portNVIC_SYSTICK_INT 0x00000002
|
||||
#define portNVIC_SYSTICK_ENABLE 0x00000001
|
||||
#define portNVIC_PENDSVSET 0x10000000
|
||||
#define portNVIC_PENDSV_PRI ( ( ( unsigned portLONG ) configKERNEL_INTERRUPT_PRIORITY ) << 16 )
|
||||
#define portNVIC_SYSTICK_PRI ( ( ( unsigned portLONG ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )
|
||||
|
||||
/* Constants required to set up the initial stack. */
|
||||
#define portINITIAL_XPSR ( 0x01000000 )
|
||||
|
||||
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
|
||||
defined. The value 255 should also ensure backward compatibility.
|
||||
FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
|
||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 0
|
||||
#endif
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
* Setup the timer to generate the tick interrupts.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* Set the MSP/PSP to a known value.
|
||||
*/
|
||||
extern void vSetMSP( unsigned long ulValue );
|
||||
extern void vSetPSP( unsigned long ulValue );
|
||||
|
||||
/*
|
||||
* Utilities called from the assembler code.
|
||||
*/
|
||||
void vPortSwitchContext( void );
|
||||
void vPortIncrementTick( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* 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 = portINITIAL_XPSR; /* xPSR */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode; /* PC */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0xfffffffd; /* LR */
|
||||
pxTopOfStack -= 5; /* R12, R3, R2 and R1. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||
pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4. */
|
||||
*pxTopOfStack = 0x00000000; /* uxCriticalNesting. */
|
||||
|
||||
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();
|
||||
|
||||
/* Start the first task. */
|
||||
vSetPSP( 0 );
|
||||
vSetMSP( *((unsigned portLONG *) 0 ) );
|
||||
*(portNVIC_INT_CTRL) |= portNVIC_PENDSVSET;
|
||||
|
||||
/* Enable interrupts */
|
||||
portENABLE_INTERRUPTS();
|
||||
|
||||
/* 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;
|
||||
|
||||
/* This function is also called in response to a Yield(), so we want
|
||||
the yield to occur immediately. */
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
uxCriticalNesting--;
|
||||
if( uxCriticalNesting == 0 )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
*(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortSwitchContext( void )
|
||||
{
|
||||
vPortSetInterruptMask();
|
||||
vTaskSwitchContext();
|
||||
vPortClearInterruptMask();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortIncrementTick( void )
|
||||
{
|
||||
vPortSetInterruptMask();
|
||||
vTaskIncrementTick();
|
||||
vPortClearInterruptMask();
|
||||
}
|
||||
|
||||
|
175
20080212/Source/portable/IAR/ARM_CM3/portasm.s
Normal file
175
20080212/Source/portable/IAR/ARM_CM3/portasm.s
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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.
|
||||
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
Change from V4.2.1:
|
||||
|
||||
+ Introduced usage of configKERNEL_INTERRUPT_PRIORITY macro to set the
|
||||
interrupt priority used by the kernel.
|
||||
*/
|
||||
|
||||
#include <FreeRTOSConfig.h>
|
||||
|
||||
/* For backward compatibility, ensure configKERNEL_INTERRUPT_PRIORITY is
|
||||
defined. The value zero should also ensure backward compatibility.
|
||||
FreeRTOS.org versions prior to V4.3.0 did not include this definition. */
|
||||
#ifndef configKERNEL_INTERRUPT_PRIORITY
|
||||
#define configKERNEL_INTERRUPT_PRIORITY 0
|
||||
#endif
|
||||
|
||||
|
||||
RSEG CODE:CODE(2)
|
||||
thumb
|
||||
|
||||
EXTERN vPortYieldFromISR
|
||||
EXTERN vPortSwitchContext
|
||||
EXTERN vPortIncrementTick
|
||||
EXTERN uxCriticalNesting
|
||||
EXTERN pxCurrentTCB
|
||||
|
||||
PUBLIC vSetPSP
|
||||
PUBLIC vSetMSP
|
||||
PUBLIC xPortPendSVHandler
|
||||
PUBLIC xPortSysTickHandler
|
||||
PUBLIC vPortSetInterruptMask
|
||||
PUBLIC vPortClearInterruptMask
|
||||
|
||||
|
||||
vSetPSP:
|
||||
msr psp, r0
|
||||
bx lr
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vSetMSP
|
||||
msr msp, r0
|
||||
bx lr
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
xPortPendSVHandler:
|
||||
mrs r0, psp
|
||||
cbz r0, no_save
|
||||
/* Save the context into the TCB. */
|
||||
stmdb r0!, {r4-r11}
|
||||
sub r0, r0, #0x04
|
||||
ldr r1, =uxCriticalNesting
|
||||
ldr r2, =pxCurrentTCB
|
||||
ldr r1, [r1]
|
||||
ldr r2, [r2]
|
||||
str r1, [r0]
|
||||
str r0, [r2]
|
||||
|
||||
no_save:
|
||||
push {r14}
|
||||
bl vPortSwitchContext
|
||||
pop {r14}
|
||||
/* Restore the context. */
|
||||
ldr r1, =pxCurrentTCB
|
||||
ldr r1, [r1]
|
||||
ldr r0, [r1]
|
||||
ldmia r0!, {r1, r4-r11}
|
||||
ldr r2, =uxCriticalNesting
|
||||
str r1, [r2]
|
||||
msr psp, r0
|
||||
orr r14, r14, #0xd
|
||||
/* Exit with interrupts in the state required by the task. */
|
||||
cbnz r1, sv_disable_interrupts
|
||||
bx r14
|
||||
|
||||
sv_disable_interrupts:
|
||||
mov r1, #configKERNEL_INTERRUPT_PRIORITY
|
||||
msr basepri, R1
|
||||
bx r14
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
xPortSysTickHandler:
|
||||
/* Call the scheduler tick function. */
|
||||
push {r14}
|
||||
bl vPortIncrementTick
|
||||
pop {r14}
|
||||
|
||||
/* If using preemption, also force a context switch. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
push {r14}
|
||||
bl vPortYieldFromISR
|
||||
pop {r14}
|
||||
#endif
|
||||
|
||||
/* Exit with interrupts in the correct state. */
|
||||
ldr r2, =uxCriticalNesting
|
||||
ldr r2, [r2]
|
||||
cbnz r2, tick_disable_interrupts
|
||||
bx r14
|
||||
|
||||
tick_disable_interrupts:
|
||||
mov r1, #configKERNEL_INTERRUPT_PRIORITY
|
||||
msr basepri, R1
|
||||
|
||||
bx r14
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortSetInterruptMask:
|
||||
push { r0 }
|
||||
mov R0, #configKERNEL_INTERRUPT_PRIORITY
|
||||
msr BASEPRI, R0
|
||||
pop { R0 }
|
||||
|
||||
bx r14
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
vPortClearInterruptMask:
|
||||
PUSH { r0 }
|
||||
MOV R0, #0
|
||||
MSR BASEPRI, R0
|
||||
POP { R0 }
|
||||
|
||||
bx r14
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
END
|
||||
|
127
20080212/Source/portable/IAR/ARM_CM3/portmacro.h
Normal file
127
20080212/Source/portable/IAR/ARM_CM3/portmacro.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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.
|
||||
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
Change from V4.2.1:
|
||||
|
||||
+ Introduced usage of configKERNEL_INTERRUPT_PRIORITY macro to set the
|
||||
interrupt priority used by the kernel.
|
||||
*/
|
||||
|
||||
|
||||
#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 4
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Scheduler utilities. */
|
||||
extern void vPortYieldFromISR( void );
|
||||
|
||||
#define portYIELD() vPortYieldFromISR()
|
||||
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Critical section management. */
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
extern void vPortSetInterruptMask( void );
|
||||
extern void vPortClearInterruptMask( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() vPortSetInterruptMask();
|
||||
#define portENABLE_INTERRUPTS() vPortClearInterruptMask();
|
||||
#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 inline
|
||||
#define portNOP()
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
355
20080212/Source/portable/IAR/ATMega323/port.c
Normal file
355
20080212/Source/portable/IAR/ATMega323/port.c
Normal file
|
@ -0,0 +1,355 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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.
|
||||
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the AVR/IAR port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Start tasks with interrupts enables. */
|
||||
#define portFLAGS_INT_ENABLED ( ( portSTACK_TYPE ) 0x80 )
|
||||
|
||||
/* Hardware constants for timer 1. */
|
||||
#define portCLEAR_COUNTER_ON_MATCH ( ( unsigned portCHAR ) 0x08 )
|
||||
#define portPRESCALE_64 ( ( unsigned portCHAR ) 0x03 )
|
||||
#define portCLOCK_PRESCALER ( ( unsigned portLONG ) 64 )
|
||||
#define portCOMPARE_MATCH_A_INTERRUPT_ENABLE ( ( unsigned portCHAR ) 0x10 )
|
||||
|
||||
/* The number of bytes used on the hardware stack by the task start address. */
|
||||
#define portBYTES_USED_BY_RETURN_ADDRESS ( 2 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Stores the critical section nesting. This must not be initialised to 0.
|
||||
It will be initialised when a task starts. */
|
||||
#define portNO_CRITICAL_NESTING ( ( unsigned portBASE_TYPE ) 0 )
|
||||
unsigned portBASE_TYPE uxCriticalNesting = 0x50;
|
||||
|
||||
|
||||
/*
|
||||
* Perform hardware setup to enable ticks from timer 1, compare match A.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*
|
||||
* The IAR compiler does not have full support for inline assembler, so
|
||||
* these are defined in the portmacro assembler file.
|
||||
*/
|
||||
extern void vPortYieldFromTick( void );
|
||||
extern void vPortStart( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* See header file for description.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||
{
|
||||
unsigned portSHORT usAddress;
|
||||
portSTACK_TYPE *pxTopOfHardwareStack;
|
||||
|
||||
/* Place a few bytes of known values on the bottom of the stack.
|
||||
This is just useful for debugging. */
|
||||
|
||||
*pxTopOfStack = 0x11;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x22;
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = 0x33;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Remember where the top of the hardware stack is - this is required
|
||||
below. */
|
||||
pxTopOfHardwareStack = pxTopOfStack;
|
||||
|
||||
|
||||
/* Simulate how the stack would look after a call to vPortYield(). */
|
||||
|
||||
/*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
|
||||
|
||||
|
||||
|
||||
/* The IAR compiler requires two stacks per task. First there is the
|
||||
hardware call stack which uses the AVR stack pointer. Second there is the
|
||||
software stack (local variables, parameter passing, etc.) which uses the
|
||||
AVR Y register.
|
||||
|
||||
This function places both stacks within the memory block passed in as the
|
||||
first parameter. The hardware stack is placed at the bottom of the memory
|
||||
block. A gap is then left for the hardware stack to grow. Next the software
|
||||
stack is placed. The amount of space between the software and hardware
|
||||
stacks is defined by configCALL_STACK_SIZE.
|
||||
|
||||
|
||||
|
||||
The first part of the stack is the hardware stack. Place the start
|
||||
address of the task on the hardware stack. */
|
||||
usAddress = ( unsigned portSHORT ) pxCode;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
|
||||
/* Leave enough space for the hardware stack before starting the software
|
||||
stack. The '- 2' is because we have already used two spaces for the
|
||||
address of the start of the task. */
|
||||
pxTopOfStack -= ( configCALL_STACK_SIZE - 2 );
|
||||
|
||||
|
||||
|
||||
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
|
||||
portSAVE_CONTEXT places the flags on the stack immediately after r0
|
||||
to ensure the interrupts get disabled as soon as possible, and so ensuring
|
||||
the stack use is minimal should a context switch interrupt occur. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x00; /* R0 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portFLAGS_INT_ENABLED;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Next place the address of the hardware stack. This is required so
|
||||
the AVR stack pointer can be restored to point to the hardware stack. */
|
||||
pxTopOfHardwareStack -= portBYTES_USED_BY_RETURN_ADDRESS;
|
||||
usAddress = ( unsigned portSHORT ) pxTopOfHardwareStack;
|
||||
|
||||
/* SPL */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
/* SPH */
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Now the remaining registers. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x01; /* R1 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x02; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x03; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x04; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x05; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x06; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x07; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x08; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x09; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x10; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x11; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x12; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x13; /* R13 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x14; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x15; /* R15 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Place the parameter on the stack in the expected location. */
|
||||
usAddress = ( unsigned portSHORT ) pvParameters;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
usAddress >>= 8;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) ( usAddress & ( unsigned portSHORT ) 0x00ff );
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x18; /* R18 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x19; /* R19 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x20; /* R20 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x21; /* R21 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x22; /* R22 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x23; /* R23 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x24; /* R24 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x25; /* R25 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x26; /* R26 X */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x27; /* R27 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The Y register is not stored as it is used as the software stack and
|
||||
gets saved into the task control block. */
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x30; /* R30 Z */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x031; /* R31 */
|
||||
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING; /* Critical nesting is zero when the task starts. */
|
||||
|
||||
/*lint +e950 +e611 +e923 */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
/* Setup the hardware to generate the tick. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Restore the context of the first task that is going to run.
|
||||
Normally we would just call portRESTORE_CONTEXT() here, but as the IAR
|
||||
compiler does not fully support inline assembler we have to make a call.*/
|
||||
vPortStart();
|
||||
|
||||
|
||||
/* Should not get here! */
|
||||
return pdTRUE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the AVR port will get stopped. If required simply
|
||||
disable the tick interrupt here. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Setup timer 1 compare match A to generate a tick interrupt.
|
||||
*/
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
unsigned portLONG ulCompareMatch;
|
||||
unsigned portCHAR ucHighByte, ucLowByte;
|
||||
|
||||
/* Using 16bit timer 1 to generate the tick. Correct fuses must be
|
||||
selected for the configCPU_CLOCK_HZ clock. */
|
||||
|
||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* We only have 16 bits so have to scale to get our required tick rate. */
|
||||
ulCompareMatch /= portCLOCK_PRESCALER;
|
||||
|
||||
/* Adjust for correct value. */
|
||||
ulCompareMatch -= ( unsigned portLONG ) 1;
|
||||
|
||||
/* Setup compare match value for compare match A. Interrupts are disabled
|
||||
before this is called so we need not worry here. */
|
||||
ucLowByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff );
|
||||
ulCompareMatch >>= 8;
|
||||
ucHighByte = ( unsigned portCHAR ) ( ulCompareMatch & ( unsigned portLONG ) 0xff );
|
||||
OCR1AH = ucHighByte;
|
||||
OCR1AL = ucLowByte;
|
||||
|
||||
/* Setup clock source and compare match behaviour. */
|
||||
ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64;
|
||||
TCCR1B = ucLowByte;
|
||||
|
||||
/* Enable the interrupt - this is okay as interrupt are currently globally
|
||||
disabled. */
|
||||
TIMSK |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configUSE_PREEMPTION == 1
|
||||
|
||||
/*
|
||||
* Tick ISR for preemptive scheduler. We can use a __task attribute as
|
||||
* the context is saved at the start of vPortYieldFromTick(). The tick
|
||||
* count is incremented after the context is saved.
|
||||
*/
|
||||
__task void SIG_OUTPUT_COMPARE1A( void )
|
||||
{
|
||||
vPortYieldFromTick();
|
||||
asm( "reti" );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Tick ISR for the cooperative scheduler. All this does is increment the
|
||||
* tick count. We don't need to switch context, this can only be done by
|
||||
* manual calls to taskYIELD();
|
||||
*
|
||||
* THE INTERRUPT VECTOR IS POPULATED IN portmacro.s90. DO NOT INSTALL
|
||||
* IT HERE USING THE USUAL PRAGMA.
|
||||
*/
|
||||
__interrupt void SIG_OUTPUT_COMPARE1A( void )
|
||||
{
|
||||
vTaskIncrementTick();
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
uxCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
uxCriticalNesting--;
|
||||
if( uxCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
|
||||
|
126
20080212/Source/portable/IAR/ATMega323/portmacro.h
Normal file
126
20080212/Source/portable/IAR/ATMega323/portmacro.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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.
|
||||
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
Changes from V1.2.3
|
||||
|
||||
+ portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it
|
||||
base 16.
|
||||
*/
|
||||
|
||||
#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 int
|
||||
#define portSTACK_TYPE unsigned portCHAR
|
||||
#define portBASE_TYPE portCHAR
|
||||
|
||||
#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
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section management. */
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
#define portDISABLE_INTERRUPTS() asm( "cli" )
|
||||
#define portENABLE_INTERRUPTS() asm( "sei" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Architecture specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 1
|
||||
#define portNOP() asm( "nop" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Kernel utilities. */
|
||||
void vPortYield( void );
|
||||
#define portYIELD() vPortYield()
|
||||
|
||||
#ifdef IAR_MEGA_AVR
|
||||
#define outb( PORT, VALUE ) PORT = VALUE
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler specifics. */
|
||||
#define inline
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
245
20080212/Source/portable/IAR/ATMega323/portmacro.s90
Normal file
245
20080212/Source/portable/IAR/ATMega323/portmacro.s90
Normal file
|
@ -0,0 +1,245 @@
|
|||
; FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
;
|
||||
; This file is part of the FreeRTOS.org distribution.
|
||||
;
|
||||
; FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation; either version 2 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; FreeRTOS.org 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
|
||||
; along with FreeRTOS.org; if not, write to the Free Software
|
||||
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
;
|
||||
; A special exception to the GPL can be applied should you wish to distribute
|
||||
; a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
; the source code for any proprietary components. See the licensing section
|
||||
; of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
; can be applied.
|
||||
;
|
||||
; ***************************************************************************
|
||||
; See http://www.FreeRTOS.org for documentation, latest information, license
|
||||
; and contact details. Please ensure to read the configuration and relevant
|
||||
; port sections of the online documentation.
|
||||
; ***************************************************************************
|
||||
|
||||
#include <iom323.h>
|
||||
|
||||
; Declare all extern symbols here - including any ISRs that are referenced in
|
||||
; the vector table.
|
||||
|
||||
; ISR functions
|
||||
; -------------
|
||||
EXTERN SIG_OUTPUT_COMPARE1A
|
||||
EXTERN SIG_UART_RECV
|
||||
EXTERN SIG_UART_DATA
|
||||
|
||||
|
||||
; Functions used by scheduler
|
||||
; ---------------------------
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN vTaskIncrementTick
|
||||
EXTERN uxCriticalNesting
|
||||
|
||||
; Functions implemented in this file
|
||||
; ----------------------------------
|
||||
PUBLIC vPortYield
|
||||
PUBLIC vPortYieldFromTick
|
||||
PUBLIC vPortStart
|
||||
|
||||
|
||||
; Interrupt vector table.
|
||||
; -----------------------
|
||||
;
|
||||
; For simplicity the RTOS tick interrupt routine uses the __task keyword.
|
||||
; As the IAR compiler does not permit a function to be declared using both
|
||||
; __task and __interrupt, the use of __task necessitates that the interrupt
|
||||
; vector table be setup manually.
|
||||
;
|
||||
; To write an ISR, implement the ISR function using the __interrupt keyword
|
||||
; but do not install the interrupt using the "#pragma vector=ABC" method.
|
||||
; Instead manually place the name of the ISR in the vector table using an
|
||||
; ORG and jmp instruction as demonstrated below.
|
||||
; You will also have to add an EXTERN statement at the top of the file.
|
||||
|
||||
ASEG
|
||||
|
||||
|
||||
ORG TIMER1_COMPA_vect ; Vector address
|
||||
jmp SIG_OUTPUT_COMPARE1A ; ISR
|
||||
|
||||
ORG USART_RXC_vect ; Vector address
|
||||
jmp SIG_UART_RECV ; ISR
|
||||
|
||||
ORG USART_UDRE_vect ; Vector address
|
||||
jmp SIG_UART_DATA ; ISR
|
||||
|
||||
|
||||
RSEG CODE
|
||||
|
||||
|
||||
|
||||
; Saving and Restoring a Task Context and Task Switching
|
||||
; ------------------------------------------------------
|
||||
;
|
||||
; The IAR compiler does not fully support inline assembler, so saving and
|
||||
; restoring a task context has to be written in an asm file.
|
||||
;
|
||||
; vPortYield() and vPortYieldFromTick() are usually written in C. Doing
|
||||
; so in this case would required calls to be made to portSAVE_CONTEXT() and
|
||||
; portRESTORE_CONTEXT(). This is dis-advantageous as the context switch
|
||||
; function would require two extra jump and return instructions over the
|
||||
; WinAVR equivalent.
|
||||
;
|
||||
; To avoid this I have opted to implement both vPortYield() and
|
||||
; vPortYieldFromTick() in this assembly file. For convenience
|
||||
; portSAVE_CONTEXT and portRESTORE_CONTEXT are implemented as macros.
|
||||
|
||||
portSAVE_CONTEXT MACRO
|
||||
st -y, r0 ; First save the r0 register - we need to use this.
|
||||
in r0, SREG ; Obtain the SREG value so we can disable interrupts...
|
||||
cli ; ... as soon as possible.
|
||||
st -y, r0 ; Store the SREG as it was before we disabled interrupts.
|
||||
|
||||
in r0, SPL ; Next store the hardware stack pointer. The IAR...
|
||||
st -y, r0 ; ... compiler uses the hardware stack as a call stack ...
|
||||
in r0, SPH ; ... only.
|
||||
st -y, r0
|
||||
|
||||
st -y, r1 ; Now store the rest of the registers. Dont store the ...
|
||||
st -y, r2 ; ... the Y register here as it is used as the software
|
||||
st -y, r3 ; stack pointer and will get saved into the TCB.
|
||||
st -y, r4
|
||||
st -y, r5
|
||||
st -y, r6
|
||||
st -y, r7
|
||||
st -y, r8
|
||||
st -y, r9
|
||||
st -y, r10
|
||||
st -y, r11
|
||||
st -y, r12
|
||||
st -y, r13
|
||||
st -y, r14
|
||||
st -y, r15
|
||||
st -y, r16
|
||||
st -y, r17
|
||||
st -y, r18
|
||||
st -y, r19
|
||||
st -y, r20
|
||||
st -y, r21
|
||||
st -y, r22
|
||||
st -y, r23
|
||||
st -y, r24
|
||||
st -y, r25
|
||||
st -y, r26
|
||||
st -y, r27
|
||||
st -y, r30
|
||||
st -y, r31
|
||||
lds r0, uxCriticalNesting
|
||||
st -y, r0 ; Store the critical nesting counter.
|
||||
|
||||
lds r26, pxCurrentTCB ; Finally save the software stack pointer (Y ...
|
||||
lds r27, pxCurrentTCB + 1 ; ... register) into the TCB.
|
||||
st x+, r28
|
||||
st x+, r29
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
portRESTORE_CONTEXT MACRO
|
||||
lds r26, pxCurrentTCB
|
||||
lds r27, pxCurrentTCB + 1 ; Restore the software stack pointer from ...
|
||||
ld r28, x+ ; the TCB into the software stack pointer (...
|
||||
ld r29, x+ ; ... the Y register).
|
||||
|
||||
ld r0, y+
|
||||
sts uxCriticalNesting, r0
|
||||
ld r31, y+ ; Restore the registers down to R0. The Y
|
||||
ld r30, y+ ; register is missing from this list as it
|
||||
ld r27, y+ ; has already been restored.
|
||||
ld r26, y+
|
||||
ld r25, y+
|
||||
ld r24, y+
|
||||
ld r23, y+
|
||||
ld r22, y+
|
||||
ld r21, y+
|
||||
ld r20, y+
|
||||
ld r19, y+
|
||||
ld r18, y+
|
||||
ld r17, y+
|
||||
ld r16, y+
|
||||
ld r15, y+
|
||||
ld r14, y+
|
||||
ld r13, y+
|
||||
ld r12, y+
|
||||
ld r11, y+
|
||||
ld r10, y+
|
||||
ld r9, y+
|
||||
ld r8, y+
|
||||
ld r7, y+
|
||||
ld r6, y+
|
||||
ld r5, y+
|
||||
ld r4, y+
|
||||
ld r3, y+
|
||||
ld r2, y+
|
||||
ld r1, y+
|
||||
|
||||
ld r0, y+ ; The next thing on the stack is the ...
|
||||
out SPH, r0 ; ... hardware stack pointer.
|
||||
ld r0, y+
|
||||
out SPL, r0
|
||||
|
||||
ld r0, y+ ; Next there is the SREG register.
|
||||
out SREG, r0
|
||||
|
||||
ld r0, y+ ; Finally we have finished with r0, so restore r0.
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
|
||||
; vPortYield() and vPortYieldFromTick()
|
||||
; -------------------------------------
|
||||
;
|
||||
; Manual and preemptive context switch functions respectively.
|
||||
; The IAR compiler does not fully support inline assembler,
|
||||
; so these are implemented here rather than the more usually
|
||||
; place of within port.c.
|
||||
|
||||
vPortYield:
|
||||
portSAVE_CONTEXT ; Save the context of the current task.
|
||||
call vTaskSwitchContext ; Call the scheduler.
|
||||
portRESTORE_CONTEXT ; Restore the context of whichever task the ...
|
||||
ret ; ... scheduler decided should run.
|
||||
|
||||
vPortYieldFromTick:
|
||||
portSAVE_CONTEXT ; Save the context of the current task.
|
||||
call vTaskIncrementTick ; Call the timer tick function.
|
||||
call vTaskSwitchContext ; Call the scheduler.
|
||||
portRESTORE_CONTEXT ; Restore the context of whichever task the ...
|
||||
ret ; ... scheduler decided should run.
|
||||
|
||||
; vPortStart()
|
||||
; ------------
|
||||
;
|
||||
; Again due to the lack of inline assembler, this is required
|
||||
; to get access to the portRESTORE_CONTEXT macro.
|
||||
|
||||
vPortStart:
|
||||
portRESTORE_CONTEXT
|
||||
ret
|
||||
|
||||
|
||||
; Just a filler for unused interrupt vectors.
|
||||
vNoISR:
|
||||
reti
|
||||
|
||||
|
||||
END
|
||||
|
310
20080212/Source/portable/IAR/AVR32_UC3/exception.s82
Normal file
310
20080212/Source/portable/IAR/AVR32_UC3/exception.s82
Normal file
|
@ -0,0 +1,310 @@
|
|||
/*This file is prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief Exception and interrupt vectors.
|
||||
*
|
||||
* This file maps all events supported by an AVR32UC.
|
||||
*
|
||||
* - Compiler: IAR EWAVR32
|
||||
* - Supported devices: All AVR32UC devices with an INTC module can be used.
|
||||
* - AppNote:
|
||||
*
|
||||
* \author Atmel Corporation: http://www.atmel.com \n
|
||||
* Support and FAQ: http://support.atmel.no/
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of ATMEL may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
|
||||
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <avr32/io.h>
|
||||
#include "intc.h"
|
||||
|
||||
|
||||
//! @{
|
||||
//! \verbatim
|
||||
|
||||
|
||||
// Start of Exception Vector Table.
|
||||
|
||||
// EVBA must be aligned with a power of two strictly greater than the EVBA-
|
||||
// relative offset of the last vector.
|
||||
COMMON EVTAB:CODE:ROOT(9)
|
||||
|
||||
|
||||
// Force EVBA initialization.
|
||||
EXTERN ??init_EVBA
|
||||
REQUIRE ??init_EVBA
|
||||
|
||||
// Export symbol.
|
||||
PUBLIC ??EVBA
|
||||
PUBLIC _evba
|
||||
??EVBA:
|
||||
_evba:
|
||||
|
||||
ORG 0x000
|
||||
// Unrecoverable Exception.
|
||||
_handle_Unrecoverable_Exception:
|
||||
rjmp $
|
||||
|
||||
ORG 0x004
|
||||
// TLB Multiple Hit: UNUSED IN AVR32UC.
|
||||
_handle_TLB_Multiple_Hit:
|
||||
rjmp $
|
||||
|
||||
ORG 0x008
|
||||
// Bus Error Data Fetch.
|
||||
_handle_Bus_Error_Data_Fetch:
|
||||
rjmp $
|
||||
|
||||
ORG 0x00C
|
||||
// Bus Error Instruction Fetch.
|
||||
_handle_Bus_Error_Instruction_Fetch:
|
||||
rjmp $
|
||||
|
||||
ORG 0x010
|
||||
// NMI.
|
||||
_handle_NMI:
|
||||
rjmp $
|
||||
|
||||
ORG 0x014
|
||||
// Instruction Address.
|
||||
_handle_Instruction_Address:
|
||||
rjmp $
|
||||
|
||||
ORG 0x018
|
||||
// ITLB Protection.
|
||||
_handle_ITLB_Protection:
|
||||
rjmp $
|
||||
|
||||
ORG 0x01C
|
||||
// Breakpoint.
|
||||
_handle_Breakpoint:
|
||||
rjmp $
|
||||
|
||||
ORG 0x020
|
||||
// Illegal Opcode.
|
||||
_handle_Illegal_Opcode:
|
||||
rjmp $
|
||||
|
||||
ORG 0x024
|
||||
// Unimplemented Instruction.
|
||||
_handle_Unimplemented_Instruction:
|
||||
rjmp $
|
||||
|
||||
ORG 0x028
|
||||
// Privilege Violation.
|
||||
_handle_Privilege_Violation:
|
||||
rjmp $
|
||||
|
||||
ORG 0x02C
|
||||
// Floating-Point: UNUSED IN AVR32UC.
|
||||
_handle_Floating_Point:
|
||||
rjmp $
|
||||
|
||||
ORG 0x030
|
||||
// Coprocessor Absent: UNUSED IN AVR32UC.
|
||||
_handle_Coprocessor_Absent:
|
||||
rjmp $
|
||||
|
||||
ORG 0x034
|
||||
// Data Address (Read).
|
||||
_handle_Data_Address_Read:
|
||||
rjmp $
|
||||
|
||||
ORG 0x038
|
||||
// Data Address (Write).
|
||||
_handle_Data_Address_Write:
|
||||
rjmp $
|
||||
|
||||
ORG 0x03C
|
||||
// DTLB Protection (Read).
|
||||
_handle_DTLB_Protection_Read:
|
||||
rjmp $
|
||||
|
||||
ORG 0x040
|
||||
// DTLB Protection (Write).
|
||||
_handle_DTLB_Protection_Write:
|
||||
rjmp $
|
||||
|
||||
ORG 0x044
|
||||
// DTLB Modified: UNUSED IN AVR32UC.
|
||||
_handle_DTLB_Modified:
|
||||
rjmp $
|
||||
|
||||
ORG 0x050
|
||||
// ITLB Miss: UNUSED IN AVR32UC.
|
||||
_handle_ITLB_Miss:
|
||||
rjmp $
|
||||
|
||||
ORG 0x060
|
||||
// DTLB Miss (Read): UNUSED IN AVR32UC.
|
||||
_handle_DTLB_Miss_Read:
|
||||
rjmp $
|
||||
|
||||
ORG 0x070
|
||||
// DTLB Miss (Write): UNUSED IN AVR32UC.
|
||||
_handle_DTLB_Miss_Write:
|
||||
rjmp $
|
||||
|
||||
ORG 0x100
|
||||
// Supervisor Call.
|
||||
_handle_Supervisor_Call:
|
||||
lddpc pc, __SCALLYield
|
||||
|
||||
|
||||
// Interrupt support.
|
||||
// The interrupt controller must provide the offset address relative to EVBA.
|
||||
// Important note:
|
||||
// All interrupts call a C function named _get_interrupt_handler.
|
||||
// This function will read group and interrupt line number to then return in
|
||||
// R12 a pointer to a user-provided interrupt handler.
|
||||
|
||||
ALIGN 2
|
||||
|
||||
_int0:
|
||||
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
||||
// CPU upon interrupt entry.
|
||||
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
||||
mfsr r12, AVR32_SR
|
||||
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
||||
cp.w r12, 110b
|
||||
brlo _int0_normal
|
||||
lddsp r12, sp[0 * 4]
|
||||
stdsp sp[6 * 4], r12
|
||||
lddsp r12, sp[1 * 4]
|
||||
stdsp sp[7 * 4], r12
|
||||
lddsp r12, sp[3 * 4]
|
||||
sub sp, -6 * 4
|
||||
rete
|
||||
_int0_normal:
|
||||
#endif
|
||||
mov r12, 0 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
||||
mcall __get_interrupt_handler
|
||||
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
||||
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
||||
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
||||
|
||||
_int1:
|
||||
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
||||
// CPU upon interrupt entry.
|
||||
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
||||
mfsr r12, AVR32_SR
|
||||
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
||||
cp.w r12, 110b
|
||||
brlo _int1_normal
|
||||
lddsp r12, sp[0 * 4]
|
||||
stdsp sp[6 * 4], r12
|
||||
lddsp r12, sp[1 * 4]
|
||||
stdsp sp[7 * 4], r12
|
||||
lddsp r12, sp[3 * 4]
|
||||
sub sp, -6 * 4
|
||||
rete
|
||||
_int1_normal:
|
||||
#endif
|
||||
mov r12, 1 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
||||
mcall __get_interrupt_handler
|
||||
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
||||
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
||||
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
||||
|
||||
_int2:
|
||||
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
||||
// CPU upon interrupt entry.
|
||||
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
||||
mfsr r12, AVR32_SR
|
||||
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
||||
cp.w r12, 110b
|
||||
brlo _int2_normal
|
||||
lddsp r12, sp[0 * 4]
|
||||
stdsp sp[6 * 4], r12
|
||||
lddsp r12, sp[1 * 4]
|
||||
stdsp sp[7 * 4], r12
|
||||
lddsp r12, sp[3 * 4]
|
||||
sub sp, -6 * 4
|
||||
rete
|
||||
_int2_normal:
|
||||
#endif
|
||||
mov r12, 2 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
||||
mcall __get_interrupt_handler
|
||||
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
||||
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
||||
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
||||
|
||||
_int3:
|
||||
// R8-R12, LR, PC and SR are automatically pushed onto the system stack by the
|
||||
// CPU upon interrupt entry.
|
||||
#if 1 // B1832: interrupt stack changed to exception stack if exception is detected.
|
||||
mfsr r12, AVR32_SR
|
||||
bfextu r12, r12, AVR32_SR_M0_OFFSET, AVR32_SR_M0_SIZE + AVR32_SR_M1_SIZE + AVR32_SR_M2_SIZE
|
||||
cp.w r12, 110b
|
||||
brlo _int3_normal
|
||||
lddsp r12, sp[0 * 4]
|
||||
stdsp sp[6 * 4], r12
|
||||
lddsp r12, sp[1 * 4]
|
||||
stdsp sp[7 * 4], r12
|
||||
lddsp r12, sp[3 * 4]
|
||||
sub sp, -6 * 4
|
||||
rete
|
||||
_int3_normal:
|
||||
#endif
|
||||
mov r12, 3 // Pass the int_lev parameter to the _get_interrupt_handler function.
|
||||
mcall __get_interrupt_handler
|
||||
cp.w r12, 0 // Get the pointer to the interrupt handler returned by the function.
|
||||
movne pc, r12 // If this was not a spurious interrupt (R12 != NULL), jump to the handler.
|
||||
rete // If this was a spurious interrupt (R12 == NULL), return from event handler.
|
||||
|
||||
|
||||
// Constant data area.
|
||||
|
||||
ALIGN 2
|
||||
|
||||
// Import symbols.
|
||||
EXTERN SCALLYield
|
||||
EXTERN _get_interrupt_handler
|
||||
__SCALLYield:
|
||||
DC32 SCALLYield
|
||||
__get_interrupt_handler:
|
||||
DC32 _get_interrupt_handler
|
||||
|
||||
// Values to store in the interrupt priority registers for the various interrupt priority levels.
|
||||
// The interrupt priority registers contain the interrupt priority level and
|
||||
// the EVBA-relative interrupt vector offset.
|
||||
PUBLIC ipr_val
|
||||
ipr_val:
|
||||
DC32 (INT0 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int0 - _evba),\
|
||||
(INT1 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int1 - _evba),\
|
||||
(INT2 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int2 - _evba),\
|
||||
(INT3 << AVR32_INTC_IPR0_INTLEV_OFFSET) | (_int3 - _evba)
|
||||
|
||||
|
||||
END
|
||||
|
||||
|
||||
//! \endverbatim
|
||||
//! @}
|
421
20080212/Source/portable/IAR/AVR32_UC3/port.c
Normal file
421
20080212/Source/portable/IAR/AVR32_UC3/port.c
Normal file
|
@ -0,0 +1,421 @@
|
|||
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief FreeRTOS port source for AVR32 UC3.
|
||||
*
|
||||
* - Compiler: IAR EWAVR32
|
||||
* - Supported devices: All AVR32 devices can be used.
|
||||
* - AppNote:
|
||||
*
|
||||
* \author Atmel Corporation: http://www.atmel.com \n
|
||||
* Support and FAQ: http://support.atmel.no/
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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.
|
||||
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* AVR32 UC3 includes. */
|
||||
#include <avr32/io.h>
|
||||
#include <intrinsics.h>
|
||||
#include "gpio.h"
|
||||
|
||||
#if configDBG
|
||||
#include "usart.h"
|
||||
#endif
|
||||
|
||||
#if( configTICK_USE_TC==1 )
|
||||
#include "tc.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Constants required to setup the task context. */
|
||||
#define portINITIAL_SR ( ( portSTACK_TYPE ) 0x00400000 ) /* AVR32 : [M2:M0]=001 I1M=0 I0M=0, GM=0 */
|
||||
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 0 )
|
||||
|
||||
/* Each task maintains its own critical nesting variable. */
|
||||
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
|
||||
volatile unsigned portLONG ulCriticalNesting = 9999UL;
|
||||
|
||||
#if( configTICK_USE_TC==0 )
|
||||
static void prvScheduleNextTick( void );
|
||||
#else
|
||||
static void prvClearTcInt( void );
|
||||
#endif
|
||||
|
||||
/* Setup the timer to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Low-level initialization routine called during startup, before the main
|
||||
* function.
|
||||
*/
|
||||
int __low_level_init(void)
|
||||
{
|
||||
#if configHEAP_INIT
|
||||
#pragma segment = "HEAP"
|
||||
portBASE_TYPE *pxMem;
|
||||
#endif
|
||||
|
||||
/* Enable exceptions. */
|
||||
ENABLE_ALL_EXCEPTIONS();
|
||||
|
||||
/* Initialize interrupt handling. */
|
||||
INTC_init_interrupts();
|
||||
|
||||
#if configHEAP_INIT
|
||||
{
|
||||
/* Initialize the heap used by malloc. */
|
||||
for( pxMem = __segment_begin( "HEAP" ); pxMem < ( portBASE_TYPE * ) __segment_end( "HEAP" ); )
|
||||
{
|
||||
*pxMem++ = 0xA5A5A5A5;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Code section present if and only if the debug trace is activated. */
|
||||
#if configDBG
|
||||
{
|
||||
static const gpio_map_t DBG_USART_GPIO_MAP =
|
||||
{
|
||||
{ configDBG_USART_RX_PIN, configDBG_USART_RX_FUNCTION },
|
||||
{ configDBG_USART_TX_PIN, configDBG_USART_TX_FUNCTION }
|
||||
};
|
||||
|
||||
static const usart_options_t DBG_USART_OPTIONS =
|
||||
{
|
||||
.baudrate = configDBG_USART_BAUDRATE,
|
||||
.charlength = 8,
|
||||
.paritytype = USART_NO_PARITY,
|
||||
.stopbits = USART_1_STOPBIT,
|
||||
.channelmode = USART_NORMAL_CHMODE
|
||||
};
|
||||
|
||||
/* Initialize the USART used for the debug trace with the configured parameters. */
|
||||
extern volatile avr32_usart_t *volatile stdio_usart_base;
|
||||
stdio_usart_base = configDBG_USART;
|
||||
gpio_enable_module( DBG_USART_GPIO_MAP,
|
||||
sizeof( DBG_USART_GPIO_MAP ) / sizeof( DBG_USART_GPIO_MAP[0] ) );
|
||||
usart_init_rs232(configDBG_USART, &DBG_USART_OPTIONS, configCPU_CLOCK_HZ);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Request initialization of data segments. */
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Added as there is no such function in FreeRTOS. */
|
||||
void *pvPortRealloc( void *pv, size_t xWantedSize )
|
||||
{
|
||||
void *pvReturn;
|
||||
|
||||
vTaskSuspendAll();
|
||||
{
|
||||
pvReturn = realloc( pv, xWantedSize );
|
||||
}
|
||||
xTaskResumeAll();
|
||||
|
||||
return pvReturn;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
/* The preemptive scheduler is defined as "naked" as the full context is saved
|
||||
on entry as part of the context switch. */
|
||||
#pragma shadow_registers = full // Naked.
|
||||
static void vTick( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT_OS_INT();
|
||||
|
||||
#if( configTICK_USE_TC==1 )
|
||||
/* Clear the interrupt flag. */
|
||||
prvClearTcInt();
|
||||
#else
|
||||
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
||||
clock cycles from now. */
|
||||
prvScheduleNextTick();
|
||||
#endif
|
||||
|
||||
/* Because FreeRTOS is not supposed to run with nested interrupts, put all OS
|
||||
calls in a critical section . */
|
||||
portENTER_CRITICAL();
|
||||
vTaskIncrementTick();
|
||||
portEXIT_CRITICAL();
|
||||
|
||||
/* Restore the context of the "elected task". */
|
||||
portRESTORE_CONTEXT_OS_INT();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#pragma shadow_registers = full // Naked.
|
||||
void SCALLYield( void )
|
||||
{
|
||||
/* Save the context of the interrupted task. */
|
||||
portSAVE_CONTEXT_SCALL();
|
||||
vTaskSwitchContext();
|
||||
portRESTORE_CONTEXT_SCALL();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The code generated by the GCC compiler uses the stack in different ways at
|
||||
different optimisation levels. The interrupt flags can therefore not always
|
||||
be saved to the stack. Instead the critical section nesting level is stored
|
||||
in a variable, which is then saved as part of the stack context. */
|
||||
#pragma optimize = no_inline
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#pragma optimize = no_inline
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if(ulCriticalNesting > portNO_CRITICAL_NESTING)
|
||||
{
|
||||
ulCriticalNesting--;
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Enable all interrupt/exception. */
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||
{
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* When the task starts, it will expect to find the function parameter in R12. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x0A0A0A0A; /* R10 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x0B0B0B0B; /* R11 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) pvParameters; /* R12 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0xDEADBEEF; /* R14/LR */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE; /* R15/PC */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) portINITIAL_SR; /* SR */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0xFF0000FF; /* R0 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||
*pxTopOfStack-- = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) portNO_CRITICAL_NESTING; /* ulCriticalNesting */
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
portRESTORE_CONTEXT();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the AVR32 port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Schedule the COUNT&COMPARE match interrupt in (configCPU_CLOCK_HZ/configTICK_RATE_HZ)
|
||||
clock cycles from now. */
|
||||
#if( configTICK_USE_TC==0 )
|
||||
static void prvScheduleFirstTick(void)
|
||||
{
|
||||
unsigned long lCycles;
|
||||
|
||||
lCycles = Get_system_register(AVR32_COUNT);
|
||||
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
|
||||
// generation feature does not get disabled.
|
||||
if(0 == lCycles)
|
||||
{
|
||||
lCycles++;
|
||||
}
|
||||
Set_system_register(AVR32_COMPARE, lCycles);
|
||||
}
|
||||
|
||||
#pragma optimize = no_inline
|
||||
static void prvScheduleNextTick(void)
|
||||
{
|
||||
unsigned long lCycles, lCount;
|
||||
|
||||
lCycles = Get_system_register(AVR32_COMPARE);
|
||||
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||
// If lCycles ends up to be 0, make it 1 so that the COMPARE and exception
|
||||
// generation feature does not get disabled.
|
||||
if(0 == lCycles)
|
||||
{
|
||||
lCycles++;
|
||||
}
|
||||
lCount = Get_system_register(AVR32_COUNT);
|
||||
if( lCycles < lCount )
|
||||
{ // We missed a tick, recover for the next.
|
||||
lCycles += (configCPU_CLOCK_HZ/configTICK_RATE_HZ);
|
||||
}
|
||||
Set_system_register(AVR32_COMPARE, lCycles);
|
||||
}
|
||||
#else
|
||||
#pragma optimize = no_inline
|
||||
static void prvClearTcInt(void)
|
||||
{
|
||||
AVR32_TC.channel[configTICK_TC_CHANNEL].sr;
|
||||
}
|
||||
#endif
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the timer to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt(void)
|
||||
{
|
||||
#if( configTICK_USE_TC==1 )
|
||||
|
||||
volatile avr32_tc_t *tc = &AVR32_TC;
|
||||
|
||||
// Options for waveform genration.
|
||||
tc_waveform_opt_t waveform_opt =
|
||||
{
|
||||
.channel = configTICK_TC_CHANNEL, /* Channel selection. */
|
||||
|
||||
.bswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOB. */
|
||||
.beevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOB. */
|
||||
.bcpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOB. */
|
||||
.bcpb = TC_EVT_EFFECT_NOOP, /* RB compare effect on TIOB. */
|
||||
|
||||
.aswtrg = TC_EVT_EFFECT_NOOP, /* Software trigger effect on TIOA. */
|
||||
.aeevt = TC_EVT_EFFECT_NOOP, /* External event effect on TIOA. */
|
||||
.acpc = TC_EVT_EFFECT_NOOP, /* RC compare effect on TIOA: toggle. */
|
||||
.acpa = TC_EVT_EFFECT_NOOP, /* RA compare effect on TIOA: toggle (other possibilities are none, set and clear). */
|
||||
|
||||
.wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,/* Waveform selection: Up mode without automatic trigger on RC compare. */
|
||||
.enetrg = FALSE, /* External event trigger enable. */
|
||||
.eevt = 0, /* External event selection. */
|
||||
.eevtedg = TC_SEL_NO_EDGE, /* External event edge selection. */
|
||||
.cpcdis = FALSE, /* Counter disable when RC compare. */
|
||||
.cpcstop = FALSE, /* Counter clock stopped with RC compare. */
|
||||
|
||||
.burst = FALSE, /* Burst signal selection. */
|
||||
.clki = FALSE, /* Clock inversion. */
|
||||
.tcclks = TC_CLOCK_SOURCE_TC2 /* Internal source clock 2. */
|
||||
};
|
||||
|
||||
tc_interrupt_t tc_interrupt =
|
||||
{
|
||||
.etrgs=0,
|
||||
.ldrbs=0,
|
||||
.ldras=0,
|
||||
.cpcs =1,
|
||||
.cpbs =0,
|
||||
.cpas =0,
|
||||
.lovrs=0,
|
||||
.covfs=0,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Disable all interrupt/exception. */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* Register the compare interrupt handler to the interrupt controller and
|
||||
enable the compare interrupt. */
|
||||
|
||||
#if( configTICK_USE_TC==1 )
|
||||
{
|
||||
INTC_register_interrupt((__int_handler)&vTick, configTICK_TC_IRQ, INT0);
|
||||
|
||||
/* Initialize the timer/counter. */
|
||||
tc_init_waveform(tc, &waveform_opt);
|
||||
|
||||
/* Set the compare triggers.
|
||||
Remember TC counter is 16-bits, so counting second is not possible!
|
||||
That's why we configure it to count ms. */
|
||||
tc_write_rc( tc, configTICK_TC_CHANNEL, ( configPBA_CLOCK_HZ / 4) / configTICK_RATE_HZ );
|
||||
|
||||
tc_configure_interrupts( tc, configTICK_TC_CHANNEL, &tc_interrupt );
|
||||
|
||||
/* Start the timer/counter. */
|
||||
tc_start(tc, configTICK_TC_CHANNEL);
|
||||
}
|
||||
#else
|
||||
{
|
||||
INTC_register_interrupt((__int_handler)&vTick, AVR32_CORE_COMPARE_IRQ, INT0);
|
||||
prvScheduleFirstTick();
|
||||
}
|
||||
#endif
|
||||
}
|
666
20080212/Source/portable/IAR/AVR32_UC3/portmacro.h
Normal file
666
20080212/Source/portable/IAR/AVR32_UC3/portmacro.h
Normal file
|
@ -0,0 +1,666 @@
|
|||
/*This file has been prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief FreeRTOS port header for AVR32 UC3.
|
||||
*
|
||||
* - Compiler: IAR EWAVR32
|
||||
* - Supported devices: All AVR32 devices can be used.
|
||||
* - AppNote:
|
||||
*
|
||||
* \author Atmel Corporation: http://www.atmel.com \n
|
||||
* Support and FAQ: http://support.atmel.no/
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
#include <avr32/io.h>
|
||||
#include "intc.h"
|
||||
#include "compiler.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* 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 portLONG
|
||||
|
||||
#define TASK_DELAY_MS(x) ( (x) /portTICK_RATE_MS )
|
||||
#define TASK_DELAY_S(x) ( (x)*1000 /portTICK_RATE_MS )
|
||||
#define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_RATE_MS )
|
||||
|
||||
#define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
|
||||
|
||||
#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 4
|
||||
#define portNOP() {__asm__ __volatile__ ("nop");}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* INTC-specific. */
|
||||
#define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
|
||||
#define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
|
||||
|
||||
#define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
|
||||
#define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
|
||||
|
||||
#define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)
|
||||
#define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)
|
||||
|
||||
|
||||
/*
|
||||
* Debug trace.
|
||||
* Activated if and only if configDBG is nonzero.
|
||||
* Prints a formatted string to stdout.
|
||||
* The current source file name and line number are output with a colon before
|
||||
* the formatted string.
|
||||
* A carriage return and a linefeed are appended to the output.
|
||||
* stdout is redirected to the USART configured by configDBG_USART.
|
||||
* The parameters are the same as for the standard printf function.
|
||||
* There is no return value.
|
||||
* SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,
|
||||
* which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.
|
||||
*/
|
||||
#if configDBG
|
||||
#define portDBG_TRACE(...) \
|
||||
{ \
|
||||
fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout); \
|
||||
printf(__VA_ARGS__); \
|
||||
fputs("\r\n", stdout); \
|
||||
}
|
||||
#else
|
||||
#define portDBG_TRACE(...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Critical section management. */
|
||||
#define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
|
||||
#define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
|
||||
|
||||
|
||||
extern void vPortEnterCritical( void );
|
||||
extern void vPortExitCritical( void );
|
||||
|
||||
#define portENTER_CRITICAL() vPortEnterCritical();
|
||||
#define portEXIT_CRITICAL() vPortExitCritical();
|
||||
|
||||
|
||||
/* Added as there is no such function in FreeRTOS. */
|
||||
extern void *pvPortRealloc( void *pv, size_t xSize );
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
/*=============================================================================================*/
|
||||
|
||||
/*
|
||||
* Restore Context for cases other than INTi.
|
||||
*/
|
||||
#define portRESTORE_CONTEXT() \
|
||||
{ \
|
||||
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||
extern volatile void *volatile pxCurrentTCB; \
|
||||
\
|
||||
__asm__ __volatile__ ( \
|
||||
/* Set SP to point to new stack */ \
|
||||
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"ld.w sp, r0[0] \n\t"\
|
||||
\
|
||||
/* Restore ulCriticalNesting variable */ \
|
||||
"ld.w r0, sp++ \n\t"\
|
||||
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"st.w r8[0], r0 \n\t"\
|
||||
\
|
||||
/* Restore R0..R7 */ \
|
||||
"ldm sp++, r0-r7 \n\t"\
|
||||
/* R0-R7 should not be used below this line */ \
|
||||
/* Skip PC and SR (will do it at the end) */ \
|
||||
"sub sp, -2*4 \n\t"\
|
||||
/* Restore R8..R12 and LR */ \
|
||||
"ldm sp++, r8-r12, lr \n\t"\
|
||||
/* Restore SR */ \
|
||||
"ld.w r0, sp[-8*4] \n\t" /* R0 is modified, is restored later. */\
|
||||
"mtsr "ASTRINGZ(AVR32_SR)", r0 \n\t"\
|
||||
/* Restore r0 */ \
|
||||
"ld.w r0, sp[-9*4] \n\t"\
|
||||
/* Restore PC */ \
|
||||
"ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \
|
||||
); \
|
||||
\
|
||||
/* Force import of global symbols from assembly */ \
|
||||
ulCriticalNesting; \
|
||||
pxCurrentTCB; \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* portSAVE_CONTEXT_INT() and portRESTORE_CONTEXT_INT(): for INT0..3 exceptions.
|
||||
* portSAVE_CONTEXT_SCALL() and portRESTORE_CONTEXT_SCALL(): for the scall exception.
|
||||
*
|
||||
* Had to make different versions because registers saved on the system stack
|
||||
* are not the same between INT0..3 exceptions and the scall exception.
|
||||
*/
|
||||
|
||||
// Task context stack layout:
|
||||
// R8 (*)
|
||||
// R9 (*)
|
||||
// R10 (*)
|
||||
// R11 (*)
|
||||
// R12 (*)
|
||||
// R14/LR (*)
|
||||
// R15/PC (*)
|
||||
// SR (*)
|
||||
// R0
|
||||
// R1
|
||||
// R2
|
||||
// R3
|
||||
// R4
|
||||
// R5
|
||||
// R6
|
||||
// R7
|
||||
// ulCriticalNesting
|
||||
// (*) automatically done for INT0..INT3, but not for SCALL
|
||||
|
||||
/*
|
||||
* The ISR used for the scheduler tick depends on whether the cooperative or
|
||||
* the preemptive scheduler is being used.
|
||||
*/
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/*
|
||||
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
|
||||
*/
|
||||
#define portSAVE_CONTEXT_OS_INT() \
|
||||
{ \
|
||||
/* Save R0..R7 */ \
|
||||
__asm__ __volatile__ ("stm --sp, r0-r7"); \
|
||||
\
|
||||
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||
/* there is also no context save. */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
|
||||
*/
|
||||
#define portRESTORE_CONTEXT_OS_INT() \
|
||||
{ \
|
||||
__asm__ __volatile__ ( \
|
||||
/* Restore R0..R7 */ \
|
||||
"ldm sp++, r0-r7 \n\t"\
|
||||
\
|
||||
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||
/* there is also no context restore. */ \
|
||||
"rete" \
|
||||
); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* portSAVE_CONTEXT_OS_INT() for OS Tick exception.
|
||||
*/
|
||||
#define portSAVE_CONTEXT_OS_INT() \
|
||||
{ \
|
||||
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||
extern volatile void *volatile pxCurrentTCB; \
|
||||
\
|
||||
/* When we come here */ \
|
||||
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
|
||||
\
|
||||
__asm__ __volatile__ ( \
|
||||
/* Save R0..R7 */ \
|
||||
"stm --sp, r0-r7 \n\t"\
|
||||
\
|
||||
/* Save ulCriticalNesting variable - R0 is overwritten */ \
|
||||
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"st.w --sp, r0 \n\t"\
|
||||
\
|
||||
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||
/* level and allow other lower interrupt level to occur). */ \
|
||||
/* In this case we don't want to do a task switch because we don't know what the stack */ \
|
||||
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
|
||||
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
|
||||
/* will just be restoring the interrupt handler, no way!!! */ \
|
||||
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
|
||||
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
|
||||
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
|
||||
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
|
||||
"brhi LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
|
||||
\
|
||||
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
|
||||
/* NOTE: we don't enter a critical section here because all interrupt handlers */ \
|
||||
/* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */ \
|
||||
/* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */ \
|
||||
/* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */ \
|
||||
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"st.w r0[0], sp \n"\
|
||||
\
|
||||
"LABEL_INT_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)":" \
|
||||
); \
|
||||
}
|
||||
|
||||
/*
|
||||
* portRESTORE_CONTEXT_OS_INT() for Tick exception.
|
||||
*/
|
||||
#define portRESTORE_CONTEXT_OS_INT() \
|
||||
{ \
|
||||
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||
extern volatile void *volatile pxCurrentTCB; \
|
||||
\
|
||||
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||
/* level and allow other lower interrupt level to occur). */ \
|
||||
/* In this case we don't want to do a task switch because we don't know what the stack */ \
|
||||
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
|
||||
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
|
||||
/* will just be restoring the interrupt handler, no way!!! */ \
|
||||
__asm__ __volatile__ ( \
|
||||
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
|
||||
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
|
||||
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
|
||||
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__) \
|
||||
); \
|
||||
\
|
||||
/* Else */ \
|
||||
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
|
||||
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
|
||||
portENTER_CRITICAL(); \
|
||||
vTaskSwitchContext(); \
|
||||
portEXIT_CRITICAL(); \
|
||||
\
|
||||
/* Restore all registers */ \
|
||||
\
|
||||
__asm__ __volatile__ ( \
|
||||
/* Set SP to point to new stack */ \
|
||||
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"ld.w sp, r0[0] \n"\
|
||||
\
|
||||
"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
|
||||
\
|
||||
/* Restore ulCriticalNesting variable */ \
|
||||
"ld.w r0, sp++ \n\t"\
|
||||
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"st.w r8[0], r0 \n\t"\
|
||||
\
|
||||
/* Restore R0..R7 */ \
|
||||
"ldm sp++, r0-r7 \n\t"\
|
||||
\
|
||||
/* Now, the stack should be R8..R12, LR, PC and SR */ \
|
||||
"rete" \
|
||||
); \
|
||||
\
|
||||
/* Force import of global symbols from assembly */ \
|
||||
ulCriticalNesting; \
|
||||
pxCurrentTCB; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* portSAVE_CONTEXT_SCALL() for SupervisorCALL exception.
|
||||
*
|
||||
* NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.
|
||||
*
|
||||
*/
|
||||
#define portSAVE_CONTEXT_SCALL() \
|
||||
{ \
|
||||
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||
extern volatile void *volatile pxCurrentTCB; \
|
||||
\
|
||||
/* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \
|
||||
/* If SR[M2:M0] == 001 */ \
|
||||
/* PC and SR are on the stack. */ \
|
||||
/* Else (other modes) */ \
|
||||
/* Nothing on the stack. */ \
|
||||
\
|
||||
/* WARNING NOTE: the else case cannot happen as it is strictly forbidden to call */ \
|
||||
/* vTaskDelay() and vTaskDelayUntil() OS functions (that result in a taskYield()) */ \
|
||||
/* in an interrupt|exception handler. */ \
|
||||
\
|
||||
__asm__ __volatile__ ( \
|
||||
/* in order to save R0-R7 */ \
|
||||
"sub sp, 6*4 \n\t"\
|
||||
/* Save R0..R7 */ \
|
||||
"stm --sp, r0-r7 \n\t"\
|
||||
\
|
||||
/* in order to save R8-R12 and LR */ \
|
||||
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
|
||||
"sub r7, sp,-16*4 \n\t"\
|
||||
/* Copy PC and SR in other places in the stack. */ \
|
||||
"ld.w r0, r7[-2*4] \n\t" /* Read SR */\
|
||||
"st.w r7[-8*4], r0 \n\t" /* Copy SR */\
|
||||
"ld.w r0, r7[-1*4] \n\t" /* Read PC */\
|
||||
"st.w r7[-7*4], r0 \n\t" /* Copy PC */\
|
||||
\
|
||||
/* Save R8..R12 and LR on the stack. */ \
|
||||
"stm --r7, r8-r12, lr \n\t"\
|
||||
\
|
||||
/* Arriving here we have the following stack organizations: */ \
|
||||
/* R8..R12, LR, PC, SR, R0..R7. */ \
|
||||
\
|
||||
/* Now we can finalize the save. */ \
|
||||
\
|
||||
/* Save ulCriticalNesting variable - R0 is overwritten */ \
|
||||
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"st.w --sp, r0" \
|
||||
); \
|
||||
\
|
||||
/* Disable the its which may cause a context switch (i.e. cause a change of */ \
|
||||
/* pxCurrentTCB). */ \
|
||||
/* Basically, all accesses to the pxCurrentTCB structure should be put in a */ \
|
||||
/* critical section because it is a global structure. */ \
|
||||
portENTER_CRITICAL(); \
|
||||
\
|
||||
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
|
||||
__asm__ __volatile__ ( \
|
||||
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"st.w r0[0], sp" \
|
||||
); \
|
||||
}
|
||||
|
||||
/*
|
||||
* portRESTORE_CONTEXT() for SupervisorCALL exception.
|
||||
*/
|
||||
#define portRESTORE_CONTEXT_SCALL() \
|
||||
{ \
|
||||
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||
extern volatile void *volatile pxCurrentTCB; \
|
||||
\
|
||||
/* Restore all registers */ \
|
||||
\
|
||||
/* Set SP to point to new stack */ \
|
||||
__asm__ __volatile__ ( \
|
||||
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"ld.w sp, r0[0]" \
|
||||
); \
|
||||
\
|
||||
/* Leave pxCurrentTCB variable access critical section */ \
|
||||
portEXIT_CRITICAL(); \
|
||||
\
|
||||
__asm__ __volatile__ ( \
|
||||
/* Restore ulCriticalNesting variable */ \
|
||||
"ld.w r0, sp++ \n\t"\
|
||||
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"st.w r8[0], r0 \n\t"\
|
||||
\
|
||||
/* skip PC and SR */ \
|
||||
/* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
|
||||
"sub r7, sp, -10*4 \n\t"\
|
||||
/* Restore r8-r12 and LR */ \
|
||||
"ldm r7++, r8-r12, lr \n\t"\
|
||||
\
|
||||
/* RETS will take care of the extra PC and SR restore. */ \
|
||||
/* So, we have to prepare the stack for this. */ \
|
||||
"ld.w r0, r7[-8*4] \n\t" /* Read SR */\
|
||||
"st.w r7[-2*4], r0 \n\t" /* Copy SR */\
|
||||
"ld.w r0, r7[-7*4] \n\t" /* Read PC */\
|
||||
"st.w r7[-1*4], r0 \n\t" /* Copy PC */\
|
||||
\
|
||||
/* Restore R0..R7 */ \
|
||||
"ldm sp++, r0-r7 \n\t"\
|
||||
\
|
||||
"sub sp, -6*4 \n\t"\
|
||||
\
|
||||
"rets" \
|
||||
); \
|
||||
\
|
||||
/* Force import of global symbols from assembly */ \
|
||||
ulCriticalNesting; \
|
||||
pxCurrentTCB; \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The ISR used depends on whether the cooperative or
|
||||
* the preemptive scheduler is being used.
|
||||
*/
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/*
|
||||
* ISR entry and exit macros. These are only required if a task switch
|
||||
* is required from the ISR.
|
||||
*/
|
||||
#define portENTER_SWITCHING_ISR() \
|
||||
{ \
|
||||
/* Save R0..R7 */ \
|
||||
__asm__ __volatile__ ("stm --sp, r0-r7"); \
|
||||
\
|
||||
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||
/* there is also no context save. */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
|
||||
*/
|
||||
#define portEXIT_SWITCHING_ISR() \
|
||||
{ \
|
||||
__asm__ __volatile__ ( \
|
||||
/* Restore R0..R7 */ \
|
||||
"ldm sp++, r0-r7 \n\t"\
|
||||
\
|
||||
/* With the cooperative scheduler, as there is no context switch by interrupt, */ \
|
||||
/* there is also no context restore. */ \
|
||||
"rete" \
|
||||
); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* ISR entry and exit macros. These are only required if a task switch
|
||||
* is required from the ISR.
|
||||
*/
|
||||
#define portENTER_SWITCHING_ISR() \
|
||||
{ \
|
||||
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||
extern volatile void *volatile pxCurrentTCB; \
|
||||
\
|
||||
/* When we come here */ \
|
||||
/* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
|
||||
\
|
||||
__asm__ __volatile__ ( \
|
||||
/* Save R0..R7 */ \
|
||||
"stm --sp, r0-r7 \n\t"\
|
||||
\
|
||||
/* Save ulCriticalNesting variable - R0 is overwritten */ \
|
||||
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"st.w --sp, r0 \n\t"\
|
||||
\
|
||||
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||
/* level and allow other lower interrupt level to occur). */ \
|
||||
/* In this case we don't want to do a task switch because we don't know what the stack */ \
|
||||
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
|
||||
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
|
||||
/* will just be restoring the interrupt handler, no way!!! */ \
|
||||
/* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
|
||||
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
|
||||
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
|
||||
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
|
||||
"brhi LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
|
||||
\
|
||||
/* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
|
||||
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"st.w r0[0], sp \n"\
|
||||
\
|
||||
"LABEL_ISR_SKIP_SAVE_CONTEXT_"ASTRINGZ(__LINE__)":" \
|
||||
); \
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
|
||||
*/
|
||||
#define portEXIT_SWITCHING_ISR() \
|
||||
{ \
|
||||
extern volatile unsigned portLONG ulCriticalNesting; \
|
||||
extern volatile void *volatile pxCurrentTCB; \
|
||||
\
|
||||
__asm__ __volatile__ ( \
|
||||
/* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
|
||||
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
|
||||
/* level and allow other lower interrupt level to occur). */ \
|
||||
/* In this case it's of no use to switch context and restore a new SP because we purposedly */ \
|
||||
/* did not previously save SP in its TCB. */ \
|
||||
"ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
|
||||
"bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
|
||||
"cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
|
||||
"brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)" \n\t"\
|
||||
\
|
||||
/* If a switch is required then we just need to call */ \
|
||||
/* vTaskSwitchContext() as the context has already been */ \
|
||||
/* saved. */ \
|
||||
"cp.w r12, 1 \n\t" /* Check if Switch context is required. */\
|
||||
"brne LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":C" \
|
||||
); \
|
||||
\
|
||||
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
|
||||
portENTER_CRITICAL(); \
|
||||
vTaskSwitchContext(); \
|
||||
portEXIT_CRITICAL(); \
|
||||
\
|
||||
__asm__ __volatile__ ( \
|
||||
"LABEL_ISR_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
|
||||
/* Restore the context of which ever task is now the highest */ \
|
||||
/* priority that is ready to run. */ \
|
||||
\
|
||||
/* Restore all registers */ \
|
||||
\
|
||||
/* Set SP to point to new stack */ \
|
||||
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)") \n\t"\
|
||||
"ld.w r0, r8[0] \n\t"\
|
||||
"ld.w sp, r0[0] \n"\
|
||||
\
|
||||
"LABEL_ISR_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)": \n\t"\
|
||||
\
|
||||
/* Restore ulCriticalNesting variable */ \
|
||||
"ld.w r0, sp++ \n\t"\
|
||||
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)") \n\t"\
|
||||
"st.w r8[0], r0 \n\t"\
|
||||
\
|
||||
/* Restore R0..R7 */ \
|
||||
"ldm sp++, r0-r7 \n\t"\
|
||||
\
|
||||
/* Now, the stack should be R8..R12, LR, PC and SR */ \
|
||||
"rete" \
|
||||
); \
|
||||
\
|
||||
/* Force import of global symbols from assembly */ \
|
||||
ulCriticalNesting; \
|
||||
pxCurrentTCB; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define portYIELD() {__asm__ __volatile__ ("scall");}
|
||||
|
||||
/* 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 inline
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
93
20080212/Source/portable/IAR/AVR32_UC3/read.c
Normal file
93
20080212/Source/portable/IAR/AVR32_UC3/read.c
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*This file is prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief System-specific implementation of the \ref __read function used by
|
||||
the standard library.
|
||||
*
|
||||
* - Compiler: IAR EWAVR32
|
||||
* - Supported devices: All AVR32 devices with a USART module can be used.
|
||||
* - AppNote:
|
||||
*
|
||||
* \author Atmel Corporation: http://www.atmel.com \n
|
||||
* Support and FAQ: http://support.atmel.no/
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of ATMEL may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
|
||||
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <yfuns.h>
|
||||
#include <avr32/io.h>
|
||||
#include "usart.h"
|
||||
|
||||
|
||||
_STD_BEGIN
|
||||
|
||||
|
||||
#pragma module_name = "?__read"
|
||||
|
||||
|
||||
extern volatile avr32_usart_t *volatile stdio_usart_base;
|
||||
|
||||
|
||||
/*! \brief Reads a number of bytes, at most \a size, into the memory area
|
||||
* pointed to by \a buffer.
|
||||
*
|
||||
* \param handle File handle to read from.
|
||||
* \param buffer Pointer to buffer to write read bytes to.
|
||||
* \param size Number of bytes to read.
|
||||
*
|
||||
* \return The number of bytes read, \c 0 at the end of the file, or
|
||||
* \c _LLIO_ERROR on failure.
|
||||
*/
|
||||
size_t __read(int handle, unsigned char *buffer, size_t size)
|
||||
{
|
||||
int nChars = 0;
|
||||
|
||||
// This implementation only reads from stdin.
|
||||
// For all other file handles, it returns failure.
|
||||
if (handle != _LLIO_STDIN)
|
||||
{
|
||||
return _LLIO_ERROR;
|
||||
}
|
||||
|
||||
for (; size > 0; --size)
|
||||
{
|
||||
int c = usart_getchar(stdio_usart_base);
|
||||
if (c < 0)
|
||||
break;
|
||||
|
||||
*buffer++ = c;
|
||||
++nChars;
|
||||
}
|
||||
|
||||
return nChars;
|
||||
}
|
||||
|
||||
|
||||
_STD_END
|
103
20080212/Source/portable/IAR/AVR32_UC3/write.c
Normal file
103
20080212/Source/portable/IAR/AVR32_UC3/write.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*This file is prepared for Doxygen automatic documentation generation.*/
|
||||
/*! \file *********************************************************************
|
||||
*
|
||||
* \brief System-specific implementation of the \ref __write function used by
|
||||
the standard library.
|
||||
*
|
||||
* - Compiler: IAR EWAVR32
|
||||
* - Supported devices: All AVR32 devices with a USART module can be used.
|
||||
* - AppNote:
|
||||
*
|
||||
* \author Atmel Corporation: http://www.atmel.com \n
|
||||
* Support and FAQ: http://support.atmel.no/
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* Copyright (c) 2007, Atmel Corporation All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of ATMEL may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
|
||||
* SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <yfuns.h>
|
||||
#include <avr32/io.h>
|
||||
#include "usart.h"
|
||||
|
||||
|
||||
_STD_BEGIN
|
||||
|
||||
|
||||
#pragma module_name = "?__write"
|
||||
|
||||
|
||||
//! Pointer to the base of the USART module instance to use for stdio.
|
||||
__no_init volatile avr32_usart_t *volatile stdio_usart_base;
|
||||
|
||||
|
||||
/*! \brief Writes a number of bytes, at most \a size, from the memory area
|
||||
* pointed to by \a buffer.
|
||||
*
|
||||
* If \a buffer is zero then \ref __write performs flushing of internal buffers,
|
||||
* if any. In this case, \a handle can be \c -1 to indicate that all handles
|
||||
* should be flushed.
|
||||
*
|
||||
* \param handle File handle to write to.
|
||||
* \param buffer Pointer to buffer to read bytes to write from.
|
||||
* \param size Number of bytes to write.
|
||||
*
|
||||
* \return The number of bytes written, or \c _LLIO_ERROR on failure.
|
||||
*/
|
||||
size_t __write(int handle, const unsigned char *buffer, size_t size)
|
||||
{
|
||||
size_t nChars = 0;
|
||||
|
||||
if (buffer == 0)
|
||||
{
|
||||
// This means that we should flush internal buffers.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This implementation only writes to stdout and stderr.
|
||||
// For all other file handles, it returns failure.
|
||||
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR)
|
||||
{
|
||||
return _LLIO_ERROR;
|
||||
}
|
||||
|
||||
for (; size != 0; --size)
|
||||
{
|
||||
if (usart_putchar(stdio_usart_base, *buffer++) < 0)
|
||||
{
|
||||
return _LLIO_ERROR;
|
||||
}
|
||||
|
||||
++nChars;
|
||||
}
|
||||
|
||||
return nChars;
|
||||
}
|
||||
|
||||
|
||||
_STD_END
|
1914
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h
Normal file
1914
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7S64.h
Normal file
File diff suppressed because it is too large
Load diff
1812
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h
Normal file
1812
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7S64_inc.h
Normal file
File diff suppressed because it is too large
Load diff
2715
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h
Normal file
2715
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7X128.h
Normal file
File diff suppressed because it is too large
Load diff
2446
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h
Normal file
2446
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7X128_inc.h
Normal file
File diff suppressed because it is too large
Load diff
2715
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h
Normal file
2715
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7X256.h
Normal file
File diff suppressed because it is too large
Load diff
2446
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h
Normal file
2446
20080212/Source/portable/IAR/AtmelSAM7S64/AT91SAM7X256_inc.h
Normal file
File diff suppressed because it is too large
Load diff
78
20080212/Source/portable/IAR/AtmelSAM7S64/ISR_Support.h
Normal file
78
20080212/Source/portable/IAR/AtmelSAM7S64/ISR_Support.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
EXTERN pxCurrentTCB
|
||||
EXTERN ulCriticalNesting
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Context save and restore macro definitions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
portSAVE_CONTEXT MACRO
|
||||
|
||||
; Push R0 as we are going to use the register.
|
||||
STMDB SP!, {R0}
|
||||
|
||||
; Set R0 to point to the task stack pointer.
|
||||
STMDB SP, {SP}^
|
||||
NOP
|
||||
SUB SP, SP, #4
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push the return address onto the stack.
|
||||
STMDB R0!, {LR}
|
||||
|
||||
; Now we have saved LR we can use it instead of R0.
|
||||
MOV LR, R0
|
||||
|
||||
; Pop R0 so we can save it onto the system mode stack.
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push all the system mode registers onto the task stack.
|
||||
STMDB LR, {R0-LR}^
|
||||
NOP
|
||||
SUB LR, LR, #60
|
||||
|
||||
; Push the SPSR onto the task stack.
|
||||
MRS R0, SPSR
|
||||
STMDB LR!, {R0}
|
||||
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDR R0, [R0]
|
||||
STMDB LR!, {R0}
|
||||
|
||||
; Store the new top of stack for the task.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
STR LR, [R0]
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
portRESTORE_CONTEXT MACRO
|
||||
|
||||
; Set the LR to the task stack.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
LDR LR, [R0]
|
||||
|
||||
; The critical nesting depth is the first item on the stack.
|
||||
; Load it into the ulCriticalNesting variable.
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDMFD LR!, {R1}
|
||||
STR R1, [R0]
|
||||
|
||||
; Get the SPSR from the stack.
|
||||
LDMFD LR!, {R0}
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
; Restore all system mode registers for the task.
|
||||
LDMFD LR, {R0-R14}^
|
||||
NOP
|
||||
|
||||
; Restore the return address.
|
||||
LDR LR, [LR, #+60]
|
||||
|
||||
; And return - correcting the offset in the LR to obtain the
|
||||
; correct address.
|
||||
SUBS PC, LR, #4
|
||||
|
||||
ENDM
|
||||
|
3265
20080212/Source/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h
Normal file
3265
20080212/Source/portable/IAR/AtmelSAM7S64/lib_AT91SAM7S64.h
Normal file
File diff suppressed because it is too large
Load diff
4558
20080212/Source/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h
Normal file
4558
20080212/Source/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X128.h
Normal file
File diff suppressed because it is too large
Load diff
4558
20080212/Source/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h
Normal file
4558
20080212/Source/portable/IAR/AtmelSAM7S64/lib_AT91SAM7X256.h
Normal file
File diff suppressed because it is too large
Load diff
262
20080212/Source/portable/IAR/AtmelSAM7S64/port.c
Normal file
262
20080212/Source/portable/IAR/AtmelSAM7S64/port.c
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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 Atmel ARM7 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to setup the initial stack. */
|
||||
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x3f ) /* System mode, THUMB mode, interrupts enabled. */
|
||||
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||
|
||||
/* Constants required to setup the PIT. */
|
||||
#define portPIT_CLOCK_DIVISOR ( ( unsigned portLONG ) 16 )
|
||||
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_RATE_MS )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
|
||||
|
||||
|
||||
#define portINT_LEVEL_SENSITIVE 0
|
||||
#define portPIT_ENABLE ( ( unsigned portSHORT ) 0x1 << 24 )
|
||||
#define portPIT_INT_ENABLE ( ( unsigned portSHORT ) 0x1 << 25 )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the PIT to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* ulCriticalNesting will get set to zero when the first task starts. It
|
||||
cannot be initialised to 0 as this will cause interrupts to be enabled
|
||||
during the kernel initialisation process. */
|
||||
unsigned portLONG ulCriticalNesting = ( unsigned portLONG ) 9999;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||
{
|
||||
portSTACK_TYPE *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The status register is set for system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
static __arm __irq void vPortNonPreemptiveTick( void );
|
||||
static __arm __irq void vPortNonPreemptiveTick( void )
|
||||
{
|
||||
unsigned portLONG ulDummy;
|
||||
|
||||
/* Increment the tick count - which may wake some tasks but as the
|
||||
preemptive scheduler is not being used any woken task is not given
|
||||
processor time no matter what its priority. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
/* Clear the PIT interrupt. */
|
||||
ulDummy = AT91C_BASE_PITC->PITC_PIVR;
|
||||
|
||||
/* End the interrupt in the AIC. */
|
||||
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Currently the IAR port requires the preemptive tick function to be
|
||||
defined in an asm file. */
|
||||
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
AT91PS_PITC pxPIT = AT91C_BASE_PITC;
|
||||
|
||||
/* Setup the AIC for PIT interrupts. The interrupt routine chosen depends
|
||||
on whether the preemptive or cooperative scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPortNonPreemptiveTick );
|
||||
|
||||
#else
|
||||
|
||||
extern void ( vPortPreemptiveTick )( void );
|
||||
AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPortPreemptiveTick );
|
||||
|
||||
#endif
|
||||
|
||||
/* Configure the PIT period. */
|
||||
pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
|
||||
|
||||
/* Enable the interrupt. Global interrupts are disables at this point so
|
||||
this is safe. */
|
||||
AT91F_AIC_EnableIt( AT91C_BASE_AIC, AT91C_ID_SYS );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts first! */
|
||||
__disable_interrupt();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
__enable_interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
59
20080212/Source/portable/IAR/AtmelSAM7S64/portasm.s79
Normal file
59
20080212/Source/portable/IAR/AtmelSAM7S64/portasm.s79
Normal file
|
@ -0,0 +1,59 @@
|
|||
RSEG ICODE:CODE
|
||||
CODE32
|
||||
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN vTaskIncrementTick
|
||||
|
||||
PUBLIC vPortYieldProcessor
|
||||
PUBLIC vPortPreemptiveTick
|
||||
PUBLIC vPortStartFirstTask
|
||||
|
||||
#include "AT91SAM7S64_inc.h"
|
||||
#include "ISR_Support.h"
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Starting the first task is just a matter of restoring the context that
|
||||
; was created by pxPortInitialiseStack().
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortStartFirstTask:
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Manual context switch function. This is the SWI hander.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortYieldProcessor:
|
||||
ADD LR, LR, #4 ; Add 4 to the LR to make the LR appear exactly
|
||||
; as if the context was saved during and IRQ
|
||||
; handler.
|
||||
|
||||
portSAVE_CONTEXT ; Save the context of the current task...
|
||||
LDR R0, =vTaskSwitchContext ; before selecting the next task to execute.
|
||||
mov lr, pc
|
||||
BX R0
|
||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Preemptive context switch function. This will only ever get installed if
|
||||
; portUSE_PREEMPTION is set to 1 in portmacro.h.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortPreemptiveTick:
|
||||
portSAVE_CONTEXT ; Save the context of the current task.
|
||||
|
||||
LDR R0, =vTaskIncrementTick ; Increment the tick count - this may wake a task.
|
||||
mov lr, pc
|
||||
BX R0
|
||||
LDR R0, =vTaskSwitchContext ; Select the next task to execute.
|
||||
mov lr, pc
|
||||
BX R0
|
||||
|
||||
LDR R14, =AT91C_BASE_PITC ; Clear the PIT interrupt
|
||||
LDR R0, [R14, #PITC_PIVR ]
|
||||
|
||||
LDR R14, =AT91C_BASE_AIC ; Mark the End of Interrupt on the AIC
|
||||
STR R14, [R14, #AIC_EOICR]
|
||||
|
||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
||||
|
||||
|
||||
END
|
||||
|
125
20080212/Source/portable/IAR/AtmelSAM7S64/portmacro.h
Normal file
125
20080212/Source/portable/IAR/AtmelSAM7S64/portmacro.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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 portLONG
|
||||
|
||||
#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
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
#define portYIELD() asm ( "SWI 0" )
|
||||
#define portNOP() asm ( "NOP" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
__arm __interwork void vPortDisableInterruptsFromThumb( void );
|
||||
__arm __interwork void vPortEnableInterruptsFromThumb( void );
|
||||
__arm __interwork void vPortEnterCritical( void );
|
||||
__arm __interwork void vPortExitCritical( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __disable_interrupt()
|
||||
#define portENABLE_INTERRUPTS() __enable_interrupt()
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern void vTaskSwitchContext( void ); \
|
||||
\
|
||||
if( xSwitchRequired ) \
|
||||
{ \
|
||||
vTaskSwitchContext(); \
|
||||
} \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler specifics. */
|
||||
#define inline
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
78
20080212/Source/portable/IAR/LPC2000/ISR_Support.h
Normal file
78
20080212/Source/portable/IAR/LPC2000/ISR_Support.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
EXTERN pxCurrentTCB
|
||||
EXTERN ulCriticalNesting
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Context save and restore macro definitions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
portSAVE_CONTEXT MACRO
|
||||
|
||||
; Push R0 as we are going to use the register.
|
||||
STMDB SP!, {R0}
|
||||
|
||||
; Set R0 to point to the task stack pointer.
|
||||
STMDB SP, {SP}^
|
||||
NOP
|
||||
SUB SP, SP, #4
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push the return address onto the stack.
|
||||
STMDB R0!, {LR}
|
||||
|
||||
; Now we have saved LR we can use it instead of R0.
|
||||
MOV LR, R0
|
||||
|
||||
; Pop R0 so we can save it onto the system mode stack.
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push all the system mode registers onto the task stack.
|
||||
STMDB LR, {R0-LR}^
|
||||
NOP
|
||||
SUB LR, LR, #60
|
||||
|
||||
; Push the SPSR onto the task stack.
|
||||
MRS R0, SPSR
|
||||
STMDB LR!, {R0}
|
||||
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDR R0, [R0]
|
||||
STMDB LR!, {R0}
|
||||
|
||||
; Store the new top of stack for the task.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
STR LR, [R0]
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
portRESTORE_CONTEXT MACRO
|
||||
|
||||
; Set the LR to the task stack.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
LDR LR, [R0]
|
||||
|
||||
; The critical nesting depth is the first item on the stack.
|
||||
; Load it into the ulCriticalNesting variable.
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDMFD LR!, {R1}
|
||||
STR R1, [R0]
|
||||
|
||||
; Get the SPSR from the stack.
|
||||
LDMFD LR!, {R0}
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
; Restore all system mode registers for the task.
|
||||
LDMFD LR, {R0-R14}^
|
||||
NOP
|
||||
|
||||
; Restore the return address.
|
||||
LDR LR, [LR, #+60]
|
||||
|
||||
; And return - correcting the offset in the LR to obtain the
|
||||
; correct address.
|
||||
SUBS PC, LR, #4
|
||||
|
||||
ENDM
|
||||
|
323
20080212/Source/portable/IAR/LPC2000/port.c
Normal file
323
20080212/Source/portable/IAR/LPC2000/port.c
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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 Philips ARM7 port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Changes from V3.2.2
|
||||
|
||||
+ Bug fix - The prescale value for the timer setup is now written to T0PR
|
||||
instead of T0PC. This bug would have had no effect unless a prescale
|
||||
value was actually used.
|
||||
*/
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
#include <intrinsics.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to setup the tick ISR. */
|
||||
#define portENABLE_TIMER ( ( unsigned portCHAR ) 0x01 )
|
||||
#define portPRESCALE_VALUE 0x00
|
||||
#define portINTERRUPT_ON_MATCH ( ( unsigned portLONG ) 0x01 )
|
||||
#define portRESET_COUNT_ON_MATCH ( ( unsigned portLONG ) 0x02 )
|
||||
|
||||
/* Constants required to setup the initial stack. */
|
||||
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x3f ) /* System mode, THUMB mode, interrupts enabled. */
|
||||
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||
|
||||
/* Constants required to setup the PIT. */
|
||||
#define portPIT_CLOCK_DIVISOR ( ( unsigned portLONG ) 16 )
|
||||
#define portPIT_COUNTER_VALUE ( ( ( configCPU_CLOCK_HZ / portPIT_CLOCK_DIVISOR ) / 1000UL ) * portTICK_RATE_MS )
|
||||
|
||||
/* Constants required to handle interrupts. */
|
||||
#define portTIMER_MATCH_ISR_BIT ( ( unsigned portCHAR ) 0x01 )
|
||||
#define portCLEAR_VIC_INTERRUPT ( ( unsigned portLONG ) 0 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
|
||||
|
||||
|
||||
#define portINT_LEVEL_SENSITIVE 0
|
||||
#define portPIT_ENABLE ( ( unsigned portSHORT ) 0x1 << 24 )
|
||||
#define portPIT_INT_ENABLE ( ( unsigned portSHORT ) 0x1 << 25 )
|
||||
|
||||
/* Constants required to setup the VIC for the tick ISR. */
|
||||
#define portTIMER_VIC_CHANNEL ( ( unsigned portLONG ) 0x0004 )
|
||||
#define portTIMER_VIC_CHANNEL_BIT ( ( unsigned portLONG ) 0x0010 )
|
||||
#define portTIMER_VIC_ENABLE ( ( unsigned portLONG ) 0x0020 )
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the PIT to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* ulCriticalNesting will get set to zero when the first task starts. It
|
||||
cannot be initialised to 0 as this will cause interrupts to be enabled
|
||||
during the kernel initialisation process. */
|
||||
unsigned portLONG ulCriticalNesting = ( unsigned portLONG ) 9999;
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||
{
|
||||
portSTACK_TYPE *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The status register is set for system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configUSE_PREEMPTION == 0
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
static __arm __irq void vPortNonPreemptiveTick( void );
|
||||
static __arm __irq void vPortNonPreemptiveTick( void )
|
||||
{
|
||||
/* Increment the tick count - which may wake some tasks but as the
|
||||
preemptive scheduler is not being used any woken task is not given
|
||||
processor time no matter what its priority. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
/* Ready for the next interrupt. */
|
||||
T0IR = portTIMER_MATCH_ISR_BIT;
|
||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* This function is called from an asm wrapper, so does not require the __irq
|
||||
keyword. */
|
||||
void vPortPreemptiveTick( void );
|
||||
void vPortPreemptiveTick( void )
|
||||
{
|
||||
/* Increment the tick counter. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
/* The new tick value might unblock a task. Ensure the highest task that
|
||||
is ready to execute is the task that will execute when the tick ISR
|
||||
exits. */
|
||||
vTaskSwitchContext();
|
||||
|
||||
/* Ready for the next interrupt. */
|
||||
T0IR = portTIMER_MATCH_ISR_BIT;
|
||||
VICVectAddr = portCLEAR_VIC_INTERRUPT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
unsigned portLONG ulCompareMatch;
|
||||
|
||||
/* A 1ms tick does not require the use of the timer prescale. This is
|
||||
defaulted to zero but can be used if necessary. */
|
||||
T0PR = portPRESCALE_VALUE;
|
||||
|
||||
/* Calculate the match value required for our wanted tick rate. */
|
||||
ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
|
||||
|
||||
/* Protect against divide by zero. Using an if() statement still results
|
||||
in a warning - hence the #if. */
|
||||
#if portPRESCALE_VALUE != 0
|
||||
{
|
||||
ulCompareMatch /= ( portPRESCALE_VALUE + 1 );
|
||||
}
|
||||
#endif
|
||||
|
||||
T0MR0 = ulCompareMatch;
|
||||
|
||||
/* Generate tick with timer 0 compare match. */
|
||||
T0MCR = portRESET_COUNT_ON_MATCH | portINTERRUPT_ON_MATCH;
|
||||
|
||||
/* Setup the VIC for the timer. */
|
||||
VICIntSelect &= ~( portTIMER_VIC_CHANNEL_BIT );
|
||||
VICIntEnable |= portTIMER_VIC_CHANNEL_BIT;
|
||||
|
||||
/* The ISR installed depends on whether the preemptive or cooperative
|
||||
scheduler is being used. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
extern void ( vPortPreemptiveTickEntry )( void );
|
||||
|
||||
VICVectAddr0 = ( unsigned portLONG ) vPortPreemptiveTickEntry;
|
||||
}
|
||||
#else
|
||||
{
|
||||
extern void ( vNonPreemptiveTick )( void );
|
||||
|
||||
VICVectAddr0 = ( portLONG ) vPortNonPreemptiveTick;
|
||||
}
|
||||
#endif
|
||||
|
||||
VICVectCntl0 = portTIMER_VIC_CHANNEL | portTIMER_VIC_ENABLE;
|
||||
|
||||
/* Start the timer - interrupts are disabled when this function is called
|
||||
so it is okay to do this here. */
|
||||
T0TCR = portENABLE_TIMER;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts first! */
|
||||
__disable_interrupt();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
__enable_interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
50
20080212/Source/portable/IAR/LPC2000/portasm.s79
Normal file
50
20080212/Source/portable/IAR/LPC2000/portasm.s79
Normal file
|
@ -0,0 +1,50 @@
|
|||
RSEG ICODE:CODE
|
||||
CODE32
|
||||
|
||||
EXTERN vTaskSwitchContext
|
||||
EXTERN vTaskIncrementTick
|
||||
EXTERN vPortPreemptiveTick
|
||||
|
||||
PUBLIC vPortPreemptiveTickEntry
|
||||
PUBLIC vPortYieldProcessor
|
||||
PUBLIC vPortStartFirstTask
|
||||
|
||||
#include "FreeRTOSConfig.h"
|
||||
#include "ISR_Support.h"
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Starting the first task is just a matter of restoring the context that
|
||||
; was created by pxPortInitialiseStack().
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortStartFirstTask:
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Manual context switch function. This is the SWI hander.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortYieldProcessor:
|
||||
ADD LR, LR, #4 ; Add 4 to the LR to make the LR appear exactly
|
||||
; as if the context was saved during and IRQ
|
||||
; handler.
|
||||
|
||||
portSAVE_CONTEXT ; Save the context of the current task...
|
||||
LDR R0, =vTaskSwitchContext ; before selecting the next task to execute.
|
||||
mov lr, pc
|
||||
BX R0
|
||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Preemptive context switch function. This will only ever get installed if
|
||||
; portUSE_PREEMPTION is set to 1 in portmacro.h.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortPreemptiveTickEntry:
|
||||
#if configUSE_PREEMPTION == 1
|
||||
portSAVE_CONTEXT ; Save the context of the current task...
|
||||
LDR R0, =vPortPreemptiveTick; before selecting the next task to execute.
|
||||
mov lr, pc
|
||||
BX R0
|
||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
||||
#endif
|
||||
|
||||
END
|
||||
|
127
20080212/Source/portable/IAR/LPC2000/portmacro.h
Normal file
127
20080212/Source/portable/IAR/LPC2000/portmacro.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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
|
||||
|
||||
#include <intrinsics.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 portLONG
|
||||
|
||||
#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
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
#define portYIELD() asm ( "SWI 0" )
|
||||
#define portNOP() asm ( "NOP" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
__arm __interwork void vPortDisableInterruptsFromThumb( void );
|
||||
__arm __interwork void vPortEnableInterruptsFromThumb( void );
|
||||
__arm __interwork void vPortEnterCritical( void );
|
||||
__arm __interwork void vPortExitCritical( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __disable_interrupt()
|
||||
#define portENABLE_INTERRUPTS() __enable_interrupt()
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern void vTaskSwitchContext( void ); \
|
||||
\
|
||||
if( xSwitchRequired ) \
|
||||
{ \
|
||||
vTaskSwitchContext(); \
|
||||
} \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler specifics. */
|
||||
#define inline
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* 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 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
78
20080212/Source/portable/IAR/STR71x/ISR_Support.h
Normal file
78
20080212/Source/portable/IAR/STR71x/ISR_Support.h
Normal file
|
@ -0,0 +1,78 @@
|
|||
EXTERN pxCurrentTCB
|
||||
EXTERN ulCriticalNesting
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Context save and restore macro definitions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
portSAVE_CONTEXT MACRO
|
||||
|
||||
; Push R0 as we are going to use the register.
|
||||
STMDB SP!, {R0}
|
||||
|
||||
; Set R0 to point to the task stack pointer.
|
||||
STMDB SP, {SP}^
|
||||
NOP
|
||||
SUB SP, SP, #4
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push the return address onto the stack.
|
||||
STMDB R0!, {LR}
|
||||
|
||||
; Now we have saved LR we can use it instead of R0.
|
||||
MOV LR, R0
|
||||
|
||||
; Pop R0 so we can save it onto the system mode stack.
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push all the system mode registers onto the task stack.
|
||||
STMDB LR, {R0-LR}^
|
||||
NOP
|
||||
SUB LR, LR, #60
|
||||
|
||||
; Push the SPSR onto the task stack.
|
||||
MRS R0, SPSR
|
||||
STMDB LR!, {R0}
|
||||
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDR R0, [R0]
|
||||
STMDB LR!, {R0}
|
||||
|
||||
; Store the new top of stack for the task.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
STR LR, [R0]
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
portRESTORE_CONTEXT MACRO
|
||||
|
||||
; Set the LR to the task stack.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
LDR LR, [R0]
|
||||
|
||||
; The critical nesting depth is the first item on the stack.
|
||||
; Load it into the ulCriticalNesting variable.
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDMFD LR!, {R1}
|
||||
STR R1, [R0]
|
||||
|
||||
; Get the SPSR from the stack.
|
||||
LDMFD LR!, {R0}
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
; Restore all system mode registers for the task.
|
||||
LDMFD LR, {R0-R14}^
|
||||
NOP
|
||||
|
||||
; Restore the return address.
|
||||
LDR LR, [LR, #+60]
|
||||
|
||||
; And return - correcting the offset in the LR to obtain the
|
||||
; correct address.
|
||||
SUBS PC, LR, #4
|
||||
|
||||
ENDM
|
||||
|
262
20080212/Source/portable/IAR/STR71x/port.c
Normal file
262
20080212/Source/portable/IAR/STR71x/port.c
Normal file
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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 ST STR71x ARM7
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Library includes. */
|
||||
#include "wdg.h"
|
||||
#include "eic.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to setup the initial stack. */
|
||||
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x3f ) /* System mode, THUMB mode, interrupts enabled. */
|
||||
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
|
||||
|
||||
#define portMICROS_PER_SECOND 1000000
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the watchdog to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* ulCriticalNesting will get set to zero when the first task starts. It
|
||||
cannot be initialised to 0 as this will cause interrupts to be enabled
|
||||
during the kernel initialisation process. */
|
||||
unsigned portLONG ulCriticalNesting = ( unsigned portLONG ) 9999;
|
||||
|
||||
/* Tick interrupt routines for cooperative and preemptive operation
|
||||
respectively. The preemptive version is not defined as __irq as it is called
|
||||
from an asm wrapper function. */
|
||||
__arm __irq void vPortNonPreemptiveTick( void );
|
||||
void vPortPreemptiveTick( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||
{
|
||||
portSTACK_TYPE *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The status register is set for system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* The cooperative scheduler requires a normal IRQ service routine to
|
||||
simply increment the system tick. */
|
||||
__arm __irq void vPortNonPreemptiveTick( void )
|
||||
{
|
||||
/* Increment the tick count - which may wake some tasks but as the
|
||||
preemptive scheduler is not being used any woken task is not given
|
||||
processor time no matter what its priority. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
/* Clear the interrupt in the watchdog and EIC. */
|
||||
WDG->SR = 0x0000;
|
||||
portCLEAR_EIC();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* This function is called from an asm wrapper, so does not require the __irq
|
||||
keyword. */
|
||||
void vPortPreemptiveTick( void )
|
||||
{
|
||||
/* Increment the tick counter. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
/* The new tick value might unblock a task. Ensure the highest task that
|
||||
is ready to execute is the task that will execute when the tick ISR
|
||||
exits. */
|
||||
vTaskSwitchContext();
|
||||
|
||||
/* Clear the interrupt in the watchdog and EIC. */
|
||||
WDG->SR = 0x0000;
|
||||
portCLEAR_EIC();
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
/* Set the watchdog up to generate a periodic tick. */
|
||||
WDG_ECITConfig( DISABLE );
|
||||
WDG_CntOnOffConfig( DISABLE );
|
||||
WDG_PeriodValueConfig( portMICROS_PER_SECOND / configTICK_RATE_HZ );
|
||||
|
||||
/* Setup the tick interrupt in the EIC. */
|
||||
EIC_IRQChannelPriorityConfig( WDG_IRQChannel, 1 );
|
||||
EIC_IRQChannelConfig( WDG_IRQChannel, ENABLE );
|
||||
EIC_IRQConfig( ENABLE );
|
||||
WDG_ECITConfig( ENABLE );
|
||||
|
||||
/* Start the timer - interrupts are actually disabled at this point so
|
||||
it is safe to do this here. */
|
||||
WDG_CntOnOffConfig( ENABLE );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__arm __interwork void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts first! */
|
||||
__disable_interrupt();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__arm __interwork void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
__enable_interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
49
20080212/Source/portable/IAR/STR71x/portasm.s79
Normal file
49
20080212/Source/portable/IAR/STR71x/portasm.s79
Normal file
|
@ -0,0 +1,49 @@
|
|||
RSEG ICODE:CODE
|
||||
CODE32
|
||||
|
||||
EXTERN vPortPreemptiveTick
|
||||
EXTERN vTaskSwitchContext
|
||||
|
||||
PUBLIC vPortYieldProcessor
|
||||
PUBLIC vPortStartFirstTask
|
||||
PUBLIC vPortPreemptiveTickISR
|
||||
|
||||
#include "ISR_Support.h"
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Starting the first task is just a matter of restoring the context that
|
||||
; was created by pxPortInitialiseStack().
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortStartFirstTask:
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Manual context switch function. This is the SWI hander.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortYieldProcessor:
|
||||
ADD LR, LR, #4 ; Add 4 to the LR to make the LR appear exactly
|
||||
; as if the context was saved during and IRQ
|
||||
; handler.
|
||||
|
||||
portSAVE_CONTEXT ; Save the context of the current task...
|
||||
LDR R0, =vTaskSwitchContext ; before selecting the next task to execute.
|
||||
mov lr, pc
|
||||
BX R0
|
||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Preemptive context switch function. This will only ever get used if
|
||||
; portUSE_PREEMPTION is set to 1 in portmacro.h.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortPreemptiveTickISR:
|
||||
portSAVE_CONTEXT ; Save the context of the current task.
|
||||
|
||||
LDR R0, =vPortPreemptiveTick ; Increment the tick count - this may wake a task.
|
||||
MOV lr, pc
|
||||
BX R0
|
||||
|
||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
||||
|
||||
|
||||
END
|
||||
|
134
20080212/Source/portable/IAR/STR71x/portmacro.h
Normal file
134
20080212/Source/portable/IAR/STR71x/portmacro.h
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <intrinsics.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* 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 portLONG
|
||||
|
||||
#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
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
#define portYIELD() asm ( "SWI 0" )
|
||||
#define portNOP() asm ( "NOP" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
__arm __interwork void vPortDisableInterruptsFromThumb( void );
|
||||
__arm __interwork void vPortEnableInterruptsFromThumb( void );
|
||||
__arm __interwork void vPortEnterCritical( void );
|
||||
__arm __interwork void vPortExitCritical( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __disable_interrupt()
|
||||
#define portENABLE_INTERRUPTS() __enable_interrupt()
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern void vTaskSwitchContext( void ); \
|
||||
\
|
||||
if( xSwitchRequired ) \
|
||||
{ \
|
||||
vTaskSwitchContext(); \
|
||||
} \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* EIC utilities. */
|
||||
#define portEIC_CICR_ADDR *( ( unsigned portLONG * ) 0xFFFFF804 )
|
||||
#define portEIC_IPR_ADDR *( ( unsigned portLONG * ) 0xFFFFF840 )
|
||||
#define portCLEAR_EIC() portEIC_IPR_ADDR = 0x01 << portEIC_CICR_ADDR
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler specifics */
|
||||
#define inline
|
||||
|
||||
/* 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 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
108
20080212/Source/portable/IAR/STR75x/ISR_Support.h
Normal file
108
20080212/Source/portable/IAR/STR75x/ISR_Support.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
; FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
;
|
||||
; This file is part of the FreeRTOS.org distribution.
|
||||
;
|
||||
; FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation; either version 2 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; FreeRTOS.org 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
|
||||
; along with FreeRTOS.org; if not, write to the Free Software
|
||||
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
;
|
||||
; A special exception to the GPL can be applied should you wish to distribute
|
||||
; a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
; the source code for any proprietary components. See the licensing section
|
||||
; of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
; can be applied.
|
||||
;
|
||||
; ***************************************************************************
|
||||
; See http://www.FreeRTOS.org for documentation, latest information, license
|
||||
; and contact details. Please ensure to read the configuration and relevant
|
||||
; port sections of the online documentation.
|
||||
; ***************************************************************************
|
||||
|
||||
EXTERN pxCurrentTCB
|
||||
EXTERN ulCriticalNesting
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Context save and restore macro definitions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
portSAVE_CONTEXT MACRO
|
||||
|
||||
; Push R0 as we are going to use the register.
|
||||
STMDB SP!, {R0}
|
||||
|
||||
; Set R0 to point to the task stack pointer.
|
||||
STMDB SP, {SP}^
|
||||
NOP
|
||||
SUB SP, SP, #4
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push the return address onto the stack.
|
||||
STMDB R0!, {LR}
|
||||
|
||||
; Now we have saved LR we can use it instead of R0.
|
||||
MOV LR, R0
|
||||
|
||||
; Pop R0 so we can save it onto the system mode stack.
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push all the system mode registers onto the task stack.
|
||||
STMDB LR, {R0-LR}^
|
||||
NOP
|
||||
SUB LR, LR, #60
|
||||
|
||||
; Push the SPSR onto the task stack.
|
||||
MRS R0, SPSR
|
||||
STMDB LR!, {R0}
|
||||
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDR R0, [R0]
|
||||
STMDB LR!, {R0}
|
||||
|
||||
; Store the new top of stack for the task.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
STR LR, [R0]
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
portRESTORE_CONTEXT MACRO
|
||||
|
||||
; Set the LR to the task stack.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
LDR LR, [R0]
|
||||
|
||||
; The critical nesting depth is the first item on the stack.
|
||||
; Load it into the ulCriticalNesting variable.
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDMFD LR!, {R1}
|
||||
STR R1, [R0]
|
||||
|
||||
; Get the SPSR from the stack.
|
||||
LDMFD LR!, {R0}
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
; Restore all system mode registers for the task.
|
||||
LDMFD LR, {R0-R14}^
|
||||
NOP
|
||||
|
||||
; Restore the return address.
|
||||
LDR LR, [LR, #+60]
|
||||
|
||||
; And return - correcting the offset in the LR to obtain the
|
||||
; correct address.
|
||||
SUBS PC, LR, #4
|
||||
|
||||
ENDM
|
||||
|
251
20080212/Source/portable/IAR/STR75x/port.c
Normal file
251
20080212/Source/portable/IAR/STR75x/port.c
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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 ST STR75x ARM7
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Library includes. */
|
||||
#include "75x_tb.h"
|
||||
#include "75x_eic.h"
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Constants required to setup the initial stack. */
|
||||
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x3f ) /* System mode, THUMB mode, interrupts enabled. */
|
||||
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
|
||||
|
||||
/* Prescale used on the timer clock when calculating the tick period. */
|
||||
#define portPRESCALE 20
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the TB to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* ulCriticalNesting will get set to zero when the first task starts. It
|
||||
cannot be initialised to 0 as this will cause interrupts to be enabled
|
||||
during the kernel initialisation process. */
|
||||
unsigned portLONG ulCriticalNesting = ( unsigned portLONG ) 9999;
|
||||
|
||||
/* Tick interrupt routines for preemptive operation. */
|
||||
__arm void vPortPreemptiveTick( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||
{
|
||||
portSTACK_TYPE *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The status register is set for system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__arm void vPortPreemptiveTick( void )
|
||||
{
|
||||
/* Increment the tick counter. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
/* The new tick value might unblock a task. Ensure the highest task that
|
||||
is ready to execute is the task that will execute when the tick ISR
|
||||
exits. */
|
||||
#if configUSE_PREEMPTION == 1
|
||||
vTaskSwitchContext();
|
||||
#endif
|
||||
|
||||
TB_ClearITPendingBit( TB_IT_Update );
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
EIC_IRQInitTypeDef EIC_IRQInitStructure;
|
||||
TB_InitTypeDef TB_InitStructure;
|
||||
|
||||
/* Setup the EIC for the TB. */
|
||||
EIC_IRQInitStructure.EIC_IRQChannelCmd = ENABLE;
|
||||
EIC_IRQInitStructure.EIC_IRQChannel = TB_IRQChannel;
|
||||
EIC_IRQInitStructure.EIC_IRQChannelPriority = 1;
|
||||
EIC_IRQInit(&EIC_IRQInitStructure);
|
||||
|
||||
/* Setup the TB for the generation of the tick interrupt. */
|
||||
TB_InitStructure.TB_Mode = TB_Mode_Timing;
|
||||
TB_InitStructure.TB_CounterMode = TB_CounterMode_Down;
|
||||
TB_InitStructure.TB_Prescaler = portPRESCALE;
|
||||
TB_InitStructure.TB_AutoReload = ( ( configCPU_CLOCK_HZ / ( portPRESCALE + 1 ) ) / configTICK_RATE_HZ ) + 1;
|
||||
TB_Init(&TB_InitStructure);
|
||||
|
||||
/* Enable TB Update interrupt */
|
||||
TB_ITConfig(TB_IT_Update, ENABLE);
|
||||
|
||||
/* Clear TB Update interrupt pending bit */
|
||||
TB_ClearITPendingBit(TB_IT_Update);
|
||||
|
||||
/* Enable TB */
|
||||
TB_Cmd(ENABLE);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__arm __interwork void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts first! */
|
||||
__disable_interrupt();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__arm __interwork void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
__enable_interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
66
20080212/Source/portable/IAR/STR75x/portasm.s79
Normal file
66
20080212/Source/portable/IAR/STR75x/portasm.s79
Normal file
|
@ -0,0 +1,66 @@
|
|||
; FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
;
|
||||
; This file is part of the FreeRTOS.org distribution.
|
||||
;
|
||||
; FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation; either version 2 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; FreeRTOS.org 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
|
||||
; along with FreeRTOS.org; if not, write to the Free Software
|
||||
; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
;
|
||||
; A special exception to the GPL can be applied should you wish to distribute
|
||||
; a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
; the source code for any proprietary components. See the licensing section
|
||||
; of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
; can be applied.
|
||||
;
|
||||
; ***************************************************************************
|
||||
; See http://www.FreeRTOS.org for documentation, latest information, license
|
||||
; and contact details. Please ensure to read the configuration and relevant
|
||||
; port sections of the online documentation.
|
||||
; ***************************************************************************
|
||||
|
||||
RSEG ICODE:CODE
|
||||
CODE32
|
||||
|
||||
EXTERN vPortPreemptiveTick
|
||||
EXTERN vTaskSwitchContext
|
||||
|
||||
PUBLIC vPortYieldProcessor
|
||||
PUBLIC vPortStartFirstTask
|
||||
|
||||
#include "ISR_Support.h"
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Starting the first task is just a matter of restoring the context that
|
||||
; was created by pxPortInitialiseStack().
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortStartFirstTask:
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Manual context switch function. This is the SWI hander.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortYieldProcessor:
|
||||
ADD LR, LR, #4 ; Add 4 to the LR to make the LR appear exactly
|
||||
; as if the context was saved during and IRQ
|
||||
; handler.
|
||||
|
||||
portSAVE_CONTEXT ; Save the context of the current task...
|
||||
LDR R0, =vTaskSwitchContext ; before selecting the next task to execute.
|
||||
mov lr, pc
|
||||
BX R0
|
||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
||||
|
||||
|
||||
|
||||
END
|
||||
|
124
20080212/Source/portable/IAR/STR75x/portmacro.h
Normal file
124
20080212/Source/portable/IAR/STR75x/portmacro.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
This file is part of the FreeRTOS.org distribution.
|
||||
|
||||
FreeRTOS.org is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
FreeRTOS.org 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
|
||||
along with FreeRTOS.org; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS.org, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <intrinsics.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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 portLONG
|
||||
|
||||
#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
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
#define portYIELD() asm ( "SWI 0" )
|
||||
#define portNOP() asm ( "NOP" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
__arm __interwork void vPortEnterCritical( void );
|
||||
__arm __interwork void vPortExitCritical( void );
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __disable_interrupt()
|
||||
#define portENABLE_INTERRUPTS() __enable_interrupt()
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern void vTaskSwitchContext( void ); \
|
||||
\
|
||||
if( xSwitchRequired ) \
|
||||
{ \
|
||||
vTaskSwitchContext(); \
|
||||
} \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler specifics */
|
||||
#define inline
|
||||
|
||||
/* 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 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
120
20080212/Source/portable/IAR/STR91x/ISR_Support.h
Normal file
120
20080212/Source/portable/IAR/STR91x/ISR_Support.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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
|
||||
along with FreeRTOS; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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 ulCriticalNesting
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Context save and restore macro definitions
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
portSAVE_CONTEXT MACRO
|
||||
|
||||
; Push R0 as we are going to use the register.
|
||||
STMDB SP!, {R0}
|
||||
|
||||
; Set R0 to point to the task stack pointer.
|
||||
STMDB SP, {SP}^
|
||||
NOP
|
||||
SUB SP, SP, #4
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push the return address onto the stack.
|
||||
STMDB R0!, {LR}
|
||||
|
||||
; Now we have saved LR we can use it instead of R0.
|
||||
MOV LR, R0
|
||||
|
||||
; Pop R0 so we can save it onto the system mode stack.
|
||||
LDMIA SP!, {R0}
|
||||
|
||||
; Push all the system mode registers onto the task stack.
|
||||
STMDB LR, {R0-LR}^
|
||||
NOP
|
||||
SUB LR, LR, #60
|
||||
|
||||
; Push the SPSR onto the task stack.
|
||||
MRS R0, SPSR
|
||||
STMDB LR!, {R0}
|
||||
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDR R0, [R0]
|
||||
STMDB LR!, {R0}
|
||||
|
||||
; Store the new top of stack for the task.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
STR LR, [R0]
|
||||
|
||||
ENDM
|
||||
|
||||
|
||||
portRESTORE_CONTEXT MACRO
|
||||
|
||||
; Set the LR to the task stack.
|
||||
LDR R1, =pxCurrentTCB
|
||||
LDR R0, [R1]
|
||||
LDR LR, [R0]
|
||||
|
||||
; The critical nesting depth is the first item on the stack.
|
||||
; Load it into the ulCriticalNesting variable.
|
||||
LDR R0, =ulCriticalNesting
|
||||
LDMFD LR!, {R1}
|
||||
STR R1, [R0]
|
||||
|
||||
; Get the SPSR from the stack.
|
||||
LDMFD LR!, {R0}
|
||||
MSR SPSR_cxsf, R0
|
||||
|
||||
; Restore all system mode registers for the task.
|
||||
LDMFD LR, {R0-R14}^
|
||||
NOP
|
||||
|
||||
; Restore the return address.
|
||||
LDR LR, [LR, #+60]
|
||||
|
||||
; And return - correcting the offset in the LR to obtain the
|
||||
; correct address.
|
||||
SUBS PC, LR, #4
|
||||
|
||||
ENDM
|
||||
|
442
20080212/Source/portable/IAR/STR91x/port.c
Normal file
442
20080212/Source/portable/IAR/STR91x/port.c
Normal file
|
@ -0,0 +1,442 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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
|
||||
along with FreeRTOS; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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 ST STR91x ARM9
|
||||
* port.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
/* Library includes. */
|
||||
#include "91x_lib.h"
|
||||
|
||||
/* Standard includes. */
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Scheduler includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
#ifndef configUSE_WATCHDOG_TICK
|
||||
#error configUSE_WATCHDOG_TICK must be set to either 1 or 0 in FreeRTOSConfig.h to use either the Watchdog or timer 2 to generate the tick interrupt respectively.
|
||||
#endif
|
||||
|
||||
/* Constants required to setup the initial stack. */
|
||||
#ifndef _RUN_TASK_IN_ARM_MODE_
|
||||
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x3f ) /* System mode, THUMB mode, interrupts enabled. */
|
||||
#else
|
||||
#define portINITIAL_SPSR ( ( portSTACK_TYPE ) 0x1f ) /* System mode, ARM mode, interrupts enabled. */
|
||||
#endif
|
||||
|
||||
#define portINSTRUCTION_SIZE ( ( portSTACK_TYPE ) 4 )
|
||||
|
||||
/* Constants required to handle critical sections. */
|
||||
#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 )
|
||||
|
||||
#ifndef abs
|
||||
#define abs(x) ((x)>0 ? (x) : -(x))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Toggle a led using the following algorithm:
|
||||
* if ( GPIO_ReadBit(GPIO9, GPIO_Pin_2) )
|
||||
* {
|
||||
* GPIO_WriteBit( GPIO9, GPIO_Pin_2, Bit_RESET );
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* GPIO_WriteBit( GPIO9, GPIO_Pin_2, Bit_RESET );
|
||||
* }
|
||||
*
|
||||
*/
|
||||
#define TOGGLE_LED(port,pin) \
|
||||
if ( ((((port)->DR[(pin)<<2])) & (pin)) != Bit_RESET ) \
|
||||
{ \
|
||||
(port)->DR[(pin) <<2] = 0x00; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(port)->DR[(pin) <<2] = (pin); \
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Setup the watchdog to generate the tick interrupts. */
|
||||
static void prvSetupTimerInterrupt( void );
|
||||
|
||||
/* ulCriticalNesting will get set to zero when the first task starts. It
|
||||
cannot be initialised to 0 as this will cause interrupts to be enabled
|
||||
during the kernel initialisation process. */
|
||||
unsigned portLONG ulCriticalNesting = ( unsigned portLONG ) 9999;
|
||||
|
||||
/* Tick interrupt routines for cooperative and preemptive operation
|
||||
respectively. The preemptive version is not defined as __irq as it is called
|
||||
from an asm wrapper function. */
|
||||
void WDG_IRQHandler( void );
|
||||
|
||||
/* VIC interrupt default handler. */
|
||||
static void prvDefaultHandler( void );
|
||||
|
||||
#if configUSE_WATCHDOG_TICK == 0
|
||||
/* Used to update the OCR timer register */
|
||||
static u16 s_nPulseLength;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Initialise the stack of a task to look exactly as if a call to
|
||||
* portSAVE_CONTEXT had been called.
|
||||
*
|
||||
* See header file for description.
|
||||
*/
|
||||
portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
|
||||
{
|
||||
portSTACK_TYPE *pxOriginalTOS;
|
||||
|
||||
pxOriginalTOS = pxTopOfStack;
|
||||
|
||||
/* Setup the initial stack of the task. The stack is set exactly as
|
||||
expected by the portRESTORE_CONTEXT() macro. */
|
||||
|
||||
/* First on the stack is the return address - which in this case is the
|
||||
start of the task. The offset is added to make the return address appear
|
||||
as it would within an IRQ ISR. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;
|
||||
pxTopOfStack--;
|
||||
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0xaaaaaaaa; /* R14 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x12121212; /* R12 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x11111111; /* R11 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x10101010; /* R10 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x09090909; /* R9 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x08080808; /* R8 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x07070707; /* R7 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x06060606; /* R6 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x05050505; /* R5 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x04040404; /* R4 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x03030303; /* R3 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x02020202; /* R2 */
|
||||
pxTopOfStack--;
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) 0x01010101; /* R1 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* When the task starts is will expect to find the function parameter in
|
||||
R0. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
|
||||
pxTopOfStack--;
|
||||
|
||||
/* The status register is set for system mode, with interrupts enabled. */
|
||||
*pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
|
||||
pxTopOfStack--;
|
||||
|
||||
/* Interrupt flags cannot always be stored on the stack and will
|
||||
instead be stored in a variable, which is then saved as part of the
|
||||
tasks context. */
|
||||
*pxTopOfStack = portNO_CRITICAL_NESTING;
|
||||
|
||||
return pxTopOfStack;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portBASE_TYPE xPortStartScheduler( void )
|
||||
{
|
||||
extern void vPortStartFirstTask( void );
|
||||
|
||||
/* Start the timer that generates the tick ISR. Interrupts are disabled
|
||||
here already. */
|
||||
prvSetupTimerInterrupt();
|
||||
|
||||
/* Start the first task. */
|
||||
vPortStartFirstTask();
|
||||
|
||||
/* Should not get here! */
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void vPortEndScheduler( void )
|
||||
{
|
||||
/* It is unlikely that the ARM port will require this function as there
|
||||
is nothing to return to. */
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* This function is called from an asm wrapper, so does not require the __irq
|
||||
keyword. */
|
||||
#if configUSE_WATCHDOG_TICK == 1
|
||||
|
||||
static void prvFindFactors(u32 n, u16 *a, u32 *b)
|
||||
{
|
||||
/* This function is copied from the ST STR7 library and is
|
||||
copyright STMicroelectronics. Reproduced with permission. */
|
||||
|
||||
u32 b0;
|
||||
u16 a0;
|
||||
long err, err_min=n;
|
||||
|
||||
*a = a0 = ((n-1)/65536ul) + 1;
|
||||
*b = b0 = n / *a;
|
||||
|
||||
for (; *a <= 256; (*a)++)
|
||||
{
|
||||
*b = n / *a;
|
||||
err = (long)*a * (long)*b - (long)n;
|
||||
if (abs(err) > (*a / 2))
|
||||
{
|
||||
(*b)++;
|
||||
err = (long)*a * (long)*b - (long)n;
|
||||
}
|
||||
if (abs(err) < abs(err_min))
|
||||
{
|
||||
err_min = err;
|
||||
a0 = *a;
|
||||
b0 = *b;
|
||||
if (err == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
*a = a0;
|
||||
*b = b0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
WDG_InitTypeDef xWdg;
|
||||
unsigned portSHORT a;
|
||||
unsigned portLONG n = configCPU_PERIPH_HZ / configTICK_RATE_HZ, b;
|
||||
|
||||
/* Configure the watchdog as a free running timer that generates a
|
||||
periodic interrupt. */
|
||||
|
||||
SCU_APBPeriphClockConfig( __WDG, ENABLE );
|
||||
WDG_DeInit();
|
||||
WDG_StructInit(&xWdg);
|
||||
prvFindFactors( n, &a, &b );
|
||||
xWdg.WDG_Prescaler = a - 1;
|
||||
xWdg.WDG_Preload = b - 1;
|
||||
WDG_Init( &xWdg );
|
||||
WDG_ITConfig(ENABLE);
|
||||
|
||||
/* Configure the VIC for the WDG interrupt. */
|
||||
VIC_Config( WDG_ITLine, VIC_IRQ, 10 );
|
||||
VIC_ITCmd( WDG_ITLine, ENABLE );
|
||||
|
||||
/* Install the default handlers for both VIC's. */
|
||||
VIC0->DVAR = ( unsigned portLONG ) prvDefaultHandler;
|
||||
VIC1->DVAR = ( unsigned portLONG ) prvDefaultHandler;
|
||||
|
||||
WDG_Cmd(ENABLE);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void WDG_IRQHandler( void )
|
||||
{
|
||||
{
|
||||
/* Increment the tick counter. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
/* The new tick value might unblock a task. Ensure the highest task that
|
||||
is ready to execute is the task that will execute when the tick ISR
|
||||
exits. */
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
#endif /* configUSE_PREEMPTION. */
|
||||
|
||||
/* Clear the interrupt in the watchdog. */
|
||||
WDG->SR &= ~0x0001;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void prvFindFactors(u32 n, u8 *a, u16 *b)
|
||||
{
|
||||
/* This function is copied from the ST STR7 library and is
|
||||
copyright STMicroelectronics. Reproduced with permission. */
|
||||
|
||||
u16 b0;
|
||||
u8 a0;
|
||||
long err, err_min=n;
|
||||
|
||||
|
||||
*a = a0 = ((n-1)/256) + 1;
|
||||
*b = b0 = n / *a;
|
||||
|
||||
for (; *a <= 256; (*a)++)
|
||||
{
|
||||
*b = n / *a;
|
||||
err = (long)*a * (long)*b - (long)n;
|
||||
if (abs(err) > (*a / 2))
|
||||
{
|
||||
(*b)++;
|
||||
err = (long)*a * (long)*b - (long)n;
|
||||
}
|
||||
if (abs(err) < abs(err_min))
|
||||
{
|
||||
err_min = err;
|
||||
a0 = *a;
|
||||
b0 = *b;
|
||||
if (err == 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
*a = a0;
|
||||
*b = b0;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvSetupTimerInterrupt( void )
|
||||
{
|
||||
unsigned portCHAR a;
|
||||
unsigned portSHORT b;
|
||||
unsigned portLONG n = configCPU_PERIPH_HZ / configTICK_RATE_HZ;
|
||||
|
||||
TIM_InitTypeDef timer;
|
||||
|
||||
SCU_APBPeriphClockConfig( __TIM23, ENABLE );
|
||||
TIM_DeInit(TIM2);
|
||||
TIM_StructInit(&timer);
|
||||
prvFindFactors( n, &a, &b );
|
||||
|
||||
timer.TIM_Mode = TIM_OCM_CHANNEL_1;
|
||||
timer.TIM_OC1_Modes = TIM_TIMING;
|
||||
timer.TIM_Clock_Source = TIM_CLK_APB;
|
||||
timer.TIM_Clock_Edge = TIM_CLK_EDGE_RISING;
|
||||
timer.TIM_Prescaler = a-1;
|
||||
timer.TIM_Pulse_Level_1 = TIM_HIGH;
|
||||
timer.TIM_Pulse_Length_1 = s_nPulseLength = b-1;
|
||||
|
||||
TIM_Init (TIM2, &timer);
|
||||
TIM_ITConfig(TIM2, TIM_IT_OC1, ENABLE);
|
||||
/* Configure the VIC for the WDG interrupt. */
|
||||
VIC_Config( TIM2_ITLine, VIC_IRQ, 10 );
|
||||
VIC_ITCmd( TIM2_ITLine, ENABLE );
|
||||
|
||||
/* Install the default handlers for both VIC's. */
|
||||
VIC0->DVAR = ( unsigned portLONG ) prvDefaultHandler;
|
||||
VIC1->DVAR = ( unsigned portLONG ) prvDefaultHandler;
|
||||
|
||||
TIM_CounterCmd(TIM2, TIM_CLEAR);
|
||||
TIM_CounterCmd(TIM2, TIM_START);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
void TIM2_IRQHandler( void )
|
||||
{
|
||||
/* Reset the timer counter to avioid overflow. */
|
||||
TIM2->OC1R += s_nPulseLength;
|
||||
|
||||
/* Increment the tick counter. */
|
||||
vTaskIncrementTick();
|
||||
|
||||
#if configUSE_PREEMPTION == 1
|
||||
{
|
||||
/* The new tick value might unblock a task. Ensure the highest task that
|
||||
is ready to execute is the task that will execute when the tick ISR
|
||||
exits. */
|
||||
vTaskSwitchContext();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clear the interrupt in the watchdog. */
|
||||
TIM2->SR &= ~TIM_FLAG_OC1;
|
||||
}
|
||||
|
||||
#endif /* USE_WATCHDOG_TICK */
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__arm __interwork void vPortEnterCritical( void )
|
||||
{
|
||||
/* Disable interrupts first! */
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* Now interrupts are disabled ulCriticalNesting can be accessed
|
||||
directly. Increment ulCriticalNesting to keep a count of how many times
|
||||
portENTER_CRITICAL() has been called. */
|
||||
ulCriticalNesting++;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
__arm __interwork void vPortExitCritical( void )
|
||||
{
|
||||
if( ulCriticalNesting > portNO_CRITICAL_NESTING )
|
||||
{
|
||||
/* Decrement the nesting count as we are leaving a critical section. */
|
||||
ulCriticalNesting--;
|
||||
|
||||
/* If the nesting level has reached zero then interrupts should be
|
||||
re-enabled. */
|
||||
if( ulCriticalNesting == portNO_CRITICAL_NESTING )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvDefaultHandler( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
75
20080212/Source/portable/IAR/STR91x/portasm.s79
Normal file
75
20080212/Source/portable/IAR/STR91x/portasm.s79
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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
|
||||
along with FreeRTOS; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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.
|
||||
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
RSEG ICODE:CODE
|
||||
CODE32
|
||||
|
||||
EXTERN vTaskSwitchContext
|
||||
|
||||
PUBLIC vPortYieldProcessor
|
||||
PUBLIC vPortStartFirstTask
|
||||
|
||||
#include "ISR_Support.h"
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Starting the first task is just a matter of restoring the context that
|
||||
; was created by pxPortInitialiseStack().
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortStartFirstTask:
|
||||
portRESTORE_CONTEXT
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Manual context switch function. This is the SWI hander.
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
vPortYieldProcessor:
|
||||
ADD LR, LR, #4 ; Add 4 to the LR to make the LR appear exactly
|
||||
; as if the context was saved during and IRQ
|
||||
; handler.
|
||||
|
||||
portSAVE_CONTEXT ; Save the context of the current task...
|
||||
LDR R0, =vTaskSwitchContext ; before selecting the next task to execute.
|
||||
MOV lr, pc
|
||||
BX R0
|
||||
portRESTORE_CONTEXT ; Restore the context of the selected task.
|
||||
|
||||
END
|
||||
|
126
20080212/Source/portable/IAR/STR91x/portmacro.h
Normal file
126
20080212/Source/portable/IAR/STR91x/portmacro.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.
|
||||
|
||||
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 as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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
|
||||
along with FreeRTOS; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
A special exception to the GPL can be applied should you wish to distribute
|
||||
a combined work that includes FreeRTOS, without being obliged to provide
|
||||
the source code for any proprietary components. See the licensing section
|
||||
of http://www.FreeRTOS.org for full details of how and when the exception
|
||||
can be applied.
|
||||
|
||||
***************************************************************************
|
||||
|
||||
Please ensure to read the configuration and relevant port sections of the
|
||||
online documentation.
|
||||
|
||||
+++ 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
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Port specific definitions.
|
||||
*
|
||||
* The settings in this file configure FreeRTOS correctly for the
|
||||
* given hardware and compiler.
|
||||
*
|
||||
* These settings should not be altered.
|
||||
*-----------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <intrinsics.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* 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 portLONG
|
||||
|
||||
#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
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Hardware specifics. */
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#define portTICK_RATE_MS ( ( portTickType ) 1000 / configTICK_RATE_HZ )
|
||||
#define portBYTE_ALIGNMENT 4
|
||||
#define portYIELD() asm ( "SWI 0" )
|
||||
#define portNOP() asm ( "NOP" )
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Critical section handling. */
|
||||
__arm __interwork void vPortEnterCritical( void );
|
||||
__arm __interwork void vPortExitCritical( void );
|
||||
#define portENTER_CRITICAL() vPortEnterCritical()
|
||||
#define portEXIT_CRITICAL() vPortExitCritical()
|
||||
|
||||
#define portDISABLE_INTERRUPTS() __disable_interrupt()
|
||||
#define portENABLE_INTERRUPTS() __enable_interrupt()
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Task utilities. */
|
||||
#define portEND_SWITCHING_ISR( xSwitchRequired ) \
|
||||
{ \
|
||||
extern void vTaskSwitchContext( void ); \
|
||||
\
|
||||
if( xSwitchRequired ) \
|
||||
{ \
|
||||
vTaskSwitchContext(); \
|
||||
} \
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Compiler specifics */
|
||||
#define inline
|
||||
|
||||
/* 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 )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PORTMACRO_H */
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue