求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
要资料
 
追随技术信仰

随时听讲座
每天看新闻
 
 
AUTOSAR实战教程
1.AUTOSAR相关知识
1. 老板说项目要上AUTOSAR,我慌得一批
2. 我淡定地撸了一遍AUTOSAR的基本概念
3. AUTOSAR初学者最想搞懂的东西
2.AUTOSAR理论基础
AUTOSAR架构
1. AUTOSAR架构的故事(干货)
2. AUTOSAR架构之通信服务(干货)
3. 这次我通过Interface来贯穿整个AUTOSAR架构
AUTOSAR启动与初始化
1. 解析AUTOSAR Startup
2.AUTOSAR架构中的配置文件
3.SWC详解与配置实现
1.AUTOSAR Port原理概念详解
4.BSW原理和实战演练
1. AUTOSAR折磨,从新建工程开始
2. AUTOSAR的BswM模块详解
3. 图解AUTOSAR NVM模块
4. AUTOSAR架构的 Pdu Router
5. AUTOSAR中的vLinkGen可以干嘛
6. MCAL Wdg模块解析
7. MCAL PWM Module详解
8. AUTOSAR的Memory是如何设计的?
9. AUTOSAR NvM Block的Native、Redundant和Dataset有什么区别?
10. AutoSAR,在多核汽车MCU中如何运行
11. AUTOSAR架构中的Configurator
12. AUTOSAR中的Fee
5.MCAL应用配置
1.ADC模块的配置
2.MCU模块的配置
3.PWM模块的配置
 
 
解析AUTOSAR Startup
作者:实战派大师兄
2608 次浏览
10次  

首先,从配置上找到工程的启动入口

/* CODE_SETUP */

_CODE_SETUP_START align(4) :> CODE_SETUP

__CODE_SETUP_START = . ;

. = align(4);

_Startup_Code_START = . ;

__Startup_Code_START = . ;

.brsStartup align (4) :> .

_RESET = brsStartupEntry;

_start = brsStartupEntry;

_brsStartupEntry = brsStartupEntry;

从这个配置可以看到, brsStartupEntry 是这个工程的入口。

然后,仿真设个断点看看:

对应的源码是

 

/* */

/* Description: Entry point for all cores */

/* */

 

BRS_SECTION_CODE ( brsStartup )

BRS_GLOBAL (brsStartupEntry)

BRS_LABEL (brsStartupEntry)

// … …

BRS_BRANCH (brsPreAsmStartupHook)

继续看仿真

后面它会跳到 brsStartupZeroInitLoop ,那么这个brsStartupZeroInitLoop做什么的呢?

 

/* */

/* Description: Initialize memory blocks and areas with zero */

/* */

 

BRS_GLOBAL (brsStartupZeroInitLoop)

BRS_LABEL (brsStartupZeroInitLoop)

/* read ID of actual running Core into Register 16 */

BRS_READ_COREID (r16)

/* Initialize memory sections with zeros */

#if defined (VLINKGEN_ZERO_INIT_BLOCK_COUNT_STARTUP)

# if (VLINKGEN_ZERO_INIT_BLOCK_COUNT_STARTUP > 1uL )

__as1 (mov _vLinkGen_ZeroInitBlocksArrayStartup , r11)

BRS_LABEL (_startup_block_zero_init_start)

__as1 (mov r11 , r12)

__as2 (addi 12 , r11, r11)

__as1 (ld.w 0 [r12], r13) /* get start address */

__as1 (ld.w 4 [r12], r14) /* get end address */

__as1 (ld.w 8 [r12], r15) /* get core ID */

__as1 (cmp r13 , r14) /* check end of table */

___asm (be _startup_block_zero_init_end )

__as1 (cmp r15 , r16) /* compare core ID */

___asm (bne _startup_block_zero_init_start )

BRS_LABEL (_startup_block_zero_init_loop_start)

__as1 (st.w r0 , 0 [r13])

__as2 (addi 4 , r13, r13)

__as1 (cmp r13 , r14) /* compare to end address */

___asm (bh _startup_block_zero_init_loop_start )

___asm (jr _startup_block_zero_init_start )

BRS_LABEL (_startup_block_zero_init_end)

# endif /*VLINKGEN_ZERO_INIT_BLOCK_COUNT_STARTUP>1uL*/

从名字看就是用来初始化内存的,什么内存?就要看看这个 vLinkGen_ZeroInitBlocksArrayStartup 了。

在vLinkGen_InitSections_Lcfg.c里面可以找到

/*! Memory region blocks to be initialized with zeros directly after reset. */

const vLinkGen_MemArea vLinkGen_ZeroInitBlocksArrayStartup [ VLINKGEN_ZERO_INIT_BLOCK_COUNT_STARTUP ] =

{

{

/* .start = */ ( uint32 ) 0xFEBD0000uL , /* LOCAL_RAM_0 */

/* .end = */ ( uint32 ) 0xFEBF0000uL ,

/* .core = */ ( uint32 ) 0uL

},

{

/* .start = */ ( uint32 ) 0uL ,

/* .end = */ ( uint32 ) 0uL ,

/* .core = */ ( uint32 ) 0uL

}

};

其实,这个内存就是RH850 MCU的 LOCAL RAM 来的。很巧妙,这段代码通过判断 .start 和 .end 的值来决定是否结束。如果这个结构体数组有好几个元素,它会一直遍历下去。

完了后,这会跳到 _startup_block_zero_init_end ,继续往下

#else

#error "Mandatory define VLINKGEN_ZERO_INIT_BLOCK_COUNT
_STARTUP missing within vLinkGen configuration!"

#endif /*VLINKGEN_ZERO_INIT_BLOCK_COUNT_STARTUP*/

#if defined (VLINKGEN_ZERO_INIT_AREA_COUNT_STARTUP)

# if (VLINKGEN_ZERO_INIT_AREA_COUNT_STARTUP > 1uL )

__as1 (mov _vLinkGen_ZeroInitAreasArrayStartup , r11)

BRS_LABEL (_startup_area_zero_init_start)

__as1 (mov r11 , r12)

__as2 (addi 12 , r11, r11)

__as1 (ld.w 0 [r12], r13) /* get start address */

__as1 (ld.w 4 [r12], r14) /* get end address */

__as1 (ld.w 8 [r12], r15) /* get core ID */

__as1 (cmp r13 , r14) /* check end of table */

___asm (be _startup_area_zero_init_end )

__as1 (cmp r15 , r16) /* compare core ID */

___asm (bne _startup_area_zero_init_start )

BRS_LABEL (_startup_area_zero_init_loop_start)

__as1 (st.w r0 , 0 [r13])

__as2 (addi 4 , r13, r13)

__as1 (cmp r13 , r14) /* compare to end address */

___asm (bh _startup_area_zero_init_loop_start )

___asm (jr _startup_area_zero_init_start )

BRS_LABEL (_startup_area_zero_init_end)

# endif /*VLINKGEN_ZERO_INIT_AREA_COUNT_STARTUP>1uL*/

#else

#error "Mandatory define VLINKGEN_ZERO_INIT_AREA
_COUNT_STARTUP missing within vLinkGen configuration!"

#endif /*VLINKGEN_ZERO_INIT_AREA_COUNT_STARTUP*/

这个 vLinkGen_ZeroInitAreasArrayStartup 又是干嘛的?

看这个结构体数组

/*! Section groups to be intialized with zeros directly after reset. */

const vLinkGen_MemArea vLinkGen_ZeroInitAreasArrayStartup [ VLINKGEN_ZERO_INIT_AREA_COUNT_STARTUP ] =

{

{

/* .start = */ ( uint32 ) _Startup_Stack_START ,

/* .end = */ ( uint32 ) _Startup_Stack_END ,

/* .core = */ ( uint32 ) 0uL

},

{

/* .start = */ ( uint32 ) 0uL ,

/* .end = */ ( uint32 ) 0uL ,

/* .core = */ ( uint32 ) 0uL

}

};

很明显,这是startup stack来的,即系统的栈初始化。

好了,继续往下走

/* */

/* Description: Jump to Brs_PreMainStartup() (BrsMainStartup.c) */

/* */

 

BRS_BRANCH (_Brs_PreMainStartup)


那么,这个 Brs_PreMainStartup 是什么东西?从上面的注释,可以在 BrsMainStartup.c 找到

FUNCTION DEFINITIONS

/**

* @brief Unified routine for Pre Main() Startup.

* @pre Stack pointer needs to be initilialized in StartUpCode before.

* @param [in] -

* @param [out] -

* @return -

* @context Function is called from assembler startup code

* Called by all cores

* All APIs are called with current Core ID

*/

void Brs_PreMainStartup ( void )

{

BrsHw_PreInitClock ( BrsHw_GetCore ()); /* optional
callout to power up the PLL for faster Memory initialization */

BrsHw_PreZeroRamHook ( BrsHw_GetCore ()); /* optional, empty by default */

// … …

main ();

}

这个是进入 main 函数之前的一些初始化,主要的也是一些RAM等初始化。本文就不细讲了。

到这里,我就找到了整个main函数之前的初始化了。再后面的就是ECUM、OS和BSWM等的初始化了。

 


您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码: 验证码,看不清楚?请点击刷新验证码 必填



2608 次浏览
10次