AliOS启动流程详解

目录结构

1、入口函数

2、详细启动流程

3、关键函数功能详解

3.1 Reset_Handler

3.2 SystemInit()

3.3 csi_coret_config()

3.4 mm_heap_initialize()

3.5 csi_vic_enable_irq

3.6 board_init()

3.7 main

1、入口函数的确认

    编译工具链为csky-elfabiv2,根据链接文件gcc_csky.ld中的关键字ENTRY可以确认程序的入口地址是Reset_Handler。

/* 指定了I-SRAM、D-SRAM、O-SRAM与SRAM的起始地址,以及大小 */
MEMORY
{
	I-SRAM : ORIGIN = 0x0        , LENGTH = 0x80000   /* I-SRAM  512KB */
	D-SRAM : ORIGIN = 0x20000000 , LENGTH = 0x80000   /* D-SRAM  512KB */
	O-SRAM : ORIGIN = 0x50000000 , LENGTH = 0x800000   /* off-chip SRAM 8MB */
	SRAM   : ORIGIN = 0x60000000 , LENGTH = 0x20000   /* on-chip SRAM 128KB */
}

__min_heap_size = 0x200;
PROVIDE (__ram_end  = 0x20080000);
PROVIDE (__heap_end = __ram_end);

REGION_ALIAS("REGION_TEXT",    I-SRAM);
REGION_ALIAS("REGION_RODATA",  I-SRAM);
REGION_ALIAS("REGION_DATA",    D-SRAM);
REGION_ALIAS("REGION_BSS",     D-SRAM);

/* 程序的入口地址 */
ENTRY(Reset_Handler)

2、详细启动流程

                                                                                     详细启动流程图

3、关键函数功能详解

函数功能讲解增加到了代码注释中。

3.1 Reset_Handler

主板上电复位后从Reset_Handler开始执行,在进入SystemInit函数前,主要做了如下事情:

  3.1.1 设置SP栈指针;

  3.1.2 data段数据从flash搬运到SRAM;

  3.1.3 bss段清零,然后跳转至SystemInit; 注意:地址相关信息均由gcc_csky.ld链接文件在编译时确定。

000000d4 <Reset_Handler>:
    .text
    .align  2
    .globl  Reset_Handler
    .type   Reset_Handler, %function
Reset_Handler:
    lrw     r0, 0x80000200
      d4:	1012      	lrw      	r0, 0x80000200	// 11c <__exit+0x2>
    mtcr    r0, psr
      d6:	c0006420 	mtcr      	r0, cr<0, 0>

    lrw     r0, g_top_irqstack
      da:	1012      	lrw      	r0, 0x20001078	// 120 <__exit+0x6>
    mov     sp, r0
      dc:	6f83      	mov      	r14, r0
 *    __data_start__: VMA of start of the section to copy to
 *    __data_end__: VMA of end of the section to copy to
 *
 *  All addresses must be aligned to 4 bytes boundary.
 */
    lrw     r1, __erodata
      de:	1032      	lrw      	r1, 0x45a4	// 124 <__exit+0xa>
    lrw     r2, __data_start__
      e0:	1052      	lrw      	r2, 0x20000000	// 128 <__exit+0xe>
    lrw     r3, __data_end__
      e2:	1073      	lrw      	r3, 0x20000078	// 12c <__exit+0x12>

    subu    r3, r2
      e4:	60ca      	subu      	r3, r2
    cmpnei  r3, 0
      e6:	3b40      	cmpnei      	r3, 0
    bf      .L_loop0_done
      e8:	0c08      	bf      	0xf8	// f8 <Reset_Handler+0x24>

.L_loop0:
    ldw     r0, (r1, 0)
      ea:	9100      	ld.w      	r0, (r1, 0x0)
    stw     r0, (r2, 0)
      ec:	b200      	st.w      	r0, (r2, 0x0)
    addi    r1, 4
      ee:	2103      	addi      	r1, 4
    addi    r2, 4
      f0:	2203      	addi      	r2, 4
    subi    r3, 4
      f2:	2b03      	subi      	r3, 4
    cmpnei  r3, 0
      f4:	3b40      	cmpnei      	r3, 0
    bt      .L_loop0
      f6:	0bfa      	bt      	0xea	// ea <Reset_Handler+0x16>
 *    __bss_start__: start of the BSS section.
 *    __bss_end__: end of the BSS section.
 *
 *  Both addresses must be aligned to 4 bytes boundary.
 */
    lrw     r1, __bss_start__
      f8:	102e      	lrw      	r1, 0x20000078	// 130 <__exit+0x16>
    lrw     r2, __bss_end__
      fa:	104f      	lrw      	r2, 0x2000167c	// 134 <__exit+0x1a>

    movi    r0, 0
      fc:	3000      	movi      	r0, 0

    subu    r2, r1
      fe:	6086      	subu      	r2, r1
    cmpnei  r2, 0
     100:	3a40      	cmpnei      	r2, 0
    bf      .L_loop1_done
     102:	0c06      	bf      	0x10e	// 10e <Reset_Handler+0x3a>

.L_loop1:
    stw     r0, (r1, 0)
     104:	b100      	st.w      	r0, (r1, 0x0)
    addi    r1, 4
     106:	2103      	addi      	r1, 4
    subi    r2, 4
     108:	2a03      	subi      	r2, 4
    cmpnei  r2, 0
     10a:	3a40      	cmpnei      	r2, 0
    bt      .L_loop1
     10c:	0bfc      	bt      	0x104	// 104 <Reset_Handler+0x30>
.L_loop1_done:

#ifndef __NO_SYSTEM_INIT
    jbsr    SystemInit
     10e:	e00014fd 	bsr      	0x2b08	// 2b08 <SystemInit>
#endif

#ifndef __NO_BOARD_INIT
    jbsr    board_init
     112:	e0001099 	bsr      	0x2244	// 2244 <board_init>
#endif

    jbsr    main
     116:	e0001a11 	bsr      	0x3538	// 3538 <main>

0000011a <__exit>:
    .size   Reset_Handler, . - Reset_Handler

__exit:
    br      __exit
     11a:	0400      	br      	0x11a	// 11a <__exit>
     11c:	80000200 	.long	0x80000200
     120:	20001078 	.long	0x20001078
     124:	000045a4 	.long	0x000045a4
     128:	20000000 	.long	0x20000000
     12c:	20000078 	.long	0x20000078
     130:	20000078 	.long	0x20000078
     134:	2000167c 	.long	0x2000167c

3.2 SystemInit()

 该函数由平头哥半导体官方提供,进行psr和vbr的初始化,中断向量表偏移地址设置。

/**
  * @brief  initialize the system
  *         Initialize the psr and vbr.
  * @param  None
  * @return None
  */
void SystemInit(void)
{
    __set_VBR((uint32_t) & (__Vectors));

#if defined(CONFIG_SEPARATE_IRQ_SP) && !defined(CONFIG_KERNEL_NONE)
    /* 801 not supported */
    __set_Int_SP((uint32_t)&g_top_irqstack);
    __set_CHR(__get_CHR() | CHR_ISE_Msk);
    VIC->TSPR = 0xFF;
#endif

    /* Clear active and pending IRQ */
    VIC->IABR[0] = 0x0;
    VIC->ICPR[0] = 0xFFFFFFFF;

#ifdef CONFIG_KERNEL_NONE
    __enable_excp_irq();
#endif

    csi_coret_config(drv_get_sys_freq() / CONFIG_SYSTICK_HZ, CORET_IRQn);    //10ms
#ifndef CONFIG_KERNEL_NONE
    csi_vic_enable_irq(CORET_IRQn);
#endif

#ifndef CONFIG_KERNEL_RHINO
#ifndef CONFIG_NUTTXMM_NONE
    extern void mm_heap_initialize(void);
    mm_heap_initialize();
#endif
#endif
}

3.3 csi_coret_config()

初始化系统定时器和中断,开启Systick定时器。

__STATIC_INLINE uint32_t csi_coret_config(uint32_t ticks, int32_t IRQn)
{
   if ((ticks - 1UL) > CORET_LOAD_RELOAD_Msk) 
   {
        return (1UL);                       /* Reload value impossible */
   }

    CORET->LOAD = (uint32_t)(ticks - 1UL);      /* set reload register */
    CORET->VAL  = 0UL;                    /* Load the CORET Counter Value */
    CORET->CTRL = CORET_CTRL_CLKSOURCE_Msk |
                   CORET_CTRL_TICKINT_Msk |
                   CORET_CTRL_ENABLE_Msk;  /* Enable CORET IRQ and CORET Timer */
    return (0UL);                            /* Function successful */
}

3.4 mm_heap_initialize

系统堆初始化,malloc函数可使用。

void mm_heap_initialize(void)
{
    mm_initialize(&g_mmheap, &__heap_start,   
                   (uint32_t)(&__heap_end) - (uint32_t)(&__heap_start))
}

3.5  csi_vic_enable_irq

使能外部中断

__STATIC_INLINE void csi_vic_enable_irq(int32_t IRQn)
{
    IRQn &= 0x7FUL;

    VIC->ISER[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
#ifdef CONFIG_SYSTEM_SECURE
    VIC->ISSR[_IR_IDX(IRQn)] = (uint32_t)(1UL << ((uint32_t)(int32_t)IRQn % 32));
#endif
}

3.6  board_init

 板级驱动,初始化console,配置串口。

void board_init(void)
{
    int32_t ret = 0;
    
    /* init the console*/
    console_handle = csi_usart_initialize(CONSOLE_IDX, NULL);  
   /* config the UART */
    ret = csi_usart_config(console_handle, 115200, USART_MODE_ASYNCHRONOUS, 
                            USART_PARITY_NONE, USART_STOP_BITS_1, USART_DATA_BITS_8);

    if (ret < 0) {
        return;
    }
}

3.7  main

main函数。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值