自己的理解,不对的地方请指正。
工程组成
初始化相关文件
初始化相关文件都放在了sys文件夹下。
单片机在main函数之前,都得先初始化堆栈和中断向量表。
在启动代码startup.s中对向量表和堆栈进行了管理,代码如下:
/*
* Copyright (C) 2017-2019 Alibaba Group Holding Limited
*/
/******************************************************************************
* @File startup.S
* @brief startup file. Should use with
* GCC for CSKY Embedded Processors
* @version V1.0
* @date 29. July 2019
******************************************************************************/
#include <csi_config.h>
.section .vectors, "aw", @progbits
.align 6
.globl __Vectors
.type __Vectors, @object
__Vectors:
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long tspend_handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_IRQHandler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
.long Default_Handler
/* External interrupts */
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.long Default_IRQHandler
.text
.align 2
.long Reset_Handler
.rept 15
.long 0
.endr
.long Reset_Handler
_start:
.text
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
.globl __driver_test_service__
.weak __driver_test_service__
.type __driver_test_service__, %function
Reset_Handler:
csrc mstatus, 8
.option push
.option norelax
la gp, __global_pointer$
.option pop
la a0, Default_Handler
ori a0, a0, 3
csrw mtvec, a0
li a0, 0x2000
csrs mstatus, a0
la a0, __Vectors
csrw mtvt, a0
la a0, 0x100000
csrw mhint, a0
la sp, g_top_irqstack
#ifndef __NO_SYSTEM_INIT
jal SystemInit
#endif
la a0, __driver_test_service__
beq zero, a0, 1f
jalr a0
j __exit
1:
jal pre_main
.size Reset_Handler, . - Reset_Handler
__exit:
j __exit
.section .stack
.align 3
.global g_base_irqstack
.global g_top_irqstack
g_base_irqstack:
.space CONFIG_ARCH_INTERRUPTSTACK
g_top_irqstack:
Default_Handler在vectors.S中定义
#ifdef CONFIG_KERNEL_NONE
.align 2
.global Default_IRQHandler
.weak Default_IRQHandler
.type Default_IRQHandler, %function
Default_IRQHandler:
.
.
.
.
.
.
#else
.align 2
.global Default_IRQHandler
.weak Default_IRQHandler
.type Default_IRQHandler, %function
Default_IRQHandler:
.
.
.
.
.
.
#endif
根据 CONFIG_KERNEL_NONE 得定义,对Default_Handler进行条件编译,用不用内核对中断是有影响的。
g_top_irqstack在vectors.S中定义
通过指令 jal SystemInit 对系统初始化
SystemInit函数定义在system.c中
/**
* @brief initialize the system
* Initialize the psr and vbr.
* @param None
* @return None
*/
void SystemInit(void)
{
enable_theadisaee();
cache_init();
section_init();
interrupt_init();
soc_set_sys_freq(CPU_196_608MHZ);
csi_etb_init();
sys_dma_init();
csi_tick_init();
#ifdef CONFIG_XIP
sys_spiflash_init();
#endif
bootrom_uart_uninit();
}
可以看出,通过SystemInit函数,基本对中断、时钟、dma、tick等等板上资源进行了初始化。
最后通过指令
jal pre_main
跳转到main函数。
pre_main函数定义:
__attribute__((weak)) void pre_main(void)
{
#ifndef CONFIG_KERNEL_RHINO
#ifndef CONFIG_NUTTXMM_NONE
extern void mm_heap_initialize();
mm_heap_initialize();
#endif
#endif
main();
}
main函数作为用户应用程序的入口。