Вграден софтуер

18 януари 2022

Общи разсъждения за embedded software

Общи разсъждения за embedded software

Общи разсъждения за embedded software

Общи разсъждения за embedded software

Общи разсъждения за embedded software

Общи разсъждения за embedded software

Общи разсъждения за embedded software

Възможни решения по дизайна на софтуера

Възможни решения по дизайна на софтуера

Често се налага да се правят компромиси, например

Възможни решения по дизайна на софтуера

Често се налага да се правят компромиси, например

Възможни решения по дизайна на софтуера

Често се налага да се правят компромиси, например

Възможни решения по дизайна на софтуера

Често се налага да се правят компромиси, например

Embedded ОС с Rust

Embedded ОС с Rust

Типични ОС с Rust: FreeRTOS, RTIC, Zephyr, Drone OS, VxWorks

Embedded ОС с Rust

Типични ОС с Rust: FreeRTOS, RTIC, Zephyr, Drone OS, VxWorks

Preemptive scheduling

Embedded ОС с Rust

Типични ОС с Rust: FreeRTOS, RTIC, Zephyr, Drone OS, VxWorks

Preemptive scheduling

Non-preemptive (cooperative) scheduling

Embedded ОС с Rust

Типични ОС с Rust: FreeRTOS, RTIC, Zephyr, Drone OS, VxWorks

Preemptive scheduling

Non-preemptive (cooperative) scheduling

WatchDog

Алгоритмичен дизайн

Алгоритмичен дизайн

Алгоритмичен дизайн

Алгоритмичен дизайн

Rust в embedded

Rust в embedded

Rust в embedded

Some comments on tools

Some comments on tools

Компилатора използва LLVM

Some comments on tools

Компилатора използва LLVM

(Дис)асемблер: cargo objdump --bin app ...

Необходимо е да сме инсталирали:
cargo install cargo-binutils
rustup component add llvm-tools-preview

Some comments on tools

Компилатора използва LLVM

(Дис)асемблер: cargo objdump --bin app ...

Необходимо е да сме инсталирали:
cargo install cargo-binutils
rustup component add llvm-tools-preview

Емулатор (QEMU): for Cortex-M3
qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb ... -kernel hello_world
Emulator crates

Some comments on tools

Компилатора използва LLVM

(Дис)асемблер: cargo objdump --bin app ...

Необходимо е да сме инсталирали:
cargo install cargo-binutils
rustup component add llvm-tools-preview

Емулатор (QEMU): for Cortex-M3
qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb ... -kernel hello_world
Emulator crates

OpenOCD е програма на host-a и превежда от GDB TCP/IP remote debug protocol и USB протокола. Допълнително
комуникира с memory-mapped registers за четене/писане и спиране на CPU-то от debug event.

Environment

Environment

Supported platforms

Environment

Supported platforms
A no_std Rust Environment

Environment

Supported platforms
A no_std Rust Environment

Environment

Supported platforms
A no_std Rust Environment

Environment

Supported platforms
A no_std Rust Environment

Environment

Supported platforms
A no_std Rust Environment

1 2 3 4
#![no_std]
fn main() {
  let a = Box::new(7);
}
error[E0433]: failed to resolve: use of undeclared type `Box` --> src/bin/main_2027d7438488e4bc0595f7894414ca942a118ce9.rs:3:11 | 3 | let a = Box::new(7); | ^^^ use of undeclared type `Box` For more information about this error, try `rustc --explain E0433`. error: could not compile `rust` due to previous error
#![no_std]
fn main() {
  let a = Box::new(7);
}

Hands on

Based on RustFest 2019

Hands on

Based on RustFest 2019

Installation on Ubuntu and installation on other platforms

1 2 3 4 5 6 7
sudo apt install -y pkg-config libusb-1.0-0-dev libftdi1-dev libudev-dev

cargo install cargo-flash

rustup target add thumbv6m-none-eabi

cargo flash --chip=LPC845M301JBD48

Hands on

Based on RustFest 2019

Installation on Ubuntu and installation on other platforms

1 2 3 4 5 6 7
sudo apt install -y pkg-config libusb-1.0-0-dev libftdi1-dev libudev-dev

cargo install cargo-flash

rustup target add thumbv6m-none-eabi

cargo flash --chip=LPC845M301JBD48

Error Failed to open the debug probe.

Hands on

Based on RustFest 2019

Installation on Ubuntu and installation on other platforms

1 2 3 4 5 6 7
sudo apt install -y pkg-config libusb-1.0-0-dev libftdi1-dev libudev-dev

cargo install cargo-flash

rustup target add thumbv6m-none-eabi

cargo flash --chip=LPC845M301JBD48

Error Failed to open the debug probe.
https://github.com/knurling-rs/probe-run

Hands on

Based on RustFest 2019

Installation on Ubuntu and installation on other platforms

1 2 3 4 5 6 7
sudo apt install -y pkg-config libusb-1.0-0-dev libftdi1-dev libudev-dev

cargo install cargo-flash

rustup target add thumbv6m-none-eabi

cargo flash --chip=LPC845M301JBD48

Error Failed to open the debug probe.
https://github.com/knurling-rs/probe-run

1 2 3
sudo apt-get install openocd

sudo cp /usr/lib/udev/rules.d/60-openocd.rules /etc/udev/rules.d/

Remove GROUP="plugdev" in /etc/udev/rules.d/60-openocd.rules

1 2 3
sudo apt-get install openocd

sudo cp /usr/lib/udev/rules.d/60-openocd.rules /etc/udev/rules.d/

Remove GROUP="plugdev" in /etc/udev/rules.d/60-openocd.rules

1 2 3
sudo udevadm control –reload

sudo udevadm trigger

Memory

Memory and all limitations are described in *.x files. Example memory.x:

1 2 3 4 5
MEMORY
{
FLASH : ORIGIN = 0x00000000, LENGTH = 64K
RAM   : ORIGIN = 0x10000000, LENGTH = 16K
}

Code:

Code:

1 2 3 4 5 6 7
#![no_main]
#![no_std]

extern crate panic_halt;

use lpc8xx_hal::{cortex_m_rt::entry, CorePeripherals, delay::Delay};
use lpc8xx_hal::embedded_hal::blocking::delay::DelayMs;

Защо трябва да се инсталира специален panic handler с panic_halt? Стандартната паника печата неща на екрана -- на платката, която ползвате, сигурно няма екран, или ако има, не е ясно какво значи "печатане".

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#[entry]
fn main() -> ! {
    let p = lpc8xx_hal::Peripherals::take().unwrap();
    let cp = CorePeripherals::take().unwrap();
    let mut syscon = p.SYSCON.split();
    let gpio = p.GPIO.enable(&mut syscon.handle);
    let mut led = p.pins.pio1_1.into_output_pin(gpio.tokens.pio1_1,
                                                lpc8xx_hal::gpio::Level::High,);
    let mut delay = Delay::new(cp.SYST);
    loop {
        delay.delay_ms(2_000u32);
        led.set_high();
        delay.delay_ms(2_000u32);
        led.set_low();
    }
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#[entry]
fn main() -> ! {
    let p = lpc8xx_hal::Peripherals::take().unwrap();
    let cp = CorePeripherals::take().unwrap();
    let mut syscon = p.SYSCON.split();
    let gpio = p.GPIO.enable(&mut syscon.handle);
    let mut led = p.pins.pio1_1.into_output_pin(gpio.tokens.pio1_1,
                                                lpc8xx_hal::gpio::Level::High,);
    let mut delay = Delay::new(cp.SYST);
    loop {
        delay.delay_ms(2_000u32);
        led.set_high();
        delay.delay_ms(2_000u32);
        led.set_low();
    }
}
1
cargo flash --chip=LPC845M301JBD48

Few words on panicking

Few words on panicking

Процес на develop-ване за embedded

Embedded Rust Ecosystem

Процес на develop-ване за embedded

Embedded Rust Ecosystem

Process: Power up the GPIO Peripherals, configure pin as output, set output to high/low

1 2 3
unsafe {
    *((GPIOC_START + CHR_OFFSET) as *mut u32) = (OUTPUT_MODE << 20) | (PUSH_PULL << 22);
}

Процес на develop-ване за embedded

Embedded Rust Ecosystem

Process: Power up the GPIO Peripherals, configure pin as output, set output to high/low

1 2 3
unsafe {
    *((GPIOC_START + CHR_OFFSET) as *mut u32) = (OUTPUT_MODE << 20) | (PUSH_PULL << 22);
}

svd files -> svd2rust generates rust crates => PAC(Peripherial Access Crates)

1 2 3 4 5 6
dp.GPIOC.crh.modify(|_r, w| {
        w.mode13().output().cnf13().push_pull()
});
dp.GPIOC.odr.modify(|_r, w| {
        w.odr13().high()
});

Процес на develop-ване за embedded

Embedded Rust Ecosystem

Process: Power up the GPIO Peripherals, configure pin as output, set output to high/low

1 2 3
unsafe {
    *((GPIOC_START + CHR_OFFSET) as *mut u32) = (OUTPUT_MODE << 20) | (PUSH_PULL << 22);
}

svd files -> svd2rust generates rust crates => PAC(Peripherial Access Crates)

1 2 3 4 5 6
dp.GPIOC.crh.modify(|_r, w| {
        w.mode13().output().cnf13().push_pull()
});
dp.GPIOC.odr.modify(|_r, w| {
        w.odr13().high()
});

Zero cost abstraction (in release mode), mostly safe

Процес на develop-ване за embedded

Embedded Rust Ecosystem

Process: Power up the GPIO Peripherals, configure pin as output, set output to high/low

1 2 3
unsafe {
    *((GPIOC_START + CHR_OFFSET) as *mut u32) = (OUTPUT_MODE << 20) | (PUSH_PULL << 22);
}

svd files -> svd2rust generates rust crates => PAC(Peripherial Access Crates)

1 2 3 4 5 6
dp.GPIOC.crh.modify(|_r, w| {
        w.mode13().output().cnf13().push_pull()
});
dp.GPIOC.odr.modify(|_r, w| {
        w.odr13().high()
});

Zero cost abstraction (in release mode), mostly safe
No check for peripheral dependencies and correct initialization

Процес на develop-ване за embedded

Embedded Rust Ecosystem

Process: Power up the GPIO Peripherals, configure pin as output, set output to high/low

1 2 3
unsafe {
    *((GPIOC_START + CHR_OFFSET) as *mut u32) = (OUTPUT_MODE << 20) | (PUSH_PULL << 22);
}

svd files -> svd2rust generates rust crates => PAC(Peripherial Access Crates)

1 2 3 4 5 6
dp.GPIOC.crh.modify(|_r, w| {
        w.mode13().output().cnf13().push_pull()
});
dp.GPIOC.odr.modify(|_r, w| {
        w.odr13().high()
});

Zero cost abstraction (in release mode), mostly safe
No check for peripheral dependencies and correct initialization

HALs - higher level interface around PAC

Embedded-hal, BSP, Crates

Embedded-hal

Rust has a common set of traits for building hardware abstraction layers: the embedded-hal crate. Includes GPIO,
timers, I2C, UART, etc…

Embedded-hal, BSP, Crates

Embedded-hal

Rust has a common set of traits for building hardware abstraction layers: the embedded-hal crate. Includes GPIO,
timers, I2C, UART, etc…
BSC: Board Support Crates

Embedded-hal, BSP, Crates

Embedded-hal

Rust has a common set of traits for building hardware abstraction layers: the embedded-hal crate. Includes GPIO,
timers, I2C, UART, etc…
BSC: Board Support Crates
RTIC: Real Time Interrupt Driven Concurrency (previoiusly known as RTFM)

Embedded-hal, BSP, Crates

Embedded-hal

Rust has a common set of traits for building hardware abstraction layers: the embedded-hal crate. Includes GPIO,
timers, I2C, UART, etc…
BSC: Board Support Crates
RTIC: Real Time Interrupt Driven Concurrency (previoiusly known as RTFM)
cortex-x crates: core peripherals, minimal runtime, debugging

Embedded-hal, BSP, Crates

Embedded-hal

Rust has a common set of traits for building hardware abstraction layers: the embedded-hal crate. Includes GPIO,
timers, I2C, UART, etc…
BSC: Board Support Crates
RTIC: Real Time Interrupt Driven Concurrency (previoiusly known as RTFM)
cortex-x crates: core peripherals, minimal runtime, debugging

Concurrency

Concurrency

Concurrency

1 2 3 4 5 6 7
cortex_m::interrupt::free(|_| {
    unsafe { COUNTER += 1 };
});

static COUNTER: AtomicUsize = AtomicUsize::new(0);
//...
COUNTER.fetch_add(1, Ordering::Relaxed);

Async/await

Async/await

Async/await

Async/await

I2C

Definition, Master-Slave, 2 lines, developed by Philips

I2C diagram

I2C

Definition, Master-Slave, 2 lines, developed by Philips

I2C diagram
Ferrous

Ползи от Rust

Ползи от Rust

Ползи от Rust

Ползи от Rust

Ползи от Rust

Ползи от Rust

Ползи от Rust

Ползи от Rust

Ползи от Rust

Въпроси