Had my first serious "I wanna write Rust" moment in embedded

I experienced a painful waste of time yesterday which really made me wish embedded C had Rust's type system to have my back.

Basic issue was as follows: in STM32 HAL, I wanted to handle GPIO EXTI interrupt. Due to how interrupts are wired into NVIC on the Arm Cortex core, lines 5..9 and 10..15 share a single interrupt. So, in the interrupt handler for that IRQ line, you'd have to check which line triggered the interrupt:

if (__HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) != 0) {
    ...
}

So far so good. However, that __EXTI_LINE__ parameter to the function-like macro must be one of GPIO_PIN_X, where X in 0..15.

However, the GPIO_PIN_X macros are just plain `#define GPIO_PIN_X (1U << X) macros.

Still no big deal. However, there are another similar set of macros defined, EXTI_LINE_X. They are also just unsigned numbers as far as the compiler is concerned.

So when I saw that the parameter to __HAL_GPIO_EXTI_GET_FLAG() is named __EXTI_LINE__, I naturally assumed it was supposed to be one of EXTI_LINE_X.

Add to all of that the fact that I was having a bit of an off day yesterday when I was writing this, and the fact that my __HAL_GPIO_EXTI_GET_FLAG(EXTI_LINE_6) compiled just fine, it took me more time than it should have to figure it out.

Rust (or disciplined template C++ in this case) could've saved me from that by making the types of GPIO_PIN_X and EXTI_LINE_X different and incompatible.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.