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