YTM32的flash應用答疑-詳解寫保護功能
文章目錄
- YTM32的flash應用答疑-詳解寫保護功能
- Introduction
- Principle
- Operation & Demonstration
- Demo #1 驗證基本的寫保護功能
- Demo #2 編程CUS_NVR設定EFM_ADDR_PROT初值
- Demo #3 啟用寫保護后試試塊擦除操作
- Conclusion
Introduction
客戶提出了一種應用場景:在使用某些授權軟件(算法)的場景中,軟件(算法)供應商向MCU的一些預留的存儲區中寫入專用的授權憑證,該憑證一機一碼,各不相同,從而確保軟件(算法)不會被非法復制。但對于MCU的應用開發者來說,經常需要刷寫片內存儲空間,更新程序或者數據,此時希望小心保存位于MCU內部存儲器上的憑證,在開發和后期正常使用的過程中,不要被意外擦除,否則重新授權需要又需要額外的費用、時間和流程等。
絕大多數MCU的片內flash存儲器管理模塊都提供了寫保護功能,當對已經設置保護功能的存儲區進行擦寫操作時,擦寫的實際效果將失效,被保護存儲區中的數據得以幸免留存,已達到防止誤擦除的效果。
Principle
以YTM32B1MD14
微控制器為例,其中片內flash控制器模塊EFM
,對應有EFM_ADDR_PROT[0]
和EFM_ADDR_PROT[1]
寄存器,其中每個比特可以保護8KB
的存儲區,按序分布,覆蓋全部的片內flash的地址區域。
EFM_ADDR_PROT
寄存器位的值為0
時,寫保護發生作用,對應位的值為1
時,寫保護不起作用,可以正常擦寫。
有兩種方式可以配置EFM_ADDR_PROT
寄存器的值:
- 向
CUS_NVR
中0x10
和0x18
地址寫數,這里的配置值將作為EFM_ADDR_PROT
寄存器的初值,在硬件復位后自動生效(由boot rom復制到EFM_ADDR_PROT
寄存器中)。但寫入每個寄存器初值時要注意,高32位數必須為0x5A5A5A5A
,然后才是32位的有效配置值。 - 向
EFM_ADDR_PROT
寄存器直接寫數,寫數之后在程序運行過程中生效,但復位后受CUS_NVR
中的初值影響,在軟件生效之前,需要保護的區域可能有被篡改的風險。- 在軟件中,從1寫0是可以的,但從0寫1是無效的。在程序運行中,只能上鎖不能解鎖。如果想重新操作,只能復位重來。
需要特別注意的是,CUS_NVR
也是位于flash存儲器上,具體是在pflash1
的尾端。如圖x所示。
這里的EFM_ADDR_PROT
保護的是地址空間,而不是物理存儲。對于YTM32B1MD14
這種用兩個pflash
物理存儲器集成在一起具有硬件AB面分區的內部存儲設備,若交換了物理存儲區,切換了地址空間和實際物理存儲器的映射關系,則原有的配置下實際執行保護的區域也會發生變化。實際上,CUS_NVR
和BOOT SWAP
操作的初始化參數共用的一個 Sector,因此在執行 BOOT_SWAP
命令(交換pflash0
和pflash1
的地址映射區域) 后,關閉調試接口和地址保護的配置會丟失,需要重新配置。同理,擦除CUS_NVR
后SWAP BOOT
信息也會丟失,如需要重映射后的地址空間,需要重新執行BOOT SWAP
操作。
另外,如果在flash塊上對任意一塊存儲區啟用了寫保護,則整塊flash存儲器的塊擦除操作都不能生效。但如果通過在CUS_NVR中解除寫保護配置后復位,就可以恢復對整塊flash的擦除操作。
Operation & Demonstration
設計用例,演示flash寫保護的起作用的情況。
Demo #1 驗證基本的寫保護功能
- 默認上電復位后,MCU未對任何地址啟用寫保護功能。
- 先向
0x3E000 - 0x40000
(pflash0的最后一個8KB存儲塊)擦除后再寫一組數據。通過調試器觀察flash存儲區的數據已經生效。
- 然后執行
EFM_ADDR_PROT |= (1u << 31u)
,配置寫保護。 - 再試著擦除
0x3E000 - 0x40000
內存區間的數據。執行擦除操作之后,通過調試器觀察flash存儲區的數據是否仍留存。
通過實驗可以觀察到,當配置寫保護后,再次試圖擦除指定內存區域的存儲空間后,原來寫入的數據仍然保留,未受擦除操作影響。
Demo #2 編程CUS_NVR設定EFM_ADDR_PROT初值
在之前的用例中,可以看到在默認情況下,EFM_ADDR_PROT[0]
和EFM_ADDR_PROT[1]
寄存器的值都是0xFFFFFFFF
。如圖x所示。
通過向CUS_NVR
中0x10
和0x18
地址寫數,更改寫保護的初值。但此時,因為尚未復位,芯片硬件也沒有執行從CUS_NVR
向EFM_ADDR_PROT
導入配置的操作,因此,仍然可以擦寫 flash。如圖x所示。
在調試環境中復位芯片,重新執行演示用例程序,從log和寄存器觀察窗口中可以觀察到,CUS_NVR
中配置的初值已經載入到了EFM_ADDR_PROT
寄存器。在執行后續的擦寫操作時,可以看到實際的flash存儲的值沒有因為擦寫操作而變化,說明寫保護作用已經生效。如圖x所示。
注意:在MD和ME的芯片里,NVR里的數據對于用戶不是直接可見的,需要通過專門的讀操作才能拿到其中存放的數據。
再繼續試一下解除寫保護的情況。重新復位芯片,在log交換中解除寫保護。發現此時不需要復位,EFM_ADDR_PROT
的寄存器的值就已經同步過來了, 對應當下就可以恢復對flash的擦寫操作。如圖x所示。
Demo #3 啟用寫保護后試試塊擦除操作
在測試用例中:
- 先在未啟用寫保護的情況下,在flash中寫好預設的數據,復位。
- 在
CUS_NVR
中啟用寫保護,復位,讓寫保護生效。 - 再試著執行塊擦除操作。
從圖x中可以看到,啟用寫保護之后,執行flash塊擦除操作后,預先存入flash中的數據未受影響。
Conclusion
本文專門講解和驗證了YTM32的flash寫保護的功能。
EFM_ADDR_PROT
寄存器中的每個bit可以控制啟用對應一塊區域(8KB for MD),但只能開啟寫保護不能解除。如需解除必須復位,重新導入CUS_NVR
的值。- 在運行軟件時,可以直接寫
EFM_ADDR_PROT
寄存器啟用寫保護。但只能1變0(啟用寫保護),不能0變1(解除寫保護)。 EFM_ADDR_PORT
寄存器的初值是從CUS_NVR
導入的,因此可以通過擦寫CUS_NVR
設定片內flash存儲的上電復位默認狀態。- 在
CUS_NVR
中啟用寫保護需要復位后才能生效,但解除寫保護是可以不等復位立即生效的。 - 如果在flash塊上對任意一塊存儲區啟用了寫保護,則整塊flash存儲器的塊擦除操作都不能生效。
本文中使用了兩個測試工程如下,或者私信作者獲取。
- https://gitee.com/suyong_yq/arm-mcu-sdk-release/blob/master/ytm32-evk/evb-ytm32b1md-q100_efm_flash_write_protect_mdk.zip
- https://gitee.com/suyong_yq/arm-mcu-sdk-release/blob/master/ytm32-evk/evb-ytm32b1md-q100_efm_flash_write_protect_cus_nvr_mdk.zip