]> begriffs open source - freertos/blob - portable/IAR/ATMega323/portmacro.s90
Fix typo in the include directory for the the GCC_ARM_CM55_TFM port (#764)
[freertos] / portable / IAR / ATMega323 / portmacro.s90
1 ;/*
2 ; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
3 ; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4 ; *
5 ; * SPDX-License-Identifier: MIT
6 ; *
7 ; * Permission is hereby granted, free of charge, to any person obtaining a copy of
8 ; * this software and associated documentation files (the "Software"), to deal in
9 ; * the Software without restriction, including without limitation the rights to
10 ; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 ; * the Software, and to permit persons to whom the Software is furnished to do so,
12 ; * subject to the following conditions:
13 ; *
14 ; * The above copyright notice and this permission notice shall be included in all
15 ; * copies or substantial portions of the Software.
16 ; *
17 ; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 ; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 ; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 ; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 ; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 ; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 ; *
24 ; * https://www.FreeRTOS.org
25 ; * https://github.com/FreeRTOS
26 ; *
27 ; */
28
29 #include <iom323.h>
30
31 ; Declare all extern symbols here - including any ISRs that are referenced in
32 ; the vector table.
33
34 ; ISR functions
35 ; -------------
36 EXTERN SIG_OUTPUT_COMPARE1A
37 EXTERN SIG_UART_RECV
38 EXTERN SIG_UART_DATA
39
40
41 ; Functions used by scheduler
42 ; ---------------------------
43 EXTERN vTaskSwitchContext
44 EXTERN pxCurrentTCB
45 EXTERN xTaskIncrementTick
46 EXTERN uxCriticalNesting
47
48 ; Functions implemented in this file
49 ; ----------------------------------
50 PUBLIC vPortYield
51 PUBLIC vPortYieldFromTick
52 PUBLIC vPortStart
53
54
55 ; Interrupt vector table.
56 ; -----------------------
57 ;
58 ; For simplicity the RTOS tick interrupt routine uses the __task keyword.
59 ; As the IAR compiler does not permit a function to be declared using both
60 ; __task and __interrupt, the use of __task necessitates that the interrupt
61 ; vector table be setup manually.
62 ;
63 ; To write an ISR, implement the ISR function using the __interrupt keyword
64 ; but do not install the interrupt using the "#pragma vector=ABC" method.
65 ; Instead manually place the name of the ISR in the vector table using an
66 ; ORG and jmp instruction as demonstrated below.
67 ; You will also have to add an EXTERN statement at the top of the file.
68
69     ASEG
70
71
72     ORG TIMER1_COMPA_vect               ; Vector address
73         jmp SIG_OUTPUT_COMPARE1A        ; ISR
74
75     ORG USART_RXC_vect                  ; Vector address
76         jmp SIG_UART_RECV               ; ISR
77
78     ORG USART_UDRE_vect                 ; Vector address
79         jmp SIG_UART_DATA               ; ISR
80
81
82     RSEG CODE
83
84
85
86 ; Saving and Restoring a Task Context and Task Switching
87 ; ------------------------------------------------------
88 ;
89 ; The IAR compiler does not fully support inline assembler, so saving and
90 ; restoring a task context has to be written in an asm file.
91 ;
92 ; vPortYield() and vPortYieldFromTick() are usually written in C.  Doing
93 ; so in this case would required calls to be made to portSAVE_CONTEXT() and
94 ; portRESTORE_CONTEXT().  This is dis-advantageous as the context switch
95 ; function would require two extra jump and return instructions over the
96 ; WinAVR equivalent.
97 ;
98 ; To avoid this I have opted to implement both vPortYield() and
99 ; vPortYieldFromTick() in this assembly file.  For convenience
100 ; portSAVE_CONTEXT and portRESTORE_CONTEXT are implemented as macros.
101
102 portSAVE_CONTEXT MACRO
103     st  -y, r0          ; First save the r0 register - we need to use this.
104     in  r0, SREG        ; Obtain the SREG value so we can disable interrupts...
105     cli                 ; ... as soon as possible.
106     st  -y, r0          ; Store the SREG as it was before we disabled interrupts.
107
108     in  r0, SPL         ; Next store the hardware stack pointer.  The IAR...
109     st  -y, r0          ; ... compiler uses the hardware stack as a call stack ...
110     in  r0, SPH         ; ...  only.
111     st  -y, r0
112
113     st  -y, r1          ; Now store the rest of the registers.  Dont store the ...
114     st  -y, r2          ; ... the Y register here as it is used as the software
115     st  -y, r3          ; stack pointer and will get saved into the TCB.
116     st  -y, r4
117     st  -y, r5
118     st  -y, r6
119     st  -y, r7
120     st  -y, r8
121     st  -y, r9
122     st  -y, r10
123     st  -y, r11
124     st  -y, r12
125     st  -y, r13
126     st  -y, r14
127     st  -y, r15
128     st  -y, r16
129     st  -y, r17
130     st  -y, r18
131     st  -y, r19
132     st  -y, r20
133     st  -y, r21
134     st  -y, r22
135     st  -y, r23
136     st  -y, r24
137     st  -y, r25
138     st  -y, r26
139     st  -y, r27
140     st  -y, r30
141     st  -y, r31
142     lds r0, uxCriticalNesting
143     st  -y, r0                  ; Store the critical nesting counter.
144
145     lds r26, pxCurrentTCB       ; Finally save the software stack pointer (Y ...
146     lds r27, pxCurrentTCB + 1   ; ... register) into the TCB.
147     st  x+, r28
148     st  x+, r29
149
150     ENDM
151
152
153 portRESTORE_CONTEXT MACRO
154     lds r26, pxCurrentTCB
155     lds r27, pxCurrentTCB + 1   ; Restore the software stack pointer from ...
156     ld  r28, x+                 ; the TCB into the software stack pointer (...
157     ld  r29, x+                 ; ... the Y register).
158
159     ld  r0, y+
160     sts uxCriticalNesting, r0
161     ld  r31, y+                 ; Restore the registers down to R0.  The Y
162     ld  r30, y+                 ; register is missing from this list as it
163     ld  r27, y+                 ; has already been restored.
164     ld  r26, y+
165     ld  r25, y+
166     ld  r24, y+
167     ld  r23, y+
168     ld  r22, y+
169     ld  r21, y+
170     ld  r20, y+
171     ld  r19, y+
172     ld  r18, y+
173     ld  r17, y+
174     ld  r16, y+
175     ld  r15, y+
176     ld  r14, y+
177     ld  r13, y+
178     ld  r12, y+
179     ld  r11, y+
180     ld  r10, y+
181     ld  r9, y+
182     ld  r8, y+
183     ld  r7, y+
184     ld  r6, y+
185     ld  r5, y+
186     ld  r4, y+
187     ld  r3, y+
188     ld  r2, y+
189     ld  r1, y+
190
191     ld  r0, y+                  ; The next thing on the stack is the ...
192     out SPH, r0                 ; ... hardware stack pointer.
193     ld  r0, y+
194     out SPL, r0
195
196     ld  r0, y+                  ; Next there is the SREG register.
197     out SREG, r0
198
199     ld  r0, y+                  ; Finally we have finished with r0, so restore r0.
200
201     ENDM
202
203
204
205 ; vPortYield() and vPortYieldFromTick()
206 ; -------------------------------------
207 ;
208 ; Manual and preemptive context switch functions respectively.
209 ; The IAR compiler does not fully support inline assembler,
210 ; so these are implemented here rather than the more usually
211 ; place of within port.c.
212
213 vPortYield:
214     portSAVE_CONTEXT            ; Save the context of the current task.
215     call vTaskSwitchContext     ; Call the scheduler.
216     portRESTORE_CONTEXT         ; Restore the context of whichever task the ...
217     ret                         ; ... scheduler decided should run.
218
219 vPortYieldFromTick:
220     portSAVE_CONTEXT            ; Save the context of the current task.
221     call xTaskIncrementTick     ; Call the timer tick function.
222     tst r16
223     breq SkipTaskSwitch
224     call vTaskSwitchContext     ; Call the scheduler.
225 SkipTaskSwitch:
226     portRESTORE_CONTEXT         ; Restore the context of whichever task the ...
227     ret                         ; ... scheduler decided should run.
228
229 ; vPortStart()
230 ; ------------
231 ;
232 ; Again due to the lack of inline assembler, this is required
233 ; to get access to the portRESTORE_CONTEXT macro.
234
235 vPortStart:
236     portRESTORE_CONTEXT
237     ret
238
239
240 ; Just a filler for unused interrupt vectors.
241 vNoISR:
242     reti
243
244
245     END