blob: 96a5993a59650ed82279ea1a92f3e448837bdc89 [file] [log] [blame]
; V5.2.0 - Copyright (C) 2003-2009 Richard Barry.
; This file is part of the distribution.
; is free software; you can redistribute it and/or modify it
; under the terms of the GNU General Public License (version 2) as published
; by the Free Software Foundation and modified by the FreeRTOS exception.
; 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; 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 is included to allow you to distribute a
; combined work that includes without being obliged to provide
; the source code for any proprietary components. See the licensing section
; of for full details.
; ***************************************************************************
; * *
; * Get the FreeRTOS eBook! See *
; * *
; * This is a concise, step by step, 'hands on' guide that describes both *
; * general multitasking concepts and FreeRTOS specifics. It presents and *
; * explains numerous examples that are written using the FreeRTOS API. *
; * Full source code for all the examples is provided in an accompanying *
; * .zip file. *
; * *
; ***************************************************************************
; 1 tab == 4 spaces!
; Please ensure to read the configuration and relevant port sections of the
; online documentation.
; - Documentation, latest information, license and
; contact details.
; - A version that is certified for use in safety
; critical systems.
; - Commercial support, development, porting,
; licensing and training services.
#include <iom323.h>
; Declare all extern symbols here - including any ISRs that are referenced in
; the vector table.
; ISR functions
; -------------
; Functions used by scheduler
; ---------------------------
EXTERN vTaskSwitchContext
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.
ORG TIMER1_COMPA_vect ; Vector address
ORG USART_RXC_vect ; Vector address
ORG USART_UDRE_vect ; Vector address
; 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.
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
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.
; 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.
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.
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.
; Just a filler for unused interrupt vectors.