ESP32-IDF
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
portmacro.h
Go to the documentation of this file.
1 /*
2  FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd.
3  All rights reserved
4 
5  VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
6 
7  ***************************************************************************
8  * *
9  * FreeRTOS provides completely free yet professionally developed, *
10  * robust, strictly quality controlled, supported, and cross *
11  * platform software that has become a de facto standard. *
12  * *
13  * Help yourself get started quickly and support the FreeRTOS *
14  * project by purchasing a FreeRTOS tutorial book, reference *
15  * manual, or both from: http://www.FreeRTOS.org/Documentation *
16  * *
17  * Thank you! *
18  * *
19  ***************************************************************************
20 
21  This file is part of the FreeRTOS distribution.
22 
23  FreeRTOS is free software; you can redistribute it and/or modify it under
24  the terms of the GNU General Public License (version 2) as published by the
25  Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
26 
27  >>! NOTE: The modification to the GPL is included to allow you to !<<
28  >>! distribute a combined work that includes FreeRTOS without being !<<
29  >>! obliged to provide the source code for proprietary components !<<
30  >>! outside of the FreeRTOS kernel. !<<
31 
32  FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
33  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
34  FOR A PARTICULAR PURPOSE. Full license text is available from the following
35  link: http://www.freertos.org/a00114.html
36 
37  1 tab == 4 spaces!
38 
39  ***************************************************************************
40  * *
41  * Having a problem? Start by reading the FAQ "My application does *
42  * not run, what could be wrong?" *
43  * *
44  * http://www.FreeRTOS.org/FAQHelp.html *
45  * *
46  ***************************************************************************
47 
48  http://www.FreeRTOS.org - Documentation, books, training, latest versions,
49  license and Real Time Engineers Ltd. contact details.
50 
51  http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
52  including FreeRTOS+Trace - an indispensable productivity tool, a DOS
53  compatible FAT file system, and our tiny thread aware UDP/IP stack.
54 
55  http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
56  Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
57  licenses offer ticketed support, indemnification and middleware.
58 
59  http://www.SafeRTOS.com - High Integrity Systems also provide a safety
60  engineered and independently SIL3 certified version for use in safety and
61  mission critical applications that require provable dependability.
62 
63  1 tab == 4 spaces!
64 */
65 
66 #ifndef PORTMACRO_H
67 #define PORTMACRO_H
68 
69 #ifdef __cplusplus
70 extern "C" {
71 #endif
72 
73 #ifndef __ASSEMBLER__
74 
75 #include <stdint.h>
76 
77 #include <xtensa/tie/xt_core.h>
78 #include <xtensa/hal.h>
79 #include <xtensa/config/core.h>
80 #include <xtensa/config/system.h> /* required for XSHAL_CLIB */
81 #include <xtensa/xtruntime.h>
82 
83 //#include "xtensa_context.h"
84 
85 /*-----------------------------------------------------------
86  * Port specific definitions.
87  *
88  * The settings in this file configure FreeRTOS correctly for the
89  * given hardware and compiler.
90  *
91  * These settings should not be altered.
92  *-----------------------------------------------------------
93  */
94 
95 /* Type definitions. */
96 
97 #define portCHAR int8_t
98 #define portFLOAT float
99 #define portDOUBLE double
100 #define portLONG int32_t
101 #define portSHORT int16_t
102 #define portSTACK_TYPE uint8_t
103 #define portBASE_TYPE int
104 
107 typedef unsigned portBASE_TYPE UBaseType_t;
108 
109 #if( configUSE_16_BIT_TICKS == 1 )
110  typedef uint16_t TickType_t;
111  #define portMAX_DELAY ( TickType_t ) 0xffff
112 #else
114  #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
115 #endif
116 /*-----------------------------------------------------------*/
117 
118 // portbenchmark
119 #include "portbenchmark.h"
120 
121 #include "sdkconfig.h"
122 
123 #define portFIRST_TASK_HOOK CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG
124 
125 
126 typedef struct {
127  volatile uint32_t mux;
128 #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
129  const char *lastLockedFn;
130  int lastLockedLine;
131 #endif
132 } portMUX_TYPE;
133 
134  /*
135  * Kernel mux values can be:
136  * 0 - Uninitialized
137  * (0-portNUM_PROCESSORS)|(recCnt<<8)|0xB33F0000 - taken by core (val), recurse count is (recCnt)
138  * 0xB33FFFFF - free
139  *
140  * The magic number in the top 16 bits is there so we can detect uninitialized and corrupted muxes.
141  */
142 
143 #define portMUX_MAGIC_VAL 0xB33F0000
144 #define portMUX_FREE_VAL 0xB33FFFFF
145 #define portMUX_MAGIC_MASK 0xFFFF0000
146 #define portMUX_MAGIC_SHIFT 16
147 #define portMUX_CNT_MASK 0x0000FF00
148 #define portMUX_CNT_SHIFT 8
149 #define portMUX_VAL_MASK 0x000000FF
150 #define portMUX_VAL_SHIFT 0
151 
152 //Keep this in sync with the portMUX_TYPE struct definition please.
153 #ifndef CONFIG_FREERTOS_PORTMUX_DEBUG
154 #define portMUX_INITIALIZER_UNLOCKED { \
155  .mux = portMUX_MAGIC_VAL|portMUX_FREE_VAL \
156  }
157 #else
158 #define portMUX_INITIALIZER_UNLOCKED { \
159  .mux = portMUX_MAGIC_VAL|portMUX_FREE_VAL, \
160  .lastLockedFn = "(never locked)", \
161  .lastLockedLine = -1 \
162  }
163 #endif
164 
165 /* Critical section management. NW-TODO: replace XTOS_SET_INTLEVEL with more efficient version, if any? */
166 // These cannot be nested. They should be used with a lot of care and cannot be called from interrupt level.
167 #define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0)
168 #define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0)
169 
170 #define portASSERT_IF_IN_ISR() vPortAssertIfInISR()
171 void vPortAssertIfInISR();
172 
173 #define portCRITICAL_NESTING_IN_TCB 1
174 
175 /*
176 Modifications to portENTER_CRITICAL:
177 
178 The original portENTER_CRITICAL only disabled the ISRs. This is enough for single-CPU operation: by
179 disabling the interrupts, there is no task switch so no other tasks can meddle in the data, and because
180 interrupts are disabled, ISRs can't corrupt data structures either.
181 
182 For multiprocessing, things get a bit more hairy. First of all, disabling the interrupts doesn't stop
183 the tasks or ISRs on the other processors meddling with our CPU. For tasks, this is solved by adding
184 a spinlock to the portENTER_CRITICAL macro. A task running on the other CPU accessing the same data will
185 spinlock in the portENTER_CRITICAL code until the first CPU is done.
186 
187 For ISRs, we now also need muxes: while portENTER_CRITICAL disabling interrupts will stop ISRs on the same
188 CPU from meddling with the data, it does not stop interrupts on the other cores from interfering with the
189 data. For this, we also use a spinlock in the routines called by the ISR, but these spinlocks
190 do not disable the interrupts (because they already are).
191 
192 This all assumes that interrupts are either entirely disabled or enabled. Interrupr priority levels
193 will break this scheme.
194 */
196 #ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
197 void vPortCPUAcquireMutex(portMUX_TYPE *mux, const char *function, int line);
198 portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux, const char *function, int line);
199 void vTaskEnterCritical( portMUX_TYPE *mux, const char *function, int line );
200 void vTaskExitCritical( portMUX_TYPE *mux, const char *function, int line );
201 #define portENTER_CRITICAL(mux) vTaskEnterCritical(mux, __FUNCTION__, __LINE__)
202 #define portEXIT_CRITICAL(mux) vTaskExitCritical(mux, __FUNCTION__, __LINE__)
203 #define portENTER_CRITICAL_ISR(mux) vPortCPUAcquireMutex(mux, __FUNCTION__, __LINE__)
204 #define portEXIT_CRITICAL_ISR(mux) vPortCPUReleaseMutex(mux, __FUNCTION__, __LINE__)
205 #else
206 void vTaskExitCritical( portMUX_TYPE *mux );
207 void vTaskEnterCritical( portMUX_TYPE *mux );
210 #define portENTER_CRITICAL(mux) vTaskEnterCritical(mux)
211 #define portEXIT_CRITICAL(mux) vTaskExitCritical(mux)
212 #define portENTER_CRITICAL_ISR(mux) vPortCPUAcquireMutex(mux)
213 #define portEXIT_CRITICAL_ISR(mux) vPortCPUReleaseMutex(mux)
214 #endif
215 
216 
217 // Cleaner and preferred solution allows nested interrupts disabling and restoring via local registers or stack.
218 // They can be called from interrupts too.
219 //NOT SMP-COMPATIBLE! Use only if all you want is to disable the interrupts locally!
220 static inline unsigned portENTER_CRITICAL_NESTED() { unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); return state; }
221 #define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0)
222 
223 // These FreeRTOS versions are similar to the nested versions above
224 #define portSET_INTERRUPT_MASK_FROM_ISR() portENTER_CRITICAL_NESTED()
225 #define portCLEAR_INTERRUPT_MASK_FROM_ISR(state) portEXIT_CRITICAL_NESTED(state)
226 
227 
228 /*-----------------------------------------------------------*/
229 
230 /* Architecture specifics. */
231 #define portSTACK_GROWTH ( -1 )
232 #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
233 #define portBYTE_ALIGNMENT 4
234 #define portNOP() XT_NOP()
235 /*-----------------------------------------------------------*/
236 
237 /* Fine resolution time */
238 #define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount()
239 
240 /* Kernel utilities. */
241 void vPortYield( void );
242 void _frxt_setup_switch( void );
243 #define portYIELD() vPortYield()
244 #define portYIELD_FROM_ISR() _frxt_setup_switch()
245 /*-----------------------------------------------------------*/
246 
247 /* Task function macros as described on the FreeRTOS.org WEB site. */
248 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
249 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
250 
251 // When coprocessors are defined, we to maintain a pointer to coprocessors area.
252 // We currently use a hack: redefine field xMPU_SETTINGS in TCB block as a structure that can hold:
253 // MPU wrappers, coprocessor area pointer, trace code structure, and more if needed.
254 // The field is normally used for memory protection. FreeRTOS should create another general purpose field.
255 typedef struct {
256  #if XCHAL_CP_NUM > 0
257  volatile StackType_t* coproc_area; // Pointer to coprocessor save area; MUST BE FIRST
258  #endif
259 
260  #if portUSING_MPU_WRAPPERS
261  // Define here mpu_settings, which is port dependent
262  int mpu_setting; // Just a dummy example here; MPU not ported to Xtensa yet
263  #endif
264 
265  #if configUSE_TRACE_FACILITY_2
266  struct {
267  // Cf. porttraceStamp()
268  int taskstamp; /* Stamp from inside task to see where we are */
269  int taskstampcount; /* A counter usually incremented when we restart the task's loop */
270  } porttrace;
271  #endif
272 } xMPU_SETTINGS;
273 
274 // Main hack to use MPU_wrappers even when no MPU is defined (warning: mpu_setting should not be accessed; otherwise move this above xMPU_SETTINGS)
275 #if (XCHAL_CP_NUM > 0 || configUSE_TRACE_FACILITY_2) && !portUSING_MPU_WRAPPERS // If MPU wrappers not used, we still need to allocate coproc area
276  #undef portUSING_MPU_WRAPPERS
277  #define portUSING_MPU_WRAPPERS 1 // Enable it to allocate coproc area
278  #define MPU_WRAPPERS_H // Override mpu_wrapper.h to disable unwanted code
279  #define PRIVILEGED_FUNCTION
280  #define PRIVILEGED_DATA
281 #endif
282 
283 // porttrace
284 #if configUSE_TRACE_FACILITY_2
285 #include "porttrace.h"
286 #endif
287 
288 // configASSERT_2 if requested
289 #if configASSERT_2
290 #include <stdio.h>
291 void exit(int);
292 #define configASSERT( x ) if (!(x)) { porttracePrint(-1); printf("\nAssertion failed in %s:%d\n", __FILE__, __LINE__); exit(-1); }
293 #endif
294 
295 #endif // __ASSEMBLER__
296 
297 #ifdef __cplusplus
298 }
299 #endif
300 
301 #endif /* PORTMACRO_H */
302 
#define XTOS_SET_INTLEVEL(intlevel)
Definition: xtruntime.h:76
volatile uint32_t mux
Definition: portmacro.h:127
#define portSTACK_TYPE
Definition: portmacro.h:102
portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux)
Definition: port.c:349
Definition: portmacro.h:255
__uint16_t uint16_t
Definition: stdint.h:33
void vPortYield(void)
__uint32_t uint32_t
Definition: stdint.h:45
#define XCHAL_EXCM_LEVEL
Definition: core-isa.h:351
uint32_t TickType_t
Definition: portmacro.h:113
void vPortAssertIfInISR()
Definition: port.c:251
xmp_atomic_int_t state
Definition: xmp-library.h:367
void vTaskEnterCritical(portMUX_TYPE *mux)
Definition: portmacro.h:126
void vPortCPUAcquireMutex(portMUX_TYPE *mux)
Definition: port.c:297
void vTaskExitCritical(portMUX_TYPE *mux)
void vPortCPUInitializeMutex(portMUX_TYPE *mux)
Definition: port.c:281
unsigned portBASE_TYPE UBaseType_t
Definition: portmacro.h:107
#define portBASE_TYPE
Definition: portmacro.h:103
#define portbenchmarkINTERRUPT_DISABLE()
Definition: portbenchmark.h:39
void _frxt_setup_switch(void)
portBASE_TYPE BaseType_t
Definition: portmacro.h:106
portSTACK_TYPE StackType_t
Definition: portmacro.h:105