当前位置: 首页 > news >正文

STM32把产品信息写入固件.hex / .bin文件中详解(分散加载)

概述

        在日常开发过程中,为了产品后续维护,版本号管理是必不可少的一项,不管是开发中测试、量产、还是后期升级迭代都是需要版本号管理来区分。在此写一篇文章做个笔录,需要用的知识分散加载,如还不太懂这方面的知识,可去“百度”或者“deepseek”科普,这里不再赘述。

这里介绍有两种方式:

1、第一种,使用__attribute__((at(ADDR_BASE))))

2、第二种,使用__attribute__((section(".version_info"))),需要在.sct文件中修改,才能使用

区别是第一种比第二种占用空间大,后面会介绍。

一、开发环境

1、硬件平台

     STM32F401CEU6
     内部Flash : 512Kbytes,SARM : 96 Kbytes

二、STM32CubeMx配置

 2.1、系统时钟配置

2.2、下载调试配置

2.3、生成代码

2.4、编译工程

2.5、查看该型号芯片Falsh的地址、大小信息

 

三、编码         

1、main.c

/* USER CODE BEGIN 0 */#define ENABLE_SCT	1		//需要添加 .sct文件里面的内容才行。/* 编译信息结构体 - 将存储在Flash中 */
typedef struct {char compile_data[12];		/* 编译日期 "MMM DD YYYY" */char compile_time[10];		/* 编译时间 "HH:MM:SS" */char compiler_info[10];		/* 编译器信息 */char hardware_version[10];	/* 硬件版本号 */char firmware_version[10];	/* 软件版本号 */char mcu_type[15];			/* MCU型号 */
} __attribute__((packed)) build_info_t;//#define INFO_ADDR_BASE   (0x8000000 + 0x80000 - 0x800)	//最后的1k地址,起始地址: 0x8000000, 大小是: 0x80000(512k), 预留2k空间存储, 有个弊端就是固件空间占很大
#define INFO_ADDR_BASE   (0x8000000 + 0x4000)	//最后的1k地址,起始地址: 0x8000000, 偏移16k地址用来存放, 通过map得知,改个合理的地址专门存放该信息即可/* 编译信息实例 - 使用特定段存储 */
//const build_info_t firmware_build_info __attribute__((section(".build_info"), used)) = {#if ENABLE_SCTconst build_info_t firmware_build_info __attribute__((section(".build_info"))) = {	//要在.sct文件中修改,才能使用
#else 	const build_info_t firmware_build_info __attribute__((at(INFO_ADDR_BASE + 0x00))) = {
#endif	__DATE__,__TIME__,
#ifdef __ICCARM__"IAR-ARM",		/* IAR编译器*/
#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)"KEIL-MDK",		/* keil编译器 */
#else"Unknown",
#endif"HW_V1.2.1",	/* 硬件版本 */"FW_V1.0.1",	/* 软件版本 */"STM32F401CEUx"	/* MCU型号 */
};/* 详细版本信息字符串 */
//const char firmware_build_info[] __attribute__((section(".version_info"), used)) = 
#if ENABLE_SCTconst char detailed_version_info[] __attribute__((section(".version_info"))) = 
#else 	const char detailed_version_info[] __attribute__((at(INFO_ADDR_BASE + 0x400))) =  // 偏移1k地址空间
#endif	"===  heihei === \r\n""Firmware Version: 1.0.1\r\n""Build Data:" __DATE__ "\r\n""Build TIME:" __TIME__ "\r\n""Cocyright (c) 2025 heihei\r\n";////------------------------------------------------------------------------------#include //------------------------------------------------------------------------------
//#define VERINFO_ADDR_BASE   (0x8004F00) // 版本信息在FLASH中的存放地址
//const char Hardware_Ver[] __attribute__((at(VERINFO_ADDR_BASE + 0x00)))  = "Hardware: 1.0.0";
//const char Firmware_Ver[] __attribute__((at(VERINFO_ADDR_BASE + 0x20)))  = "Firmware: 1.0.0";
//const char Compiler_Date[] __attribute__((at(VERINFO_ADDR_BASE + 0x40))) = "Date: "__DATE__;
//const char Compiler_Time[] __attribute__((at(VERINFO_ADDR_BASE + 0x60))) = "Time: "__TIME__;
////------------------------------------------------------------------------------//volatile int test_num 	__attribute__((at(0x20018040))) = 0;
//volatile int num 		__attribute__((at(0x8080400))) = 0;
//	
//void AA(void)			__attribute__((section("RAM1")));
//void AA(void)
//{
//	volatile int a = 1;
//}//void BB(void)			__attribute__((section("ROM1")));
//void BB(void)
//{
//	volatile int test_num = 2;
//}/* USER CODE END 0 */int main(void)
{/* USER CODE BEGIN 1 */
//	void AA(void);
//		AA();
//	void BB(void);
//		BB();
//	test_num = 9;
//	num = 6;/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_TIM1_Init();MX_IWDG_Init();MX_USART6_UART_Init();/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim1);HAL_UART_Receive_IT_Enable();printf("heihei min task \r\n");//    printf("buildData: %s\r\n", firmware_build_info.compile_data);
//    printf("buildTime: %s\r\n", firmware_build_info.compile_time);
//	printf("buildInfo: %s\r\n", firmware_build_info.compiler_info);
//	printf("firwareVersion: %s\r\n", firmware_build_info.firmware_version);
//	printf("mcu_type: %s\r\n", firmware_build_info.mcu_type);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

四、结果

A、第一种方式

1、在main.c文件第 62行代码 

#define ENABLE_SCT    1

改成

#define ENABLE_SCT    0

2、再次编译工程,如下所示

3、编译时间

4、使用.map文件查看地址分配信息

5、使用ST- LINK 查看hex文件内容

6、使用软件debug模式,查看内容信息

B、第二种方式

1、在main.c文件第 62行代码 

#define ENABLE_SCT    1

改成

#define ENABLE_SCT    0

2、找到.sct文件,重新命名避免原文件的覆盖。

3、修改.sct文件内容

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************LR_IROM1 0x08000000 0x00080000  {    ; load region size_regionER_IROM1 0x08000000 0x00080000  {  ; load address = execution address*.o (RESET, +First)*(InRoot$$Sections).ANY (+RO).ANY (+XO)}; 新增代码 startER_BUILD_INFO 0x08040000 0x1000 {main.o (.build_info, +First) ;}ER_VERSION_INFO 0x08050000 0x1000 {main.o (.version_info, +First) ;}; 新增代码 endRW_IRAM1 0x20000000 0x00018000  {  ; RW data.ANY (+RW +ZI)}
}

4、同理上面都修改好后,再次编译工程。

5、使用.map文件查看地址分配信息

6、使用ST-LINK 查看hex固件内容

五、总结

        好了,讲解完毕,希望能帮助到大家,蟹蟹参阅。

参考文章:1、https://blog.csdn.net/2303_76316997/article/details/150590604?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogOpenSearchComplete%7ECtr-2-150590604-blog-154213939.235%5Ev43%5Epc_blog_bottom_relevance_base2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogOpenSearchComplete%7ECtr-2-150590604-blog-154213939.235%5Ev43%5Epc_blog_bottom_relevance_base2&utm_relevant_index=3

2、https://blog.csdn.net/qq_38113006/article/details/113005745?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-113005745-blog-88835999.235^v43^pc_blog_bottom_relevance_base2&spm=1001.2101.3001.4242.2&utm_relevant_index=4

3、大佬B站视频分享https://www.bilibili.com/video/BV12BWzzAEav/?spm_id_from=333.1391.0.0&vd_source=9333592be49ce686d634d8027764755c

 

http://www.dtcms.com/a/557392.html

相关文章:

  • 考研408--计算机网络--day2--性能指标分层结构OSITCP/IP
  • 刘洋洋全新单曲《小小的我》温情上线,诠释“渺小”的力量
  • Photoshop - Photoshop 工具栏(19)颜色替换工具
  • 进程等待(解决僵尸进程)
  • 划时代的协作:GitHub Agent HQ 如何开启AI原生开发新纪元
  • Jmeter基础知识详解
  • 设计素材网站合集手机电子商务网站建设
  • 2025年江西省职业院校技能大赛高职组“区块链技术应用”任务书(3卷)
  • Day75 RS-485 通信协议设计、串口编程与嵌入式系统部署实践
  • 中文编码、乱码问题解析处理
  • 如何设计一款百兆网络监控器H81220S
  • 2025年ASOC SCI2区TOP,双重防御网络阻断模型下的供给路线优化,深度解析+性能实测
  • seo关键词教程国外seo综合查询
  • 郑州网站建设饣汉狮网络wordpress重置主题
  • 算法——二叉树、dfs、bfs、适配器、队列练习
  • Linux_Socket_浅谈UDP
  • dfs|位运算
  • 网站开发内容商用图片的网站
  • 凡客建站免费的可以用多久win优化大师有用吗
  • DevOps的实现路径与关键实践
  • 开发实战 - ego商城 - 6 购物车模块
  • 虚幻引擎5 GAS开发俯视角RPG游戏 P06-28 构建属性菜单小部件控制器
  • 线程协作——生产者消费者问题:
  • ROS2系列 (14) : 服务通信介绍——双向通信的核心机制
  • C语言入门(十三):操作符详解(1)
  • 化妆品设计网站家用宽带做网站
  • 雄安建设集团 网站湖北做网站教程哪家好
  • 晋城市 制作网站织梦网站文章发布模板下载
  • Microsoft Speech TTS微软语音识别ISpeechRecoGrammar,ISpeechRecoResult
  • 【Java 开发日记】运行时有出现过什么异常?