@@ -41,10 +41,36 @@ pub mod gpio {
4141 //! devices. We want to have stronger typing in the Zephyr interfaces, so most of these types
4242 //! will be wrapped in another structure. This wraps a Gpio device, and provides methods to
4343 //! most of the operations on gpios.
44+ //!
45+ //! Safey: In general, even just using gpio pins is unsafe in Zephyr. The gpio drivers are used
46+ //! pervasively throughout Zephyr device drivers. As such, most of the calls in this module are
47+ //! unsafe.
4448
4549 use crate :: raw;
4650 use super :: Unique ;
4751
52+ /// Global instance to help make gpio in Rust slightly safer.
53+ ///
54+ /// To help with safety, the rust types use a global instance of a gpio-token. Methods will
55+ /// take a mutable reference to this, which will require either a single thread in the
56+ /// application code, or something like a mutex or critical section to manage. The operation
57+ /// methods are still unsafe, because we have no control over what happens with the gpio
58+ /// operations outside of Rust code, but this will help make the Rust usage at least better.
59+ pub struct GpioToken ( ( ) ) ;
60+
61+ static GPIO_TOKEN : Unique = Unique :: new ( ) ;
62+
63+ impl GpioToken {
64+ /// Retrieves the gpio token. This is unsafe because lots of code in zephyr operates on the
65+ /// gpio drivers.
66+ pub unsafe fn get_instance ( ) -> Option < GpioToken > {
67+ if !GPIO_TOKEN . once ( ) {
68+ return None ;
69+ }
70+ Some ( GpioToken ( ( ) ) )
71+ }
72+ }
73+
4874 /// A single instance of a zephyr device to manage a gpio controller. A gpio controller
4975 /// represents a set of gpio pins, that are generally operated on by the same hardware block.
5076 pub struct Gpio {
@@ -73,8 +99,11 @@ pub mod gpio {
7399 }
74100 }
75101
76- /// A GpioPin represents a single pin on a gpio device. This is a lightweight wrapper around
77- /// the Zephyr `gpio_dt_spec` structure.
102+ /// A GpioPin represents a single pin on a gpio device.
103+ ///
104+ /// This is a lightweight wrapper around the Zephyr `gpio_dt_spec` structure. Note that
105+ /// multiple pins may share a gpio controller, and as such, all methods on this are both unsafe,
106+ /// and require a mutable reference to the [`GpioToken`].
78107 #[ allow( dead_code) ]
79108 pub struct GpioPin {
80109 pub ( crate ) pin : raw:: gpio_dt_spec ,
@@ -111,7 +140,7 @@ pub mod gpio {
111140 }
112141
113142 /// Configure a single pin.
114- pub fn configure ( & mut self , extra_flags : raw:: gpio_flags_t ) {
143+ pub unsafe fn configure ( & mut self , _token : & mut GpioToken , extra_flags : raw:: gpio_flags_t ) {
115144 // TODO: Error?
116145 unsafe {
117146 raw:: gpio_pin_configure ( self . pin . port ,
@@ -121,7 +150,7 @@ pub mod gpio {
121150 }
122151
123152 /// Toggle pin level.
124- pub fn toggle_pin ( & mut self ) {
153+ pub unsafe fn toggle_pin ( & mut self , _token : & mut GpioToken ) {
125154 // TODO: Error?
126155 unsafe {
127156 raw:: gpio_pin_toggle_dt ( & self . pin ) ;
0 commit comments