Не так давно компания Google объявила, что в Android теперь поддерживается язык программирования Rust. В этой статье мы хотим показать, как язык Rust становится востребованным в разработке ядра Linux, в программировании микроконтроллеров и зачем нужен Rust и его польза для всей индустрии Embedded. В этом статье на нескольких простых примерах рассмотрим технические аспекты языка Rust для Embedded.
Rust – это язык системного программирования, предназначенный для обеспечения безопасности, скорости и параллелизма. Rust имеет множество функций времени и безопасности во время компиляции, чтобы избежать сбоев данных и общих ошибок, все с минимальными издержками до нуля. Язык сфокусирован на безопасной работе с памятью, обеспечивает автоматическое управление памятью и предоставляет средства для достижения высокого параллелизма выполнения заданий, при этом обходясь без использования сборщика мусора и runtime. Автоматическое управление памятью в Rust избавляет разработчика от манипулирования указателями и защищает от проблем, возникающих из-за низкоуровневой работы с памятью, таких как обращение к области памяти после её освобождения, разыменование нулевых указателей, выход за границы буфера и т.п. Для распространения библиотек, обеспечения сборки и управления зависимостями проектом развивается пакетный менеджер Cargo, позволяющий получить нужные для программы библиотеки в один клик. Cargo – это инструмент, который позволяет указывать необходимые зависимости для проектов на языке Rust и убедиться, что вы получите воспроизводимые сборки.
У Rust много плюсов:
Уже сегодня язык Rust в компании ShuraCore является любимым языком программирования у разработчиков, все больше клиентов при разработке ПО хотят видеть Rust, как базовый язык разработки софта, Embedded не исключение. Вот несколько пунктов почему Rust уже равный конкурент C/C++ в Embedded.
Мы подготовили небольшой пример мигания светодиодами на отладочной плате STM32f429i-disco.
cargo-features = ["default-run"]
[package]
authors = ["ShuraCore info@shuracore.com"]
categories = ["embedded", "no-std"]
name = "stm32f429i_disco"
version = "0.1.0"
edition = "2018"
[dependencies]
cortex-m = "0.6.2"
cortex-m-rt = "0.6.12"
panic-halt = "0.2.0"
[dependencies.stm32f4]
version = "0.10.0"
features = ["stm32f429", "rt"]
[dependencies.stm32f4xx-hal]
version = "0.7"
features = ["rt", "stm32f429"]
#![deny(unsafe_code)]
#![no_main]
#![no_std]
// Halt on panic
#[allow(unused_extern_crates)]
extern crate panic_halt; // panic handler
use cortex_m;
use cortex_m_rt::entry;
use stm32f4xx_hal as hal;
use crate::hal::{prelude::*, stm32};
#[entry]
fn main() -> ! {
if let (Some(dp), Some(cp)) = (
stm32::Peripherals::take(),
cortex_m::peripheral::Peripherals::take(),
) {
// Set up the LEDs. On the stm32f429i-disco they are connected to pin PG13 and PG14.
let gpiog = dp.GPIOG.split();
let mut led3 = gpiog.pg13.into_push_pull_output();
let mut led4 = gpiog.pg14.into_push_pull_output();
// Set up the system clock. We want to run at 180MHz for this one.
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.sysclk(180.mhz()).freeze();
// Create a delay abstraction based on SysTick
let mut delay = hal::delay::Delay::new(cp.SYST, clocks);
loop {
// On for 1s, off for 1s.
led3.set_high().unwrap();
led4.set_low().unwrap();
delay.delay_ms(1000_u32);
led3.set_low().unwrap();
led4.set_high().unwrap();
delay.delay_ms(1000_u32);
}
}
loop {}
}
В 2020 году разработчики ядра Linux предложили использовать Rust для разработки нового кода. В марте 2021 года эта идея была частично реализована — в состав ветки linux-next, на которой базироваться Linux 5.13, включили начальный набор компонентов для разработки драйверов устройств на Rust. Корпорация Google уже заявила о намерении принять участие в инициативе по продвижению поддержки Rust в ядро Linux. Компания привела примеры целесообразности внедрения Rust для борьбы с проблемами, которые возникают из-за ошибок при работе с памятью. Представители компании также считают, что Rust вполне готов присоединиться к C, став еще одним языком разработки компонентов ядра Linux.
Вашему вниманию пример драйвера для Linux на языке Rust.
[package] name = "test_example" version = "0.1.0" authors = ["ShuraCore <info@shuracore.com>"] edition = "2018" [lib] crate-type = ["staticlib"] [dependencies] linux-kernel-module = { path = ".." } [profile.release] panic = "abort" lto = true [profile.dev] panic = "abort"
#![no_std] #![feature(alloc)] extern crate alloc; use crate::alloc::string::{String, ToString}; use linux_kernel_module::c_types; use linux_kernel_module::println; struct ShuraCoreModule { message: String, } impl linux_kernel_module::KernelModule for ShuraCoreModule { fn init() -> linux_kernel_module::KernelResult { println!("Hello from ShuraCore!"); Ok(ShuraCoreModule { message: "Hello ShuraCore!".to_string(), }) } } impl Drop for ShuraCoreModule { fn drop(&mut self) { println!("Goodbye from ShuraCore!"); } } static mut MODULE: Option = None; #[no_mangle] pub extern "C" fn init_module() -> c_types::c_int { match ::init() { Ok(m) => { unsafe { MODULE = Some(m); } return 0; } Err(_e) => { return 1; } } } #[no_mangle] pub extern "C" fn cleanup_module() { unsafe { MODULE = None; } } #[link_section = ".modinfo"] pub static MODINFO: [u8; 12] = *b"license=GPL\0";
В тенденциях Google вы можете увидеть, как результаты поиска Rust растут из года в год, все потому что у Rust народная любовь.
Когда дело доходит до популярности, Rust на первом месте. С 2015 года Rust был признан разработчиками самым любимым языком программирования в опросе разработчиков Stack Overflow пять лет подряд (2016, 2017, 2018, 2019, 2020):
Все больше и больше корпораций и компаний используют Rust в коммерческой разработке, вот их небольшая часть: Dropbox, Coursera, Figma, npm, Microsoft, Cloudflare, Facebook, Amazon, Discord и другие крупные игроки. По официальной статистике уже более 300 компаний по всему миру используют Rust в коммерческой разработке.
Итого, Rust – это язык системного программирования, который сочетает в себе гарантии надёжности и корректности процесса формирования программного обеспечения во время компиляции с высокой производительностью. Он улучшает идеи других системных языков, таких как С/C++, обеспечивая при этом гарантированную безопасность памяти (без сбоев, без скачков данных) и полный контроль над жизненным циклом памяти. Цель Rust – показать высокую продуктивность программного обеспечения в конкретных областях использования. Наша команда специалистов использует Rust в качестве языка программирования для создания системного программного обеспечения нового уровня со взглядом на завтрашний день. Инженеры ШураКор разрабатывают ПО для следующих областей применения: