Бесплатная библиотека
Читайте книгу на сайте или телефоне
The Embedded Rust Book - Читать Любимую Русскую Полную Книгу 👉 Read-E-Book.com

The Embedded Rust Book

Электронная книга - «The Embedded Rust Book». Краткое содержание книги:

An introductory book about using the Rust Programming Language on Bare Metal embedded systems, such as Microcontrollers.
https://docs.rust-embedded.org/book/
1 ... 14 15 16 17 18 19 20 21 22 ... 34
Перейти на страницу:

We could expose the following structure in Rust to control this GPIO:

/// GPIO interface

struct GpioConfig {

/// GPIO Configuration structure generated by svd2rust

periph: GPIO_CONFIG,

}

impl GpioConfig {

pub fn set_enable(&mut self, is_enabled: bool) {

self.periph.modify(|_r, w| {

w.enable().set_bit(is_enabled)

});

}

pub fn set_direction(&mut self, is_output: bool) {

self.periph.modify(|_r, w| {

w.direction().set_bit(is_output)

});

}

pub fn set_input_mode(&mut self, variant: InputMode) {

self.periph.modify(|_r, w| {

w.input_mode().variant(variant)

});

}

pub fn set_output_mode(&mut self, is_high: bool) {

self.periph.modify(|_r, w| {

w.output_mode.set_bit(is_high)

});

}

pub fn get_input_status(&self) -> bool {

self.periph.read().input_status().bit_is_set()

}

}

However, this would allow us to modify certain registers that do not make sense. For example, what happens if we set the output_mode field when our GPIO is configured as an input?

In general, use of this structure would allow us to reach states not defined by our state machine above: e.g. an output that is pulled low, or an input that is set high. For some hardware, this may not matter. On other hardware, it could cause unexpected or undefined behavior!

Although this interface is convenient to write, it doesn't enforce the design contracts set out by our hardware implementation.

Design Contracts

In our last chapter, we wrote an interface that didn't enforce design contracts. Let's take another look at our imaginary GPIO configuration register:

Name Bit Number(s) Value Meaning Notes enable 0 0 disabled Disables the GPIO 1 enabled Enables the GPIO direction 1 0 input Sets the direction to Input 1 output Sets the direction to Output input_mode 2..3 00 hi-z Sets the input as high resistance 01 pull-low Input pin is pulled low 10 pull-high Input pin is pulled high 11 n/a Invalid state. Do not set output_mode 4 0 set-low Output pin is driven low 1 set-high Output pin is driven high input_status 5 x in-val 0 if input is < 1.5v, 1 if input >= 1.5v

If we instead checked the state before making use of the underlying hardware, enforcing our design contracts at runtime, we might write code that looks like this instead:

/// GPIO interface

struct GpioConfig {

/// GPIO Configuration structure generated by svd2rust

periph: GPIO_CONFIG,

}

impl GpioConfig {

pub fn set_enable(&mut self, is_enabled: bool) {

self.periph.modify(|_r, w| {

w.enable().set_bit(is_enabled)

});

}

pub fn set_direction(&mut self, is_output: bool) -> Result<(), ()> {

if self.periph.read().enable().bit_is_clear() {

// Must be enabled to set direction

return Err(());

}

self.periph.modify(|r, w| {

w.direction().set_bit(is_output)

});

Ok(())

}

pub fn set_input_mode(&mut self, variant: InputMode) -> Result<(), ()> {

if self.periph.read().enable().bit_is_clear() {

// Must be enabled to set input mode

return Err(());

}

if self.periph.read().direction().bit_is_set() {

// Direction must be input

return Err(());

}

self.periph.modify(|_r, w| {

w.input_mode().variant(variant)

});

Ok(())

}

pub fn set_output_status(&mut self, is_high: bool) -> Result<(), ()> {

if self.periph.read().enable().bit_is_clear() {

// Must be enabled to set output status

return Err(());

}

if self.periph.read().direction().bit_is_clear() {

// Direction must be output

return Err(());

}

self.periph.modify(|_r, w| {

w.output_mode.set_bit(is_high)

});

1 ... 14 15 16 17 18 19 20 21 22 ... 34
Перейти на страницу:
0
Сюжет
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
0
Атмосфера
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
0
Главный герой
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
0
Общее впечатление
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
Итоговая оценка: 0.0 из 10 (голосов: 0 / История оценок)