Hi!
I'm getting a hard fault on nRF52480 due to Rust generating a stack pointer that points into the FLASH memory region. This happens with 1.85.1 as well as 1.84. A proper memory.x file is present in the build target.
I tracked down the fault to the following assembly instructions:
; SP: 0x2000 34E0
0000C46A SUB.W SP, SP, #0x025C00
; SP: 0x1FFD D8E0 - this is already wrong because RAM >= 0x2000 0000
0000C46E SUB SP, SP, #32
; SP: 0x1FFD D8C0
0000C470 STR R1, [SP, #76] ; Triggers the Hard Fault
These instructions are being generated within the preamble of an async method call in the embassy framework:
impl<R, Rng, U, TIMER> Device<R, Rng, U, TIMER>
where
R: Radio,
for<'a> R::RadioFrame<&'a mut [u8]>: RadioFrameMut<&'a mut [u8]>,
for<'a> R::TxToken<'a>: From<&'a mut [u8]>,
Rng: RngCore,
U: UpperLayer,
TIMER: DelayNs + Clone,
{
// The preamble to the following method fails!
pub async fn run(&mut self) -> ! {
let (mut tx, mut rx) = (Channel::new(), Channel::new());
let (tx_send, tx_recv) = tx.split();
let (rx_send, rx_recv) = rx.split();
let mut tx_done = Channel::new();
let (tx_done_send, tx_done_recv) = tx_done.split();
let mut phy_service = PhyService::new(&mut self.radio, tx_recv, rx_send, tx_done_send);
let mut mac_service = MacService::<'_, Rng, U, TIMER, R>::new(
&mut self.rng,
&mut self.upper_layer,
self.timer.clone(),
rx_recv,
tx_send,
tx_done_recv,
);
match select::select(mac_service.run(), phy_service.run()).await {
Either::First(_) => panic!("Tasks should never terminate, MAC service just did"),
Either::Second(_) => panic!("Tasks should never terminate, PHY service just did"),
}
}
}
I've no idea at all how I could further debug that. Help is very much appreciated!