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