如何在 Rust 中使用 RP2040 上的两个内核?

问题描述 投票:0回答:2

我读到RP2040有两个核心。如何在 Rust 程序中使用第二个核心?

我不需要一路通用多线程,我只想有两个线程,每个线程拥有一个核心,并且它们可以相互通信。

Rust 书中关于无畏并发的部分(由 Jeremy 建议)没有多大帮助。

thread::spawn(|| {
    let mut x = 0;
    x = x + 1;
});

编译失败

error[E0433]: failed to resolve: use of undeclared crate or module `thread`
   --> src/main.rs:108:5
    |
108 |     thread::spawn(|| {
    |     ^^^^^^ use of undeclared crate or module `thread`

这并不奇怪,因为

thread
std
的一部分,并且 RP2040 是一个
#![no_std]
环境。

在 C API 中有一个函数

multicore_launch_core1
。是否有等效的 Rust API?

multithreading rust embedded rp2040
2个回答
6
投票

正如您已经发现的,Rust

std
库的多线程设施依赖于操作系统内核的设施,而这些设施在裸机嵌入式环境中工作时不可用。

让第二个核心执行代码的实际过程有点复杂和低级。 RP2040 数据表中标题为“2.8.2. 在处理器核心 1 上启动代码”的部分对此进行了描述。

总而言之,第二个内核启动后,它会进入睡眠状态,等待通过 SIO FIFO(两个内核之间的通信通道)发送指令。发送的指令提供了一个中断向量表、一个堆栈指针和一个内核开始执行的入口点。

幸运的是,rp2040_hal板条箱为此提供了更高级别的抽象。下面的示例来自此板条箱的

multicore
模块:

use rp2040_hal::{pac, gpio::Pins, sio::Sio, multicore::{Multicore, Stack}};

static mut CORE1_STACK: Stack<4096> = Stack::new();

fn core1_task() -> ! {
    loop {}
}

fn main() -> ! {
    let mut pac = pac::Peripherals::take().unwrap();
    let mut sio = Sio::new(pac.SIO);
    // Other init code above this line
    let mut mc = Multicore::new(&mut pac.PSM, &mut pac.PPB, &mut sio.fifo);
    let cores = mc.cores();
    let core1 = &mut cores[1];
    let _test = core1.spawn(unsafe { &mut CORE1_STACK.mem }, core1_task);
    // The rest of your application below this line
}

在上面的示例中,

core1_task
函数中的代码将在第二个核心上执行,而第一个核心继续执行
main
函数。板条箱的示例目录中有更完整的示例。

免责声明:我自己没有使用过这个板条箱或微控制器 - 所有信息都是从在线文档中找到的。


0
投票

现在官方项目中有一个小型的多核示例: https://github.com/embassy-rs/embassy/blob/main/examples/rp/src/bin/multicore.rs

© www.soinside.com 2019 - 2024. All rights reserved.