I’m currently working on a product using rust on stm32 hardware. I’m very thankful to be using rust instead of c/c++ for a variety of reasons. That said, so far the big pain points so far have been:

Each HAL implements different things, or the same thing in different ways. I’m in the middle of switching from the stm32f1 i started on to the more capable stm32f4 and it’s been a painful switch. I assume this would also suck in other languages, but it seems fixable in rust. There’s also widely varied support for other MCUs

Lack of emulation. You can emulate an arm cpu in qemu, but there’s no tools for mocking out hardware - which means testing has to happen on device (or you need to fragment your application into qemu-testable pieces)

Shared memory / global initialization is overly complex. If you have a resource (say a gpio pin) that you want to set up in main but use in an interrupt and nowhere else, you have to use like five layers of abstraction to “safely” do that.

You might want to take a look at the embassy project for a unified stm32 HAL. The idea is that it defines the APIs per peripheral version as defined by STM (spi v1, spi v2, usart v1 etc). The advantage is that a given peripheral can be used across all stm32 families with that version. This makes maintaining a HAL and keeping a unified API much simpler.

The other part is the stm32-metapac (not specific to async) that generates the PAC for any stm32 chip.

Read more about embassy here: https://github.com/embassy-rs/embassy