You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
246 lines
7.1 KiB
Plaintext
246 lines
7.1 KiB
Plaintext
; 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
|
|
|