Rust एम्बेडेड दुनिया में धमाल मचा रहा है: C अब राजा क्यों नहीं है

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

परिचय: 'हार्डवेयर' का युग भाषा बदल रहा है

\n\n

यदि आपने कभी C में माइक्रोकंट्रोलर के लिए फर्मवेयर लिखा है, तो आप उस भावना को जानते हैं। वह भावना जब तीन घंटे की डिबगिंग के बाद आपको एक हैंग मिलता है — पॉइंटर आसमान में उड़ गया, और watchdog ने सब सहन कर लिया। एम्बेडेड डेवलपमेंट वर्षों तक C और असेंबली का क्षेत्र रहा। लेकिन पिछले कुछ वर्षों में, एक नया खिलाड़ी मैदान में आया है — Rust। और यह सिर्फ 'एक और भाषा' नहीं है, बल्कि एम्बेडेड सिस्टम के लिए एक वास्तविक सफलता है।

\n\n

इस लेख में, हम समझेंगे कि क्यों Rust पर एम्बेडेड डेवलपमेंट कोई हाइप नहीं, बल्कि एक आवश्यकता है। हम वास्तविक कोड उदाहरण देखेंगे, C से तुलना करेंगे और समझेंगे कि कहाँ से शुरू करें। यदि आप STM32, ESP32 या ARM Cortex-M के लिए लिखते हैं, तो यह आपके लिए है।

\n\n

क्यों Rust एम्बेडेड के लिए एक आदर्श जोड़ी है

\n\n

एम्बेडेड सिस्टम सीमाओं की दुनिया हैं। कम मेमोरी, कोई OS नहीं, कोई हीप नहीं, कोई अपवाद नहीं। कंपाइलेशन त्रुटि अच्छी है, रनटाइम त्रुटि बुरी है। Rust को ऐसी स्थितियों के लिए ही डिज़ाइन किया गया था।

\n\n

गार्बेज कलेक्टर के बिना मेमोरी सुरक्षा

\n\n

C में एम्बेडेड डेवलपर का मुख्य दर्द use-after-free, डबल मेमोरी फ्री और बफर ओवरफ्लो है। Rust इसे टाइप स्तर पर हल करता है। स्वामित्व (ownership) और उधार (borrowing) मॉडल no_std वातावरण में भी काम करता है — बिना एलोकेटर, OS या GC के।

\n\n

कल्पना करें कि आप एक LED के लिए ड्राइवर लिख रहे हैं। C में आप लिखेंगे:

\n\n
// C code\nvoid led_on(GPIO_TypeDef *gpio, uint16_t pin) {\n    gpio->BSRR = pin;\n}
\n\n

सब ठीक है, जब तक कोई NULL पॉइंटर पास न करे। Rust आपको ऐसा करने नहीं देगा:

\n\n
// Rust code\nfn led_on(gpio: &mut GpioRegisters, pin: u16) {\n    gpio.bsrr.write(|w| w.bits(pin.into()));\n}
\n\n

यहाँ &mut GpioRegisters एक गारंटी है कि रेफरेंस वैध है और रजिस्टरों तक पहुंच अनन्य है। कंपाइलर खतरनाक कोड को पास ही नहीं होने देगा।

\n\n

शून्य-लागत अब्स्ट्रैक्शन

\n\n

एम्बेडेड डेवलपर्स का एक मुख्य डर यह है कि एक उच्च-स्तरीय भाषा प्रोसेसर चक्रों को 'खाएगी'। Rust zero-cost abstractions के सिद्धांत का पालन करता है: आप केवल उसी के लिए भुगतान करते हैं जो आप उपयोग करते हैं। इटरेटर, क्लोजर, ट्रेट्स — ये सब उतने ही कुशल मशीन कोड में कंपाइल होते हैं जितना C में मैन्युअल लूप अनरोलिंग।

\n\n

इससे भी अधिक, Rust की एम्बेडेड इकोसिस्टम में ऐसे क्रेट हैं जो व्यक्तिगत निर्देशों के स्तर पर काम करते हैं। उदाहरण के लिए, cortex-m-rt बिना एक भी अनावश्यक निर्देश के इंटरप्ट वेक्टर और स्टार्टअप कोड उत्पन्न करता है।

\n\n

वास्तविक प्रोजेक्ट: Rust पर LED ब्लिंक करना (STM32)

\n\n

आइए STM32F3Discovery बोर्ड के लिए एक सरल प्रोग्राम लिखें। हम cortex-m-quickstart और embedded rust समुदाय के HAL का उपयोग करेंगे।

\n\n

चरण 1: प्रोजेक्ट सेटअप

\n\n

सुनिश्चित करें कि आपके पास Rust और ARM Cortex-M के लिए टूलचेन स्थापित है:

\n\n
rustup target add thumbv7em-none-eabihf\ncargo install cargo-generate
\n\n

टेम्पलेट से प्रोजेक्ट बनाएँ:

\n\n
cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart
\n\n

चरण 2: कोड लिखें

\n\n

src/main.rs खोलें और क्लासिक Blinky लिखें:

\n\n
#![no_std]\n#![no_main]\n\nuse cortex_m_rt::entry;\nuse panic_halt as _;\nuse stm32f3xx_hal::{pac, prelude::*};\n\n#[entry]\nfn main() -> ! {\n    // पेरिफेरल तक पहुंच प्राप्त करें\n    let dp = pac::Peripherals::take().unwrap();\n    let mut rcc = dp.RCC.constrain();\n    let mut gpioe = dp.GPIOE.split(&mut rcc.ahb);\n\n    // पिन PE9 को आउटपुट के रूप में कॉन्फ़िगर करें (LED LD1)\n    let mut led = gpioe\n        .pe9\n        .into_push_pull_output(&mut gpioe.moder, &mut gpioe.otyper);\n\n    loop {\n        led.set_high().unwrap();\n        cortex_m::asm::delay(8_000_000);\n        led.set_low().unwrap();\n        cortex_m::asm::delay(8_000_000);\n    }\n}
\n\n

यहाँ क्या हो रहा है?

\n
    \n
  • #![no_std] — हम नहीं हैं

ब्लॉग

पुस्तक अनुशंसाएँ