1 /*
2  * FreeRTOS Kernel V11.1.0
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 
30 #ifndef PORTMACRO_H
31 #define PORTMACRO_H
32 
33 /* *INDENT-OFF* */
34 #ifdef __cplusplus
35     extern "C" {
36 #endif
37 /* *INDENT-ON* */
38 
39 /*-----------------------------------------------------------
40  * Port specific definitions.
41  *
42  * The settings in this file configure FreeRTOS correctly for the
43  * given hardware and compiler.
44  *
45  * These settings should not be altered.
46  *-----------------------------------------------------------
47  */
48 
49 /* Type definitions. */
50 #define portCHAR          char
51 #define portFLOAT         float
52 #define portDOUBLE        double
53 #define portLONG          long
54 #define portSHORT         short
55 #define portSTACK_TYPE    uint8_t
56 #define portBASE_TYPE     char
57 
58 typedef portSTACK_TYPE   StackType_t;
59 typedef signed char      BaseType_t;
60 typedef unsigned char    UBaseType_t;
61 
62 
63 #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
64     typedef uint16_t     TickType_t;
65     #define portMAX_DELAY    ( TickType_t ) 0xffff
66 #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
67     typedef uint32_t     TickType_t;
68     #define portMAX_DELAY    ( TickType_t ) ( 0xFFFFFFFFUL )
69 #else
70     #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
71 #endif
72 /*-----------------------------------------------------------*/
73 
74 /* Hardware specifics. */
75 #define portBYTE_ALIGNMENT    1
76 #define portSTACK_GROWTH      ( -1 )
77 #define portTICK_PERIOD_MS    ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
78 #define portYIELD()    __asm( "swi" );
79 /*-----------------------------------------------------------*/
80 
81 /* Critical section handling. */
82 #define portENABLE_INTERRUPTS()     __asm( "cli" )
83 #define portDISABLE_INTERRUPTS()    __asm( "sei" )
84 
85 /*
86  * Disable interrupts before incrementing the count of critical section nesting.
87  * The nesting count is maintained so we know when interrupts should be
88  * re-enabled.  Once interrupts are disabled the nesting count can be accessed
89  * directly.  Each task maintains its own nesting count.
90  */
91 #define portENTER_CRITICAL()                           \
92     {                                                  \
93         extern volatile UBaseType_t uxCriticalNesting; \
94                                                        \
95         portDISABLE_INTERRUPTS();                      \
96         uxCriticalNesting++;                           \
97     }
98 
99 /*
100  * Interrupts are disabled so we can access the nesting count directly.  If the
101  * nesting is found to be 0 (no nesting) then we are leaving the critical
102  * section and interrupts can be re-enabled.
103  */
104 #define  portEXIT_CRITICAL()                           \
105     {                                                  \
106         extern volatile UBaseType_t uxCriticalNesting; \
107                                                        \
108         uxCriticalNesting--;                           \
109         if( uxCriticalNesting == 0 )                   \
110         {                                              \
111             portENABLE_INTERRUPTS();                   \
112         }                                              \
113     }
114 /*-----------------------------------------------------------*/
115 
116 /* Task utilities. */
117 
118 /*
119  * These macros are very simple as the processor automatically saves and
120  * restores its registers as interrupts are entered and exited.  In
121  * addition to the (automatically stacked) registers we also stack the
122  * critical nesting count.  Each task maintains its own critical nesting
123  * count as it is legitimate for a task to yield from within a critical
124  * section.  If the banked memory model is being used then the PPAGE
125  * register is also stored as part of the tasks context.
126  */
127 
128 #ifdef BANKED_MODEL
129 
130 /*
131  * Load the stack pointer for the task, then pull the critical nesting
132  * count and PPAGE register from the stack.  The remains of the
133  * context are restored by the RTI instruction.
134  */
135     #define portRESTORE_CONTEXT() \
136     {                             \
137         __asm( "                                \n\
138         .globl pxCurrentTCB         ; void *            \n\
139         .globl uxCriticalNesting        ; char              \n\
140                                             \n\
141         ldx  pxCurrentTCB                           \n\
142         lds  0,x                ; Stack             \n\
143                                             \n\
144         movb 1,sp+,uxCriticalNesting                        \n\
145         movb 1,sp+,0x30             ; PPAGE             \n\
146         " );                      \
147     }
148 
149 /*
150  * By the time this macro is called the processor has already stacked the
151  * registers.  Simply stack the nesting count and PPAGE value, then save
152  * the task stack pointer.
153  */
154     #define portSAVE_CONTEXT() \
155     {                          \
156         __asm( "                                \n\
157         .globl pxCurrentTCB         ; void *            \n\
158         .globl uxCriticalNesting        ; char              \n\
159                                             \n\
160         movb 0x30, 1,-sp            ; PPAGE             \n\
161         movb uxCriticalNesting, 1,-sp                       \n\
162                                             \n\
163         ldx  pxCurrentTCB                           \n\
164         sts  0,x                ; Stack             \n\
165         " );                   \
166     }
167 #else /* ifdef BANKED_MODEL */
168 
169 /*
170  * These macros are as per the BANKED versions above, but without saving
171  * and restoring the PPAGE register.
172  */
173 
174     #define portRESTORE_CONTEXT() \
175     {                             \
176         __asm( "                                \n\
177         .globl pxCurrentTCB         ; void *            \n\
178         .globl uxCriticalNesting        ; char              \n\
179                                             \n\
180         ldx  pxCurrentTCB                           \n\
181         lds  0,x                ; Stack             \n\
182                                             \n\
183         movb 1,sp+,uxCriticalNesting                        \n\
184         " );                      \
185     }
186 
187     #define portSAVE_CONTEXT() \
188     {                          \
189         __asm( "                                \n\
190         .globl pxCurrentTCB         ; void *            \n\
191         .globl uxCriticalNesting        ; char              \n\
192                                             \n\
193         movb uxCriticalNesting, 1,-sp                       \n\
194                                             \n\
195         ldx  pxCurrentTCB                           \n\
196         sts  0,x                ; Stack             \n\
197         " );                   \
198     }
199 #endif /* ifdef BANKED_MODEL */
200 
201 /*
202  * Utility macros to save/restore correct software registers for GCC. This is
203  * useful when GCC does not generate appropriate ISR head/tail code.
204  */
205 #define portISR_HEAD() \
206     {                  \
207         __asm( "                                 \n\
208         movw _.frame, 2,-sp                         \n\
209         movw _.tmp, 2,-sp                           \n\
210         movw _.z, 2,-sp                             \n\
211         movw _.xy, 2,-sp                            \n\
212         ;movw _.d2, 2,-sp                           \n\
213         ;movw _.d1, 2,-sp                           \n\
214         " );           \
215     }
216 
217 #define portISR_TAIL() \
218     {                  \
219         __asm( "                                 \n\
220         movw 2,sp+, _.xy                            \n\
221         movw 2,sp+, _.z                             \n\
222         movw 2,sp+, _.tmp                           \n\
223         movw 2,sp+, _.frame                         \n\
224         ;movw 2,sp+, _.d1                           \n\
225         ;movw 2,sp+, _.d2                           \n\
226         rti                                 \n\
227         " );           \
228     }
229 
230 /*
231  * Utility macro to call macros above in correct order in order to perform a
232  * task switch from within a standard ISR.  This macro can only be used if
233  * the ISR does not use any local (stack) variables.  If the ISR uses stack
234  * variables portYIELD() should be used in it's place.
235  */
236 
237 #define portTASK_SWITCH_FROM_ISR() \
238     portSAVE_CONTEXT();            \
239     vTaskSwitchContext();          \
240     portRESTORE_CONTEXT();
241 
242 
243 /* Task function macros as described on the FreeRTOS.org WEB site. */
244 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
245 #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
246 
247 /* *INDENT-OFF* */
248 #ifdef __cplusplus
249     }
250 #endif
251 /* *INDENT-ON* */
252 
253 #endif /* PORTMACRO_H */
254