Читаем Real-Time Interrupt-driven Concurrency полностью

Real-Time Interrupt-driven Concurrency

https://rtic.rs/dev/book/ru/ Конкурентный фреймворк для создания систем реального времени #Rust , #RTIC , #RTOS

Коллектив авторов

Компьютеры и Интернет / Учебные пособия, самоучители 18+

   • etrombly/sandbox. Аппаратный дзэн-сад, рисующий картинки на песке. Картинки передаются по последовательному порту с помощью G-кода.

<p id="Атрибут_app"><strong><a l:href="#Атрибут_app">Атрибут</a></strong><code><strong><a l:href="#Атрибут_app">app</a></strong></code></p>

Это простейшая из возможных программ на RTIC:

#![allow(unused)]

fn main() {

//! examples/smallest.rs

#![no_main]

#![no_std]

use panic_semihosting as _; // panic handler

use rtic::app;

#[app(device = lm3s6965)]

mod app {

#[shared]

struct Shared {}

#[local]

struct Local {}

#[init]

fn init(_: init::Context) -> (Shared, Local, init::Monotonics) {

(Shared {}, Local {}, init::Monotonics())

}

}

}

Все программы на RTIC используют атрибут app (#[app(..)]). Этот атрибут должен применяться к элементу mod. Атрибут app имеет обязательный аргумент device, который принимает путь как значение. Это должен быть полный путь, указывающий на крейт доступа к периферии (PAC), сгенерированный с помощью svd2rust версии v0.14.x или новее. Более подробно в разделе Создание нового проекта.

Атрибут app будет раскрыт в подходящую точку входа программы, поэтому атрибут cortex_m_rt::entry не нужен.

<p id="init"><code><strong><a l:href="#init">init</a></strong></code></p>

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

Эта функция инициализации будет первой частью программы, выполняемой при запуске. Функция init будет запущена с отключенными прерываниями и будет иметь эксклюзивный доступ к Cortex-M, в котором токен bare_metal::CriticalSection доступен как cs. Опционально, устройство-специфичные периферия доступна через поля core и device структуры init::Context.

static mut переменные, определенные в начале init будут преобразованы в &'static mut ссылки, безопасные для доступа. Обратите внимание, данная возможность может быть удалена в следующем релизе, см. task_local ресурсы.

Пример ниже показывает типы полей core, device и cs, и демонстрирует безопасный доступ к static mut переменной. Поле device доступно только когда аргумент peripherals установлен в true (по умолчанию). В редких случаях, когда вы захотите создать приложение с минимальным потреблением ресурсов, можно явно установить peripherals в false.

#![allow(unused)]

fn main() {

//! examples/init.rs

#![deny(unsafe_code)]

#![deny(warnings)]

#![no_main]

#![no_std]

use panic_semihosting as _;

#[rtic::app(device = lm3s6965, peripherals = true)]

mod app {

use cortex_m_semihosting::{debug, hprintln};

#[shared]

struct Shared {}

#[local]

struct Local {}

#[init(local = [x: u32 = 0])]

fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) {

// Cortex-M peripherals

let _core: cortex_m::Peripherals = cx.core;

// Device specific peripherals

let _device: lm3s6965::Peripherals = cx.device;

// Locals in `init` have 'static lifetime

let _x: &'static mut u32 = cx.local.x;

// Access to the critical section token,

// to indicate that this is a critical seciton

let _cs_token: bare_metal::CriticalSection = cx.cs;

hprintln!("init").unwrap();

debug::exit(debug::EXIT_SUCCESS);

(Shared {}, Local {}, init::Monotonics())

}

}

}

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

$ cargo run --example init

init

<p id="idle"><code><strong><a l:href="#idle">idle</a></strong></code></p>

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

Если она присутствует, задача idle будет запущена после init. В отличие от init, idle будет запущена с включенными прерываниями и она не может вернуть результат, а значит должна работать вечно.

Если функция idle не определена, среда вполнения устанавливает бит SLEEPONEXIT, а затем отправляет микроконтроллер в сон после запуска init.

Похожие книги