Выбрать главу

--name app

$ # следуйте остальным инструкциям

   2. Добавьте крейт доступа к периферии (PAC), сгенерированный с помощьюsvd2rust v0.14.x, или крейт отладочной платы, у которой в зависимостях один из таких PAC'ов. Убедитесь, что опция rt крейта включена.

В этом примере я буду использовать крейт устройства lm3s6965. Эта библиотека не имеет Cargo-опции rt; эта опция всегда включена.

Этот крейт устройства предоставляет линковочный скрипт с макетом памяти целевого устройства, поэтому memory.x и build.rs нужно удалить.

$ cargo add lm3s6965 --vers 0.1.3

$ rm memory.x build.rs

   3. Добавьте крейт cortex-m-rtic как зависимость.

$ cargo add cortex-m-rtic --allow-prerelease

   4. Напишите свою RTIC программу.

Здесь я буду использовать пример init из крейта cortex-m-rtic.

Примеры находтся в папке examples, а содержание init.rs показано здесь:

//! 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_metaclass="underline" :CriticalSection = cx.cs;

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

debug::exit(debug::EXIT_SUCCESS);

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

}

}

Пример init использует устройство lm3s6965. Не забудьте настроить аргумент device в атрибуте макроса app так, чтобы он соответствовал пути к PAC-крейту, если он отличается, а также добавить перифериб и другие аргументы если необходимо. Несмотря на то, что в программе могут использоваться псевдонимы типов, здесь необходимо указать полный путь (из корня крейта). Для многих устройств, есть общий подход в крейтах реализации HAL (с псевдонимом hal) и крейтах поддержки отладочных плат реекспортиорвать PAC как pac, что приводит нас к образцу, аналогичному приведенному ниже:

#![allow(unused)]

fn main() {

use abcd123_hal as hal;

//...

#[rtic::app(device = crate::haclass="underline" :pac, peripherals = true, monotonic = rtic::cyccnt::CYCCNT)]

mod app { /*...*/ }

}

Пример init также зависит от крейта panic-semihosting:

$ cargo add panic-semihosting

   5. Соберите его, загрузите в микроконтроллер и запустите.

$ # ПРИМЕЧАНИЕ: Я раскомментировал опцию `runner` в `.cargo/config`

$ cargo run

init

Все объекты, предоставляющие ресурысы реализуют трейт rtic::Mutex. Если ресурс не реализует его, можно обернуть его в новый тип rtic::Exclusive, который реализует трейт Mutex. С помощью этого нового типа можно написать обобщенную функцию, которая работает с обобщенным ресурсом и вызывать его из различных задач, чтобы производить однотипные операции над похожим множеством ресурсов. Вот один такой пример:

#![allow(unused)]

fn main() {

//! examples/generics.rs

#![deny(unsafe_code)]

#![deny(warnings)]

#![no_main]

#![no_std]

use cortex_m_semihosting::hprintln;

use panic_semihosting as _;

use rtic::Mutex;

#[rtic::app(device = lm3s6965)]

mod app {

use cortex_m_semihosting::{debug, hprintln};

use lm3s6965::Interrupt;

#[shared]

struct Shared {

shared: u32,

}

#[local]

struct Local {}

#[init]

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

rtic::pend(Interrupt::UART0);

rtic::pend(Interrupt::UART1);

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

}

#[task(binds = UART0, shared = [shared], local = [state: u32 = 0])]

fn uart0(c: uart0::Context) {

hprintln!("UART0(STATE = {})", *c.local.state).unwrap();

// second argument has type `shared::shared`

super::advance(c.local.state, c.shared.shared);

rtic::pend(Interrupt::UART1);

debug::exit(debug::EXIT_SUCCESS);