最近有朋友问到是否用overlay标定完后数据就直接在Flash中,其实不然,是需要关闭overlay然后通过XCPProgram指令集或者UDS刷进Flash。
我们知道,标定参数(即Parameter)实际上对于ECU的控制算法来说是一个常数,最简单的例子,油门踏板开度影响喷油量,假设算法为y=ax+b。要在某个固定踏板开度(x)达到我们预期喷油量(y),要反复调整的只能是常数a和b。
因此,所谓参数的标定,就是通过技术手段保证在ECU的开发阶段能够调整paremeter的值。那么我们就来看看有哪些技术手段可以实现参数的调整。
我们在开发的时候,对于常数其实会用修饰符进行限定的,如下:
constuint32Parameter_A=1;
在进行编译链接之后,编译器会把这个Parameter_A分配到Flash的区间(链接文件里的ROM段)并给定一个地址(通过Map文件可以查找),同时也从编译出来的hex的地址去找到这个值1,如下图所示:
那么要修改这些参数,应该怎么办呢?有两个办法:
通过在源码中修改常数值,重新进行编译,然后刷进ECU里。这样很麻烦,遇到稍微大一点的工程,编译都得十几二十分钟,很显然这种方法是不符合现在的开发流程的。
通过FlashDriver对存放Paremeter_A的Flash空间进行重编程,这种方式比上述重新编译要好一点,但是还是实时性不够,并且目前的FLash特性是没有办法按照Byte进行擦除的,意味着要修改一个标定参数就必须擦掉整个Sector,重新刷写所有的标定参数,这显然是不可接受的。当然,如果ECU外挂的EEPROM,那么就不会存在这个问题了,但是访问速度和相应的开发成本也是阻碍参数的实时标定。
另外,还需要提一点的就是,如果编译器优化等级开的比较高,作为常量的Parameter_A有可能会被优化,直接作为一个数值出现嵌入到代码中,而不会出现在map文件里。因此我们在定义标定参数这种类型常量时,通常会按照如下定义:
volatileconstuint32Parameter_A=1;
volatile可以有效防止被编译器优化;
此外,为了方便管理和能迅速定位到标定参数,我们通常也会在链接文件里定义一块单独的空间,在代码里使用#pragma把参数放到该空间里,如下:
#pragmasection'Cal_Flash'constuint32Parameter_A=1;
这里我们简单讲了标定参数只在Flash里的时候应该如何修改,实际上这种方式并不能支持我们在ECU运行过程中动态修改
所以,我们能不能想个办法把这些参数搬到一段RAM中,在RAM里实时修改,修改完成后再把标好的参数重新刷进Flash。
显然这个想法是成立的。
我们定义一个带初值的变量,如下图:
uint32Parameter_A=1;
编译器会给这个参数分配RAM空间地址,并且初值存放在Flash中。我做过一个试验,用英飞凌TC2xx系列,在不修改链接文件的情况下,编译器给标定参数分配一个RAM地址,但实际上存在Flash里,如下图: