CC26XX IAR程序启动流程

1、向量表__vector_table位于startup_iar.c

__root void (* const __vector_table[])(void) @ ".intvec" =
{
    (void (*)(void))&STACK_TOP,             //  0 The initial stack pointer
    ResetISR,                               //  1 The reset handler
    NmiSR,                                  //  2 The NMI handler
    FaultISR,                               //  3 The hard fault handler
    MPUFaultIntHandler,                     //  4 Memory Management (MemManage) Fault
    BusFaultIntHandler,                     //  5 The bus fault handler
    UsageFaultIntHandler,                   //  6 The usage fault handler
    0,                                      //  7 Reserved
    0,                                      //  8 Reserved
    0,                                      //  9 Reserved
    0,                                      // 10 Reserved
    SVCallIntHandler,                       // 11 Supervisor Call (SVCall)
    DebugMonIntHandler,                     // 12 Debug monitor handler
    0,                                      // 13 Reserved
    PendSVIntHandler,                       // 14 The PendSV handler
    SysTickIntHandler,                      // 15 The SysTick handler
    //--- External interrupts ---
    GPIOIntHandler,                         // 16 AON edge detect
    I2CIntHandler,                          // 17 I2C
    RFCCPE1IntHandler,                      // 18 RF Core Command & Packet Engine 1
    PKAIntHandler,                          // 19 PKA Interrupt event
    AONRTCIntHandler,                       // 20 AON RTC
    UART0IntHandler,                        // 21 UART0 Rx and Tx
    AUXSWEvent0IntHandler,                  // 22 AUX software event 0
    SSI0IntHandler,                         // 23 SSI0 Rx and Tx
    SSI1IntHandler,                         // 24 SSI1 Rx and Tx
    RFCCPE0IntHandler,                      // 25 RF Core Command & Packet Engine 0
    RFCHardwareIntHandler,                  // 26 RF Core Hardware
    RFCCmdAckIntHandler,                    // 27 RF Core Command Acknowledge
    I2SIntHandler,                          // 28 I2S
    AUXSWEvent1IntHandler,                  // 29 AUX software event 1
    WatchdogIntHandler,                     // 30 Watchdog timer
    Timer0AIntHandler,                      // 31 Timer 0 subtimer A
    Timer0BIntHandler,                      // 32 Timer 0 subtimer B
    Timer1AIntHandler,                      // 33 Timer 1 subtimer A
    Timer1BIntHandler,                      // 34 Timer 1 subtimer B
    Timer2AIntHandler,                      // 35 Timer 2 subtimer A
    Timer2BIntHandler,                      // 36 Timer 2 subtimer B
    Timer3AIntHandler,                      // 37 Timer 3 subtimer A
    Timer3BIntHandler,                      // 38 Timer 3 subtimer B
    CryptoIntHandler,                       // 39 Crypto Core Result available
    uDMAIntHandler,                         // 40 uDMA Software
    uDMAErrIntHandler,                      // 41 uDMA Error
    FlashIntHandler,                        // 42 Flash controller
    SWEvent0IntHandler,                     // 43 Software Event 0
    AUXCombEventIntHandler,                 // 44 AUX combined event
    AONProgIntHandler,                      // 45 AON programmable 0
    DynProgIntHandler,                      // 46 Dynamic Programmable interrupt
                                            //    source (Default: PRCM)
    AUXCompAIntHandler,                     // 47 AUX Comparator A
    AUXADCIntHandler,                       // 48 AUX ADC new sample or ADC DMA
                                            //    done, ADC underflow, ADC overflow
    TRNGIntHandler,                         // 49 TRNG event
    OSCIntHandler,                          // 50 Combined event from Oscillator control
    AUXTimer2IntHandler,                    // 51 AUX Timer2 event 0
    UART1IntHandler,                        // 52 UART1 combined interrupt
    BatMonIntHandler                        // 53 Combined event from battery monitor
};

2、复位向量ResetISR

void ResetISR(void)
{
    //
    // Final trim of device
    //
    SetupTrimDevice();

    //
    // Jump to IAR initialization routine
    //
    __iar_program_start();

    //
    // If we ever return signal Error
    //
    FaultISR();
}

3、跳转到IAR初始化程序 __iar_program_start 位于boot.s文件

        PUBLIC  __iar_program_start
        EXTERN  CSTACK$$Limit
        EXTERN  __iar_program_startC

        THUMB
__iar_program_start:
        LDR     R0, cstacklimit
        MOV     SP, R0
        LDR     R0, program_startc
        BLX     R0

        DATA
        ALIGNROM 2
cstacklimit:
        DC32    CSTACK$$Limit

program_startc:
        DC32   __iar_program_startC

通过下面两条汇编代码可以看出,程序跳转到program_startc

LDR R0, program_startc;
BLX R0

program_startc对应的是__iar_program_startC,所以程序实际是跳转到__iar_program_startC

program_startc:
DC32 __iar_program_startC

4、__iar_program_startC函数位于cstartup_M.c文件

void __iar_program_startC( void )
{
    /* XDC startup reset hook */
    iar_xdc_startup_reset();

    __iar_init_core();

#if defined (__ARMVFP__)
/*------------------------------------------------------
 * SETUP FULL ACCESS TO COPROCESSORS 10 AND 11,
 * REQUIRED FOR FP. COPROCESSOR ACCESS CONTROL REG
 * BITS [23:22] - CP11, [21:20] - CP10
 * SET TO 0b11 TO ENABLE FULL ACCESS
 *------------------------------------------------------
 */
    asm volatile( 
        " MOVW     r1, #0xE000ED88 & 0xFFFF\n"
        " MOVT     r1, #0xE000ED88 >> 16\n"
        " LDR      r0, [ r1 ]\n"
        " MOV      r3, #0xf0\n"
        " ORR      r0,r0,r3, LSL #16\n"
        " STR      r0, [ r1 ]\n"
    );   
#endif

    __cmain();
}

程序最后调用汇编的__cmain,位于文件cmain.s

        PUBLIC  __cmain
        ;; Keep ?main for legacy reasons, it is accessed in countless instances of cstartup.s around the world...
        PUBLIC  ?main
        EXTWEAK __iar_data_init3
        EXTERN  __low_level_init
        EXTERN  iar_xdc_startup_exec
        EXTERN  __call_ctors
        EXTERN  main
        EXTERN  xdc_runtime_System_exit__E

        THUMB
__cmain:
?main:

; Initialize segments.
; __segment_init and __low_level_init are assumed to use the same
; instruction set and to be reachable by BL from the ICODE segment
; (it is safest to link them in segment ICODE).

          FUNCALL __cmain, __low_level_init
        bl      __low_level_init
        cmp     r0,#0
        beq     ?l1
          FUNCALL __cmain, __iar_data_init3
        bl      __iar_data_init3
; XDC startup exec hook 
          FUNCALL __cmain, iar_xdc_startup_exec 
        bl      iar_xdc_startup_exec

?l1:
        REQUIRE ?l3

        SECTION .text:CODE:NOROOT(2)

        PUBLIC  _main
        PUBLIC _call_main
        THUMB

__iar_init$$done:               ; Copy initialization is done

?l3:
_call_main:
        MOVS    r0,#0   ;  No parameters
          FUNCALL __cmain, main
        BL      main
_main:
          FUNCALL __cmain, xdc_runtime_System_exit__E
        BL      xdc_runtime_System_exit__E

        END


a、程序调用__low_level_init函数

int __low_level_init(void)
{
    IntMasterDisable();

    //
    // Final trim of device
    //
    SetupTrimDevice();

    /*==================================*/
    /* Choose if segment initialization */
    /* should be done or not.           */
    /* Return: 0 to omit seg_init       */
    /*         1 to run seg_init        */
    /*==================================*/
    return 1;
}


b、程序调用__iar_data_init3函数

void __iar_data_init3(void)
{
  char const * p = __section_begin("Region$$Table");
  uint32_t const * pe = __section_end("Region$$Table");
  uint32_t const * pi = (uint32_t const *)(p);
  while (pi != pe)
  {
    init_fun_t * fun = (init_fun_t *)((char *)pi + *(int32_t *)pi);
    pi++;
    pi = fun(pi);
  }
}


c、程序调用iar_xdc_startup_exec函数

void iar_xdc_startup_exec(void)
{
    /*------------------------------------------------------------------------*/
    /* Process XDC Startup                                                    */
    /*------------------------------------------------------------------------*/
    if (&xdc_runtime_Startup__EXECFXN__C == (int*)1) {
        xdc_runtime_Startup_exec__E();
    }
}


d、最后程序执行下面语句,进入c的main函数
        BL      main
    

int main()
{
  /* Register Application callback to trap asserts raised in the Stack */
  RegisterAssertCback(AssertHandler); 

  Board_initGeneral();

  // Enable iCache prefetching
  VIMSConfigure(VIMS_BASE, TRUE, TRUE);
  // Enable cache
  VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);


#if !defined( POWER_SAVING )
  /* Set constraints for Standby, powerdown and idle mode */
  // PowerCC26XX_SB_DISALLOW may be redundant
  Power_setConstraint(PowerCC26XX_SB_DISALLOW);
  Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
#endif // POWER_SAVING


  /* Update User Configuration of the stack */
  user0Cfg.appServiceInfo->timerTickPeriod = Clock_tickPeriod;
  user0Cfg.appServiceInfo->timerMaxMillisecond  = ICall_getMaxMSecs();

  /* Initialize ICall module */
  ICall_init();

#if (!defined(STACK_LIBRARY) && (defined(SPLIT_APP_STACK_IMAGE)))
  {
    /* Find stack entry page */
    uint32_t stackAddr = findStackBoundaryAddr();

    if(stackAddr == 0xFFFFFFFF)
    {
      // If we cannot find the stack start address, exit
      ICall_abort();
    }

    /* set the stack image header based on the stack addr */
    stackImageHeader = (imgHdr_t *)stackAddr;

    /* Start tasks of external images - Priority 5 */
    const ICall_RemoteTask_t remoteTaskTbl[] =
    {
      (ICall_RemoteTaskEntry) (stackImageHeader->prgEntry),
      5,
      1000,
      &user0Cfg
    };

    /* Start tasks of external images - Priority 5 */
    ICall_createRemoteTasksAtRuntime((ICall_RemoteTask_t *) remoteTaskTbl,
                                   (sizeof(remoteTaskTbl)/sizeof(ICall_RemoteTask_t)));
  }
#else

  /* Start tasks of external images - Priority 5 */
  ICall_createRemoteTasks();
#endif

  SimplePeripheral_createTask();

  /* enable interrupts and start SYS/BIOS */
  BIOS_start();

  return (0);
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dear_Wally

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值