Rust ile MahirKart Programlama

M Bilal Alpaslan
3 min readJun 3, 2023

--

MahirKart raspberry tarafından üretilen RP2040 işlemcisini kullanan bir aviyonik(havacılık elektroniği) geliştirme kartıdır. Bu makalede, MahirKart’ı Rust programlama diliyle nasıl programlayabileceğimizi göreceğiz.

Ön gereksinimler:

  • MahirKart
  • Type-C USB kablosu
  • Rust geliştirme ortamı(Rustup, Rustc ve cargo)

Derlenecek platformun eklenmesi

derleme adımında eğer hedef platformu belirtmezsek derleyici yalnızca derleme işleminin yapıldığı bilgisayarın işlemci mimarisine göre derleme işlemi yapacaktır. MahirKartın işlemcisi RP2040 ARMv6 mimarisinde olduğu için ilk önce bu mimari için gereken gereksinimleri kurmalıyız.

Rustup aracını kullanarak ARMv6 mimarisini ekliyoruz:

rustup target add thumbv6m-none-eabi

Platformu ekledikten sonra kodlamaya geçebiliriz.

Projemizi başlatalım

cargo init diyerek projemizi başlatıyoruz

cargo init

Sonrasında gereksinimleri kuruyoruz. Aslında bir gereksinim kurmadan da kodumuzu yazabiliriz ama işlemci ile alakalı bazı bilgiler için sürekli datasheet yada pin şeması üzerinden okuma işlemi yapmak yerine daha önceden hazırlanmış ve içerisinde birçok yardımcı işlev bulunduran HAL pakedini kullanıyoruz. Normalde bu yazıda PAC kullanarak nasıl programlayacağımızdan bahsedicektim.Peripheral Access Crate (PAC) paketleri Hardware Abstraction Layer (HAL) paketlerinin aksine kodunuzda sıfır yük oluşturlar. Tabiki bunun yanında da HAL pakedinin sağladığı bazı işlemleri manuel yapmanız gerekebilir ve kod çok uzadığı ve bu makalenin konusundan uzaklaştığı için bu yazıda HAL kullanmayı tercih ettim.

Gerekli paketleri ekledikten sonra Cargo.Toml sayfamız şöyle gözüküyor:

[package]
name = "blink-rp2040"
version = "0.1.0"
edition = "2021"

[dependencies]
cortex-m-rt = "0.7.0"
cortex-m = "0.7.0"
rp2040-boot2 = '0.3.0'
rp2040-pac = { git = "https://github.com/rp-rs/rp2040-pac", branch = "main" }
panic-halt = "0.2.0"
rp2040-hal = '0.8.2'
embedded-hal = '0.2.5'

Build ayarları için .cargo/config.toml dosyamızıda ARMv6 için ayarlıyoruz:

# .cargo/config.toml
[target.thumbv6m-none-eabi]
runner = "elf2uf2-rs -d"

rustflags = [
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=--nmagic",
]

[build]
target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0+

tabi burda runner kısmında kullandığımız elf2uf2-rs aracınıda kurmamız gerekiyor. Bu araç derlediğimiz kodu uf2 dosya formatına çeviriyor. kartı bilgisayarımıza takıldığımızda kendini depolama cihazı olarak gösteriyor ve uf2 uzantılı kodumuzu burdan yüklüyoruz.

Son olarak da MahirKart için memory.x dosyasında bellek ayarlarını tanıtmamız gerekiyor:

MEMORY {
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
RAM : ORIGIN = 0x20000000, LENGTH = 256K
}

EXTERN(BOOT2_FIRMWARE)

SECTIONS {
/* ### Boot loader */
.boot2 ORIGIN(BOOT2) :
{
KEEP(*(.boot2));
} > BOOT2
} INSERT BEFORE .text;

konfigürasyonlarla işimiz bittiğine göre artık koda geçebiliriz.

#![no_std]
#![no_main]

use embedded_hal::digital::v2::OutputPin;
use hal::{pac};
use rp2040_hal as hal;

use panic_halt as _;

#[link_section = ".boot2"]
#[used]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080;

const XTAL_FREQUENCY_HZ: u32 = 12_000_000u32;

#[cortex_m_rt::entry]
fn main() -> ! {
let mut pac = pac::Peripherals::take().unwrap();
let cp = pac::CorePeripherals::take().unwrap();

let mut watchdog = hal::watchdog::Watchdog::new(pac.WATCHDOG);

let _clocks = hal::clocks::init_clocks_and_plls(
XTAL_FREQUENCY_HZ,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();

let mut delay = cortex_m::delay::Delay::new(cp.SYST, 125_000_000);

let sio = hal::sio::Sio::new(pac.SIO);

let pins = hal::gpio::Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);

let mut led_pin = pins.gpio25.into_push_pull_output();

loop {
led_pin.set_high().unwrap();
delay.delay_ms(1000u32);
led_pin.set_low().unwrap();
delay.delay_ms(1000u32);
}
}

Aslında burdaki led_pin tanımlaması ve sonrasındaki loop dışında kalan kısımlar kullanıcağımız işlemcinin hazır hale gelmesi, kodun derlenme hedefinin belirtilmesi gibi işlemleri yapıyor, yine onları da da yorum satırlarında açıklamaya çalıştım ama asıl döngümüzü incelersek HAL pakedi ile birlikte basit bir şekilde kodumuzu yazabilliyoruz.

loop {
led_pin.set_high().unwrap();
delay.delay_ms(1000u32);
led_pin.set_low().unwrap();
delay.delay_ms(1000u32);
}

Hal kütüphanesini, sadece cortex-m pakedini ve hiçbir bağımlılık kullanmadan da bu işi nasıl yapacağımızı merak ediyorsanız sonraki yazılarımı bekleyebilirsiniz. o zamana kadar herkese hayırlı kodlamalar.

Hal ve Pac kullanarak Blink uygulamasını bu github reposunda bulabilirsiniz: https://github.com/BilalAlpaslan/rust-rp2040-blink

Kaynakça

https://mahirkart.net/
http://docs.mahirkart.net/

--

--