pico-sdk(十)-程序架构之其他
多核支持
在其他环境上有过编程经验的开发人员应该对使用线程编程比较熟悉。通常把第二个内核视为应用程序的第二个线程(第二个内核通常称为core1,主应用程序线程运行在1号内核core0上),可以从主线程启动第二个线程并在第二个内核中执行某个函数。
可以在 core0 上调用 multicore_launch_core1(some_function_pointer);
来启动 core1,这样会唤醒处理器内核,使其从低功耗睡眠状态中苏醒,并为其提供入口点 —— 提供的一个具有描述性名称如 void core1_main() { }
的函数。multicore_launch_core1(some_function_pointer);
函数以及其它函数,比如通过内核间信箱FIFO队列(inter-core mailbox FIFOs1)推送和弹出数据等函数,都由 pico_multicore
库提供。
需要注意的是,同时从两个核心调用C库函数通常是不安全的,因为它们一般没有针对Raspberry Pi Pico系列的C/C++ SDK线程安全进行额外的设计。可以在用户代码中使用 SDK 提供的 pico_sync
库(互斥锁)中的mutex_
API 来进行线程间的同步。
SDK版本的
printf
可以在两个核心中安全调用。为方面使用 C++ 进行编程,SDK中的一些接口也提供了线程安全的保障,当包含pico_multicore
时,malloc
、calloc
和free
被确保是线程安全的。
使用 C++
SDK 具有一套 C 风格的 API,能够在 C++ 代码中使用(它们被声明为C链接,使用extern "C"
2 确保不会被编译器处理为 C++ 函数)。
C++ 文件与 C 文件一样可以被整合到 SDK 项目中:在 CMakeLists.txt
文件中的 add_executable()
命令,或者单独使用 target_sources()
3 命令来添加 C++ 代码文件,这样 CMake 就会把这些 C++ 代码文件编译构建到目标中。
为了节省空间,默认情况下禁用了异常处理;可以通过设置 CMake 环境变量PICO_CXX_ENABLE_EXCEPTIONS=1
来启用。
RP2040 和 RP2350 支持情况
RP2350 支持 Cortex-M33 (Arm4) 和 Hazard3 (RISC-V5) 处理器。当前 SDK 同时支持这些处理器以及 RP2040 上的 Cortex-M0 Plus 处理器。
大多数现有代码无需修改即可编译和运行在 RSC-V 的处理器上,唯一需要调整的是 Arm 汇编代码或那些与处理器内部交互的代码。
虽然 GCC 是 SDK 唯一正式支持的编译器,但 SDK 同时支持如下的编译器:
需要将编译器命令的路径添加到系统的环境变量 PATH 中,通过配置
PICO_PLATFORM
和PICO_COMPILER
参数,编译就应该可以正常工作了。
对于 Arm 架构处理器:
- GCC arm-none-eabi (
PICO_COMPILER=pico_arm_gcc
- Arm 的默认值)- 对于 RP2040,需要版本 6 及以上
- 对于 RP2350,由于这是第一个支持 Arm Cortex-M33 的版本,所以需要版本 9 及以上
- LLVM Embedded Toolchain For ARM (
PICO_COMPILER=pico_arm_clang
)- 版本 14 及以上
- Pigweed LLVM。这是 PigWeed 使用的原版构建的 LLVM,带有
llvm-libc
(PICO_COMPILER=pico_arm_clang
)- clang_linux-x86_64 (
sha256 e12ee0db9226f5b4a4400c5eb2c0f757d7056181b651622b5453acb00105fd87
) - clang_win-x86_64 (
sha256 8c41e8b507f4dfede80842f98a716cac209f552064088fa1b7f4c64a1e547534
) - clang_mac-x86_64 (
sha256 1d92f52609d3c1e958fd56f5e9a68ab99b2042ddcc6e90a5eb5009cf7ac4897d
) - clang_mac-aarch64 (
sha256 53184680db7e0043a8fba1556c7644b8f5e6c8cdffa4436a92a8e8adb0f45b8d
)
- clang_linux-x86_64 (
对于 RISC-V 架构处理器:
-
GCC (
PICO_COMPILER=pico_arm_gcc - RISC-V
的默认值),只有非常新的 GCC 版本完全支持 Hazard 3 RISC-V 处理器,推荐以下编译器:- CORE-V GCC 最新版本编译器
- 作为高级选项,自行构建 GCC 14 版本。例如,在 Ubuntu 上参照如下教程编译:
sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpcdev ibmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool
patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev libslirp-dev
sudo mkdir -p /opt/riscv/gcc14-rp2350-no-zcmp
sudo chown -R $(whoami) /opt/riscv/gcc14-rp2350-no-zcmp
git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain
git clone https://github.com/gcc-mirror/gcc gcc-14 -b releases/gcc-14
./configure --prefix=/opt/riscv/gcc14-rp2350-no-zcmp --with
-arch=rv32ima_zicsr_zifencei_zba_zbb_zbs_zbkb_zca_zcb --with-abi=ilp32 --with-multilib
-generator="rv32ima_zicsr_zifencei_zba_zbb_zbs_zbkb_zca_zcb-ilp32--
;rv32imac_zicsr_zifencei_zba_zbb_zbs_zbkb-ilp32--" --with-gcc-src=`pwd`/gcc-14
make -j$(nproc)
Inter-core mailbox FIFOs 是一种在多核处理器中实现核心间通信的技术。FIFO 是 First-In-First-Out(先进先出)的缩写,表示数据按照进入的顺序被处理。具体来说,当一个核心向另一个核心发送数据或消息时,这些数据会暂时存储在一个 FIFO 队列中,直到接收核心准备好处理它们。 ↩︎
在 C++ 中,
extern "C"
是一个链接说明符,用于告诉编译器使用 C 语言的链接规则来处理指定的函数或变量。这在混合使用 C 和 C++ 代码时非常有用,因为 C++ 支持函数重载(即多个同名但参数不同的函数),而 C 语言则不支持这种特性。 ↩︎在 CMake 中,
target_sources()
命令用于向目标(target)添加源文件。这个命令非常灵活,可以用于动态地添加源文件,特别是在构建过程中需要根据条件添加不同文件的情况下非常有用。 ↩︎ARM(Advanced RISC Machine)是一种广泛使用的低功耗、高性能的处理器架构。ARM 架构最初由 Acorn Computers 开发,后来成立了 ARM Holdings 公司专门负责 ARM 架构的开发和授权。ARM 架构的特点使其在移动设备、嵌入式系统、物联网(IoT)设备以及服务器等领域得到广泛应用。。 ↩︎
RISC-V(读作 “RISC-five”)是一个基于精简指令集计算(RISC)原则的开放标准指令集架构(ISA)。RISC-V 的设计目的是为了提供一个免费、开放的指令集,以促进创新和协作。 ↩︎