Recent submissions

Comment · 4 years ago
Good question! I'm also not a Rust expert, but maybe that syntax would be considered unsafe in some situations?

I think the 'peripheral access crates' try to auto-generate those sorts of struct objects from SVD files, but you still need to obey Rust's ownership rules to get the advantage of its built-in memory safety.

So if a function needs to modify a peripheral's memory, it needs to claim mutable ownership of the relevant peripheral registers. That's a feature of the language which makes it 'safer', but the cost/benefit calculation is a bit different on embedded platforms. They have less memory, and static allocation is usually preferred.

Still, microcontrollers are getting faster quickly. You can even run Linux on some cortex-M4/M7 chips. The verbose syntax might be worthwhile if you're collaborating on complicated firmware.

Comment · 4 years ago
Lots of people pointing out that Rust isn't very ergonomic on embedded platforms. IMO one huge issue is how verbose the syntax needs to be.

Look at some of the cases in the article, such as:

    let mut dp = pac::Peripherals::take().unwrap();
    dp.RCC.ahb2enr.modify(|_, w| w.gpioaen().set_bit());
In C that would be:

    RCC->AHBENR2 |= RCC_AHBENR2_GPIOAEN;
Okay, you only have to take ownership of the Peripherals object once, but what about when they want to set a UART register in a function? Rust wants mutable pointers to have a trail of ownership outside of 'unsafe' blocks, so now we need:

    pub fn setup_transmission(regs: &mut R, [...])
    where R: Deref<Target = pac::usart1::RegisterBlock> {
        [...]
        regs.cr2.modify(|_, w| w.stop().bits(config.stop_bits as u8));
        [...]
    }
This is a bit of a construction, in C(++) we can just do something like:

    void setup_transmission([...]) {
        [...]
        USART1->CR2 &= ~(USART_CR2_STOP_BITS);
        USART1->CR2 |= ((uint8_t)config.stop_bits << USART_CR2_STOP_BITS_Pos);
        [...]
    }
The Rust snippet seems like it would be safer in a multi-threaded environment like an RTOS, or in cases where interrupts might modify peripheral registers, but...there are so many syntactical details to remember.

I really tried to like embedded Rust, and I still think it compares favorably with the sort of C HALs that most chip manufacturers distribute. But the syntax seems to get in the way of quick simple access to peripheral registers.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton