STM32 BootLoader 刷新项目 (七) 获取芯片ID-0x53
1. 概述
前面的一系列文章中,我们介绍了整体的BootLoader的一个方案,现在我们针对该BootLoader设计多个命令,下面我们来讲述获取芯片ID的命令-0x53。
1.1 芯片Device ID和类型ID描述
STM32F407的Device ID(设备标识符)和Type ID(类型标识符)是用于标识芯片的唯一性信息。Device ID通常是芯片生产时赋予的唯一序列号,而Type ID用于标识芯片的型号和系列。
1.2 作用
- 设备识别:在大规模部署或生产中,可以通过Device ID唯一标识每一个设备。
- 型号确认:Type ID可以帮助软件确定正在运行的硬件型号,从而加载正确的驱动程序或配置。
- 安全验证:在启动过程中,可以通过验证Device ID来确保设备的合法性,增加系统的安全性。
1.3 读取方法
Device ID和Type ID通常存储在STM32F407的特定内存地址中。可以通过直接读取这些内存地址来获取这些信息。
1.4 应用场景
- 设备管理:在设备固件升级和维护时确认设备型号。
- 软件授权:确保软件只能在特定型号的硬件上运行。
- 安全启动:在设备启动时验证芯片类型,增加启动过程的安全性。
2. Device ID和芯片类型ID
STM32F407的Device ID(设备标识符)和Type ID(类型标识符)是用于标识芯片的唯一性信息。Device ID通常是芯片生产时赋予的唯一序列号,而Type ID用于标识芯片的型号和系列。
2.1 Device ID
从STM32F4芯片手册可以看出,Device ID是独一无二的设备标识符,由96位 bit组成。目前了解到的可以作为信息安全加密算法中的加密种子,具有和芯片强绑定的特性。
2.2 Type ID即MCU device ID
Type ID是经常在芯片中使用的,这个主要是表示该芯片的类型,例如我们现在用的STM32F407ZGT6,读取这个芯片Type ID可以读出上面的数值类型,可以方便软件针对该类型的芯片做适配。比如说我们的软件可能是平台软件,支持STM32F1、STM32F4、STM32F7或者其他别家供应商的芯片,我们可以通过读取这个Type ID走平台软件的不同分支,进而将不同芯片的软件做成一个,减少软件分支的管理,这对具有很多项目的公司来说是将本增效和增加可维护性的软件工程方法。
如果大家对软件工程的开发模式比较感兴趣的话,推荐大家看两本书**《人月神话》,《观止-微软创建NT和未来的夺命狂奔》**。人月神话大家应该都听说过,为什么叫这个名字呢?其实是一种比喻,一个人干十个月的话,那反之10个人能否一个月干完?在软件这种繁琐复杂的工程中简直如同神话一般,加人战术在软件工程中似乎失效了,大家可以感兴趣的话可以看这本书,讲述作者在IBM开发大型软件中遇到的问题和解决的方法。另外一本书我详细介绍一下《观止:微软创建NT和未来的夺命狂奔》是一本揭示微软公司如何通过Windows NT重新定义计算标准的书籍。它详细讲述了在比尔·盖茨的领导下,微软不断追求技术创新的故事。书中特别强调了大卫·卡特勒这位传奇程序员在NT开发中的重要作用,以及他如何带领团队克服重重困难,最终完成这一里程碑式的项目。这本书不仅是对微软历史的记录,也是对软件开发过程中挑战和胜利的真实描绘。大家有兴趣的话可以阅读这两本书。
下面我们来讲述Type ID,通过读取地址0xE004200,则可以获得该芯片的Mcu Device ID,由下图可以看到,芯片STM32F405xx/07xx and STM32F415xx/17xx的ID为 0x413,STM32F42xxx and STM32F43xxx芯片ID为0x419。
3. 代码实现
下面是我们获取的命令结构。上位机向MCU发送6 Byte的数据,第一个Byte为发送的数据长度,第二位为命令,第3-6 Byte发送的是前2个Byte的CRC校验。
通过按键进入到BootLoader后,软件会一直在bootloader_uart_read_data()函数中循环,当上位机发送了相应的指令0x53后,即case BL_GET_CID,则会进入到bootloader_handle_getcid_cmd(bl_rx_buffer)函数,读取芯片ID地址0xE004200并返回MCU Device ID。
void bootloader_uart_read_data(void)
{uint8_t rcv_len=0;printmsg_Host("BL_DEBUG_MSG: Receive CMD\n\r");while (1){HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);memset(bl_rx_buffer, 0, 200);//here we will read and decode the commands coming from host//first read only one byte from the host , which is the "length" field of the command packetHAL_UART_Receive(C_UART,bl_rx_buffer,1,HAL_MAX_DELAY);rcv_len= bl_rx_buffer[0];HAL_UART_Receive(C_UART,&bl_rx_buffer[1],rcv_len,HAL_MAX_DELAY);switch(bl_rx_buffer[1]){case BL_GET_VER:bootloader_handle_getver_cmd(bl_rx_buffer);break;case BL_GET_HELP:bootloader_handle_gethelp_cmd(bl_rx_buffer);break;case BL_GET_CID:bootloader_handle_getcid_cmd(bl_rx_buffer);break;default:printmsg("BL_DEBUG_MSG:Invalid command code received from host \n");break;}}
}
下面是获取芯片ID的代码,地址为0xE004200。
//Read the chip identifier or device Identifier
uint16_t get_mcu_chip_id(void)
{
/*The STM32F407xx MCUs integrate an MCU ID code. This ID identifies the ST MCU partnumberand the die revision. It is part of the DBG_MCU component and is mapped on theexternal PPB bus (see Section 38.6.1 on page 1702). This code is accessible using theJTAG debug pCat.2ort (4 to 5 pins) or the SW debug port (two pins) or by the user software.It is even accessible while the MCU is under system reset. */uint16_t cid;cid = (uint16_t)(DBGMCU->IDCODE) & 0x0FFF;return cid;
}
4. 功能实现
上位机是用Python脚本写的,后续所有BootLoader文章更新完后会将代码开源出来。
我的电脑是COM19,输入后上位机与开发版连接成功
输入3,则下位机回复0x413即为STM32F407的芯片MCU Device ID。
至此,STM32 BootLoader 刷新项目 (七) 获取芯片ID-0x53完成。
5. 系列文章
STM32 BootLoader 刷新项目 (一) STM32CubeMX UART串口通信工程搭建
STM32 BootLoader 刷新项目 (二) 方案介绍
STM32 BootLoader 刷新项目 (三) 程序框架搭建及刷新演示
STM32 BootLoader 刷新项目 (四) 通信协议
STM32 BootLoader 刷新项目 (五) 获取软件版本号-命令0x51
STM32 BootLoader 刷新项目 (六) 获取帮助-命令0x52