diff options
| author | Henrik Tjäder <henrik@tjaders.com> | 2023-02-24 21:28:13 +0100 |
|---|---|---|
| committer | Henrik Tjäder <henrik@tjaders.com> | 2023-03-01 00:35:25 +0100 |
| commit | 0fc86d972c0305e73252dc20d702d647eb342ee5 (patch) | |
| tree | eb01e1556958912344b890c964ff3f364aaad0d2 /book/ru/src/internals/late-resources.md | |
| parent | 032316855d8b55fc572ab7fcbd1de7ba394b2fd1 (diff) | |
Book: Remove RTIC v1 Russian translation
Diffstat (limited to 'book/ru/src/internals/late-resources.md')
| -rw-r--r-- | book/ru/src/internals/late-resources.md | 113 |
1 files changed, 0 insertions, 113 deletions
diff --git a/book/ru/src/internals/late-resources.md b/book/ru/src/internals/late-resources.md deleted file mode 100644 index 146c438..0000000 --- a/book/ru/src/internals/late-resources.md +++ /dev/null @@ -1,113 +0,0 @@ -# Поздние ресурсы - -Некоторые ресурсы инициализируются во время выполнения после завершения функции `init`. -Важно то, что ресурсы (статические переменные) полностью инициализируются -до того, как задачи смогут запуститься, вот почему они должны быть инициализированы -пока прерывания отключены. - -Ниже показан пример кода, генерируемого фреймворком для инициализации позних ресурсов. - -``` rust -#[rtic::app(device = ..)] -mod app { - struct Resources { - x: Thing, - } - - #[init] - fn init() -> init::LateResources { - // .. - - init::LateResources { - x: Thing::new(..), - } - } - - #[task(binds = UART0, resources = [x])] - fn foo(c: foo::Context) { - let x: &mut Thing = c.resources.x; - - x.frob(); - - // .. - } - - // .. -} -``` - -Код, генерируемы фреймворком выглядит примерно так: - -``` rust -fn init(c: init::Context) -> init::LateResources { - // .. пользовательский код .. -} - -fn foo(c: foo::Context) { - // .. пользовательский код .. -} - -// Public API -pub mod init { - pub struct LateResources { - pub x: Thing, - } - - // .. -} - -pub mod foo { - pub struct Resources<'a> { - pub x: &'a mut Thing, - } - - pub struct Context<'a> { - pub resources: Resources<'a>, - // .. - } -} - -/// Детали реализации -mod app { - // неинициализированная статическая переменная - static mut x: MaybeUninit<Thing> = MaybeUninit::uninit(); - - #[no_mangle] - unsafe fn main() -> ! { - cortex_m::interrupt::disable(); - - // .. - - let late = init(..); - - // инициализация поздних ресурсов - x.as_mut_ptr().write(late.x); - - cortex_m::interrupt::enable(); //~ compiler fence - - // исключения, прерывания и задачи могут вытеснить `main` в этой точке - - idle(..) - } - - #[no_mangle] - unsafe fn UART0() { - foo(foo::Context { - resources: foo::Resources { - // `x` уже инициализирована к этому моменту - x: &mut *x.as_mut_ptr(), - }, - // .. - }) - } -} -``` - -Важная деталь здесь то, что `interrupt::enable` ведет себя как *барьер компиляции*, который не дает компилятору переставить запись в `X` *после* -`interrupt::enable`. Если бы компилятор мог делать такие перестановки появились -бы гонки данных между этой записью и любой операцией `foo`, взаимодействующей с `X`. - -Архитектурам с более сложным конвейером инструкций нужен барьер памяти -(`atomic::fence`) вместо compiler fence для полной очистки операции записи -перед включением прерываний. Архитектура ARM Cortex-M не нуждается в барьере памяти -в одноядерном контексте. |
