Welcome to mirror list, hosted at ThFree Co, Russian Federation.

portmacro.s90 « AVR_Mega0 « IAR « portable - github.com/FreeRTOS/FreeRTOS-Kernel.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 7ec1aee5025aa6315a51d740a5d8ede17ca46077 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
;/*
; * FreeRTOS Kernel <DEVELOPMENT BRANCH>
; * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
; *
; * SPDX-License-Identifier: MIT
; *
; * Permission is hereby granted, free of charge, to any person obtaining a copy of
; * this software and associated documentation files (the "Software"), to deal in
; * the Software without restriction, including without limitation the rights to
; * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
; * the Software, and to permit persons to whom the Software is furnished to do so,
; * subject to the following conditions:
; *
; * The above copyright notice and this permission notice shall be included in all
; * copies or substantial portions of the Software.
; *
; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
; * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
; * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
; * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
; * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
; *
; * https://www.FreeRTOS.org
; * https://github.com/FreeRTOS
; *
; */

#include "porthardware.h"

; Declare all extern symbols here - including any ISRs that are referenced in
; the vector table.

; ISR functions
; -------------
EXTERN TICK_INT

; Functions used by scheduler
; ---------------------------
EXTERN vTaskSwitchContext
EXTERN pxCurrentTCB
EXTERN xTaskIncrementTick
EXTERN uxCriticalNesting

; Functions implemented in this file
; ----------------------------------
PUBLIC vPortYield
PUBLIC vPortYieldFromTick
PUBLIC vPortYieldFromISR
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 TICK_INT_vect                   ; Vector address
        jmp TICK_INT                    ; ISR

    RSEG CODE

CLR_INT MACRO  FLAG_REG, FLAG_MASK
    st -y, r16
    ldi r16, FLAG_MASK
    sts FLAG_REG, r16
    ld r16, y+
        
    ENDM

; 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(), vPortYieldFromTick() and vPortYieldFromISR()
; -------------------------------------
;
; 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:
    CLR_INT INT_FLAGS, INT_MASK     ; Clear tick interrupt flag
 
    portSAVE_CONTEXT                ; Save the context of the current task.
    call xTaskIncrementTick         ; Call the timer tick function.
    tst r16
    breq SkipTaskSwitch
    call vTaskSwitchContext         ; Call the scheduler.

SkipTaskSwitch:
    portRESTORE_CONTEXT             ; Restore the context of whichever task the ...
    reti                            ; ... scheduler decided should run.

vPortYieldFromISR:
    portSAVE_CONTEXT                ; Save the context of the current task.
    call vTaskSwitchContext         ; Call the scheduler.
    portRESTORE_CONTEXT             ; Restore the context of whichever task the ...
    reti                            ; ... 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