根据链接文件 ld\w800\gcc_csky.ld 找到启动文件:platform\arch\xt804\bsp\startup.S
1 ENTRY(Reset_Handler) 2 SECTIONS 3 { 4 .text : { 5 . = ALIGN(0x4) ; 6 KEEP(*startup.o(.vectors)) 7 __stext = . ;
分析startup.S:
1.最开始是中断向量表__Vectors
.section .vectors .align 10 .globl __Vectors .type __Vectors, @object __Vectors: .long Reset_Handler .long Default_Handler .long Default_Handler ...... ...... /* External interrupts */ .long SDIO_IRQHandler /* 0: SDIO */ .long MAC_IRQHandler /* 1: MAC */ .long RF_Cfg_IRQHandler /* 2: RF Cfg */ .long SEC_IRQHandler /* 3: SEC */ .long DMA_Channel0_IRQHandler /* 4: DMA_Channel0 */ ......
2.紧接着是_start:调用Reset_Handler函数
_start: .text .align 2 .globl Reset_Handler .type Reset_Handler, %function
Reset_Handler函数:用于配置堆栈,data段,bss段,初始化内存。最后调用3个函数SystemInit board_init main
Reset_Handler: #ifdef CONFIG_KERNEL_NONE lrw r0, 0xe0000200 #else lrw r0, 0x80000200 mtcr r0, psr #endif mtcr r0, psr lrw r0, g_top_irqstack mov sp, r0 /* * move __Vectors to irq_vectors */ lrw r1, __Vectors lrw r2, __vdata_start__ lrw r3, __vdata_end__ subu r3, r2 cmpnei r3, 0 bf .L_loopv0_done .L_loopv0: ldw r0, (r1, 0) stw r0, (r2, 0) addi r1, 4 addi r2, 4 subi r3, 4 cmpnei r3, 0 bt .L_loopv0 .L_loopv0_done: /* * The ranges of copy from/to are specified by following symbols * __etext: LMA of start of the section to copy from. Usually end of text * __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 lrw r2, __data_start__ lrw r3, __data_end__ subu r3, r2 cmpnei r3, 0 bf .L_loop0_done .L_loop0: ldw r0, (r1, 0) stw r0, (r2, 0) addi r1, 4 addi r2, 4 subi r3, 4 cmpnei r3, 0 bt .L_loop0 .L_loop0_done: /* * The BSS section is specified by following symbols * __bss_start__: start of the BSS section. * __bss_end__: end of the BSS section. * * Both addresses must be aligned to 4 bytes boundary. */ #if 1 lrw r1, __bss_start__ lrw r2, __bss_end__ movi r0, 0 subu r2, r1 cmpnei r2, 0 bf .L_loop1_done .L_loop1: stw r0, (r1, 0) addi r1, 4 subi r2, 4 cmpnei r2, 0 bt .L_loop1 .L_loop1_done: #endif
#ifndef __NO_SYSTEM_INIT
jbsr SystemInit
#endif
#ifndef __NO_BOARD_INIT
jbsr board_init
#endif
jbsr main
.size Reset_Handler, . - Reset_Handler
SystemInit函数分析:位于platform\arch\xt804\bsp\system.c
void SystemInit(void) { __set_VBR((uint32_t) & (irq_vectors)); //设置VBR寄存器 #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 __set_CHR(__get_CHR() | CHR_IAE_Msk); //设置CHR寄存器 /* Clear active and pending IRQ */ //清pending中断 VIC->IABR[0] = 0x0; VIC->ICPR[0] = 0xFFFFFFFF; #ifdef CONFIG_KERNEL_NONE __enable_excp_irq(); #endif //csi_coret_config(g_system_clock / CONFIG_SYSTICK_HZ, SYS_TICK_IRQn); //10ms //#ifndef CONFIG_KERNEL_NONE csi_vic_enable_irq(SYS_TICK_IRQn); //开启系统滴答 //#endif }
board_init函数分析:位于platform\arch\xt804\bsp\board_init.c
void board_init(void) { #if USE_UART0_PRINT /* use uart0 as log output io */ uart0Init(115200); //初始化UART0 #else uart1_io_init(); /* use uart1 as log output io */ uart1Init(115200); #endif }
main函数分析:位于platform\sys\wm_main.c
int main(void) { u32 value = 0; /*32K switch to use RC circuit & calibration*/ tls_pmu_clk_select(0); //设置PMU时钟 /*Switch to DBG*/ //设置DBG value = tls_reg_read32(HR_PMU_BK_REG); value &= ~(BIT(19)); tls_reg_write32(HR_PMU_BK_REG, value); value = tls_reg_read32(HR_PMU_PS_CR); value &= ~(BIT(5)); tls_reg_write32(HR_PMU_PS_CR, value); /*Close those not initialized clk except uart0,sdadc,gpio,rfcfg*/ //关闭除uart0外,如sdadc,gpio,rfcfg的时钟 value = tls_reg_read32(HR_CLK_BASE_ADDR); value &= ~0x3fffff; value |= 0x1a02; tls_reg_write32(HR_CLK_BASE_ADDR, value); tls_sys_clk_set(CPU_CLK_80M); //设置系统时钟 tls_os_init(NULL); //初始化OS /* before use malloc() function, must create mutex used by c_lib */ tls_os_sem_create(&libc_sem, 1); /*configure wake up source begin*/ csi_vic_set_wakeup_irq(SDIO_IRQn); csi_vic_set_wakeup_irq(MAC_IRQn); csi_vic_set_wakeup_irq(SEC_IRQn); csi_vic_set_wakeup_irq(DMA_Channel0_IRQn); csi_vic_set_wakeup_irq(DMA_Channel1_IRQn); csi_vic_set_wakeup_irq(DMA_Channel2_IRQn); csi_vic_set_wakeup_irq(DMA_Channel3_IRQn); csi_vic_set_wakeup_irq(DMA_Channel4_7_IRQn); csi_vic_set_wakeup_irq(DMA_BRUST_IRQn); csi_vic_set_wakeup_irq(I2C_IRQn); csi_vic_set_wakeup_irq(ADC_IRQn); csi_vic_set_wakeup_irq(SPI_LS_IRQn); csi_vic_set_wakeup_irq(SPI_HS_IRQn); csi_vic_set_wakeup_irq(GPIOA_IRQn); csi_vic_set_wakeup_irq(GPIOB_IRQn); csi_vic_set_wakeup_irq(UART0_IRQn); csi_vic_set_wakeup_irq(UART1_IRQn); csi_vic_set_wakeup_irq(UART24_IRQn); csi_vic_set_wakeup_irq(BLE_IRQn); csi_vic_set_wakeup_irq(BT_IRQn); csi_vic_set_wakeup_irq(PWM_IRQn); csi_vic_set_wakeup_irq(I2S_IRQn); csi_vic_set_wakeup_irq(SIDO_HOST_IRQn); csi_vic_set_wakeup_irq(SYS_TICK_IRQn); csi_vic_set_wakeup_irq(RSA_IRQn); csi_vic_set_wakeup_irq(CRYPTION_IRQn); csi_vic_set_wakeup_irq(PMU_IRQn); csi_vic_set_wakeup_irq(TIMER_IRQn); csi_vic_set_wakeup_irq(WDG_IRQn); /*configure wake up source end*/ TaskStartStk = tls_mem_alloc(sizeof(u32)*TASK_START_STK_SIZE); //创建线程task_start if (TaskStartStk) { tls_os_task_create(&tststarthdl, NULL, task_start, (void *)0, (void *)TaskStartStk, /* 任务栈的起始地址 */ TASK_START_STK_SIZE * sizeof(u32), /* 任务栈的大小 */ 1, 0); tls_os_start_scheduler(); } else { while(1); } return 0; }
线程task_start: 最后会调用UserMain函数
void task_start (void *data) { u8 enable = 0; u8 mac_addr[6] = {0x00, 0x25, 0x08, 0x09, 0x01, 0x0F}; #if TLS_CONFIG_CRYSTAL_24M tls_wl_hw_using_24m_crystal(); #endif tls_mem_get_init_available_size(); /* must call first to configure gpio Alternate functions according the hardware design */ wm_gpio_config(); tls_irq_init(); #if TLS_CONFIG_HARD_CRYPTO tls_crypto_init(); #endif #if (TLS_CONFIG_LS_SPI) tls_spi_init(); tls_spifls_init(); #endif tls_fls_init(); tls_fls_sys_param_postion_init(); /*PARAM GAIN,MAC default*/ tls_ft_param_init(); tls_param_load_factory_default(); tls_param_init(); /*add param to init sysparam_lock sem*/ tls_get_tx_gain(&tx_gain_group[0]); TLS_DBGPRT_INFO("tx gain "); TLS_DBGPRT_DUMP((char *)(&tx_gain_group[0]), 27); if (tls_wifi_mem_cfg(WIFI_MEM_START_ADDR, 7, 7)) /*wifi tx&rx mem customized interface*/ { TLS_DBGPRT_INFO("wl mem initial failured\n"); } tls_get_mac_addr(&mac_addr[0]); TLS_DBGPRT_INFO("mac addr "); TLS_DBGPRT_DUMP((char *)(&mac_addr[0]), 6); if(tls_wl_init(NULL, &mac_addr[0], NULL) == NULL) { TLS_DBGPRT_INFO("wl driver initial failured\n"); } if (wpa_supplicant_init(mac_addr)) { TLS_DBGPRT_INFO("supplicant initial failured\n"); } /*wifi-temperature compensation,default:open*/ tls_wifi_set_tempcomp_flag(0); tls_wifi_set_psm_chipsleep_flag(0); tls_wifi_psm_chipsleep_cb_register(tls_pmu_chipsleep_callback, NULL, NULL); tls_ethernet_init(); #if TLS_CONFIG_BT tls_bt_entry(); #endif tls_sys_init(); /*HOSTIF&UART*/ #if TLS_CONFIG_HOSTIF tls_hostif_init(); #if (TLS_CONFIG_HS_SPI) tls_hspi_init(); #endif #if TLS_CONFIG_UART tls_uart_init(); #endif #if TLS_CONFIG_HTTP_CLIENT_TASK http_client_task_init(); #endif #endif tls_param_get(TLS_PARAM_ID_PSM, &enable, TRUE); if (enable != TRUE) { enable = TRUE; tls_param_set(TLS_PARAM_ID_PSM, &enable, TRUE); } UserMain(); tls_sys_auto_mode_run(); for (;;) { #if MAIN_TASK_DELETE_AFTER_START_FTR if (tststarthdl) { tls_os_task_del_by_task_handle(tststarthdl,task_start_free); } #endif #if 1 tls_os_time_delay(0x10000000); #else //printf("start up\n"); extern void tls_os_disp_task_stat_info(void); tls_os_disp_task_stat_info(); tls_os_time_delay(1000); #endif } }