自动以版本号命名keil生成的bin文件

2023-05-16

0、 前言

在做项目中一直遇到一个小问题。一直也没管,最近花了点时间处理了,效果还不错。问题是这样的:每次编译后的生成的bin文件需要给客户,烧录到设备里进行更新。每次生成的bin文件都是固定的文件名,发给客户前,需要人为将bin文件改为vx.x.x.bin再发送。这一步需要人工命名,虽然花不了几分钟,但是还是觉得体验不太好,因为如果一次编译的版本多的话,人容易命名出现纰漏。所以如果能生成bin文件后,自动进行重命名,那可靠性比人工高多了。

1、方案:

仔细想了下,以及跟同事交流后,主要有两种方案:
方案一,编写一个可执行文件,来读取keil项目中的.c .h文件,找到其中的版本号信息,然后自动将版本号信息填写到生成bin文件名称中。

方案二,将版本号信息,写入bin文件的固定地址。然后编写一个可执行文件,来读取bin文件固定地址的版本号信息。最后将读到的版本号信息,写入生成的bin文件名称中。

最优的方案是方案一,但是难度比较大,兼容性较差,不利于移植到其他项目,还没想好如何实现。方案二兼容性更强,不过需要修改项目文件,将版本信息写入bin文件的固定地址。实现更为简单。

本次是基于方案二的实现。

2、版本号写入bin文件固定地址

写入固定地址的方式其实很简单。只需要在main函数前面添加1行代码即可

uint16_t version_addr[3]  __attribute__((at(0x8010000))) = {MAIN_VERSION_MAJOR,MAIN_VERSION_MINOR,MAIN_VERSION_BUILD}; 

这句话的意思是将version_addr数组写入到固定地址为0x8050000,其内容是版本号,版本号每个字段占2个字节。为什么要用两个字节来表示,主要是考虑到兼容性,一个字节最多是255,假如有个版本号是1.2.300,那么每个字段用一字节表示,就无法满足需求。

0x8050000是stm32的flash地址,那么对应bin文件的偏移地址是多少呢?已知stm32 内部flash的首地址是0x8000000,0x10000是偏移地址,bin文件地址是从0开始,则bin文件的0x10000开始就是version_addr数据。
下面验证下。
当前的
MAIN_VERSION_MAJOR 4
MAIN_VERSION_MINOR 2
MAIN_VERSION_BUILD 50
在这里插入图片描述
bin文件的0x10000地址后面的数据是0x0004 0x0002 0x0035,35十进制是50。
接下来的可执行文件只需要读取到这个地址的数据,然后重命名bin文件即可。

3、重命名bin文件

对于重命名的可执行文件,需要知道2个信息。
其一:生成的bin文件的路径
其二:版本信息的偏移地址

对于版本号而言,最好加上前缀,可以是公司简称,设备简称。比如abc_v1.1.1.bin这种形式。

所以要实现比较完成的名称,还需要告知可执行文件,版本号的前缀。

这san个信息可以抽象成可执行文件的3个输入参数。

比如:version.exe aa/bb/cc/dd.bin 0x10000 abc_v

可执行文件实现原理见后文。这里先说下操作方式。在keil的项目options里面按照Run #2输入,实际上就是上文说的可执行的3个参数。
在这里插入图片描述
编译以后生成效果如下:

在这里插入图片描述
可以看到,确实生成了对应的版本号。

至此功能全部实现,bin_read.exe下载链接如下:
https://download.csdn.net/download/sinat_36568888/87621034

4、bin_read.exe源码

bin_read源码采用c编写,编译采用gcc编译器,源码如下:

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>


/**
 * @description: 获取当前文件所在的路径
 * @return {*}
 * @Date: 2023-03-24 17:01:37
 * 比如aa/bb/cc/123.bin,则返回的路径是aa/bb/cc
 * 目的是为了后面修改新的文件名称
 */
int get_file_dir(char*filename, char*file_dir)
{
	int res = 0;
	char *file_name = strrchr(filename, '/');
	if(file_name != NULL)
	{
		int file_dir_len =strlen(filename)-strlen(file_name) ;
		printf("file dir len: %d\r\n", file_dir_len);
		memcpy(file_dir, filename, strlen(filename)-strlen(file_name));
		file_dir[file_dir_len] = '\0';
		printf("file dir:%s\r\n", file_dir);
		res = 0;
	}
	else
	{
		res = 1;
	}
	return res;

}
char file_dir[256] = {0};
char new_name[24] = {0};
char new_file_name[24] = {0};
int main(int argc, char **argv)
{
	int rename_res = 0;
	FILE *fp;
	uint16_t buf[10]={0};
	
	// printf("%s\r\n", argv[1]);
	
	fp = fopen(argv[1], "rb");
	if(fp == NULL)
	{
		printf("Error: file open failed\r\n");
		return 1;
	}
	uint32_t version_addr = strtol(argv[3],NULL,16);
	fseek(fp, version_addr, SEEK_SET);
	uint16_t len = fread(buf,2,3,fp);
	printf("len:%d data:",len);
	for(int i =0;i<len;i++)
	{
		printf("%02X ",buf[i]);
	}
	sprintf(new_name,"%s%d.%d.%d.bin",argv[2],buf[0],buf[1],buf[2]);
	printf("\r\n");
	fclose(fp);
	int ret = get_file_dir(argv[1],file_dir);
	if(ret ==0)//文件不在当前目录
	{
		sprintf(new_file_name,"%s/%s",file_dir,new_name);
	}
	else
	{
		sprintf(new_file_name,"%s",new_name);
	}
	remove(new_file_name);
	rename_res = rename(argv[1],new_file_name); //如果修改后的名称不加路径,rename函数就会把命名后的文件移动到当前的根目录
	printf("new name:%s\r\n",new_file_name);
	printf("res = %d\r\n",rename_res);
}

编译,win下打开powershell,在read_bin.c目录下,输入

 gcc bin_read.c -o bin_read.exe

想自己研究的,可以直接编译源码。不想研究的,下载可执行文件即可使用。

windows下配置gcc编译环境请参考:
https://blog.csdn.net/sinat_36568888/article/details/129091766

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自动以版本号命名keil生成的bin文件 的相关文章

  • STM32 Keil:warning: #223-D: function "LED_Init" declared implicitly

    include stm32f10x h include led h int main LED Init while 1 GPIO SetBits GPIOD GPIO Pin 6 运行时警告 warning 223 D function L
  • 基于stm32cubemx和keil的stm32(以stm32F407ZGTx为例)单片机的开发----实现printf函数将信息打印至串口

    一 printf打印函数实验 二 实验步骤 1 在cube里设置引脚 串口 串口5设置成异步 2 生成代码打开工程 别忘了先调试JLink 在main c文件开头添加头文件 在主函数外的用户区书写读取文件流函数 这样就可以使用printf函
  • Jlink SWD和Jtag下载失败总结

    学习STM32或者说使用Jlink的同学都有很多的困扰 我把自己遇到的情况总结一下 并给出解决方法 希望后来人少走点弯路 第一次写博客 勿喷 一 提示No Jlink Device Found 错误 没有发现Jlink 可能原因 1 Jli
  • keil提示No Browse Information available in ‘..\OBJ\SPI‘解决方法

    1 No Browse Information available in OBJ SPI 解决方法 https blog csdn net frozennet article details 107213145
  • keil5烧录或下载程序出现停止工作的问题

    本人在使用keil5烧录或下载程序出现停止工作的问题 开始认为是keil版本的原因 后来使用了keil4发现问题依然存在 发现因为本人使用了盗版JLINK被驱动检测出来了 由于安装的驱动版本为V6 14 新版的驱动检测到盗版JLINK 一旦
  • keil软件安装与破解

    目录 目录 下载 安装 破解 下载 学习51单片机必要的开发工具是 KEIL C51 下载密码dsfs 安装 按照一般安装软件顺序即可 此处随便填写 破解 注意 需以管理员身份 运行 按照如下图片步骤 弹出如下对话框 再打开软件按如下操作
  • COLMAP导出相机外参(bin文件转txt文件)

    官方给出的images txt如下图 Image list with two lines of data per image 每张图像数据占两行 IMAGE ID QW QX QY QZ TX TY TZ CAMERA ID NAME 图像
  • KEIL编译出现错误“source file is not valid utf-8”

    KEIL编译出现错误 source file is not valid utf 8 在外面复制了一段代码 c文件一直报错source file is not valid utf 8的错误 经查找原因就是 文件中出现中文符号导致的 特别是中文
  • Undefined symbol assert_param

    Undefined symbol assert param Objects led axf Error L6218E Undefined symbol assert param referred from misc o Keil MDK 5
  • keil调试stm32无法退出debug

    keil调试stm32 debug之后有时会遇到这种情况 导致无法退出debug 只能任务管理器强制结束任务 原因 keil对中文的支持不够友好 工程路径过深或路径中有中文 调试过程中打了断电 解决方式 把工程的路径改浅 改成英文路径 例如
  • 关于Keil不识别系统头文件core_cm3.h的问题

    之前遇到一次这个问题 解决了 之后又遇到一次就忘了之前是怎么解决的了 所以记录一下 所有不识别系统头文件的问题都可以用这种方式解决 找到你工程目录下的头文件 我以core cm3 h为例 这个头文件在STM32 LIBRARY CMSIS
  • STM32如何使用超声波传感器(HC-SR04)。(HAL库版本)

    目录 作用 引脚作用以及接线 原理讲解 项目配置stm32cubmx 代码是实现 作用 首先我们先了解超声波传感器是用来干嘛的 目前我自认为这个传感器就是用来测量距离的 引脚作用以及接线 其次我们先来了解超声波传感器的4个引脚的作用 VCC
  • 关于KEIL MDK调试ARM程序不能仿真的问题

    在单片机程序调试过程中 由于程序量小 利用仿真器进行仿真调试方便直观 所以一般经常使用 但是keil经常会出现罢工 无法用仿真器调试的现象 如下图 解决方法也很简单 按照下图设置即可
  • C51简介及Keil的使用

    前言 此文档主要是针对有一定C C 编程基础 并打算用Keil从事C51开发的开发人员 C51涉及的知识比较多 但是入门基本的开发 还是容易的 C51简介 1 C51概念 C51继承于C语言 主要运行于51内核的单片机平台 单片机 单片微型
  • 如何直接在 C# 中执行批处理命令?

    我想执行批处理命令并将输出保存在字符串中 但我只能执行文件而无法将内容保存在字符串中 批处理文件 回声关闭 C lmxendutil exe licstatxml 主机 serv005 端口 6200 gt C Temp HW Lic XM
  • 如何在 Cortex-M3 (STM32) 上从 RAM 执行函数?

    我正在尝试从 Cortex M3 处理器 STM32 上的 RAM 执行函数 该函数会擦除并重写内部闪存 所以我肯定需要在 RAM 中 但我该怎么做呢 我尝试过的是 使用 memcpy 将函数复制到 RAM 中的字节数组 检查它是否正确对齐
  • C 易失性位域结构的复制构造函数

    Good day 我正在尝试在 C 11 项目中使用 C SD 驱动程序 文件系统库 Keil MDK 它是由 Keil MDK 5 23 中的 Pack 管理器添加的 我正在使用 ARMCC 5 06u4 进行编译 我收到警告class
  • 获取 R 中直方图 bin 的索引

    这是我的问题 如何找到数字所在的直方图箱的索引 在 Matlab 中 解决方案很简单 HISTC 的工作 counts bin histc data edges bin 就是我正在寻找的东西 但我在 R 工作 并且histR 的函数没有提出
  • Android APK 文件和 DEX 文件未创建,没有警告或错误

    我开发Android已经有一段时间了 使用WIN7 64位和Eclipse 由于我尝试安装新的 ADT 1 5 我遇到了一个非常奇怪的现象 我的构建未完成 并且未生成 APK 文件 也未生成 dex 文件 类文件已创建 但没有其他任何内容
  • 使用 pnpm 工作区时,在 GitHub Actions 中找不到 NodeJS 包二进制文件

    Overview 我有一个使用 pnpm 工作区和 Turborepo 的 monorepo 我有一个包 它是节点二进制文件 deploy script 我想从另一个包中的包脚本调用 website 在本地一切正常 但是 在 GitHub

随机推荐