内存映射(MemMap)
头文件
原理:利用#if #elif #ifndef #undef #pragma(将源代码中的字符串编码直接转换为编译指令)进行条件编译
以一个BSW模块DCM的内存映射为例:
1. Dcm_MemMap.h
/** @file Dcm_MemMap.h
*
* @brief RTE Sample SWC MemMap file
*
* @note AUTOMATICALLY GENERATED FILE! DO NOT EDIT!
*
*/
#if defined (START_WITH_IF)
#elif defined(Dcm_START_SEC_CODE)
#undef Dcm_START_SEC_CODE
#define RTE_START_SEC_APPL_CODE
#elif defined(Dcm_STOP_SEC_CODE)
#undef Dcm_STOP_SEC_CODE
#define RTE_STOP_SEC_APPL_CODE
#endif /* START_WITH_IF */
#include "Rte_MemMap.h"
嵌套include了 Rte_MemMap.h
2. Rte_MemMap.h
/** \file Rte_MemMap.h
*
* \brief RTE Memory Mapping header file
*
* \note Implemented SWS: N/A
*
* \note PLATFORM DEPENDANT [yes/no]: no
*
* \note TO BE CHANGED BY USER [yes/no]: yes
*
*/
#ifndef RTE_MEMMAP_H_ //避免重复定义
#define RTE_MEMMAP_H_
#include "MemMap.h"
#endif /* RTE_MEMMAP_H_ */
再一次嵌套include了 MemMap.h
3 MemMap.h
/*----------------------------------------------------------------------------*/
/************** *SAMPLE* of MemMap.h. Not for production purposes *************/
/*----------------------------------------------------------------------------*/
#define MEM_VENDOR_ID (11U)
#define MEM_AR_MAJOR_VERSION (4U)
#define MEM_AR_MINOR_VERSION (0U)
#define MEM_AR_PATCH_VERSION (3U)
#define MEM_SW_MAJOR_VERSION (5U)
#define MEM_SW_MINOR_VERSION (6U)
#define MEM_SW_PATCH_VERSION (3U)
/*******************************************************************************
** Default section mapping **
*******************************************************************************/
#if defined (START_WITH_IF)
/* -------------------------------------------------------------------------- */
/* RAM variables not initialized */
/* -------------------------------------------------------------------------- */
#elif defined (DEFAULT_START_SEC_VAR_NOINIT_BOOLEAN)
#undef DEFAULT_START_SEC_VAR_NOINIT_BOOLEAN
#elif defined (DEFAULT_STOP_SEC_VAR_NOINIT_BOOLEAN)
#undef DEFAULT_STOP_SEC_VAR_NOINIT_BOOLEAN
#elif defined (DEFAULT_START_SEC_VAR_NOINIT_8BIT)
#undef DEFAULT_START_SEC_VAR_NOINIT_8BIT
#elif defined (DEFAULT_STOP_SEC_VAR_NOINIT_8BIT)
#undef DEFAULT_STOP_SEC_VAR_NOINIT_8BIT
#elif defined (DEFAULT_START_SEC_VAR_NOINIT_16BIT)
#undef DEFAULT_START_SEC_VAR_NOINIT_16BIT
#elif defined (DEFAULT_STOP_SEC_VAR_NOINIT_16BIT)
#undef DEFAULT_STOP_SEC_VAR_NOINIT_16BIT
。。。
#elif defined CALIB_START_SEC_CONST_BOOL
#undef CALIB_START_SEC_CONST_BOOL
#ifdef __TASKING__
#pragma section farrom="Calib_bool"
#pragma align 1
#elif __GNUC__
#pragma section ".rodata.Calib_bool" a 1
#elif _DIABDATA_C_TRICORE_
#endif
#elif defined CALIB_STOP_SEC_CONST_BOOL
#undef CALIB_STOP_SEC_CONST_BOOL
#ifdef __TASKING__
#pragma align restore
#pragma section farrom restore
#elif __GNUC__
#pragma section
#elif _DIABDATA_C_TRICORE_
#endif
#elif defined CALIB_START_SEC_CONST_8
#undef CALIB_START_SEC_CONST_8
#ifdef __TASKING__
#pragma section farrom="Calib_8"
#pragma align 1
#elif __GNUC__
#pragma section ".rodata.Calib_8" a 1
#elif _DIABDATA_C_TRICORE_
#endif
#elif defined CALIB_STOP_SEC_CONST_8
#undef CALIB_STOP_SEC_CONST_8
#ifdef __TASKING__
#pragma align restore
#pragma section farrom restore
#elif __GNUC__
#pragma section
#elif _DIABDATA_C_TRICORE_
#endif
/* -------------------------------------------------------------------------- */
/* RAM variables power-on initialized */
/* -------------------------------------------------------------------------- */
#elif defined (DEFAULT_START_SEC_VAR_POWER_ON_INIT_BOOLEAN)
#undef DEFAULT_START_SEC_VAR_POWER_ON_INIT_BOOLEAN
#elif defined (DEFAULT_STOP_SEC_VAR_POWER_ON_INIT_BOOLEAN)
#undef DEFAULT_STOP_SEC_VAR_POWER_ON_INIT_BOOLEAN
#elif defined (DEFAULT_START_SEC_VAR_POWER_ON_INIT_8BIT)
#undef DEFAULT_START_SEC_VAR_POWER_ON_INIT_8BIT
#elif defined (DEFAULT_STOP_SEC_VAR_POWER_ON_INIT_8BIT)
#undef DEFAULT_STOP_SEC_VAR_POWER_ON_INIT_8BIT
#elif defined (DEFAULT_START_SEC_VAR_POWER_ON_INIT_16BIT)
#undef DEFAULT_START_SEC_VAR_POWER_ON_INIT_16BIT
#elif defined (DEFAULT_STOP_SEC_VAR_POWER_ON_INIT_16BIT)
#undef DEFAULT_STOP_SEC_VAR_POWER_ON_INIT_16BIT
#elif defined (DEFAULT_START_SEC_VAR_NO_INIT_UNSPECIFIED)
#undef DEFAULT_START_SEC_VAR_NO_INIT_UNSPECIFIED
#ifdef __TASKING__
#pragma section farbss="DEFAULT_START_SEC_VAR_NO_INIT_UNSPECIFIED"
#elif __GNUC__
#pragma section ".bss.DEFAULT_START_SEC_VAR_NO_INIT_UNSPECIFIED"
#elif _DIABDATA_C_TRICORE_
#endif
#elif defined (DEFAULT_STOP_SEC_VAR_NO_INIT_UNSPECIFIED)
#undef DEFAULT_STOP_SEC_VAR_NO_INIT_UNSPECIFIED
#ifdef __TASKING__
#pragma section farbss restore
#elif __GNUC__
#pragma section
#elif _DIABDATA_C_TRICORE_
#endif
/* -------------------------------------------------------------------------- */
/* RAM variables initialized from ROM on reset */
/* -------------------------------------------------------------------------- */
#elif defined (DEFAULT_START_SEC_VAR_BOOLEAN)
#undef DEFAULT_START_SEC_VAR_BOOLEAN
#elif defined (DEFAULT_STOP_SEC_VAR_BOOLEAN)
#undef DEFAULT_STOP_SEC_VAR_BOOLEAN
#elif defined (DEFAULT_START_SEC_VAR_8BIT)
#undef DEFAULT_START_SEC_VAR_8BIT
#elif defined (DEFAULT_STOP_SEC_VAR_8BIT)
#undef DEFAULT_STOP_SEC_VAR_8BIT
#elif defined (DEFAULT_START_SEC_VAR_16BIT)
#undef DEFAULT_START_SEC_VAR_16BIT
#elif defined (DEFAULT_STOP_SEC_VAR_16BIT)
#undef DEFAULT_STOP_SEC_VAR_16BIT
/* -------------------------------------------------------------------------- */
/* RAM variables frequently used or accessed bitwise */
/* -------------------------------------------------------------------------- */
#elif defined (DEFAULT_START_SEC_VAR_FAST_BOOLEAN)
#undef DEFAULT_START_SEC_VAR_FAST_BOOLEAN
#elif defined (DEFAULT_STOP_SEC_VAR_FAST_BOOLEAN)
#undef DEFAULT_STOP_SEC_VAR_FAST_BOOLEAN
#elif defined (DEFAULT_START_SEC_VAR_FAST_8BIT)
#undef DEFAULT_START_SEC_VAR_FAST_8BIT
#elif defined (DEFAULT_STOP_SEC_VAR_FAST_8BIT)
#undef DEFAULT_STOP_SEC_VAR_FAST_8BIT
#elif defined (DEFAULT_START_SEC_VAR_FAST_16BIT)
#undef DEFAULT_START_SEC_VAR_FAST_16BIT
#elif defined (DEFAULT_STOP_SEC_VAR_FAST_16BIT)
#undef DEFAULT_STOP_SEC_VAR_FAST_16BIT
/* -------------------------------------------------------------------------- */
/* ROM constants */
/* -------------------------------------------------------------------------- */
#elif defined (DEFAULT_START_SEC_CONST_BOOLEAN)
#undef DEFAULT_START_SEC_CONST_BOOLEAN
#elif defined (DEFAULT_STOP_SEC_CONST_BOOLEAN)
#undef DEFAULT_STOP_SEC_CONST_BOOLEAN
#elif defined (DEFAULT_START_SEC_CONST_8BIT)
#undef DEFAULT_START_SEC_CONST_8BIT
#elif defined (DEFAULT_STOP_SEC_CONST_8BIT)
#undef DEFAULT_STOP_SEC_CONST_8BIT
#elif defined (DEFAULT_STOP_SEC_CONST_UNSPECIFIED)
#undef DEFAULT_STOP_SEC_CONST_UNSPECIFIED
#ifdef __TASKING__
#pragma align restore
#pragma section farrom restore
#elif __GNUC__
#pragma section
#elif _DIABDATA_C_TRICORE_
#endif
/* -------------------------------------------------------------------------- */
/* ROM FAR constants */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* ROM code */
/* -------------------------------------------------------------------------- */
。。。
/*BMHD_0_COPY*/
/*BMHD_1_ORIG*/
/*BMHD_1_COPY*/
。。。
/*BMHD_2_ORIG*/
。。。
/*BMHD_2_COPY*/
。。。
/*BMHD_3_ORIG*/
。。。
/*BMHD_3_COPY*/
。。。
/*MCAL lib*/
/*Start up*/
。。。
/*fix cstart address*/
/*Main*/
/*CAT1_ISR*/
/* ---The following sections attempt to locate FLS Write and Erase command-----
---Cycles in an order. It is essential to enforce the correct sequence------
---so that the FLS driver can perform as requird.-------------------------*/
。。。
/* -------------------------------------------------------------------------- */
/* End of default section mapping */
/* -------------------------------------------------------------------------- */
#endif /* START_WITH_IF */
/*** End of file **************************************************************/
4 Dcm_Cfg_MemMap.h
#if defined(DCM_START_SEC_CODE)
#if defined DCM_WAS_STARTED_SEC_ROM_CODE
#error DCM_WAS_STARTED_SEC_ROM_CODE already defined
#endif
#define BSW_START_SEC_DEFAULT_CODE
#include "Bsw_MemMap.h"
#undef BSW_START_SEC_DEFAULT_CODE
#undef MEMMAP_ERROR
#undef DCM_START_SEC_CODE
#define DCM_WAS_STARTED_SEC_ROM_CODE
基本上所有模块的内存映射.h文件的关包含关系都是这样,这样做的目的:
-
Dcm_MemMap.h 定义模块特定的宏
-
Rte_MemMap.h 避免重定义
-
Dcm_Cfg_MemMap.h 这里#include了Bsw_MemMap.h 目的是将底层DCM模块生成的代码进一步mapping
-
MemMap.h来自于MCAL integration code里面定义了除基本模块之外的所有的不同代码或者数据的映射宏定义,包括:
-
RAM variables not initialized
-
RAM variables power-on initialized
-
RAM variables initialized from ROM on reset
-
RAM variables frequently used or accessed bitwise
-
ROM constants
-
ROM FAR constants
-
ROM code
-
BMHD_0_ORIG
-
BMHD_0_COPY
-
BMHD_1_ORIG
-
BMHD_1_COPY
-
BMHD_2_ORIG
-
BMHD_2_COPY
-
BMHD_3_ORIG
-
BMHD_3_COPY
-
MCAL lib
-
Start up
-
fix cstart address
-
Main
-
CAT1_ISR
其实不管他的头文件怎么变化,其主要目的就是将通过定义#define宏定义实现条件编译
源文件
1. Dcm_Dsl_Protocol.c 自动生成的代码
#include "DcmCore_DslDsd_Inf.h"
#define DCM_START_SEC_CODE /*Adding this for memory mapping*/
#include "Dcm_Cfg_MemMap.h"
FUNC(Std_ReturnType,DCM_CODE) Dcm_GetActiveProtocol(P2VAR(Dcm_ProtocolType, AUTOMATIC, DCM_APPL_DATA)
{
...
}
2. xxx_task.c RTE生成
#define DCM_START_SEC_CODE
#include "Dcm_MemMap.h"
FUNC(void, DCM_CODE) Dcm_MainFunction(void);
#define DCM_STOP_SEC_CODE
#include "Dcm_MemMap.h"
当然源文件还有很多,主要是bsw生成的静态代码和动态配置代码
需要注意的几点
- Rte中生成的.h中include的一些 MemMap.h比如ASW_Diag_MemMap.h是按照 XXX_MemMap.h生成的,所以在配置对应的MemMap.h也就应该按照对应的名字来。
内存映射的作用(转)
1.避免RAM的浪费
在同一个模块下定义了不同类型的变量(比如8bit、16bit、32bit),则为了对齐,会在不同类型变量间留间隙。比如8bit变量和32bit变量存放在一起,在两个变量都要对齐到32bit。
2.特殊RAM用途
比如一些变量通过位掩码来获取,如果map到RAM可以通过编译器的位掩码功能来加快执行效率
3.特殊ROM用途
一些频繁执行的函数可以映射到RAM中,而不经常执行的函数可以映射到外部ROM。
4. 同一段代码用在bootloader和应用
如果同一个模块同时需要被bootloader和应用使用,则需要同时映射到不同的段中
5. 支持内存保护
使用硬件存储器保护需要将模块变量分离到不同的存储器区域。内部变量映射到受保护的内存中,用于数据交换的缓冲区映射到不受保护的内存中。
6. 支持分区
可以将一个模块的变量映射到不同的分区中