xref: /Kernel-v11.0.1/portable/GCC/ARM7_LPC2000/portmacro.h (revision 65c72e485a63577f5d15096d5a53c9dca8822d65)
1 /*
2  * FreeRTOS Kernel V11.0.1
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 #ifndef PORTMACRO_H
30 #define PORTMACRO_H
31 
32 /* *INDENT-OFF* */
33 #ifdef __cplusplus
34     extern "C" {
35 #endif
36 /* *INDENT-ON* */
37 
38 /*-----------------------------------------------------------
39  * Port specific definitions.
40  *
41  * The settings in this file configure FreeRTOS correctly for the
42  * given hardware and compiler.
43  *
44  * These settings should not be altered.
45  *-----------------------------------------------------------
46  */
47 
48 /* Type definitions. */
49 #define portCHAR          char
50 #define portFLOAT         float
51 #define portDOUBLE        double
52 #define portLONG          long
53 #define portSHORT         short
54 #define portSTACK_TYPE    uint32_t
55 #define portBASE_TYPE     portLONG
56 
57 typedef portSTACK_TYPE   StackType_t;
58 typedef long             BaseType_t;
59 typedef unsigned long    UBaseType_t;
60 
61 #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
62     typedef uint16_t     TickType_t;
63     #define portMAX_DELAY    ( TickType_t ) 0xffff
64 #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
65     typedef uint32_t     TickType_t;
66     #define portMAX_DELAY    ( TickType_t ) ( 0xFFFFFFFFUL )
67 #else
68     #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
69 #endif
70 /*-----------------------------------------------------------*/
71 
72 /* Architecture specifics. */
73 #define portSTACK_GROWTH      ( -1 )
74 #define portTICK_PERIOD_MS    ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
75 #define portBYTE_ALIGNMENT    8
76 #define portNOP()    __asm volatile ( "NOP" );
77 /*-----------------------------------------------------------*/
78 
79 
80 /* Scheduler utilities. */
81 
82 /*
83  * portRESTORE_CONTEXT, portRESTORE_CONTEXT, portENTER_SWITCHING_ISR
84  * and portEXIT_SWITCHING_ISR can only be called from ARM mode, but
85  * are included here for efficiency.  An attempt to call one from
86  * THUMB mode code will result in a compile time error.
87  */
88 
89 #define portRESTORE_CONTEXT()                                                 \
90     {                                                                         \
91         extern volatile void * volatile pxCurrentTCB;                         \
92         extern volatile uint32_t ulCriticalNesting;                           \
93                                                                               \
94         /* Set the LR to the task stack. */                                   \
95         __asm volatile (                                                      \
96             "LDR        R0, =pxCurrentTCB                               \n\t" \
97             "LDR        R0, [R0]                                        \n\t" \
98             "LDR        LR, [R0]                                        \n\t" \
99                                                                               \
100             /* The critical nesting depth is the first item on the stack. */  \
101             /* Load it into the ulCriticalNesting variable. */                \
102             "LDR        R0, =ulCriticalNesting                          \n\t" \
103             "LDMFD  LR!, {R1}                                           \n\t" \
104             "STR        R1, [R0]                                        \n\t" \
105                                                                               \
106             /* Get the SPSR from the stack. */                                \
107             "LDMFD  LR!, {R0}                                           \n\t" \
108             "MSR        SPSR, R0                                        \n\t" \
109                                                                               \
110             /* Restore all system mode registers for the task. */             \
111             "LDMFD  LR, {R0-R14}^                                       \n\t" \
112             "NOP                                                        \n\t" \
113                                                                               \
114             /* Restore the return address. */                                 \
115             "LDR        LR, [LR, #+60]                                  \n\t" \
116                                                                               \
117             /* And return - correcting the offset in the LR to obtain the */  \
118             /* correct address. */                                            \
119             "SUBS   PC, LR, #4                                          \n\t" \
120             );                                                                \
121         ( void ) ulCriticalNesting;                                           \
122         ( void ) pxCurrentTCB;                                                \
123     }
124 /*-----------------------------------------------------------*/
125 
126 #define portSAVE_CONTEXT()                                                    \
127     {                                                                         \
128         extern volatile void * volatile pxCurrentTCB;                         \
129         extern volatile uint32_t ulCriticalNesting;                           \
130                                                                               \
131         /* Push R0 as we are going to use the register. */                    \
132         __asm volatile (                                                      \
133             "STMDB  SP!, {R0}                                           \n\t" \
134                                                                               \
135             /* Set R0 to point to the task stack pointer. */                  \
136             "STMDB  SP,{SP}^                                            \n\t" \
137             "NOP                                                        \n\t" \
138             "SUB    SP, SP, #4                                          \n\t" \
139             "LDMIA  SP!,{R0}                                            \n\t" \
140                                                                               \
141             /* Push the return address onto the stack. */                     \
142             "STMDB  R0!, {LR}                                           \n\t" \
143                                                                               \
144             /* Now we have saved LR we can use it instead of R0. */           \
145             "MOV    LR, R0                                              \n\t" \
146                                                                               \
147             /* Pop R0 so we can save it onto the system mode stack. */        \
148             "LDMIA  SP!, {R0}                                           \n\t" \
149                                                                               \
150             /* Push all the system mode registers onto the task stack. */     \
151             "STMDB  LR,{R0-LR}^                                         \n\t" \
152             "NOP                                                        \n\t" \
153             "SUB    LR, LR, #60                                         \n\t" \
154                                                                               \
155             /* Push the SPSR onto the task stack. */                          \
156             "MRS    R0, SPSR                                            \n\t" \
157             "STMDB  LR!, {R0}                                           \n\t" \
158                                                                               \
159             "LDR    R0, =ulCriticalNesting                              \n\t" \
160             "LDR    R0, [R0]                                            \n\t" \
161             "STMDB  LR!, {R0}                                           \n\t" \
162                                                                               \
163             /* Store the new top of stack for the task. */                    \
164             "LDR    R0, =pxCurrentTCB                                   \n\t" \
165             "LDR    R0, [R0]                                            \n\t" \
166             "STR    LR, [R0]                                            \n\t" \
167             );                                                                \
168         ( void ) ulCriticalNesting;                                           \
169         ( void ) pxCurrentTCB;                                                \
170     }
171 
172 extern void vTaskSwitchContext( void );
173 #define portYIELD_FROM_ISR()    vTaskSwitchContext()
174 #define portYIELD()             __asm volatile ( "SWI 0" )
175 /*-----------------------------------------------------------*/
176 
177 
178 /* Critical section management. */
179 
180 /*
181  * The interrupt management utilities can only be called from ARM mode.  When
182  * THUMB_INTERWORK is defined the utilities are defined as functions in
183  * portISR.c to ensure a switch to ARM mode.  When THUMB_INTERWORK is not
184  * defined then the utilities are defined as macros here - as per other ports.
185  */
186 
187 #ifdef THUMB_INTERWORK
188 
189     extern void vPortDisableInterruptsFromThumb( void ) __attribute__( ( naked ) );
190     extern void vPortEnableInterruptsFromThumb( void ) __attribute__( ( naked ) );
191 
192     #define portDISABLE_INTERRUPTS()    vPortDisableInterruptsFromThumb()
193     #define portENABLE_INTERRUPTS()     vPortEnableInterruptsFromThumb()
194 
195 #else
196 
197     #define portDISABLE_INTERRUPTS()                                       \
198     __asm volatile (                                                       \
199         "STMDB  SP!, {R0}       \n\t"   /* Push R0.                     */ \
200         "MRS    R0, CPSR        \n\t"   /* Get CPSR.                    */ \
201         "ORR    R0, R0, #0xC0   \n\t"   /* Disable IRQ, FIQ.            */ \
202         "MSR    CPSR, R0        \n\t"   /* Write back modified value.   */ \
203         "LDMIA  SP!, {R0}           " ) /* Pop R0.                      */
204 
205     #define portENABLE_INTERRUPTS()                                        \
206     __asm volatile (                                                       \
207         "STMDB  SP!, {R0}       \n\t"   /* Push R0.                     */ \
208         "MRS    R0, CPSR        \n\t"   /* Get CPSR.                    */ \
209         "BIC    R0, R0, #0xC0   \n\t"   /* Enable IRQ, FIQ.             */ \
210         "MSR    CPSR, R0        \n\t"   /* Write back modified value.   */ \
211         "LDMIA  SP!, {R0}           " ) /* Pop R0.                      */
212 
213 #endif /* THUMB_INTERWORK */
214 
215 extern void vPortEnterCritical( void );
216 extern void vPortExitCritical( void );
217 
218 #define portENTER_CRITICAL()    vPortEnterCritical();
219 #define portEXIT_CRITICAL()     vPortExitCritical();
220 /*-----------------------------------------------------------*/
221 
222 /* Task function macros as described on the FreeRTOS.org WEB site. */
223 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
224 #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
225 
226 /* *INDENT-OFF* */
227 #ifdef __cplusplus
228     }
229 #endif
230 /* *INDENT-ON* */
231 
232 #endif /* PORTMACRO_H */
233