STM32 USB轉串口驅動移植到SylixOS中遇到的問題總結

1. 簡介 
        由於客戶項目需求,需要在STM32的硬件平臺上實現USB轉串口的功能,由於ST公司基於STM32硬件平臺實現了相應的USB庫以方便開發者進行開發,因此,在SylixOS下實現USB轉串口功能時對該USB庫進行了移植。由於該USB庫的實現是基於STM32的裸機代碼實現,因此在移植的過程中,不需要做過多的修改。 
        下面章節主要介紹在移植STM32的USB轉串口驅動到SylixOS下遇到的問題以及對應的解決方法。對於其中的有些解決方法在移植STM32其他外設驅動的過程中也依然適用。 

2. 移植遇到的問題及解決方法 
2.1 非對齊內存訪問錯誤 
        在移植完USB轉串口驅動後,燒寫SylixOS到STM32後,在運行過程中提示非法非對齊內存訪問的錯誤,並且在產生該問題後會導致系統一直重啓。調試過程中發現代碼運行到數據拷貝的語句發生錯誤,具體代碼如程序清單2.1所示。

程序清單2.1  非對齊內存訪問錯誤

USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev, 
                                uint8_t             *src, 
                                uint8_t              ch_ep_num, 
                                uint16_t             len)
{
    USB_OTG_STS status = USB_OTG_OK;
    if (pdev->cfg.dma_enable == 0) {
        uint32_t count32b = 0, i= 0;
        __IO uint32_t *fifo;
    
        count32b =  (len + 3) / 4;
        fifo = pdev->regs.DFIFO[ch_ep_num];
        for (i = 0; i < count32b; i++) {
            USB_OTG_WRITE_REG32(fifo, *((__packed uint32_t *)src));
            src += 4;
        }
    }
 
    return  status;
}

        運行過程中發現src的地址在會出現非四字節對齊的情況,並且在該情況發生後系統便會宕機重啓,對於該種問題可增加一個臨時變量解決,具體解決方法如程序清單2.2所示。

程序清單2.2  非對齊內存訪問錯誤解決方法

USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE    *pdev, 
                                uint8_t                *src, 
                                uint8_t                 ch_ep_num, 
                                uint16_t                len)
{
    USB_OTG_STS status = USB_OTG_OK;
    if (pdev->cfg.dma_enable == 0) {
        uint32_t count32b = 0, i = 0;
        __IO uint32_t *fifo;
        uint32_t data = 0;
 
        count32b = (len + 3) / 4;
        fifo = pdev->regs.DFIFO[ch_ep_num];
        for (i = 0; i < count32b; i++) {
            if (((uint32_t) src) % 4 == 0) {
                USB_OTG_WRITE_REG32(fifo, *((__packed uint32_t *)src));
            } else {
                lib_memcpy(&data, src, 4);
                USB_OTG_WRITE_REG32(fifo, data);
            }
            src += 4;
        }
    }
 
    return  status;
}

2.2 中斷優先級設置不當導致進入”Hard Fault”中斷 
        STM32採用的中斷控制器是NVIC,全稱爲Nested Vector Interrupt Controller,人們一般稱之爲“嵌套中斷向量控制器”,是用來管理中斷嵌套的,核心任務就是在於其優先級的管理。NVIC給每個中斷賦予先佔優先級和次佔優先級。具體關係描述如下: 
        1) 擁有較高先佔優先級的中斷可以打斷先佔優先級較低的中斷; 
        2) 若兩個先佔優先級的中斷同時掛起,則優先執行次佔優先級較高的中斷; 
        3) 若兩個掛起的中斷兩個優先級都一致,則優先執行位於中斷向量表中位置較高的中斷; 
        4) 無論任何時刻,次佔優先級都不會造成中斷嵌套,即中斷嵌套完全是由先佔優先級決定的。 
        在調試USB轉串口的過程中,由於系統tick中斷的先佔優先級被設置爲0(最高優先級)導致系統不停的重啓。需要注意的是,在對外設初始化的過程中,需要對外設中斷優先級進行手動設置,否則該外設中斷的先佔優先級將默認爲0。對於STM32的外設中斷優先級可以使用ST公司提供的庫函數進行設置,函數原型如程序清單2.3所示。

程序清單2.3  設置中斷優先級函數原型

void  HAL_NVIC_SetPriority(IRQn_Type       IRQn,
                           uint32_t        PreemptPriority, 
                           uint32_t        SubPriority)

函數HAL_NVIC_SetPriority原型分析: 
參數IRQn是中斷號; 
參數PreemptPriority是先佔優先級; 
參數SubPriority是子優先級。 
通常情況下,將外設中斷的先佔優先級設置爲0xF(最低優先級)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章