I would like to know how to create a static (global) LCD
or USART
object that different parts of my program can use. I've tried various approaches, but I believe it may not be possible.
In embedded Rust, you need to take ownership of the hardware, as shown below:
rust
let mut dp = pac::Peripherals::take().unwrap();
Once you take ownership, you cannot take it again. Taking partial ownership also prevents you from passing dp
to other places.
How can you send text to USART
or LCD
from different functions—not just from main
? I am beginning to think this might not be feasible.
Please avoid suggesting the use of Mutex
or other multi-thread-safe constructs. This issue is not about safety; it’s about the ability to access peripherals from different functions within my project. Thank you.
Not sure what platform you are working with, but on Cortex-M, I have use RTIC to get around this problematic. It is a concurrency framework, though.
I use stm32f7xx hal. and some Nucleo board. But would you confirm that is not possible to have the LCD and Serial normally?
What do you mean by "normally"? I remember it being very complicated (I would not say impossible) to share your hardware (dp
) on different places of a complex program using only main
.
I found the approach taken by RTIC solves this issue very elegantly: you define your "global" resources (typically your hardware) during initialization of your App
, and you can share those resources with any tasks within that App
. RTIC is relatively light-weight, and has a modest learning curve.
I haven't use Embassy, but I guess it allows you to accomplish the same, but differently.
Thank you very much for your answer. I meant by "normaly" to do the task using only main .. similar to what you would do in cpp /c which you declare them globally.
Implementation of hal object also quite complicated. For example for creating the serial you shouldn't be pushed to provide 4 arguments to create the serial object. If you look at MbedOS you see that the only 2 things you need is Tx, Rx pins. And the Os determine what to use. Configurations should be with the default. if you want you can then change it later.
pub fn new(usart: U, pins: PINS, clocks: &Clocks, config: Config) -> Self { //HAL Implementation
//This is how i create the serial
//All these lines to define a serial port which is only one line in cpp
// Configure the serial instance
let mut serial_config = Config::default();
serial_config.baud_rate=HertzU32::Hz(115200);
// Configure UART2 on PD5 (TX) and PD6 (RX)
let tx = gpiod.pd5.into_alternate(); // Set PA9 to alternate function for TX
let rx = gpiod.pd6.into_alternate(); // Set PA10 to alternate function for RX
//new(usart: U, pins: PINS, clocks: &Clocks, config: Config)
let serial = Serial::new(dp.USART2,(tx,rx), &clocks, serial_config );
let (mut txU,mut rxU)=serial.split();
Thanks again for your input. I appreciate it. I have been trying to find a solution for several days, I though I was too lazy to figure out.
1 Like