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 非對齊內存訪問錯誤ui
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 非對齊內存訪問錯誤解決方法code
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(最低優先級)。原型