第十六周工作总结
本周完成的功能
本周成功实现了JH7110双核系统之间的双向核间通信:
- embassy_preempt → StarryOS:hart0定时发送IPI到hart1,StarryOS成功接收并记录
- StarryOS → embassy_preempt:在StarryOS中执行
echo 1 > /dev/ipi可触发hart0中断
第一部分:实现Hart间通信基础机制
本周在embassy_preempt和StarryOS中分别实现了hart0和hart1之间的双向通信机制。
工作目的
为JH7110的多核配置实现完整的核间通信(IPI, Inter-Processor Interrupt)机制:
- hart0 (M态): embassy_preempt RTOS
- hart1 (S态): StarryOS
工作成果
1. 简单Hart同步标志结构体
在 example/src/bin/console.rs 中实现了共享内存同步机制:
目前暂时将HartSyncFlags放在0xc8000000
rust
#[repr(C)]
pub struct HartSyncFlags {
pub magic_number: u16,
/// Hart1 上的 OS 是否已经启动
pub hart1_os_ready: AtomicBool,
/// Hart0 是否发送了 IPI
pub hart0_ipi_sent: AtomicBool,
}2. Machine Software Interrupt 处理
在 interrupt.rs 中添加了MSIP中断处理:
rust
riscv_irq::M_SOFT => {
os_log!(trace, "[IRQ] MSIP");
let msip: *mut usize = 0x02000000 as *mut usize;
core::ptr::write_volatile(msip, 0);
}MSIP寄存器地址:
- Hart0:
0x02000000 - Hart1:
0x02000004
3. 任务7 - 定时IPI测试
添加了异步任务测试hart间通信:
rust
async fn task7(_args: *mut c_void) {
let hart_sync = get_hart_sync();
loop {
task_log!(info, "hello");
Timer::after_ticks(16_000_000).await;
if hart_sync.is_hart1_ready() {
hart_sync.set_ipi_sent();
// 触发hart1的MSIP
let msip_hart1: *mut u32 = 0x0200_0004 as *mut u32;
core::ptr::write_volatile(msip_hart1, 1);
}
}
}4. 启用Machine Software Interrupt
在 platform.rs 中启用MSIP:
rust
unsafe {
riscv::register::mstatus::set_mie();
riscv::register::mie::set_msoft(); // 新增
// ...
}第二部分:StarryOS端IPI设备实现
在StarryOS中实现了完整的IPI字符设备,支持与hart0的核间通信。
1. IPI字符设备 (kernel/src/pseudofs/dev/ipi.rs)
功能:
- 写设备:通过SBI调用发送IPI到hart0
- 读设备:获取接收到的IPI事件消息
- IRQ处理:注册软件中断处理函数
核心实现:
rust
/// IPI Character Device
pub struct IpiDevice;
impl DeviceOps for IpiDevice {
fn write_at(&self, buf: &[u8], _offset: u64) -> VfsResult<usize> {
// 通过SBI调用发送IPI到hart0
send_ipi_to_hart0()?;
Ok(buf.len())
}
fn read_at(&self, buf: &mut [u8], _offset: u64) -> VfsResult<usize> {
// 读取IPI消息队列
let mut messages = IPI_MESSAGES.lock();
// ...
}
}2. Hart同步机制
与embassy_preempt使用相同的共享内存结构体:
rust
#[repr(C)]
pub struct HartSyncFlags {
pub magic_number: u16,
pub hart1_os_ready: AtomicBool,
pub hart0_ipi_sent: AtomicBool,
}设备初始化时自动标记hart1 OS已就绪:
rust
fn mark_hart1_os_ready() {
let sync = get_hart_sync();
sync.hart1_os_ready.store(true, Ordering::Release);
}3. 设备注册
在 /dev/ipi 创建字符设备:
rust
root.add(
"ipi",
Device::new(
fs.clone(),
NodeType::CharacterDevice,
DeviceId::new(10, 200),
Arc::new(ipi::IpiDevice::new()),
),
);第三部分:修复上下文切换mepc错误
本周修复了上下文切换时 mepc 寄存器会被错误设置的问题。
问题描述
在中断处理完成后进行上下文切换时,mepc (Machine Exception Program Counter) 的值不正确,导致程序跳转到错误的地址。
第四部分:构建系统更新
升级了Rust工具链并优化了构建配置:
- Rust版本更新:
nightly-2025-11-05→nightly-2026-03-15 - 添加StarryOS构建环境:增加
riscv64-unknown-linux-musl交叉编译支持
第五部分:中断处理重构
在 interrupt.rs 中进行了代码重构:
- RISC-V中断编号常量化:新增
riscv_irq模块 - PLIC中断处理改进:支持多个挂起中断的循环处理
- 中断处理函数表:分离 RISC-V 中断和 PLIC 外部中断的处理
下一步计划
- 独立的Hart通信库:将
HartSyncFlags抽取为独立库,供embassy_preempt和StarryOS共同调用 - 消息队列功能:在共享库中实现环形缓冲区消息队列
- 中断驱动接收:IPI中断触发时自动调用消息接收处理