OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Source/] [portable/] [IAR/] [ATMega323/] [portmacro.s90] - Rev 612

Go to most recent revision | Compare with Previous | Blame | View Log

;/*
;    FreeRTOS V6.1.1 - Copyright (C) 2011 Real Time Engineers Ltd.
;
;    ***************************************************************************
;    *                                                                         *
;    * If you are:                                                             *
;    *                                                                         *
;    *    + New to FreeRTOS,                                                   *
;    *    + Wanting to learn FreeRTOS or multitasking in general quickly       *
;    *    + Looking for basic training,                                        *
;    *    + Wanting to improve your FreeRTOS skills and productivity           *
;    *                                                                         *
;    * then take a look at the FreeRTOS books - available as PDF or paperback  *
;    *                                                                         *
;    *        "Using the FreeRTOS Real Time Kernel - a Practical Guide"        *
;    *                  http://www.FreeRTOS.org/Documentation                  *
;    *                                                                         *
;    * A pdf reference manual is also available.  Both are usually delivered   *
;    * to your inbox within 20 minutes to two hours when purchased between 8am *
;    * and 8pm GMT (although please allow up to 24 hours in case of            *
;    * exceptional circumstances).  Thank you for your support!                *
;    *                                                                         *
;    ***************************************************************************
;
;    This file is part of the FreeRTOS distribution.
;
;    FreeRTOS is free software; you can redistribute it and/or modify it under
;    the terms of the GNU General Public License (version 2) as published by the
;    Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
;    ***NOTE*** The exception to the GPL is included to allow you to distribute
;    a combined work that includes FreeRTOS without being obliged to provide the
;    source code for proprietary components outside of the FreeRTOS kernel.
;    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT
;    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
;    more details. You should have received a copy of the GNU General Public 
;    License and the FreeRTOS license exception along with FreeRTOS; if not it 
;    can be viewed here: http://www.freertos.org/a00114.html and also obtained 
;    by writing to Richard Barry, contact details for whom are available on the
;    FreeRTOS WEB site.
;
;    1 tab == 4 spaces!
;
;    http://www.FreeRTOS.org - Documentation, latest information, license and
;    contact details.
;
;    http://www.SafeRTOS.com - A version that is certified for use in safety
;    critical systems.
;
;    http://www.OpenRTOS.com - Commercial support, development, porting,
;    licensing and training services.
;*/

#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

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.