如何获取STM32 MCU的唯一ID
前段時間由于應用需要對產(chǎn)品授權(quán)進行限制,所以研究了一下有關(guān)STM32 MCU的唯一ID的資料,并最終利用它實現(xiàn)了我們的目標。
1、基本描述
在STM32的全系列MCU中均有一個96位的唯一設(shè)備標識符。在ST的相關(guān)資料中,對其功能的描述有3各方面:
- 用作序列號(例如 USB 字符串序列號或其它終端應用程序)
- 在對內(nèi)部 Flash 進行編程前將唯一 ID 與軟件加密原語和協(xié)議結(jié)合使用時用作安全密鑰以提高 Flash 中代碼的安全性
- 激活安全自舉過程等
在資料中對其特性的描述是:96 位的唯一設(shè)備標識符提供了一個對于任何設(shè)備和任何上下文都唯一的參考號碼。用戶永遠不能改變這些位。96 位的唯一設(shè)備標識符也可以以單字節(jié)/半字/字等不同方式讀取,然后使用自定義算法連接起來。
想要讀取唯一ID,就需要知道它的存儲地址,在不同系列的MCU中地址是有差別的,我們查詢了部分MCU的資料并將其總結(jié)如下:
2、獲取唯一ID
前面我們對唯一ID做了簡單的描述,并且得到了其存儲地址,接下來我們說以說如何得到這個ID。
前面已經(jīng)描述過唯一ID可以按字節(jié)、半字、字等方式讀取。唯一ID是一個96位的信息串,所以按字讀取就是3個字,按半字讀取就是6個,按字節(jié)讀取就是12個。本質(zhì)上沒有區(qū)別,在這里我們按字讀取。
/*定義STM32 MCU的類型*/ typedef enum {STM32F0,STM32F1,STM32F2,STM32F3,STM32F4,STM32F7,STM32L0,STM32L1,STM32L4,STM32H7, }MCUTypedef;uint32_tidAddr[]={0x1FFFF7AC,? /*STM32F0唯一ID起始地址*/0x1FFFF7E8,? /*STM32F1唯一ID起始地址*/0x1FFF7A10,? /*STM32F2唯一ID起始地址*/0x1FFFF7AC,? /*STM32F3唯一ID起始地址*/0x1FFF7A10,? /*STM32F4唯一ID起始地址*/0x1FF0F420,? /*STM32F7唯一ID起始地址*/0x1FF80050,? /*STM32L0唯一ID起始地址*/0x1FF80050,? /*STM32L1唯一ID起始地址*/0x1FFF7590,? /*STM32L4唯一ID起始地址*/0x1FF0F420}; /*STM32H7唯一ID起始地址*//*獲取MCU的唯一ID*/ voidGetSTM32MCUID(uint32_t *id,MCUTypedef type) {if(id!=NULL){id[0]=*(uint32_t*)(idAddr[type]);id[1]=*(uint32_t*)(idAddr[type]+4);id[2]=*(uint32_t*)(idAddr[type]+8);} }3、使用唯一ID
我們得到唯一ID當然是為了使用它,前面在ST資料中描述了三個使用方式。我們在這里來使用它實現(xiàn)軟件權(quán)限的限制。那么如何用唯一ID來實現(xiàn)軟件運行權(quán)限的限制呢?我們說一說思路:
首先,我們需要指定一個Flash地址,至于于地址空間的大小則與我們xu要存儲的信息有關(guān),一般都不會太長。例如,我們使用MD5來生成加密信息,則最多需要16個字節(jié)的存儲空間;如果我們使用SHA1來作為生成算法,則最多需要20個字節(jié)的空間。當然,我們也可以選取其中的一段或幾段。不管選用多大的空間都炫耀將其清零,即初始化為0xFFFFFFFF。
接下來再程序運行前讀取前面指定的地址并讀取其值,并判斷是否全部為0xFFFFFFFF,即判斷程序是否第一次運行。如果是,那么就獲取唯一ID并作相應的處理,然后將信息寫入前面的地址中。
如果不是第一次運行,則讀取指定地址的值,并用同樣的算法處理唯一ID。然后比較存儲的信息與計算的信息是否一致,一致則啟動程序運行,不一致則終止運行。
如果有人使用工具讀出FLASH內(nèi)容時,因為改制定的地址已經(jīng)被寫入了信息,所以如果把讀出的文件再燒到其它MCU芯片,因唯一ID不同所以信息完全不符程序就不會運行。從而實現(xiàn)了對程序權(quán)限的限制。
?歡迎關(guān)注:
?
總結(jié)
以上是生活随笔為你收集整理的如何获取STM32 MCU的唯一ID的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用知识总结——模板Template
- 下一篇: 关于栈实践总结