First version under SVN is V4.0.1

This commit is contained in:
Richard Barry 2006-05-02 09:39:15 +00:00
parent 243393860c
commit b6df57c7e3
918 changed files with 269038 additions and 0 deletions

View file

@ -0,0 +1,320 @@
/*
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
***************************************************************************
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 <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 )
/*-----------------------------------------------------------*/
/*
* 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 */
/*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

View file

@ -0,0 +1,110 @@
/*
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
***************************************************************************
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.
***************************************************************************
*/
/*
Changes from V1.2.3
+ portCPU_CLOSK_HZ definition changed to 8MHz base 10, previously it
base 16.
*/
#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.
*-----------------------------------------------------------
*/
/* 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. */
#define portENTER_CRITICAL() asm( "in r15, 3fh" ); \
asm( "cli" ); \
asm( "st -y, r15" )
#define portEXIT_CRITICAL() asm( "ld r15, y+" ); \
asm( "out 3fh, r15" )
#define portDISABLE_INTERRUPTS() asm( "cli" );
#define portENABLE_INTERRUPTS() asm( "sti" );
/*-----------------------------------------------------------*/
/* 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 )
#endif /* PORTMACRO_H */

View file

@ -0,0 +1,240 @@
; FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
;
; ***************************************************************************
; 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
; 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 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 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,253 @@
/*
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
***************************************************************************
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.
***************************************************************************
*/
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the Atmel ARM7 port.
*----------------------------------------------------------*/
/* Standard includes. */
#include <stdlib.h>
#include <intrinsic.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();
}
}
}
/*-----------------------------------------------------------*/

View 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

View file

@ -0,0 +1,109 @@
/*
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
***************************************************************************
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.
***************************************************************************
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#include <intrinsic.h>
/*-----------------------------------------------------------
* 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 )
#endif /* PORTMACRO_H */

View 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

View file

@ -0,0 +1,313 @@
/*
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
***************************************************************************
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.
***************************************************************************
*/
/*-----------------------------------------------------------
* 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 <intrinsic.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();
}
}
}
/*-----------------------------------------------------------*/

View 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

View file

@ -0,0 +1,109 @@
/*
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
***************************************************************************
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.
***************************************************************************
*/
#ifndef PORTMACRO_H
#define PORTMACRO_H
#include <intrinsic.h>
/*-----------------------------------------------------------
* 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 )
#endif /* PORTMACRO_H */

View 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

View file

@ -0,0 +1,250 @@
/*
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
***************************************************************************
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.
***************************************************************************
*/
/*-----------------------------------------------------------
* 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 )
/*-----------------------------------------------------------*/
/* 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( 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();
}
}
}
/*-----------------------------------------------------------*/

View 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

View file

@ -0,0 +1,115 @@
/*
FreeRTOS V4.0.1 - Copyright (C) 2003-2006 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.
***************************************************************************
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.
***************************************************************************
*/
#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 <intrinsic.h>
/* 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 )
#endif /* PORTMACRO_H */