]> begriffs open source - freertos/blob - portable/GCC/ARM_CM3/portmacro.h
SMP version (#401)
[freertos] / portable / GCC / ARM_CM3 / portmacro.h
1 /*
2  * FreeRTOS Kernel V202110.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  * 1 tab == 4 spaces!
26  */
27
28
29 #ifndef PORTMACRO_H
30     #define PORTMACRO_H
31
32     #ifdef __cplusplus
33         extern "C" {
34     #endif
35
36 /*-----------------------------------------------------------
37  * Port specific definitions.
38  *
39  * The settings in this file configure FreeRTOS correctly for the
40  * given hardware and compiler.
41  *
42  * These settings should not be altered.
43  *-----------------------------------------------------------
44  */
45
46 /* Type definitions. */
47     #define portCHAR          char
48     #define portFLOAT         float
49     #define portDOUBLE        double
50     #define portLONG          long
51     #define portSHORT         short
52     #define portSTACK_TYPE    uint32_t
53     #define portBASE_TYPE     long
54
55     typedef portSTACK_TYPE   StackType_t;
56     typedef long             BaseType_t;
57     typedef unsigned long    UBaseType_t;
58
59     #if ( configUSE_16_BIT_TICKS == 1 )
60         typedef uint16_t     TickType_t;
61         #define portMAX_DELAY              ( TickType_t ) 0xffff
62     #else
63         typedef uint32_t     TickType_t;
64         #define portMAX_DELAY              ( TickType_t ) 0xffffffffUL
65
66 /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
67  * not need to be guarded with a critical section. */
68         #define portTICK_TYPE_IS_ATOMIC    1
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 portDONT_DISCARD      __attribute__( ( used ) )
77 /*-----------------------------------------------------------*/
78
79 /* Scheduler utilities. */
80     #define portYIELD()                                 \
81     {                                                   \
82         /* Set a PendSV to request a context switch. */ \
83         portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \
84                                                         \
85         /* Barriers are normally not required but do ensure the code is completely \
86          * within the specified behaviour for the architecture. */ \
87         __asm volatile ( "dsb" ::: "memory" );                     \
88         __asm volatile ( "isb" );                                  \
89     }
90
91     #define portNVIC_INT_CTRL_REG     ( *( ( volatile uint32_t * ) 0xe000ed04 ) )
92     #define portNVIC_PENDSVSET_BIT    ( 1UL << 28UL )
93     #define portEND_SWITCHING_ISR( xSwitchRequired )    if( xSwitchRequired != pdFALSE ) portYIELD()
94     #define portYIELD_FROM_ISR( x )                     portEND_SWITCHING_ISR( x )
95 /*-----------------------------------------------------------*/
96
97 /* Critical section management. */
98     extern void vPortEnterCritical( void );
99     extern void vPortExitCritical( void );
100     #define portSET_INTERRUPT_MASK_FROM_ISR()         ulPortRaiseBASEPRI()
101     #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x )    vPortSetBASEPRI( x )
102     #define portDISABLE_INTERRUPTS()                  vPortRaiseBASEPRI()
103     #define portENABLE_INTERRUPTS()                   vPortSetBASEPRI( 0 )
104     #define portENTER_CRITICAL()                      vPortEnterCritical()
105     #define portEXIT_CRITICAL()                       vPortExitCritical()
106
107 /*-----------------------------------------------------------*/
108
109 /* Task function macros as described on the FreeRTOS.org WEB site.  These are
110  * not necessary for to use this port.  They are defined so the common demo files
111  * (which build with all the ports) will build. */
112     #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
113     #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
114 /*-----------------------------------------------------------*/
115
116 /* Tickless idle/low power functionality. */
117     #ifndef portSUPPRESS_TICKS_AND_SLEEP
118         extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
119         #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime )    vPortSuppressTicksAndSleep( xExpectedIdleTime )
120     #endif
121 /*-----------------------------------------------------------*/
122
123 /* Architecture specific optimisations. */
124     #ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION
125         #define configUSE_PORT_OPTIMISED_TASK_SELECTION    1
126     #endif
127
128     #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1
129
130 /* Generic helper function. */
131         __attribute__( ( always_inline ) ) static inline uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap )
132         {
133             uint8_t ucReturn;
134
135             __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
136
137             return ucReturn;
138         }
139
140 /* Check the configuration. */
141         #if ( configMAX_PRIORITIES > 32 )
142             #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32.  It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice.
143         #endif
144
145 /* Store/clear the ready priorities in a bit map. */
146         #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities )    ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) )
147         #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities )     ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) )
148
149 /*-----------------------------------------------------------*/
150
151         #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities )    uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) )
152
153     #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */
154
155 /*-----------------------------------------------------------*/
156
157     #ifdef configASSERT
158         void vPortValidateInterruptPriority( void );
159         #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID()    vPortValidateInterruptPriority()
160     #endif
161
162 /* portNOP() is not required by this port. */
163     #define portNOP()
164
165     #define portINLINE              __inline
166
167     #ifndef portFORCE_INLINE
168         #define portFORCE_INLINE    inline __attribute__( ( always_inline ) )
169     #endif
170
171 /*-----------------------------------------------------------*/
172
173     portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
174     {
175         uint32_t ulCurrentInterrupt;
176         BaseType_t xReturn;
177
178         /* Obtain the number of the currently executing interrupt. */
179         __asm volatile ( "mrs %0, ipsr" : "=r" ( ulCurrentInterrupt )::"memory" );
180
181         if( ulCurrentInterrupt == 0 )
182         {
183             xReturn = pdFALSE;
184         }
185         else
186         {
187             xReturn = pdTRUE;
188         }
189
190         return xReturn;
191     }
192
193 /*-----------------------------------------------------------*/
194
195     portFORCE_INLINE static void vPortRaiseBASEPRI( void )
196     {
197         uint32_t ulNewBASEPRI;
198
199         __asm volatile
200         (
201             "   mov %0, %1                                                                                              \n"\
202             "   msr basepri, %0                                                                                 \n"\
203             "   isb                                                                                                             \n"\
204             "   dsb                                                                                                             \n"\
205             : "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
206         );
207     }
208
209 /*-----------------------------------------------------------*/
210
211     portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void )
212     {
213         uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
214
215         __asm volatile
216         (
217             "   mrs %0, basepri                                                                                 \n"\
218             "   mov %1, %2                                                                                              \n"\
219             "   msr basepri, %1                                                                                 \n"\
220             "   isb                                                                                                             \n"\
221             "   dsb                                                                                                             \n"\
222             : "=r" ( ulOriginalBASEPRI ), "=r" ( ulNewBASEPRI ) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
223         );
224
225         /* This return will not be reached but is necessary to prevent compiler
226          * warnings. */
227         return ulOriginalBASEPRI;
228     }
229 /*-----------------------------------------------------------*/
230
231     portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
232     {
233         __asm volatile
234         (
235             "   msr basepri, %0 "::"r" ( ulNewMaskValue ) : "memory"
236         );
237     }
238 /*-----------------------------------------------------------*/
239
240     #define portMEMORY_BARRIER()    __asm volatile ( "" ::: "memory" )
241
242     #ifdef __cplusplus
243         }
244     #endif
245
246 #endif /* PORTMACRO_H */