embassy-rs / embassy

Modern embedded framework, using Rust and async.
https://embassy.dev
Apache License 2.0
5.65k stars 788 forks source link

stm32f401 Hardfault in i2cv1 write_frame (only with SPI enabled) #3048

Closed dvdsk closed 5 months ago

dvdsk commented 5 months ago

Setup

Symptom:

program hangs.

Investigated with debugger (probe-rs dap server). An initial breakpoint just above self.info.regs.cr2().modify( etc etc it is reachable. A second breakpoint is set beyond the modify(. Then we continue from the inital breakpoint. Instead of halting at the second breakpoint the program hangs.

    async fn write_frame(&mut self, address: u8, write: &[u8], frame: FrameOptions) -> Result<(), Error> {
    // we can reach a breakpoint set here.
        self.info.regs.cr2().modify(|w| {
            // Note: Do not enable the ITBUFEN bit in the I2C_CR2 register if DMA is used for
            // reception.
            w.set_itbufen(false);
            // DMA mode can be enabled for transmission by setting the DMAEN bit in the I2C_CR2
            // register.
            w.set_dmaen(true);
            // Sending NACK is not necessary (nor possible) for write transfer.
            w.set_last(false);
        });

Callstack

When we tell de debugger to halt we find we are in the HardFault handler. From the callstack below we see that the cause was a BusFault due to a Precise data access error at memory adress: 0x20010004. On Arm precise means the error was caused by the preceding instruction. In this case the read_volatile.

HardFault_ (/home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cortex-m-rt-0.7.3/src/lib.rs:1046)
"HardFault handler. Cause: Escalated BusFault (Precise data access error) at location: 0x20010004." (Unknown Source:0)
read_volatile<stm32_metapac::i2c::regs::Cr2> #[inline] (/rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/ptr/mod.rs:1665)
read_volatile<stm32_metapac::i2c::regs::Cr2> #[inline] (/rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/ptr/mut_ptr.rs:1361)
read<stm32_metapac::i2c::regs::Cr2, stm32_metapac::common::RW> #[inline] (/home/david/.cargo/git/checkouts/stm32-data-generated-cb34dad5f3150296/2ad3397/stm32-metapac/src/common.rs:58)
modify<stm32_metapac::i2c::regs::Cr2, stm32_metapac::common::RW, (), embassy_stm32::i2c::_version::{impl#1}::write_frame::{async_fn#0}::{closure_env#0}> #[inline] (/home/david/.cargo/git/checkouts/stm32-data-generated-cb34dad5f3150296/2ad3397/stm32-metapac/src/common.rs:82)
{async_fn#0} #[inline] (/home/david/Documents/embassy/embassy-stm32/src/i2c/v1.rs:364)
{async_fn#0} #[inline] (/home/david/Documents/embassy/embassy-stm32/src/i2c/v1.rs:515)
{async_fn#0} #[inline] (/home/david/tmp/i2c_hangs/src/main.rs:121)
<unknown function @ 0x08002e5a> (/home/david/Documents/embassy/embassy-executor/src/raw/mod.rs:159)
poll #[inline] (/home/david/Documents/embassy/embassy-executor/src/raw/mod.rs:405)
<unknown function @ 0x08008056> (/home/david/Documents/embassy/embassy-executor/src/raw/mod.rs:526)
<unknown function @ 0x08003c54> (/home/david/Documents/embassy/embassy-executor/src/arch/cortex_m.rs:106)
panic (/home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/panic-probe-0.3.2/src/lib.rs:42)
panic (/home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/panic-probe-0.3.2/src/lib.rs:42)

min example repo

https://github.com/dvdsk/i2c_hangs_min_example

related

This might very well be the same as the harder to replicate: #2968

dvdsk commented 5 months ago

False alarm, the issue was on my size. Specifically the EMBASSY_EXECUTOR_TASK_ARENA_SIZE was set to 2000 which seems to be too high. Removing stopped the issue.

edit: want actually that, it was the embassy net w5500 state that had a too big a queue