Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Effect of VolatileCell's interior mutability on borrow checking #888

Open
emmet-horgan opened this issue Nov 14, 2024 · 0 comments
Open

Comments

@emmet-horgan
Copy link

emmet-horgan commented Nov 14, 2024

Hi,
I'm not sure if this is the correct communication channel but figured I would ask here, apologies if it is not. I've been looking into the rust abstractions over peripheral registers and have become slightly confused.

svd2rust wraps registers at the lowest level in the vcell::VolatileCell type. This type is essentially a volatile wrapper for std::cell:UnsafeCell which is the foundational type for interior mutability. What are the reasons for which interior mutability is required for peripheral register access ?

This property means that the write and modify methods of the Reg type created by svd2rust do not require a mutable reference to the register to modify it, and the API is usually pretty good in my experience meaning that several methods usually exist to perform the exact operation you would like without using unsafe. I personally find this a little bit unsettling as it means the following code is allowed to compile with an svd2rust generated pac.

let dp = pac::Peripherals::take().unwrap();
let tmr_ref1 = &dp.TMR;
let tmr_ref2 = &dp.TMR;

tmr_ref1.some_reg().modify(|_, w| w.some_reg().clear_bit());
tmr_ref2.some_reg().modify(|_, w| w.some_reg().set_bit());

Whereas for example looking at the SysTick API in the cortex_m crate, it can be see that a mutable reference to the RegisterBlock is required for any reads or writes. I have seen in some generated pacs that a mutable reference to the specific register's writer type is required (it is not for the reader type even though reads can effect the state also).

This property means that there is nothing stopping a HAL from creating multiple types with non-mutable references to a peripheral and all modifying it in ways that could be confusing. Fortunately, in most HAL implementations I have seen, generally ownership of the peripheral is moved ensuring exclusive access.

I was hoping someone could clarify if what I have described is in fact correct and if so why that particular design choice was made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant