前段时间由于运用需求对产品授权进行约束,所以研讨了一下有关STM32 MCU的仅有ID的材料,并终究利用它完成了咱们的方针。
1、根本描绘
在STM32的全系列MCU中均有一个96位的仅有设备标识符。在ST的相关材猜中,对其功用的描绘有3各方面:
用作序列号(例如 USB 字符串序列号或其它终端运用程序)
在对内部 Flash 进行编程前将仅有 ID 与软件加密原语和协议结合运用时用作安全密钥以进步 Flash 中代码的安全性
激活安全自举进程等
在材猜中对其特性的描绘是:96 位的仅有设备标识符供给了一个关于任何设备和任何上下文都仅有的参阅号码。用户永久不能改动这些位。96 位的仅有设备标识符也能够以单字节/半字/字等不同方法读取,然后运用自界说算法连接起来。
想要读取仅有ID,就需求知道它的存储地址,在不同系列的MCU中地址是有不同的,咱们查询了部分MCU的材料并将其总结如下:
2、获取仅有ID
前面咱们对仅有ID做了简略的描绘,而且得到了其存储地址,接下来咱们说以说怎么得到这个ID。
前面现已描绘过仅有ID能够按字节、半字、字等方法读取。仅有ID是一个96位的信息串,所以按字读取便是3个字,按半字读取便是6个,按字节读取便是12个。本质上没有差异,在这里咱们按字读取。
1 /*界说STM32 MCU的类型*/
2 typedef enum {
3 STM32F0,
4 STM32F1,
5 STM32F2,
6 STM32F3,
7 STM32F4,
8 STM32F7,
9 STM32L0,
10 STM32L1,
11 STM32L4,
12 STM32H7,
13 }MCUTypedef;
14
15
16 uint32_t idAddr[]={0x1FFFF7AC, /*STM32F0仅有ID开始地址*/
17 0x1FFFF7E8, /*STM32F1仅有ID开始地址*/
18 0x1FFF7A10, /*STM32F2仅有ID开始地址*/
19 0x1FFFF7AC, /*STM32F3仅有ID开始地址*/
20 0x1FFF7A10, /*STM32F4仅有ID开始地址*/
21 0x1FF0F420, /*STM32F7仅有ID开始地址*/
22 0x1FF80050, /*STM32L0仅有ID开始地址*/
23 0x1FF80050, /*STM32L1仅有ID开始地址*/
24 0x1FFF7590, /*STM32L4仅有ID开始地址*/
25 0x1FF0F420}; /*STM32H7仅有ID开始地址*/
26
27 /*获取MCU的仅有ID*/
28 void GetSTM32MCUID(uint32_t *id,MCUTypedef type)
29 {
30 if(id!=NULL)
31 {
32 id[0]=*(uint32_t*)(idAddr[type]);
33 id[1]=*(uint32_t*)(idAddr[type]+4);
34 id[2]=*(uint32_t*)(idAddr[type]+8);
35 }
36 }
3、运用仅有ID
咱们得到仅有ID当然是为了运用它,前面在ST材猜中描绘了三个运用方法。咱们在这里来运用它完成软件权限的约束。那么怎么用仅有ID来完成软件运转权限的约束呢?咱们说一说思路:
首要,咱们需求指定一个Flash地址,至于于地址空间的大小则与咱们xu要存储的信息有关,一般都不会太长。例如,咱们运用MD5来生成加密信息,则最多需求16个字节的存储空间;假如咱们运用SHA1来作为生成算法,则最多需求20个字节的空间。当然,咱们也能够选取其间的一段或几段。不论选用多大的空间都夸耀将其清零,即初始化为0xFFFFFFFF。
接下来再程序运转前读取前面指定的地址并读取其值,并判别是否悉数为0xFFFFFFFF,即判别程序是否第一次运转。假如是,那么就获取仅有ID并作相应的处理,然后将信息写入前面的地址中。
假如不是第一次运转,则读取指定地址的值,并用相同的算法处理仅有ID。然后比较存储的信息与核算的信息是否共同,共同则发动程序运转,不共同则停止运转。
假如有人运用东西读出FLASH内容时,由于改拟定的地址现已被写入了信息,所以假如把读出的文件再烧到其它MCU芯片,因仅有ID不同所以信息彻底不符程序就不会运转。然后完成了对程序权限的约束。