【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
对于stm32f103系列mcu来说,一般每一颗原厂的mcu,都会对应一个唯一的id。那这个id可以用来做什么用呢?个人认为,可以用来做激活使用。举个例子,第一次mcu模块使用的时候,一般可以通过认证的上位机激活。激活的时候,模块把自己的id告诉上位机,等上位机根据id生成一串校验码之后传给模块,模块收到这个检验码,并且保存到自己的flash上面。下次模块启动的时候,就会确认当前模块是不是合法认证过,如果是,继续启动;反之,则拒绝启动运行。这样,即使别人把flash里面的程序和数据都copy走,换到新的设备上,也是启动不起来的。
1、芯片id的获取
103系列的芯片id主要就是从三个地址获取三个32位数据就可以了。这三个地址分别是0X1FFFF7F0、0X1FFFF7EC、0X1FFFF7E8。
void Get_ChipID(void)
{
ChipUniqueID[0] = *(__IO uint32_t *)(0X1FFFF7F0); // high
ChipUniqueID[1] = *(__IO uint32_t *)(0X1FFFF7EC); //
ChipUniqueID[2] = *(__IO uint32_t *)(0X1FFFF7E8); // low
}
2、flash容量的获取
flash容量的获取和id的获取其实是一个模式,也是从一个固定地址0X1FFFF7E0获取。虽然我们的mcu是c8t6,但是实际获取的大小是128k。按照道理,只有cbt6才是128k,根据网上的介绍,说这两颗mcu是共线生产的,一般情况下,不推荐c8t6使用后面的64k,最好按照厂家实际说明书标明的大小来使用。
3、测试代码
测试代码就比较简单了。一般就是初始化一下时钟、初始化串口、获取id和flash大小之后,打印一下即可,
int main(void)
{
SystemClock_Config();
DEBUG_USART_Config();
Get_ChipID();
printf("\r\nID: 0x%08X-%08X-%08X\r\n",
ChipUniqueID[0],ChipUniqueID[1],ChipUniqueID[2]);
printf("\r\nflash size: %dK \r\n", *(__IO uint16_t *)(0X1FFFF7E0));
while(1) {}
}
最后打印的效果如下所示,
4、固件和芯片id
其实,不管是mcu,还是linux soc,很多时候我们都希望固件里面可以包含一些芯片id的信息。不然,要是没有这些信息的话,这意味着固件或者linux程序可以被随意拷贝、复制。而一旦有了这些id之后,那我们就可以通过固件下载、校验的方法来判断,当前的模块是不是合法、正版的模块,这对保护开发者的权益来说,还是大有裨益的。