注:本文首发于公众号“嵌入式软件实战派”
你有没有发觉AUTOSAR代码里面有些文件名很是引起你注意,如xxx_PBcfg.c、xxx_Lcfg.c和xxx_Cfg.h。
看起来,这像是配置文件,实际也证明跟AUTOSAR配置有关(更改配置工具如Davinci Configurator上的配置信息)生成代码时,这些文件会有相应的变化。
那么,问题来了,一个xxx_cfg.h或者xxx_cfg.c就搞定了,为什么会有三种配置文件呢?
于是,我要刨根问底了。
cfg还好理解,就是configuration的意思,这个PB和L又是什么意思?
翻了很多AUTOSAR官方文档,终于找到了,其实AUTOSAR Base Software支持以下几种配置类型:
1. Pre-compile time
-
处理器指令
-
代码生成(选择和合成)
2. Link time
-
module外的const数据; 模块编译后和配置数据
3. Post-build time
-
加载Module外部的const数据. 加载数据到指定的memory段
独立于配置类,可以通过变化点提供单个或多个配置集。如果提供了多个配置集,则在运行时绑定变量点的情况下,将在运行时选择实际使用的配置集。
在许多情况下,一个模块的配置参数将具有不同的配置类别。
例如,提供构建后时间配置参数的模块仍将具有一些可进行预编译时间配置的参数。
这样看来,这个PB就是post-build time了,而L就是Link time了。那么各个配置文件有什么作用和区别呢?
Pre-compile time
使用:
-
启用/禁用可选功能。这样可以排除不需要的部分源代码。
-
优化性能和代码大小。在大多数情况下,使用#defines比访问常量甚至通过指针访问常量的代码效率更高。
生成的代码避免了代码和运行时开销。
Pre-compile的配置要通过两个配置文件(xxx_Cfg.h, xxx_Cfg.c) 实现:
-
xxx_Cfg.h 包含如 宏定义和或者#defines
-
xxx_Cfg.c 包含如const数据
Nm_cfg.c
#include "Nm_Cfg.h"
/*lint -restore */
CONST(Nm_NmFunctionTableType, NM_CONST) Nm_NmFunctionTable[1] = { /* PRQA S 1514, 1533 */ /* MD_CSL_ObjectOnlyAccessedOnce */
/* Index GetLocalNodeIdentifier GetNodeIdentifier GetPduData GetState NetworkRelease NetworkRequest PassiveStartUp Referable Keys */
{ /* 0 */ CanNm_GetLocalNodeIdentifier, CanNm_GetNodeIdentifier, CanNm_GetPduData, CanNm_GetState, CanNm_NetworkRelease, CanNm_NetworkRequest, CanNm_PassiveStartUp } /* [CanNm] */
};
m_Cfg.h
/* Global Properties */
#ifndef NM_DEV_ERROR_DETECT
#define NM_DEV_ERROR_DETECT STD_ON
#endif
#ifndef NM_DEV_ERROR_REPORT
#define NM_DEV_ERROR_REPORT STD_ON
#endif
#define NM_VERSION_INFO_API STD_OFF
Nm.c
/* NM Interface version is decimal coded. */
CONST(uint8, NM_CONST) Nm_MainVersion = NM_SW_MAJOR_VERSION;
CONST(uint8, NM_CONST) Nm_SubVersion = NM_SW_MINOR_VERSION;
CONST(uint8, NM_CONST) Nm_ReleaseVersion = NM_SW_PATCH_VERSION;
Link time
Link time配置用于:
-
模块配置仅仅对目标代码可用(例如IP Protection和warranty原因)
-
在编译之后但在链接之前创建配置。
例如
Mcu_Lcfg.c
/* QAC Warning: START Msg(2:3211)-2 */
/* Data Structure of RAM setting Configuration */
CONST(Mcu_RamSetting, MCU_VAR) Mcu_GstRamSetting[1] =
{
/* Index: 0 - McuRamInitConfiguration */
{
/* pRamStartAddress */
/* MISRA Violation: START Msg(4:0306)-1 */
/* QAC Warning: START Msg(2:0315)-3 */
/* QAC Warning: START Msg(2:3892)-4 */
(P2VAR(uint8, TYPEDEF, MCU_CONFIG_DATA)) 0xFEBD0000UL,
/* END Msg(2:3892)-4 */
/* END Msg(2:0315)-3 */
/* END Msg(4:0306)-1 */
/* ulRamSectionSize */
0x00000100UL,
/* ucRamInitValue */
0xFFU,
/* enRamWriteSizeSel */
MCU_8BIT_SIZE
}
};
Mcu.c
/* Get the pointer to the RAM structure */
LpRamSetting = &Mcu_GstRamSetting[RamSection];
Post-build time
Post-build time会用于
-
数据配置,其中仅定义结构,但在ECU生成期间未知内容
-
在ECU-build时之后(例如,生产end of line,测试和校准期间)可能会更改或必须修改的数据配置
-
跨不同汽车版本(相同应用,不同配置)的ECU的可重用性,例如 与豪华版轿车的ECU相比,低成本版轿车的ECU在总线上传输的信号更少。
例如
关注“嵌入式软件实战派”,回复“AUTOSAR”获得更多实战教程。