-
Notifications
You must be signed in to change notification settings - Fork 234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multicore Lockout #795
Comments
I dig a bit and wanted to try implementing a SIO interrupt like they did with the lockout function. For that, on core 0 I did: vt.init(&mut pac.PPB);
vt.register_handler(pac::Interrupt::SIO_IRQ_PROC0 as usize, test);
unsafe {
vt.activate(&mut pac.PPB);
pac::NVIC::unmask(pac::Interrupt::SIO_IRQ_PROC0);
} Here is my function test: #[inline(always)]
#[link_section = ".data.ram_func"]
extern "C" fn test() {
...
} The function is triggered, however it seems like the core never come back from it and the execution stop. (I removed all flash function for my tests) |
It's not obvious to me what's going wrong here. Can you publish a small example reproducing the issue into a git repo? Perhaps I can see more looking at the full code. |
Hey, Thanks, for looking at this issue! I'm going to write a small example to isolate the behavior I'm trying to achieve so hopefully it will makes more sense to you. I've done some test and almost figure out how to achieve what I wanted. Basically, the problem with the interrupts occurs when I was trying to use fancy calls inside the interrupt (like rebuild builtin WS2812 object for debugging) but I think it was conflicting with object inside the main function causing corruption and unwanted behavior in the main function (basically crashing it when the interrupt returned). Now that I've a cleaner interrupt with only required code inside it seems to work. The only problem left is that even if the interrupt function runs from RAM when interacting with the flash using core1, core0 seems to have a hard time recovering from the interrupt. I'll send you the repos link with the code soon. (it will makes more sense) |
Here is the example code: https://github.com/Captainfl4me/rust-2-rp/blob/master/multicore-lockout-irq/src/main.rs |
While I do not yet know what exactly causes your code to fail, some ideas where I'd investigate further:
|
Uh, even worse, it looks like rustc doesn't inline the sio
So your (Generated with |
Thank you so much for the insights! I did know about objdump I think it will be very useful to better understand what is actually going on. For the write_flash function I replicated the code from rp2040_flash library but without the writing parts because I didn't think it was actually needed. I just use the Hal functions but as you say maybe that's also causing issue. I'll take a look and let you know! |
Well you're right after a close inspection of the dump file it seems like all the function calls ( Not sure if there is a way to force rust to inline the functions ? So I guess I'll try writing my RAM function in asm directly so that it is inline (like they did with rp2040_flash) |
I refactor the code to have the following (I push the changes if you want to take a look on the repos), #[inline(never)]
#[link_section = ".data.ram_func"]
extern "C" fn fifo_wait_in_ram() {
// critical_section::with(|_| {
if fifo_is_read_ready() {
if fifo_read() != LOCKOUT_CORE {
return;
}
loop {
if fifo_is_read_ready() && fifo_read() == UNLOCKOUT_CORE {
break;
}
}
}
// Drain the FIFO before returning
while fifo_is_read_ready() {
let _ = fifo_read();
}
// });
}
#[link_section = ".data.ram_func"]
pub fn fifo_is_read_ready() -> bool {
let sio = unsafe { &(*pac::SIO::ptr()) };
sio.fifo_st.read().vld().bit_is_set()
}
#[link_section = ".data.ram_func"]
pub fn fifo_read() -> u32 {
let sio = unsafe { &(*pac::SIO::ptr()) };
sio.fifo_rd.read().bits()
} According to the objdump, there is no more call to functions living in ROM. (I also update the core1 to use rp2040_flash so that I don't have to call |
Okay my bad it was just a problem with the way I was passing the buffer to the Code here |
Glad to hear that it works now, and thanks for posting the working code! |
I was experimenting with flash writing using rp2040-flash and littlefs2. Everything was running smoothly until I wanted to try multicore with it.
As I understand it is because both cores run directly from the flash (unless you use
#[link_section = ".data.ram_func"]
) and as one core litteraly unplug the flash the other instantly crash and cannot recover when the flash is plugged back.To solve this issue, there is these functions: multicore_lockout provided by the C SDK, that can pause the other core in a safe mode until the lock is unlock (like a SpinLock but for the entire core). However, I cannot find any implementation of this in the crate, neither any pratical way to solve the problem using other ways.
The text was updated successfully, but these errors were encountered: