2019-02-08 21:18:51 +01:00
|
|
|
|
# Советы и хитрости
|
|
|
|
|
|
2019-02-09 06:48:12 +01:00
|
|
|
|
## Обобщенное программирование (Generics)
|
2019-02-08 21:18:51 +01:00
|
|
|
|
|
2019-02-09 06:48:12 +01:00
|
|
|
|
Ресурсы, совместно используемые двумя или более задачами, реализуют трейт `Mutex`
|
2019-02-08 21:18:51 +01:00
|
|
|
|
во *всех* контекстах, даже в тех, где для доступа к данным не требуются
|
|
|
|
|
критические секции. Это позволяет легко писать обобщенный код оперирующий
|
|
|
|
|
ресурсами, который можно вызывать из различных задач. Вот такой пример:
|
|
|
|
|
|
|
|
|
|
``` rust
|
2019-02-11 21:40:53 +01:00
|
|
|
|
{{#include ../../../../examples/generics.rs}}
|
2019-02-08 21:18:51 +01:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
``` console
|
|
|
|
|
$ cargo run --example generics
|
2019-02-11 21:40:53 +01:00
|
|
|
|
{{#include ../../../../ci/expected/generics.run}}```
|
2019-02-08 21:18:51 +01:00
|
|
|
|
|
|
|
|
|
Это также позволяет Вам изменять статические приоритеты задач без
|
|
|
|
|
переписывания кода. Если Вы единообразно используете `lock`-и для доступа
|
|
|
|
|
к данным в разделяемых ресурсах, тогда Ваш код продолжит компилироваться,
|
|
|
|
|
когда Вы измените приоритет задач.
|
|
|
|
|
|
2019-02-09 06:48:12 +01:00
|
|
|
|
## Запуск задач из ОЗУ
|
2019-02-08 21:18:51 +01:00
|
|
|
|
|
2020-06-11 19:18:29 +02:00
|
|
|
|
Главной целью переноса описания программы на RTIC в атрибуты в
|
|
|
|
|
RTIC v0.4.x была возможность взаимодействия с другими атрибутами.
|
2019-02-08 21:18:51 +01:00
|
|
|
|
Напримерe, атрибут `link_section` можно применять к задачам, чтобы разместить
|
2019-02-09 06:48:12 +01:00
|
|
|
|
их в ОЗУ; это может улучшить производительность в некоторых случаях.
|
2019-02-08 21:18:51 +01:00
|
|
|
|
|
|
|
|
|
> **ВАЖНО**: Обычно атрибуты `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
|
|
|
|
|
|
2019-02-09 06:48:12 +01:00
|
|
|
|
В примере ниже показано как разместить высокоприоритетную задачу `bar` в ОЗУ.
|
2019-02-08 21:18:51 +01:00
|
|
|
|
|
|
|
|
|
``` rust
|
2019-02-11 21:40:53 +01:00
|
|
|
|
{{#include ../../../../examples/ramfunc.rs}}
|
2019-02-08 21:18:51 +01:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Запуск этой программы произведет ожидаемый вывод.
|
|
|
|
|
|
|
|
|
|
``` console
|
|
|
|
|
$ cargo run --example ramfunc
|
2019-02-11 21:40:53 +01:00
|
|
|
|
{{#include ../../../../ci/expected/ramfunc.run}}```
|
2019-02-08 21:18:51 +01:00
|
|
|
|
|
2019-02-09 06:48:12 +01:00
|
|
|
|
Можно посмотреть на вывод `cargo-nm`, чтобы убедиться, что `bar` расположен в ОЗУ
|
2019-02-08 21:18:51 +01:00
|
|
|
|
(`0x2000_0000`), тогда как `foo` расположен во Flash (`0x0000_0000`).
|
|
|
|
|
|
|
|
|
|
``` console
|
|
|
|
|
$ cargo nm --example ramfunc --release | grep ' foo::'
|
2019-02-11 21:40:53 +01:00
|
|
|
|
{{#include ../../../../ci/expected/ramfunc.grep.foo}}```
|
2019-02-08 21:18:51 +01:00
|
|
|
|
|
|
|
|
|
``` console
|
|
|
|
|
$ cargo nm --example ramfunc --release | grep ' bar::'
|
2019-02-11 21:40:53 +01:00
|
|
|
|
{{#include ../../../../ci/expected/ramfunc.grep.bar}}```
|
2019-02-24 05:38:21 +01:00
|
|
|
|
|
|
|
|
|
## `binds`
|
|
|
|
|
|
2020-06-11 19:18:29 +02:00
|
|
|
|
**ПРИМЕЧАНИЕ**: Требуется RTIC не ниже 0.4.2
|
2019-02-24 05:38:21 +01:00
|
|
|
|
|
|
|
|
|
Вы можете давать аппаратным задачам имена похожие на имена обычных задач.
|
|
|
|
|
Для этого нужно использовать аргумент `binds`: Вы называете функцию
|
|
|
|
|
по своему желанию и назначаете ей прерывание / исключение
|
|
|
|
|
через аргумент `binds`. `Spawn` и другие служебные типы будут размещены в модуле,
|
|
|
|
|
названном в соответствии с названием функции, а не прерывания / исключения.
|
|
|
|
|
Давайте посмотрим пример:
|
|
|
|
|
|
|
|
|
|
``` rust
|
|
|
|
|
{{#include ../../../../examples/binds.rs}}
|
|
|
|
|
```
|
|
|
|
|
``` console
|
|
|
|
|
$ cargo run --example binds
|
|
|
|
|
{{#include ../../../../ci/expected/binds.run}}```
|