Изменяемое глобальное состояние
К сожалению, аппаратура — это, по сути, не что иное, как изменяемое глобальное состояние, и для разработчика на Rust это может быть очень пугающе. Аппаратура существует независимо от структур нашего кода и может быть изменена в любой момент реальным миром.
Какими должны быть наши правила?
Как нам надёжно взаимодействовать с этой периферией?
- Всегда использовать
volatile-методы для чтения и записи в память периферии, так как она может измениться в любой момент. - В программе мы должны иметь возможность разделять любое количество доступов только для чтения к этой периферии.
- Если какой-то части программы нужен доступ на чтение и запись к периферии, она должна владеть единственной ссылкой на эту периферию.
Анализатор заимствований (borrow checker)
Последние два из этих правил звучат подозрительно похоже на то, что уже делает анализатор заимствований!
Представьте, что мы могли бы передавать владение этой периферией или предоставлять неизменяемые или изменяемые ссылки на неё?
Что ж, мы можем, но анализатор заимствований требует, чтобы существовал ровно один экземпляр каждой периферии, чтобы Rust мог корректно с этим работать. К счастью, в аппаратуре действительно есть только один экземпляр любой данной периферии, но как отразить это в структуре нашего кода?