aboutsummaryrefslogtreecommitdiff
path: root/book/ru/src/by-example/tips.md
blob: 4a39cbc87da7602076a3dcff4391ecd91037146f (plain) (blame)
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
# Советы и хитрости

## Обобщенное программирование (Generics)

Ресурсы, совместно используемые двумя или более задачами, реализуют трейт `Mutex`
во *всех* контекстах, даже в тех, где для доступа к данным не требуются
критические секции. Это позволяет легко писать обобщенный код оперирующий
ресурсами, который можно вызывать из различных задач. Вот такой пример:

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

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

Это также позволяет Вам изменять статические приоритеты задач без
переписывания кода. Если Вы единообразно используете `lock`-и для доступа
к данным в разделяемых ресурсах, тогда Ваш код продолжит компилироваться,
когда Вы измените приоритет задач.

## Запуск задач из ОЗУ

Главной целью переноса описания программы на RTFM в атрибуты в
RTFM v0.4.x была возможность взаимодействия с другими атрибутами.
Напримерe, атрибут `link_section` можно применять к задачам, чтобы разместить
их в ОЗУ; это может улучшить производительность в некоторых случаях.

> **ВАЖНО**: Обычно атрибуты `link_section`, `export_name` и `no_mangle`
> очень мощные, но их легко использовать неправильно. Неверное использование
> любого из этих атрибутов может вызвать неопределенное поведение;
> Вам следует всегда предпочитать использование безопасных, высокоуровневых
> атрибутов вокруг них, таких как атрибуты `interrupt` и `exception`
> из `cortex-m-rt`.
>
> В особых случаях функций RAM нет безопасной абстракции в `cortex-m-rt`
> v0.6.5 но создано [RFC] для добавления атрибута `ramfunc` в будущем релизе.

[RFC]: https://github.com/rust-embedded/cortex-m-rt/pull/100

В примере ниже показано как разместить высокоприоритетную задачу `bar` в ОЗУ.

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

Запуск этой программы произведет ожидаемый вывод.

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

Можно посмотреть на вывод `cargo-nm`, чтобы убедиться, что `bar` расположен в ОЗУ
(`0x2000_0000`), тогда как `foo` расположен во Flash (`0x0000_0000`).

``` console
$ cargo nm --example ramfunc --release | grep ' foo::'
{{#include ../../../../ci/expected/ramfunc.grep.foo}}```

``` console
$ cargo nm --example ramfunc --release | grep ' bar::'
{{#include ../../../../ci/expected/ramfunc.grep.bar}}```

## `binds`

**ПРИМЕЧАНИЕ**: Требуется RTFM не ниже 0.4.2

Вы можете давать аппаратным задачам имена похожие на имена обычных задач.
Для этого нужно использовать аргумент `binds`: Вы называете функцию
по своему желанию и назначаете ей прерывание / исключение
через аргумент `binds`. `Spawn` и другие служебные типы будут размещены в модуле,
названном в соответствии с названием функции, а не прерывания / исключения.
Давайте посмотрим пример:

``` rust
{{#include ../../../../examples/binds.rs}}
```
``` console
$ cargo run --example binds
{{#include ../../../../ci/expected/binds.run}}```