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