Skip to content
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

Delay panics #203

Closed
pdgilbert opened this issue Mar 1, 2021 · 6 comments · Fixed by #208
Closed

Delay panics #203

pdgilbert opened this issue Mar 1, 2021 · 6 comments · Fixed by #208
Labels
bug Something isn't working

Comments

@pdgilbert
Copy link

(This may be related to #190 and stm32-rs/stm32f1xx-hal#225.)
The hal code for stm32f3xx_hal::delay::Delay::new(cp.SYST, clocks) panics when the delay time is set above 2097ms. I have found the panic behaviour in several examples but isolated time with the simple blink example below. The problem can be avoided by using another delay function, as seems to be done in stm32f3xx-hal examples.

Click to view code example
//! stm32f3xx.  Uses PE15  which is onboard green LD6 (West) LED on STM32F303 Discovery kit.

#![deny(unsafe_code)]
#![no_std]
#![no_main]

#[cfg(debug_assertions)]
extern crate panic_semihosting;

#[cfg(not(debug_assertions))]
extern crate panic_halt;

use cortex_m_rt::entry;

//use asm_delay::{ AsmDelay, bitrate, };

#[cfg(feature = "stm32f3xx")]  //  eg Discovery-stm32f303
use stm32f3xx_hal::{prelude::*,
                    stm32::{Peripherals, CorePeripherals},
                    gpio::{gpioe::PE15, Output, PushPull,}, 
		    delay::Delay ,
                    };


    #[cfg(feature = "stm32f3xx")]
    fn setup() -> (PE15<Output<PushPull>>,  Delay) {
    //fn setup() -> (PE15<Output<PushPull>>, AsmDelay) {

       let cp = CorePeripherals::take().unwrap();
       let dp        = Peripherals::take().unwrap();
       let mut rcc   = dp.RCC.constrain();
       let clocks    = rcc.cfgr.freeze(&mut dp.FLASH.constrain().acr);

       let mut gpioe = dp.GPIOE.split(&mut rcc.ahb);
       
       impl LED for PE15<Output<PushPull>> {
           fn   on(&mut self)  -> () { self.set_high().unwrap()  }   
           fn  off(&mut self)  -> () { self.set_low().unwrap() }
           };

       //let mut delay = AsmDelay::new(bitrate::U32BitrateExt::mhz(16)); //works
       let delay = Delay::new(cp.SYST, clocks);                          // panics
       
       
       // return tuple  (led, delay)
       (gpioe.pe15.into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper),  // led on pe15 with on/off
        delay )                       
       }

// End of hal/MCU specific setup. Following should be generic code.

 
pub trait LED {
   fn  on(&mut self)  -> () ;
   fn off(&mut self)  -> () ;
}

#[entry]
fn main() -> ! {

    let (mut led, mut delay)  = setup();

    let on  : u32 = 1000;
    let off : u32 = 2098;  //works with 1000, 2097, panics at  2098 and above

    // Wait for the timer to trigger an update and change the state of the LED
    loop {
        let _r = led.on();  
        delay.delay_ms(on);
        let _r = led.off(); 
        delay.delay_ms(off);
    }
}
@Sh3Rm4n Sh3Rm4n added the bug Something isn't working label Mar 2, 2021
@Sh3Rm4n
Copy link
Member

Sh3Rm4n commented Mar 7, 2021

Do you have any backtrace at hand, which show, where the code panics? When building for debug mode and depending on the panic strategy this is printed out to e.g. a UART or via ITM.

The Delay function is independent of the timer and PWM implementation and has nothing to do with #190. This sound like a bug and should be easy to solve.

@Sh3Rm4n
Copy link
Member

Sh3Rm4n commented Mar 7, 2021

Because the delay is dependent on the system clock, I bet you can delay for longer, when you setup your cpu frequency at a higher rate.

But this is definitely a call for improving src/delay.rs.

@pdgilbert
Copy link
Author

The gdb window shows

Breakpoint 3, rust_begin_unwind (info=0x20009f20)
    at /home/paul/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.5.6/src/lib.rs:79
79	    interrupt::disable();

and the openocd semihost shows

panicked at 'assertion failed: rvr < (1 << 24)', /home/paul/.cargo/git/checkouts/stm32f3xx-hal-572339a820137a38/2b41132/src/delay.rs:53:9

gdb bt gives

Click to expand
Breakpoint 3, rust_begin_unwind (info=0x20009f20)
    at /home/paul/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.5.6/src/lib.rs:79
79	    interrupt::disable();
(gdb) bt
#0  rust_begin_unwind (info=0x20009f20)
    at /home/paul/.cargo/registry/src/github.com-1ecc6299db9ec823/panic-semihosting-0.5.6/src/lib.rs:79
#1  0x08002c70 in core::panicking::panic_fmt ()
    at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b//library/core/src/panicking.rs:92
#2  0x08002c4a in core::panicking::panic ()
    at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b//library/core/src/panicking.rs:50
#3  0x08000fb4 in <stm32f3xx_hal::delay::Delay as embedded_hal::blocking::delay::DelayUs<u32>>::delay_us (self=0x20009fa8, us=2098000)
    at /home/paul/.cargo/git/checkouts/stm32f3xx-hal-572339a820137a38/2b41132/src/delay.rs:53
#4  0x08000f32 in <stm32f3xx_hal::delay::Delay as embedded_hal::blocking::delay::DelayMs<u32>>::delay_ms (self=0x20009fa8, ms=2098)
    at /home/paul/.cargo/git/checkouts/stm32f3xx-hal-572339a820137a38/2b41132/src/delay.rs:33
#5  0x08000952 in zzblink::__cortex_m_rt_main ()
    at /home/paul/githubClones/eg_stm_hal/boards/discovery-stm32f303/examples/zzblink.rs:71
#6  0x08000902 in main ()
    at /home/paul/githubClones/eg_stm_hal/boards/discovery-stm32f303/examples/zzblink.rs:58
(gdb) 

If I continue after that I get
Program received signal SIGTRAP, Trace/breakpoint trap.
lib::__bkpt () at asm/lib.rs:49
49	asm/lib.rs: No such file or directory.

which I have not figured out, but I think it is a problem in the panic code rather than the cause of the panic.

I've failed previously in trying to get ITM to work, but it is about time I tried again. Let me know if above is not enough.

@Sh3Rm4n
Copy link
Member

Sh3Rm4n commented Mar 8, 2021

Thank you for this trace back. This is exactly what I expected.

panicked at 'assertion failed: rvr < (1 << 24)', /home/paul/.cargo/git/checkouts/stm32f3xx-hal-572339a820137a38/2b41132/src/delay.rs:53:9

I'll look into it, to check, what can be done about it. But I am afraid, that the only thing that can be done in this case, is to return an error, instead of panicking. (which is much better than now, IMO!)

But this seems like a limitation of the delay method used. For longer delays you need another method. Sadly timers are not working for this, neither. Not at least with some abstraction code, which artificially allows periods above 1 seconds. I have no good example at hand right now.

Regarding ITM, remember this line: https://github.com/rust-embedded/cortex-m-quickstart/blob/18bb68071011967d957a5df6c2e5d513e80b2fcb/openocd.gdb#L30
This is, what bit me all the time, when I started out and tried to configure ITM :)

@pdgilbert
Copy link
Author

There is no rush for this on my account. I have a good workaround using AsmDelay. But it is useful to know there is a problem.

Thanks for the pointer on ITM.

@Sh3Rm4n
Copy link
Member

Sh3Rm4n commented Mar 8, 2021

I'll look into it, to check, what can be done about it. But I am afraid, that the only thing that can be done in this case, is to return an error, instead of panicking. (which is much better than now, IMO!)

Alternatively, we could introduce a new counter variable, which would increase the maximum delay quite a bit. There is still a limit, but it is in a reasonable range, instead of surprising the user with a panic. Just under 3 seconds is pretty low, IMO.

There is no rush for this on my account. I have a good workaround using AsmDelay. But it is useful to know there is a problem.

Definitely. Thanks for reporting!

Sh3Rm4n added a commit to Sh3Rm4n/stm32f3xx-hal that referenced this issue Mar 9, 2021
Leverage a full 32 bit range instead of only 24 bit range.
This will increase the maximum possible delay from ~2 seconds
up to 9 minutes.

Also cap the value, instead of panicking, if the value is to high.

Fixes stm32-rs#203
Sh3Rm4n added a commit to Sh3Rm4n/stm32f3xx-hal that referenced this issue Mar 9, 2021
Leverage a full 32 bit range instead of only 24 bit range.
This will increase the maximum possible delay from ~2 seconds
up to 9 minutes.

Also cap the value, instead of panicking, if the value is to high.

Fixes stm32-rs#203
Sh3Rm4n added a commit to Sh3Rm4n/stm32f3xx-hal that referenced this issue Mar 9, 2021
Leverage a full 32 bit range instead of only 24 bit range.
This will increase the maximum possible delay from ~2 seconds
up to 9 minutes.

Also cap the value, instead of panicking, if the value is to high.

Fixes stm32-rs#203
Sh3Rm4n added a commit to Sh3Rm4n/stm32f3xx-hal that referenced this issue Mar 9, 2021
Leverage a full 32 bit range instead of only 24 bit range.
This will increase the maximum possible delay from ~2 seconds
up to 9 minutes.

Also cap the value, instead of panicking, if the value is to high.

Fixes stm32-rs#203
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants