BL IOT SDK启动链接及FreeRTOS简要分析 ===================================== 本文简要分析bl iot SDK的start.S文件的初始化过程,FreeRTOS以及链接脚本。 start.S --------------- 该文件路径:components/platform/soc/bl602/bl602/evb/src/boot/gcc/start.S - 关闭中断 :: li t0, MSTATUS_MIE csrc mstatus, t0 - 初始化GP寄存器 :: la gp, __global_pointer GP附近的数据会通过GP寄存器相对寻址来访问,GP的值在链接时决定,不可更改。 - 初始化栈指针 :: la sp, _sp_main - 读取boot2中约定好的partition地址来设置sdk中的boot2_partition_table变量,该变量放置在指定的section中 :: la a0, __boot2_pt_addr_src la a1, __boot2_pt_addr_start la a2, __boot2_pt_addr_end - 读取boot2中约定好的flash地址来设置sdk中的boot2_flashCfg变量,该变量放置在指定的section中 :: jal hal_boot2_get_flash_addr la a1, __boot2_flashCfg_start la a2, __boot2_flashCfg_end - 初始化data段 :: la a0, _data_load la a1, _data_run la a2, _data_run_end - 初始化bss段 :: la a0, __bss_start la a1, __bss_end - 初始化main入口地址 :: li a0, 0 li a1, 0 call bfl_main FreeRTOS ----------- FreeRTOS由Richard Barry开发,是一个开源的、可移植的、小型的嵌入式实时操作系统内核。FreeRTOS既支持抢占式多任务,也支持协作式多任务,SDK中源码路径:components/platform/soc/bl602/freertos_riscv_ram。 - 中断入口 SDK中components/platform/soc/bl602/freertos_riscv_ram/portable/GCC/RISC-V/portASM.S里的freertos_risc_v_trap_handler。 flash_rom.ld -------------- 该文件路径:components/platform/soc/bl602/bl602/evb/ld/flash_rom.ld - 设置输出文件的machine architecture(体系结构) :: OUTPUT_ARCH( "riscv" ) - 设置入口地址 :: ENTRY( bl602_start ) - MEMORY命令 :: MEMORY { rom (rxai!w) : ORIGIN = 0x21015000, LENGTH = 44K flash (rxai!w) : ORIGIN = 0x23000000, LENGTH = 4M ram_tcm (wxa) : ORIGIN = 0x4200C000, LENGTH = (16K + 16K + 48K + 64K + 64K + 8K - __EM_SIZE) /*put itcm with dtam and also OCRAM*/ ram_wifi (wxa) : ORIGIN = 0x42042000 - __EM_SIZE, LENGTH = (8K + 104K - 64K - 8K) /*leave 8K left for BLE*/ } 例:rom表示存储区域名,(rxai!w)表示该存储区域的属性,ATTR属性内可以出现以下7个字符, R 只读section W 读/写section X 可执行section A ‘可分配的’section I 初始化了的section L 同I ! 不满足该字符之后的任何一个属性的section ORIGIN :关键字,区域的开始地址,可简写成org或o LENGTH :关键字,区域的大小,可简写成len或l - SECTIONS命令 在链接脚本中定义了.init段,.text段,.rodata段,.wifibss段,.romdata段,.data段,.boot2段,.bss段,.stack段。 例: - .init段 :: .init : { KEEP (*(SORT_NONE(.init))) } > flash KEEP()关键字强制连接器保留.init段, > flash表示:将输出的.init段放置在flash中 - .rodata段 :: .rodata : { *(.rdata) *(.rodata .rodata.*) *(.sdata2.*) /* static cli cmds */ . = ALIGN(4); _bl_static_cli_cmds_start = .; KEEP(*(.static_cli_cmds)) *(.static_cli_cmds) _bl_static_cli_cmds_end = .; ... ... ... } > flash 其中花括号外面的.rodata表示输出段的名字,花括号中表示输入的段。 整个代码段表示:所有文件的.rdata段,.rodata段,.rodata.*段,.sdata2.*段等段输出到.rodata段中,并将其放置在flash中。 . = ALIGN(4); .表示当前地址,ALIGN(4):4字节对齐。 - PROVIDE命令 该关键字用于定义这类符号:在目标文件内被引用,但没有在任何目标文件内被定义的符号。 例: :: PROVIDE( _ld_bl_static_cli_cmds_start = _bl_static_cli_cmds_start ); PROVIDE( _ld_bl_static_cli_cmds_end = _bl_static_cli_cmds_end ); _ld_bl_static_cli_cmds_start和_ld_bl_static_cli_cmds_end在sdk中的aos_cli_init()函数中被引用。_bl_static_cli_cmds_start和_bl_static_cli_cmds_end在上文中已经定义了。