aboutsummaryrefslogtreecommitdiff
path: root/book/ru/src/by-example/app.md
blob: 18147dc3f8ffbd78782611f1d220531221ec3560 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# The `app` attribute

Это наименьшая возможная программа на RTFM:

``` rust
{{#include ../../../../examples/smallest.rs}}
```

Все программы на RTFM используют атрибут [`app`] (`#[app(..)]`). Этот атрибут
нужно применять к `const`-элементам, содержащим элементы. Атрибут `app` имеет
обязательный аргумент `device`, в качестве значения которому передается *путь*.
Этот путь должен указывать на библиотеку *устройства*, сгенерированную с помощью
[`svd2rust`] **v0.14.x**. Атрибут `app` развернется в удобную точку входа,
поэтому нет необходимости использовать атрибут [`cortex_m_rt::entry`].

[`app`]: ../../api/cortex_m_rtfm_macros/attr.app.html
[`svd2rust`]: https://crates.io/crates/svd2rust
[`cortex_m_rt::entry`]: ../../api/cortex_m_rt_macros/attr.entry.html

> **ОТСТУПЛЕНИЕ**: Некоторые из вас удивятся, почему мы используем ключевое слово `const` как
> модуль, а не правильное `mod`. Причина в том, что использование атрибутов на
> модулях требует feature gate, который требует ночную сборку. Чтобы заставить
> RTFM работать на стабильной сборке, мы используем вместо него слово `const`.
> Когда большая часть макросов 1.2 стабилизируются, мы прейдем от `const` к `mod` и в конце концов в атрибуту уровне приложения (`#![app]`).

## `init`

Внутри псевдо-модуля атрибут `app` ожидает найти функцию инициализации, обозначенную
атрибутом `init`. Эта функция должна иметь сигнатуру `[unsafe] fn()`.

Эта функция инициализации будет первой частью запускаемого приложения.
Функция `init` запустится *с отключенными прерываниями* и будет иметь эксклюзивный
доступ к периферии Cortex-M и специфичной для устройства периферии через переменные
`core` and `device`, которые внедряются в область видимости `init` атрибутом `app`.
Не вся периферия Cortex-M доступна в `core`, потому что рантайм RTFM принимает владение
частью из неё -- более подробно см. структуру [`rtfm::Peripherals`].

Переменные `static mut`, определённые в начале `init` будут преобразованы
в ссылки `&'static mut` с безопасным доступом.

[`rtfm::Peripherals`]: ../../api/rtfm/struct.Peripherals.html

Пример ниже показывает типы переменных `core` и `device` и
демонстрирует безопасный доступ к переменной `static mut`.

``` rust
{{#include ../../../../examples/init.rs}}
```

Запуск примера напечатает  `init` в консоли и завершит процесс QEMU.

```  console
$ cargo run --example init
{{#include ../../../../ci/expected/init.run}}```

## `idle`

Функция, помеченная атрибутом `idle` может присутствовать в псевдо-модуле
опционально. Эта функция используется как специальная *задача ожидания* и должна иметь
сигнатуру `[unsafe] fn() - > !`.

Когда она присутствует, рантайм запустит задачу `idle` после `init`. В отличие от
`init`, `idle` запустится *с включенными прерываниями* и не может завершиться,
поэтому будет работать бесконечно.

Когда функция `idle` определена, рантайм устанавливает бит [SLEEPONEXIT], после чего
отправляет микроконтроллер в состояние сна после выполнения `init`.

[SLEEPONEXIT]: https://developer.arm.com/products/architecture/cpu-architecture/m-profile/docs/100737/0100/power-management/sleep-mode/sleep-on-exit-bit

Как и в `init`, переменные `static mut`будут преобразованы в ссылки `&'static mut`
с безопасным доступом.

В примере ниже показан запуск `idle` после `init`.

``` rust
{{#include ../../../../examples/idle.rs}}
```

``` console
$ cargo run --example idle
{{#include ../../../../ci/expected/idle.run}}```

## `interrupt` / `exception`

Как Вы бы сделали с помощью библиотеки `cortex-m-rt`, Вы можете использовать атрибуты
`interrupt` и `exception` внутри псевдо-модуля `app`, чтобы определить обработчики
прерываний и исключений. В RTFM, мы называем обработчики прерываний и исключений
*аппаратными* задачами.

``` rust
{{#include ../../../../examples/interrupt.rs}}
```

``` console
$ cargo run --example interrupt
{{#include ../../../../ci/expected/interrupt.run}}```

До сих пор программы RTFM, которые мы видели не отличались от программ, которые
можно написать, используя только библиотеку `cortex-m-rt`. В следующем разделе
мы начнем знакомиться с функционалом, присущим только RTFM.