Skip to content

What about: volatile accesses and memory-mapped IO #33

Closed
@cramertj

Description

@cramertj

Folks who want to write drivers and embedded code using Rust need to have a way to guarantee exactly-once access to certain memory locations. Today, the embedded wg makes extensive use of @japaric's VolatileCell crate, along with RegisterBlock structures containing VolatileCell wrappers around each field of the register block, and a function to provide a single access to the register block at a fixed address. The API exposed in the the stdm32f103xx crate and similar only expose *const RegisterBlock values (example) from the overall Peripherals object. This then requires unsafe code to access and mutate any particular field.

Asks:

  • Is this pattern sufficient to guarantee that the number of writes to IO-mapped memory will exactly match the number of calls to unsafe { (*x.volatile_cell_field).set(...) }, and that the number of reads will exactly match the number of calls to unsafe { (*x.volatile_cell_field).get(...) }? it seems like it should be.
  • Is it possible to provide the same guarantee while exposing the register block via a safe reference type such as &? It would be possible to provide a custom RegisterRef<'a, T> that consisted of a raw pointer internally as well as a custom derive for projecting this to fields of the register block, but this seems unfortunately complicated and unergonomic.

Complicating factors:

  • LLVM's precise definition of "volatile" is a bit shakey. It says that optimizers must not change the number of volatile operations or change their order of execution relative to other volatile operations. However, it doesn't seem to specify that non-volatile operations can't be inserted-- this is something we need to prevent, but which LLVM might insert in an attempt to pre-load a value (as allowed by the "dereferencable" attribute that we apply to references). Can we make sure that LLVM doesn't do such a thing? If we fail in that, could we potentially make the compiler understand that VolatileCell is special, similar to UnsafeCell, and cannot have "dereferenceable" applied to references to it (and objects that contain it), in order to prevent this misoptimization? This seems potentially more complicated and intrusive, but IMO still worth considering.

cc @RalfJung @kulakowski @teisenbe @rkruppe

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-memoryTopic: Related to memory accessesC-open-questionCategory: An open question that we should revisit

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions