精品国产一区在线_av无码中文字幕无码王_天海翼三点刺激高潮不停_好硬好大好爽视频_欧美高清一区三区在线专区_香蕉黄色片

Rust 如何安全操作MCU寄存器

在嵌入式開發中,不可避免需要操作MCU的外設寄存器。在C/C++中通常根據芯片手冊的外設寄存器清單來定義一系列的寄存器結構體和位域偏移宏、位域掩碼宏等。C/C++的寄存器操作接口雖然使得執行效率非常高,且易于編寫,但通常需要非常小心核對寄存器偏移、位域偏移、位域值的有效范圍,因此驅動工程師需要非常小心對照芯片手冊去定義大量的硬件相關的接口,非常考驗耐心和細心。

通常來說,外設寄存器的接口普遍一致,不同的是寄存器名字和偏移值、位域定義等,定義這些接口需要實現大量重復的工作。

typedef struct 
{
  uint32_t Pin;        /*!< Specifies the GPIO pins to be configured.
                           This parameter can be any value of @ref GPIO_pins */
  uint32_t Mode;       /*!< Specifies the operating mode for the selected pins.
                           This parameter can be a value of @ref GPIO_mode */
  uint32_t Pull;       /*!< Specifies the Pull-Up or Pull-Down activation for the selected pins.
                           This parameter can be a value of @ref GPIO_pull */
  uint32_t Speed;      /*!< Specifies the speed for the selected pins.
                           This parameter can be a value of @ref GPIO_speed */
  uint32_t Alternate;  /*!< Peripheral to be connected to the selected pins
                            This parameter can be a value of @ref GPIOEx_Alternate_function_selection */
} GPIO_InitTypeDef;

#define  GPIO_MODE_INPUT                        (0x00000000u)   /*!< Input Floating Mode                   */
#define  GPIO_MODE_OUTPUT_PP                    (0x00000001u)   /*!< Output Push Pull Mode                 */
#define  GPIO_MODE_OUTPUT_OD                    (0x00000011u)   /*!< Output Open Drain Mode                */
#define  GPIO_MODE_AF_PP                        (0x00000002u)   /*!< Alternate Function Push Pull Mode     */
#define  GPIO_MODE_AF_OD                        (0x00000012u)   /*!< Alternate Function Open Drain Mode    */
#define  GPIO_MODE_ANALOG                       (0x00000003u)   /*!< Analog Mode  */

那么在Rust的MCU驅動開發中是否也同樣需要定義大量的結構體和常量宏呢?當然不再需要!

Rust 是一門高級語言, 最大的特點是安全,同時也非常適合系統級的開發,能直接操作底層內存。Rust可以像C/C++一樣操作裸指針,如Systick驅動可以定義如下

use volatile_register::{RW, RO}; 

pub struct SystemTimer { 
    p: &'static mut RegisterBlock 
}

#[repr(C)]  
struct RegisterBlock {  
    pub csr: RW,  
    pub rvr: RW,  
    pub cvr: RW,  
    pub calib: RO,  
}

impl SystemTimer {  
    pub fn new() -> SystemTimer {  
        SystemTimer {  
            p: unsafe { &mut *(0xE000_E010 as *mut RegisterBlock) }
        }
    }

    pub fn get_time(&self) -> u32 {  
        self.p.cvr.read()   
    }

    pub fn set_reload(&mut self, reload_value: u32) {
        unsafe { self.p.rvr.write(reload_value) }   
    }
}

pub fn example_usage() -> String {   
    let mut st = SystemTimer::new();   
    st.set_reload(0x00FF_FFFF);   
    format!("Time is now 0x{:08x}", st.get_time())   
}

該方式非常類似于C/C++中直接操作外設寄存器地址的方式來編寫驅動,顯而易見可以看到充斥著大量的unsafe標記的語句,表明該驅動可能調用了太多不安全的接口。

Rust 官方則推薦使用另外一種更加優雅,便捷的方式去操作寄存器。

如上圖所示,Rust在MCU寄存器與hal庫之間添加一個PACPeripheral Access Crate外設訪問庫),使用PAC單獨描述MCU和外設寄存器抽象接口層,該層無需手動編寫代碼,通過工具svd2rust自動生成。pac將會提供所有寄存器的操作接口,根據寄存器的只讀、只寫、讀寫權限自動生成接口,同時生成位域的屬性和相應的讀或寫接口。保證軟件層不會超出硬件的約束,因而可以避免產生未定義的行為。

以STM32的外設時鐘使能寄存器為例:

pac提供的接口使用如下:

let dp = pac::Peripherals::take().unwrap();
dp.RCC
  .ahb1enr
  .write(|w| w.gpioaen().set_bit().gpiocen().set_bit());
loop {
    // Read PC13 Input Value
    if !dp.GPIOC.idr.read().idr13().bit() {
        // Code if PC13 Low
    } else {
        // Code if PC13 High
    }
}

這種方式能非常直接的被調用,無需關注寄存器操作中常用的移位、與、或、非等位操作。編寫hal時只需要關注寄存器名稱、位域名稱即可。

在提供便捷的接口的同時,編譯出的二進制代碼的執行效率也幾乎與匯編代碼一致。

參考

STM32F4 Embedded Rust at the PAC: svd2rust (theembeddedrustacean.com)

PACs - Comprehensive Rust ???? (google.github.io)

Rust Embedded terminology - Discovery (rust-embedded.org)

聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 3
關注 15
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧
主站蜘蛛池模板: 日本最新在线 | 国产无遮挡又黄又爽免费视频 | 伊人av超碰久久久麻豆 | 一区二区三区日本 | 日本免费看黄 | 日本欧美精品 | 天天爽夜夜爽人人爽从早干到睌 | 极品大长腿啪啪高潮露脸 | 国产精品一区二区三区乱码 | 国产精品爽爽AV在线观看 | 欧美日韩高清无码 | 亚洲欧美日韩中文字幕在线一区 | 尤物av无码色av无码 | 人人妻人人添人人爽欧美一区 | 曰批全过程40分钟免费视频多人 | 国产精品一区二区久久沈樵 | 国产成人AV片无码免费 | 娇妻被黑人夹成了三明治 | 免费观看a级毛片视频 | 国产乱人乱精一区二视频国产精品 | 久久久99品牌的特色产品 | 在线观看免费视频网站 | 中文字幕网资源站97 | 一级黄色片一级黄色片 | 一群黑人大战亚裔女在线播放 | 国模吧av | 国产精品亚洲αv天堂无码 亚洲中文字幕精品一区二区三区 | 国产精品成人无码久久久久久 | 成人欧美一区二区三区视频不卡 | 丁香色天天 | 中文字幕在线中文一页 | 久久无套| 国产精品久久久久久久久久无遮挡 | 免费欧三a大片 | 国产精品久久久久久久四虎电影 | bbwcuckold精品熟妇 | com.国产 | 网站黄色在线观看免费 | 免费A级毛片无码免费视 | 久久亚洲aⅴ永久无码精品 五月天久久久久久九一站片 | 亚洲一区二区三区观看 |