一.前言
前面几篇文章写了一下关于cmake改造嵌入式编程的体验,点击查看
摆脱MDK,用cmake改造嵌入式软件开发体验
用IDE配置并运行cmake工程
读者反响不错,至今已有3个赞了,给了我很大的鼓舞(手动滑稽),今天就来分享一下嵌入式开发中最重要的环节,固件发布,毕竟,程序写的再溜,不出固件,老板拿什么卖钱嘛.
二.普通做法
首先说明一下一般大家做嵌入式发布程序的一般流程:程序猿在MDK编好固件之后,在工程目录的build的文件夹会产生编译出来的hex文件,如下图:
然后程序猿就把固件拷贝到一个新建的文件夹,重新命个名(因为mdk里生成的固件名称是固定的),一般是写上产品名称,版本号啊然后有一些特殊的定义也会加上(比如什么至尊版,加强版,普通版之类的区分同一产品的不同价位或者功能),再编写一个changlist或者版本记录,然后把版本记录也拷贝一份到文件夹内,然后再压缩发给测试人员或者生产负责人.
二.高级做法1.0
高级做法是编写一个脚本,比如python脚本或者bat(shell)脚本,在脚本里面执行一些拷贝或者某些系统命令,比如nrf52832带sdk的程序就需要把sdk合并到最终的hex文件里去.
比如这样:
这种方式比手动修改就要高级一些,我们称为高级1.0,但是这种做法有一个弊端,没法根据固件编译时的参数去定制固件的名称,倒是有一个方法,在build文件夹下有一个.dep文件可以利用python脚本去解析里面的特定字符,比如:
比如我需要知道固件编译的时候有没有定义TIANYI这个宏,可以这样写:
这样的话可以做到针对某个编译参数生成特定名称的固件,可以算是一个提高吧,用MDK的话就可以采取这种方式
三.高级方法2.0
高级做法2.0是高级做法1.0的升级版,前提是需要搭建好cmake的编译环境,闲话少说,上法宝:
这段代码是cmake里面添加编译期间定义的语句,结合前面的cmake环境搭建教程,结合语句按字面意思应该不难理解,首先我们定义了这么一些编译参数,然后我们把所有的编译参数获取出来,形成一个叫defs的数组(cmake语法里的数组类型,这里不用理解这个数组到底怎么存储的)
在cmake里面添加一个目标,叫做merge,名字可以随便取:
这段代码可以理解为:如果我需要产生一个merge的目标,就调用后面的cmd命令行语句,这个语句的作用是用python来启动一个脚本,启动脚本的时候会带上相应的参数,这个参数就是我们提取出来的defs,然后在python脚本里面把参数打印出来会是这样会是这样:
看到没有,刚刚我们定义的宏定义在python文件里面获取到了,但是有一点不太好,比如我们cmake文件里面SOFT_VER=809,在python里面也是这样子显示的,不利于我们把真实的数据提取出来,没事,python这么先进的语言,这还不是小事一桩,盘他:
如上图所示,我们花分把钟(专业人员,请勿羡慕)把解析函数写出来,形成一个字典(dict,python的一种数据结构):
字典是一种键值对的数据结构,可以理解成不用数字做下标的数组,但是python的类型很灵活,不理解的同学可以研究一下python
接下来的事就太简单了,我们只需要把字典的键和值分别取出来就行了,对于有的参数,没有值的说明咱们不需要他的值,看图:
这样的操作就把之前我们复杂的需要把.dep文件打开然后一行一行的找对应的宏有没有来的简便,而且效率也更高(不需要读文件了)
你以为到这就完事了,错,接下来我们还有合并固件,然后把所有相关文件压缩成压缩包,单独存储,而你只需要点一个按钮
比如我的工程里,除了要把hex生成出来,还要生成一个用于ota升级的固件包,同时编译的源hex也要保存,以方便追溯问题,请上眼:
对,就是这么短短的几行语句,你之前需要花好几分钟还不一定不出错的步骤,我们用几行脚本语句就实现了,接下来就是运行脚本了,怎么运行:
打开cmd命令行,输入:
`
cmake --build .build --target merge
`
就等着电脑帮你打包吧,如果还想简单一点,qtcreater,clion,包括mdk都有一个外部工具可以创建,创建完之后点击运行就ok了:
这是clion的
这是qtcreater的
这是mdk的
四.总结
目前,关于固件生成的批量化就简单研究到这里了,如果同学们还有什么需求可以一起探讨.文章有错误在所难免,欢迎指正.