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
Guillaume K
ST Employee

How do you connect the STM32F446 USART2 to the rest of the RS485 link ?

Are you using a TTL-to-RS485 adapter like MAX485 ?

@Guillaume KI'm just using stm32f4xx-hal with the stm32f446re I have on the Nucleo 64 board, which is working for the two things I wanted: laser LED control and temp monitoring (via max31865). I also got the Nucleo 144 (stm32f429) and Bluepill (stm32f103) that I'm experimenting with. I'm planning to check out embassy though in the near future but don't have a need for it right now.

Guillaume K
ST Employee

Hi @sekhar 

Here are some info I found about using modbus/RS485 on STM32 (with Rust and C):

The STM32s don't have RS485 interface. You can use USART with an external adapter.

example in Rust using MAX485 and STM32F103:

https://github.com/alttch/stm32f1-modbus-example

The stm32f4xx-hal has an example in Rust of USART with DMA (and interrupts) :
https://github.com/stm32-rs/stm32f4xx-hal/blob/master/examples/uart-dma.rs

we can see use of #[interrupt] to declare interrupt vector
#[interrupt]
fn USART3() {
}

the interrupt vectors like USART3 are declared in the stm32f4 peripheral access crate . it must be included in your project. If you use stm32f4xx-hal, it uses stm32f4 PAC.

also:

cortex_m::interrupt::free(|cs| { /* some code in critical section */}
this function ensure the closure is running free of interrupts.


I found some posts about using modbus/RS485 on STM32 (using C code):


https://community.st.com/t5/stm32-mcus-products/modbus-over-rs485-with-stm32f303k8/td-p/165261
https://community.st.com/t5/stm32-mcus-products/modbus-with-rs-485-communication/td-p/228333
https://community.st.com/t5/stm32cubemx-mcus/stm32g484-rs-485-and-modbus-how-to-configure-in-cubemx/td-p/176276

Note that there are some STM32 series that have basic "support" of modbus .
it is limited. on USART. only few feature in HW: detection of end of transmission (end of word).
the user has to implement a lot in software.
the STM32F446 doesn't have this. other series have it. STM32F303 for example. but also the H7.

Still, on STM32F446 It may be possible to do same function in software (detection of end of modbus command).

 

for a modbus crate in Rust you can have a look at:

https://crates.io/crates/rmodbus

 

sekhar
Associate II

Thank you @Guillaume K, I'll check these out, much appreciated.

Guillaume K
ST Employee

If you are happy with my answer, please click on Accept as Solution.