Abstract: There are more rigorous safety requirements on input and output variables when developing automotive controller torque monitor function to meet the second level requirement of the 3 level safety structure defined in ISO 26262. Low level software only supports fixedpoint variable input, and C code generated by torque monitor algorithm model developed via Simulink only supports the floatingpoint variable. There is a conflict when compiling the two parts to generate the executable file. One method that rewrites the TLC scripts to control the generated code by Simulink RTW tools is selected after comparing several solutions. A big progress that the solution has not any extra work to Simulink modeling engineer, meets ISO 26262 safety function requirements, at the same time successfully solves the conflict of low level software and algorithm models.
Key words: fixed-point; floating-point; ISO 26262; safety RAM
引言
在现代的汽车电子控制器开发中,普遍采用了国际知名供应商开发的硬件控制器和包括Bootloader、符合OSEK标准的实时操作系统,以及底层硬件驱动等底层软件,并提供相应的软件接口层给上层控制策略应用软件。但根据底层软件因不同的硬件设计而不同的特点,以及考虑到代码执行效率的原因,多采用定点手写代码来完成。
而随着微电子技术的不断进步和电子芯片价格的不断下降,越来越多的控制器已支持32位带浮点数运算单元的解决方案,这就为基于模型的控制算法的开发提供了广阔空间。
1 ISO 26262三层安全架构
1.1 架构简介
在最新的ISO 26262(汽车行业功能安全标准)中对控制器的三层安全架构要求如下:
① Level1实现动力系统管理功能,如转换动力系统请求扭矩、零部件监控、输入/输出变量诊断及在错误确认时控制系统响应。
② Level2负责监控Level1功能软件缺陷,如监控计算的扭矩值或车辆的加速度值,如果检测到此类错误将触发系统错误。
③ Level3监控模块独立于Level2和Level1,通过应答机制监控Level2和Level1层软件是否正常运行,如错误发生将触发独立于功能控制器的系统错误。
1.2 ISO 26262在扭矩监控软件的应用
根据ISO 26262三层安全架构的阐述,第二层负责监控第一层与安全相关的功能,与安全相关的输入变量的值在被第一层软件读取的同时也要被第二层监控软件读取,且要有冗余备份。例如,通过监控计算的或车辆加速时的扭矩输出,当第二层监控模块计算扭矩与第一层功能层计算扭矩不一致时,会引起控制系统故障响应。
根据以上安全相关需求,在设计扭矩监控模块TQM时,极大地提高了对参与计算的输入/输出变量的安全性的要求,由此引入了安全内存(Safety RAM)。下面首先介绍底层软件中基于定点数的安全内存的实现原理。
2 基于定点数的安全内存应用
2.1 安全内存工作原理
与安全有关的RAM中的数据在防止信息丢失、读写能力的保护等方面需要额外的保护。基于这个原因,将双倍的RAM内存区用于软件比较和读/写测试可大幅提高数据的安全性。地址空间在两个内存区域复制,原始数据存储在第一个内存区域,第二个内存包含补充信息,将与第一块内存区并行访问。在输出时比较两块内存的数值,如果发现任何偏差,会产生一个复位。为了检测特定类型的位错误,在第二个内存区域的数据存储采用二进制补码的形式。一般安全内存支持访问下列类型:不受中断保护的访问类型、写入或读取的安全内存数据、中断保护的访问类型。需要写入或读取相关数据的安全保护。
在当前的底层,基于定点数接口说明如下:存储到安全内存区变量定义,分为变量的源地址定义与补码地址定义,分别存放在两处非相邻内存区;读取存储在安全内存区的变量参与逻辑运算的接口RdSafetyRam32(&Var),当这个接口被调用时与存储在源码区与补码区的值进行比较,如发现任何不一致将导致系统错误发生;存储变量到安全内存区接口函数为WrSafetyRam32(&Var,com_var),通用内存区变量com_var的当前值将分别存放到Safety RAM区变量var的源码地址区和补码地址区。
2.2 安全内存接口典型应用
/*定义存储到安全内存区变量源址定义*/
#define SECTION SAFRAM
uint32 Var1;
/* 定义存储到安全内存区变量二进制补码地址定义*/
#define SECTION SAFRAM_CPL
uint32 Var1Cpl;
/*典型应用*/
/*读经过校验的uint32安全内存变量*/
Saf_var1 = RdSafetyRam32(&Var1);
Saf_var1 = Saf_var1 + val;
/* 写安全内存变量 */
WrSafetyRam32(&Var1,Saf_var1);
在关于安全内存典型应用的示例中,Var1为定义到安全内存区的变量,同时在安全内存补码区定义了相同变量名,即用后缀Cpl加以区分的补码。RdSaftyRam32(&Var)和WrSafetyRam32(&Var,Common_Var)两个函数分别为读32位变量和写32位变量的接口函数。在读写两个函数中完成变量Var的源码与补码的效验以确保示例中变量Var1的安全,从而提高整个扭矩监控算法的安全等级。
3 针对Simulink浮点扭矩监控模块的解决方案
目前的实际情况是,底层软件提供的接口API函数只支持uint8、uint16、uint32三种数据类型,对于定点数的操作完全没有问题。可是对于基于Simulink模型生成的基于浮点数的C代码,主要应用single的数据类型就没有办法直接应用安全内存的接口函数了,以下是针对这个问题的几个解决方案的比较。
3.1 强制类型转换
single A=32.235;
uin32 B;
强制类型转换为:
B=(uint32)A;
结果会导致B精度损失,不能满足工程需要。
3.2 使用union数据类型
union SafetyRAM_Signal_Type_tag {
uint32 IntegerValue;
real32 Value;
} SafetyRAM_Signal_Type;
SafetyRAM_Signal_Type Val_A;
SafetyRAM_Signal_Type Val_2;
/* 声明安全内存变量Var32Val_A */
#define SECTION SAFRAM
uint32 Var32Val_A;
#define SECTION SAFRAM_CPL
uint32 Var32Val_ACpl;
/*读取安全内存变量 Var32Val_A*/
Val_A.IntegerValue=RdSafteyRam32 (&Var32Val_A);
Val_2.Value=Val_A.Value + 5;
/*写安全内存变量 Var32Val_A */
WrSafetyRam32(&Var32Val_A,Val_2.IntegerValue);
上述代码对应的Matlab模型如图1所示。