Select one of the symbols to view example projects that use it.
 
Outline
#define _PICO_PLATFORM_H
#include "pico/platform/compiler.h"
#include "pico/platform/sections.h"
#include "pico/platform/panic.h"
#include "hardware/regs/addressmap.h"
#include "hardware/regs/sio.h"
#include "hardware/regs/rvcsr.h"
#define PICO_STACK_SIZE
#define PICO_HEAP_SIZE
#define PICO_NO_RAM_VECTOR_TABLE
#define PICO_RAM_VECTOR_TABLE_SIZE
#define PICO_USE_STACK_GUARDS
tight_loop_contents()
busy_wait_at_least_cycles(uint32_t)
#define PICO_NO_FPGA_CHECK
#define PICO_NO_SIM_CHECK
running_on_fpga()
running_in_sim()
__breakpoint()
get_core_num()
__get_current_exception()
pico_processor_state_is_nonsecure()
#define host_safe_hw_ptr
#define native_safe_hw_ptr
rp2350_chip_version();
rp2040_chip_version()
rp2040_rom_version()
__mul_instruction(int32_t, int32_t)
Files
loading...
SourceVuRaspberry Pi Pico SDK and ExamplesPicoSDKsrc/rp2350/pico_platform/include/pico/platform.h
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause *//* ... */ /** \file platform.h * \defgroup pico_platform pico_platform * * \brief Macros and definitions (and functions when included by non assembly code) for the RP2 family device / architecture * to provide a common abstraction over low level compiler / platform specifics * * This header may be included by assembly code *//* ... */ #ifndef _PICO_PLATFORM_H #define _PICO_PLATFORM_H #ifndef _PICO_H #error pico/platform.h should not be included directly; include pico.h instead #endif #include "pico/platform/compiler.h" #include "pico/platform/sections.h" #include "pico/platform/panic.h" #include "hardware/regs/addressmap.h" #include "hardware/regs/sio.h" 5 includes#ifdef __riscv #include "hardware/regs/rvcsr.h" #endif // PICO_CONFIG: PICO_RP2350A, Whether the current board has an RP2350 in an A (30 GPIO) package, type=bool, default=Usually provided via board header, group=pico_platform // PICO_CONFIG: PICO_STACK_SIZE, Minimum amount of stack space reserved in the linker script for each core. See also PICO_CORE1_STACK_SIZE, min=0x100, default=0x800, advanced=true, group=pico_platform #ifndef PICO_STACK_SIZE #define PICO_STACK_SIZE _u(0x800) #endif // PICO_CONFIG: PICO_HEAP_SIZE, Minimum amount of heap space reserved by the linker script, min=0x100, default=0x800, advanced=true, group=pico_platform #ifndef PICO_HEAP_SIZE #define PICO_HEAP_SIZE _u(0x800) #endif // PICO_CONFIG: PICO_NO_RAM_VECTOR_TABLE, Enable/disable the RAM vector table, type=bool, default=0, advanced=true, group=pico_platform #ifndef PICO_NO_RAM_VECTOR_TABLE #define PICO_NO_RAM_VECTOR_TABLE 0 #endif #ifndef PICO_RAM_VECTOR_TABLE_SIZE #define PICO_RAM_VECTOR_TABLE_SIZE (VTABLE_FIRST_IRQ + NUM_IRQS) #endif // PICO_CONFIG: PICO_USE_STACK_GUARDS, Enable/disable stack guards, type=bool, default=0, advanced=true, group=pico_platform #ifndef PICO_USE_STACK_GUARDS #define PICO_USE_STACK_GUARDS 0 #endif #ifndef __ASSEMBLER__ /*! \brief No-op function for the body of tight loops * \ingroup pico_platform * * No-op function intended to be called by any tight hardware polling loop. Using this ubiquitously * makes it much easier to find tight loops, but also in the future \#ifdef-ed support for lockup * debugging might be added *//* ... */ static __force_inline void tight_loop_contents(void) {} /*! \brief Helper method to busy-wait for at least the given number of cycles * \ingroup pico_platform * * This method is useful for introducing very short delays. * * This method busy-waits in a tight loop for the given number of system clock cycles. The total wait time is only accurate to within 2 cycles, * and this method uses a loop counter rather than a hardware timer, so the method will always take longer than expected if an * interrupt is handled on the calling core during the busy-wait; you can of course disable interrupts to prevent this. * * You can use \ref clock_get_hz(clk_sys) to determine the number of clock cycles per second if you want to convert an actual * time duration to a number of cycles. * * \param minimum_cycles the minimum number of system clock cycles to delay for *//* ... */ static inline void busy_wait_at_least_cycles(uint32_t minimum_cycles) { pico_default_asm_volatile ( #ifdef __riscv // Note the range is halved on RISC-V due to signed comparison (no carry flag) ".option push\n" ".option norvc\n" // force 32 bit addi, so branch prediction guaranteed ".p2align 2\n" "1: \n" "addi %0, %0, -2 \n" "bgez %0, 1b\n" ".option pop"/* ... */ #else "1: subs %0, #3\n" "bcs 1b\n"/* ... */ #endif : "+r" (minimum_cycles) : : "cc", "memory" ); }{ ... } // PICO_CONFIG: PICO_NO_FPGA_CHECK, Remove the FPGA platform check for small code size reduction, type=bool, default=platform dependent, advanced=true, group=pico_runtime #ifndef PICO_NO_FPGA_CHECK #if !PICO_RP2040 #define PICO_NO_FPGA_CHECK 1 #endif/* ... */ #endif // PICO_CONFIG: PICO_NO_SIM_CHECK, Remove the SIM platform check for small code size reduction, type=bool, default=1, advanced=true, group=pico_runtime #ifndef PICO_NO_SIM_CHECK #define PICO_NO_SIM_CHECK 1 #endif #if PICO_NO_FPGA_CHECK static inline bool running_on_fpga(void) {return false;} #else bool running_on_fpga(void); #endif #if PICO_NO_SIM_CHECK static inline bool running_in_sim(void) {return false;} #else bool running_in_sim(void); #endif /*! \brief Execute a breakpoint instruction * \ingroup pico_platform *//* ... */ static __force_inline void __breakpoint(void) { #ifdef __riscv __asm ("ebreak"); #else pico_default_asm_volatile ("bkpt #0" : : : "memory"); #endif }{ ... } /*! \brief Get the current core number * \ingroup pico_platform * * \return The core number the call was made from *//* ... */ __force_inline static uint get_core_num(void) { return (*(uint32_t *) (SIO_BASE + SIO_CPUID_OFFSET)); }{ ... } /*! \brief Get the current exception level on this core * \ingroup pico_platform * * On Cortex-M this is the exception number defined in the architecture * reference, which is equal to VTABLE_FIRST_IRQ + irq num if inside an * interrupt handler. (VTABLE_FIRST_IRQ is defined in platform_defs.h). * * On Hazard3, this function returns VTABLE_FIRST_IRQ + irq num if inside of * an external IRQ handler (or a fault from such a handler), and 0 otherwise, * generally aligning with the Cortex-M values. * * \return the exception number if the CPU is handling an exception, or 0 otherwise *//* ... */ static __force_inline uint __get_current_exception(void) { #ifdef __riscv uint32_t meicontext; pico_default_asm_volatile ( "csrr %0, %1\n" : "=r" (meicontext) : "i" (RVCSR_MEICONTEXT_OFFSET) ); if (meicontext & RVCSR_MEICONTEXT_NOIRQ_BITS) { return 0; }if (meicontext & RVCSR_MEICONTEXT_NOIRQ_BITS) { ... } else { return VTABLE_FIRST_IRQ + ( (meicontext & RVCSR_MEICONTEXT_IRQ_BITS) >> RVCSR_MEICONTEXT_IRQ_LSB ); }else { ... } /* ... */#else uint exception; pico_default_asm_volatile ( "mrs %0, ipsr\n" "uxtb %0, %0\n" : "=l" (exception) ); return exception;/* ... */ #endif }{ ... } /*! \brief Return true if executing in the NonSecure state (Arm-only) * \ingroup pico_platform * * \return True if currently executing in the NonSecure state on an Arm processor *//* ... */ __force_inline static bool pico_processor_state_is_nonsecure(void) { #ifndef __riscv // todo add a define to disable NS checking at all? // IDAU-Exempt addresses return S=1 when tested in the Secure state, // whereas executing a tt in the NonSecure state will always return S=0. uint32_t tt; pico_default_asm_volatile ( "movs %0, #0\n" "tt %0, %0\n" : "=r" (tt) : : "cc" ); return !(tt & (1u << 22));/* ... */ #else // NonSecure is an Arm concept, there is nothing meaningful to return // here. Note it's not possible in general to detect whether you are // executing in U-mode as, for example, M-mode is classically // virtualisable in U-mode. return false;/* ... */ #endif }{ ... } #define host_safe_hw_ptr(x) ((uintptr_t)(x)) #define native_safe_hw_ptr(x) host_safe_hw_ptr(x) /*! \brief Returns the RP2350 chip revision number * \ingroup pico_platform * @return the RP2350 chip revision number (1 for B0/B1, 2 for B2) *//* ... */ uint8_t rp2350_chip_version(void); /*! \brief Returns the RP2040 chip revision number for compatibility * \ingroup pico_platform * @return 2 RP2040 errata fixed in B2 are fixed in RP2350 *//* ... */ static inline uint8_t rp2040_chip_version(void) { return 2; }{ ... } /*! \brief Returns the RP2040 rom version number * \ingroup pico_platform * @return the RP2040 rom version number (1 for RP2040-B0, 2 for RP2040-B1, 3 for RP2040-B2) *//* ... */ static inline uint8_t rp2040_rom_version(void) { GCC_Pragma("GCC diagnostic push") GCC_Pragma("GCC diagnostic ignored \"-Warray-bounds\"") return *(uint8_t*)0x13; GCC_Pragma("GCC diagnostic pop") }{ ... } /*! \brief Multiply two integers using an assembly `MUL` instruction * \ingroup pico_platform * * This multiplies a by b using multiply instruction using the ARM mul instruction regardless of values (the compiler * might otherwise choose to perform shifts/adds), i.e. this is a 1 cycle operation. * * \param a the first operand * \param b the second operand * \return a * b *//* ... */ __force_inline static int32_t __mul_instruction(int32_t a, int32_t b) { #ifdef __riscv __asm ("mul %0, %0, %1" : "+l" (a) : "l" (b) : ); #else pico_default_asm ("muls %0, %1" : "+l" (a) : "l" (b) : "cc"); #endif return a; }{ ... } /*! \brief multiply two integer values using the fastest method possible * \ingroup pico_platform * * Efficiently multiplies value a by possibly constant value b. * * If b is known to be constant and not zero or a power of 2, then a mul instruction is used rather than gcc's default * which is often a slow combination of shifts and adds. If b is a power of 2 then a single shift is of course preferable * and will be used * * \param a the first operand * \param b the second operand * \return a * b *//* ... */ #define __fast_mul(a, b) __builtin_choose_expr(__builtin_constant_p(b) && !__builtin_constant_p(a), \ (__builtin_popcount(b) >= 2 ? __mul_instruction(a,b) : (a)*(b)), \ (a)*(b))... /* ... */ #endif // __ASSEMBLER__ /* ... */ #endif
Details