近日,有位STM32用戶在使用STM32芯片內置的BOOTLOADER對芯片進行MCU芯片的信息讀取及編程。他發現通過UART接口使用相關BOOTLAODER指令對STM32F1系列芯片的各項功能進行讀寫時都正常。當改到STM32F4系列時發現有些命令運行就不正常,比如通過READ MEMORY指令獲取UID或FLASH SIZE時就會出錯。
從STM32F4參考手冊中可以得知:Flash size Base address: 0x1FFF 7A22; 讀取FLASH SIZE操作步驟及現象如下: 1、啟動讀內存指令 11 EE 反饋79 2、讀內存地址 1F FF 7A 22 B8 反饋79 1F 3、讀內存字節數 01 FE 反饋 79 31 00 00 79 上面的現象除了第一步,另外兩步都不是用戶所期待的數據或反饋。其中第三步的01 FE正好跟獲取自舉程序版本和讀保護狀態的命令相同,用戶懷疑是否發生了命令沖突。
在談這個問題之前,我們有必要大致了解一些背景知識。 STM32芯片的片上FLASH往往由幾部分組成。以STM32F40X/STM32F41X為例,主要由以下幾部分組成:【main memory/system memory/OTP/option bytes】 
其中SYSTEM MEMORY[系統存儲區]用來存放系統啟動程序和部分其它芯片特征信息,當芯片配置為從SYSTEM MEMORY啟動時,芯片復位后就會從這里開始執行程序。 當MCU進入系統啟動模式后,用戶可以通過多種串行接口與MCU通信。自然,這里就定義了一些相關協議的操作命令。

上表是針對UART接口的BOOTLOADER命令集及說明,比方GO/Get ID/Read Memory/Write memory等。其實不管你用哪種接口,這些BOOTLOADER協議命令都是一樣的。
當主機【比如PC】給MCU發正確命令包時 BOOTLOADER會反饋一個ACK, 即0X79。 當主機給MCU發出錯誤指令或指令運行異常時它會反饋NACK,即0X1F。

盡管說不論哪種接口或芯片的BOOTLOADER的協議命令是一樣的,但這些命令所操作的對象或參數可能會因芯片型號或bootloader版本的的不同而呈現差異。

也就是說,不同STM32系列的PID數據、bootloader命令可訪問的RAM和system memory的存儲空間范圍可能不同。
好,該回到開篇客戶反映的問題了。客戶想通過READ MEMORY指令讀取片內FLASH SIZE.
我們查看STM32F1參考手冊得知有關FLASH SIZE寄存器的地址是:0x1fff f7e0; 查看STM32F4參考手冊得知有關FLASH SIZE寄存器的地址是:0x1fff 7a22; 現在現象是命令一樣,接口一樣,唯一差別就是二者地址不一樣。結合前面的介紹,難道是二者SYSTEM MEMORY地址空間不一樣導致?我們可以查看二者的參考手冊或者ST官方的應用筆記AN2606查看二者的信息。
我們可以得知STM32F1的SYSTEM MEMORY地址空間為0x1ffff 000--0x1fff f7ff或0x1fff b000--0x1fff f7ff。STM32F4的SYSTEM MEMORY地址空間為0x1ffff000--0x1fff77ff。【在本文的第一個表格里就可看到】

到此,不難看出F4的flash size寄存器地址沒有落在自身的SYSTEM MEMORY區,而F1的就落在它自身的SYSTEM MEMORY之內。也就是說,在用READMEMORY命令對STM32F4芯片發送的那個地址是非法的,從而導致錯誤。當然對于讀STM32F4的UID也有同樣的問題。所以在應用中我們要注意這些諸如Read /Write/Go命令是有地址范圍訪問限制的。

下面對客戶反饋過來的結果做個簡單解讀: 從STM32F4參考手冊中可以得知:Flash size Base address: 0x1FFF 7A22; 讀取FLASH SIZE操作步驟及現象如下: 1、讀內存指令啟動 11 EE 反饋79 2、讀內存地址 1F FF 7A22 B8 反饋79 1F 3、讀內存字節數 01 FE 反饋 79 31 00 00 79
第一步,主機發出read memory 指令,MCU反饋ACK,即0X79,這步正確的。 緊跟第二步,主機發出地址及地址數據的異或碼【藍色數據】。命令本身是沒問題的,MCU反饋ACK,0X79,但地址數據非法,隨即反饋NACK即0X1F;此次命令以失敗而結束。 當進行到第三步時,01 FE被重新識別為獲取自舉程序版本和讀保護狀態的命令。命令正確并給予ACK確認,并給出版本號3.1及相關選項數據,最后以ACK 0x79結束。 經過三步下來,最后并沒有出現客戶所期待的結果。原因很簡單,命令地址非法。
關于使用systembootloader的調試編程,ST官方有篇應用筆記AN2606首先需要閱讀,再就是結合你的通信接口選擇下面羅列出的相應筆記進行閱讀。 
相關話題鏈接【點擊即可閱讀】
1.一個關于STM32 FLASH編程應用相關的話題 2.STM32F0的BOOT配置及相關話題 3.聊聊STM32芯片的DFU編程及相關話題
|