解析AUTOSAR Startup

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

 

 /* 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_InitSections_Lcfg.c里面可以找到从名字看就是用来初始化内存的,什么内存?就要看看这个vLinkGen_ZeroInitBlocksArrayStartup了。

/*! 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
  }
};


完了后,这会跳到_startup_block_zero_init_end,继续往下其实,这个内存就是RH850 MCU的LOCAL RAM来的。很巧妙,这段代码通过判断.start和.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等初始化。本文就不细讲了。那么,这个Brs_PreMainStartup是什么东西?从上面的注释,可以在BrsMainStartup.c找到

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

关注“嵌入式软件实战派”回复“AUTOSAR”获得更多​实战教程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值