作者:Stephen Du
免责声明: 本文为个人学习笔记及总结,仅代表个人观点,尽可能保证内容准确性。
所有文字均是自己码出来的,所有图片均为自己勾画(除部分来源于原始标准)。
复制/转发请注明来源/作者。
欢迎添加微信交流学习。
本文是否适合你看?如果你有以下疑问,可以继续浏览:
- 如何在S32DS里面调用自己的脚本?
- S32DS如何生成
*.hex
,*.srec
,*.bin
等格式文件? - 脚本处理
*.hex
,*.srec
,*.bin
文件时,提示找不到文件?
1. 前言
在嵌入式开发过程中,很大一部分人还是很青睐于使用IDE进行开发工作。毕竟IDE在大部分使用场景下还是要方便很多,学习门槛相对也低很多,很容易上手。很多芯片厂商都会提供自家的IDE。比如以前飞思卡尔提供的很经典的Codewarrior。现在NXP则提供了统一的开发平台S32DS(针对S32系列众多芯片)。如前所述,使用S32DS进行相关芯片的开发工作可以大大提高开发效率,尤其是当你需要快速验证某些简单工作的时候,可以直接使用里面提供的丰富的示例工程进行快速验证。
当然任何东西都是两面的,IDE也有它的不足,比如灵活性就比不上makefile这种方式。当你具有某些特殊使用需求的时候,可能IDE就显得力不从心。
显然,作为现代化的效率工具,如果完全没有留给用户扩展的空间,那显然是很失败的设计。针对灵活性或者是可扩展性方面,实际上S32DS已经为大家尽可能的考虑到了。S32DS支持调用用户脚本,这样一来,脚本里面用户可做的事情就很灵活了。但这里面其实也会有一些小坑。本文就给大家介绍使用S32DS进行开发的工程中会碰到的问题。
在实际项目中,我们经常会有这样的需求:编译完成后需要生成指定格式的文件:*.hex
, *.srec
, *.bin
等。然后基于这些指定格式的文件还会进行后续处理,比如插入某些特殊内容:标定数据,安全校验码等等。
针对这种需求,首先S32DS是可以配置生成常见格式文件的。针对上述提到的后续处理,大部分伙伴都会想到使用脚本来处理这个工作,只需要在S32DS里面设置调用脚本即可。但当去实施的时候才发现有问题。比如当脚本里面去处理生成的*.srec
文件的时候会提示找不到文件。很多人就疑惑了,我不是配置了生成srec格式文件么?怎么提示找不到呢。
实际上导致这个问题的原因在于,S32DS生成指定格式文件这个步骤是晚于你在Post-build Steps里面设置的脚本执行时间的。也就是执行你脚本的时候实际上指定那个文件还没有生成呢,但是你的需要或者说你的假设是已经生成这个文件,然后脚本去处理这个文件。
接下来就告诉你如果处理这个问题。本文一共提供三种方案:
2. 方案
2.1 方案一
直接关闭S32DS默认提供生成指定格式文件这个功能,然后把这个事情直接交给你的脚本里面去实现。也就是你的脚本先将elf文件转换为你想要的文件,然后再做后续处理。
第一步: 在工程属性配置里面,取消勾选Create flash image。
第二步: 将你的脚本文件放到工程根目录(有.project和.cproject那个文件夹)(放到其他路径也行,但会导致设置路径不一样),然后在S32DS里面设置调用你的脚本文件。(如果没有脚本文件,那就再工程根目录创建一个后缀为.bat
格式的文件)
第三步: 在脚本文件里面添加如下命令。(下面是一个示例脚本文件,我想你知道怎么做了,核心就最后那句话)
@echo off
setlocal enabledelayedexpansion
set compilerToolchainPath="C:\NXP\S32DS.3.4\S32DS\build_tools\gcc_v10.2\gcc-10.2-arm32-eabi\bin"
echo User post build: Generate srec file.
%compilerToolchainPath%\arm-none-eabi-objcopy -O srec S32K324_WB_M2xxG1_200.elf "S32K324_WB_M2xxG1_200.srec"
要求不完美的人,喜欢偷懒的人,我我个人是比较推荐第一种方法的,这个方法最简单,不用做过多设置。但有时候也有一点点小弊端,请看后续方法。
2.2 方案二
第一步: 使能S32DS自带的生成指定格式文件的功能(默认是关闭的)。方法:在工程属性配置里面,勾选Create flash image。
第二步: 上图勾选相关选项后,点 Apply and Close
按钮 。然后重新进入工程属性配置页面,选择你需要输出的文件格式。
第三步: 在工程根目录下(有.project和.cproject那个文件夹)创建一个名为:makefile.targets
的文件,注意这个文件名不能随意修改。然后打开文件,添加如下内容(第一行的user_post_build是自定义的编译目标,这个名字可以修改为你喜欢的。最后一行是你的脚本名称):
user_post_build: all post_build_step
post_build_step: $(SECONDARY_FLASH)
@echo 'You specified format file generated.'
.\..\userScript.bat
第四步: 工程属性修改编译目标:Build (Incremental build)处将默认的all
修改为我们第三步文件里面自己定义的user_post_build
。
这种方法相比第一种方法稍微复杂一些(其实也不难),但相比于第一种方法也有一些优势。比如有时候当你已经编译过(elf文件及指定格式文件(比如*.srec)都已经生成过),突然发现你的脚本有bug,需要修改(源代码不需要修改)。当你修改完脚本需要重新运行你脚本的时候,如果使用第一种方法,你需要clean后重新编译才能执行你的脚本。但是第二种方法只需要再次执行编译即可,不需要clean。
2.3 方案三
关于方案三,我只说一下大概思路,就不详细介绍流程了,因为我不推荐这种方法,这种方法在我看来相比于前面两种方法没有任何优势。方法一的弊端方案三也有。且设置比方案二更复杂。编译效率也比前面两种更低。
它的思想大概就是建两个调试目标,然后第一个目标设置为依赖项,这样当你每次编译第二个调试目标的时候会先编译第一个调试目标。而第一个调试目标里面会生成elf和你指定格式的文件。然后用户的脚本放到第二个调试目标里面去调用,这样就解决了调用顺序的问题。
这里大家也明白了,每次编译实际上是要执行两个调试目标的流程,所以时间会久一些,且方法二里面提到的方法一的弊端在方案三里面依然存在。