cancel
Showing results for 
Search instead for 
Did you mean: 

USART interrupt handling in Rust

sekhar
Associate II

Hi, I'm new to embedded (as in one week old) and am trying to build a small system to do a few things for an optical product we're building: mainly temp measurement (Omega SA1-RTD with MAX31865) and LED management for optical lasers. Currently I have both working on STM32F446RE (Nucleo board for now), which is great.

Now, I need to be able to communicate with the system from the computer (Ubuntu box). We have the rest of the system (a collection of 10 motors, all daisy chained to work with MODBUS over RS485) connected to the computer via an RS485/USB adapter. I was thinking of making this STM32 system act as another peripheral to be part of that daisy chain.

My question now is: how can I build this communication link? I have a working example of interrupt handling with the user button on the Nucleo on EXTI15_10. However, I'm not sure how I can set up interrupts for USART (I'm assuming that'd be the way for MODBUS). I hooked up for USART2, but don't see how I can receive the MODBUS messages via interrupts. In general, what is the process for interrupt handling? E.g., where is the info on which kind of event (like the serial event) generates what kind of interrupt (like the EXTI15_10 above)?

I'm building this in Rust, so unfortunately the C/C++ code examples online aren't super helpful, but even if you don't have pointers on Rust code, if you could just explain the theory or point to references, I'd really appreciate it. I do have Electronics background. Thanks a bunch!

14 REPLIES 14
KnarfB
Principal III

Peripherals like UART have their own interrupts besides EXTI. See the reference manual RM0390 USART chapter for details at the register level. Set the RXNEIE (receive register not em,pty interrupt enable) bit in the CR1 register and implement an interrupt handler. You also have to enable the interrupt in NVIC and, for reliable communication, implement error handling. 

For higher baud rates/less CPU load, UART is often combined with DMA: MaJerle/stm32-usart-uart-dma-rx-tx: STM32 examples for USART using DMA for efficient RX and TX transmission (github.com).

Not idea how this all translates to Rust :).

Looking from the other side, there are MODBUS libraries like https://github.com/alejoseb/Modbus-STM32-HAL-FreeRTOS.git 

hth

KnarfB

sekhar
Associate II

Thank you for the prompt response. I was connecting for USART via PA2/PA3, but I now see from the doc that USART is via ST-Link by default. I tried sending via the USB, and yes the interrupts triggered. I need to look at the DMA option you mentioned next. Much appreciated!

Pavel A.
Evangelist III

 I'm new to embedded (as in one week old) 

Consider for this mini-project on STM32 to descend to plain C or C++ from the rusty heights. You will lose only a week, but will save much more time end effort. Because most of available examples are in C/C++. 


@Pavel A. wrote:

Consider for this mini-project on STM32 to descend to plain C or C++ from the rusty heights.


+1 to this 

@sekhar  Get a C example working. Then you can take that as the specification of what your Rust code needs to do...

sekhar
Associate II

Thank you @Pavel A. and @Andrew Neil, yes that is good and very practical advice. But doing it in Rust isn't as hard as it might sound though, even with lack of examples. Look at it this way. I started with all this on Monday, as in: I knew nothing at all about using microcontrollers, let alone STM32, actually no experience with HW of any kind (all my work has been in software). By Tuesday I had the dev setup (VSCode with debugging) worked out and a blinking LED; and by Wednesday, temperature access of an RT100 device with another board (MAX31865) in the mix. This is not to brag, but to say that if I can do it, so can others; and it can be quick to get started with microcontrollers (certainly SMT32) using Rust.

I do agree though there are a ton of examples on C/C++, but I'm not sure starting from them is ideal if your goal is to do in Rust based on the examples I found (I did try that BTW, trying to go from C++ examples to Rust). For starters, it appears to me (I'm new, so may be wrong here), the way you approach coding for STM32 and organize your code is very different, so the logic doesn't seem to translate.

Also, on day one (Monday) I did try to use STM32CubeIDE, not to do it in C++ but to just look at the board I connected via the USB (which I didn't know how to access). And I immediately ran into a bunch of issues. The deb version would not work on Ubuntu box. Searching online led me to installing the generic Linux version, but I couldn't do anything useful with it either because it ran into other issues like no libncurses.so.5 (I have libncurses.so.6 and there is no option anymore that I see to get this outdated version). Rash of issues like this. Not to mention that this is based on Eclipse, which IMO is dated compared to newer ones like VSCode.

Anyway, all this is from a newbie viewpoint, please take it from what it's worth. I'm only writing to encourage other folks looking to do it in Rust. Bottom line though, the USART interrupts worked immediately when I accessed via ST-Link (I was connecting through the on-board pins, which apparently are not set by default for USART). I'm sure I'll run into other issues, but at least this hurdle is crossed.

This community is great BTW, and you're so welcoming of newbies like me.

Pavel A.
Evangelist III

Of course it depends on your actual goal. I've guessed that the goal is getting working solution, as fast as possible, with minimal bruises, but it was a wrong guess ))

 

No, you were absolutely correct: the #1 priority right now is speed, which is why I'm scrambling. We're planning for user tests on 8/22, which gives me only one more week to not only have everything running but also have it installed in the machine and tested, which is crazy. But as I explained above, for me it is turning out to be slower to build in C++ and perhaps not even feasible: trying the IDE was one of the first things I tried on Monday to save time but I couldn't get the darned STM32CubeIDE to work on Ubuntu because of the issues. Are you guys not working on Ubuntu? May be I'm missing something.

If you ask me - my primary working system is Windows, exactly because everything Just Works on it. We use Ubuntu, Fedora, Debian, OS/X and anything needed for the customer. But to save our time, work-life balance and nerve cells - only Windows for the tools. Of course, with wsl, Docker Desktop, gitlab and all that stuff as needed. Not free - so what? I'm grown up and can pay for my tools and toys.

 

Guillaume K
ST Employee

Hello 

Just curious: what Rust framework are you using for STM32F4 Peripheral Access Crate / HAL ?

stm32-rs ?

Embassy ?

Guillaume