1651|0

504

帖子

4

TA的资源

纯净的硅(高级)

楼主
 

【国产FPGA安路 高集成低功耗SF1系列FPSoC新品】RISC-V SDK代码框架分析 [复制链接]

 

前言

前面搭建了RISC-V的开发环境,这一篇来讲讲SDK代码框架,这有利于后面程序开发。

过程

查找链接脚本

对于嵌入式项目,要了解代码框架,最先要从链接脚本入手,从这里可以找到启动代码,程序入口等信息,然后层层递进抽丝剥茧才能了解全貌。

 

右键点击工程->Properties

 

 

看到链接脚本如下

 

D:\BOARD\SF1-FPSoC\SF1S60CG121I_SF102\SF1S60CG121I_SF102\TN810_SF102\src\mcu_ahb_to_fpga\sdk_project\bmp_image_display\anlogic_sdk\SoC\anlogic\Board\sf1_eval\Source\GCC\gcc_anlogic_work3.ld

我们就打开这个文件看看

 

看到该目录下还有其他不同的ld文件,应用于不同工作模式的工程,原理都是一样的,看一个就行。

 

ld文件格式可以网上搜索文档查阅,这里不再赘述,主要讲和本工程相关的内容。

 

先看前面定义了存储

MEMORY

{

  flash (rxai!w) : ORIGIN = 0x000E0000, LENGTH = 4M

  ilm (rxai!w)   : ORIGIN = 0x08000000, LENGTH = 8K  

  ram (wxa!ri)   : ORIGIN = 0x20000000, LENGTH = 8K

}

 

从这里可以看到存储的布局。

 

我们然后来找程序的入口

 .init           :

  {

    *(.vtable)

    KEEP (*(SORT_NONE(.init)))

  } >flash AT>flash

 

这里最新将.vtable放在了flash处,所以这里指导就是程序的入口

搜索.vtable

菜单栏Serch->Search

 

看到该段正是启动代码

 

固定中断向量

开始定义的是固定的终端向量表

/*** Vector Table Code Section ***/

    /*

     * Put the interrupt vectors in this section according to the run mode:

     * FlashXIP: .vtable

     * ILM: .vtable

     * Flash: .vtable_ilm

     */

#if defined(DOWNLOAD_MODE) && (DOWNLOAD_MODE == DOWNLOAD_MODE_FLASH)

    .section .vtable_ilm

#else

    .section .vtable

#endif

 

    .weak  eclic_msip_handler

    .weak  eclic_mtip_handler

    .weak  uart0_handler

    .weak  i2c_handler

    .weak  QSPI0_handler

    .weak  QSPI_handler

    .weak  gpio0_handler

    .weak  gpio1_handler

    .weak  gpio2_handler

    .weak  gpio3_handler

    .weak  gpio4_handler

    .weak  gpio5_handler

    .weak  gpio6_handler

    .weak  gpio7_handler

    .weak  fpga0_handler

    .weak  fpga1_handler

    .weak  fpga2_handler

    .weak  fpga3_handler

    .weak  fpga4_handler

    .weak  fpga5_handler

    .weak  fpga6_handler

    .weak  fpga7_handler

    .weak  fpga8_handler

    .weak  fpga9_handler

    .weak  fpga10_handler

    .weak  fpga11_handler

    .weak  fpga12_handler

    .weak  fpga13_handler

    .weak  fpga14_handler

.weak  fpga15_handler

 

用户中断向量

然后后面才是用户中断向量入口 

  .globl vector_base

vector_base:

#if defined(DOWNLOAD_MODE) && (DOWNLOAD_MODE != DOWNLOAD_MODE_FLASH)

  //  j _start                                                /* 0: Reserved, Jump to _start when reset for ILM/FlashXIP mode.*/

    la ra,_start    // fix according to suggestion of S.W

    ret

    .align LOG_REGBYTES                                     /*    Need to align 4 byte for RV32, 8 Byte for RV64 */

#else

    DECLARE_INT_HANDLER     default_intexc_handler          /* 0: Reserved, default handler for Flash download mode */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 1: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 2: Reserved */

#endif

   // DECLARE_INT_HANDLER     default_intexc_handler          /* 1: Reserved */

   // DECLARE_INT_HANDLER     default_intexc_handler          /* 2: Reserved */

    DECLARE_INT_HANDLER     eclic_msip_handler              /* 3: Machine software interrupt */

 

    DECLARE_INT_HANDLER     default_intexc_handler          /* 4: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 5: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 6: Reserved */

    DECLARE_INT_HANDLER     eclic_mtip_handler              /* 7: Machine timer interrupt */

 

    DECLARE_INT_HANDLER     default_intexc_handler          /* 8: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 9: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 10: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 11: Reserved */

 

    DECLARE_INT_HANDLER     default_intexc_handler          /* 12: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 13: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 14: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 15: Reserved */

 

    DECLARE_INT_HANDLER     default_intexc_handler          /* 16: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 17: Reserved */

    DECLARE_INT_HANDLER     default_intexc_handler          /* 18: Reserved */

    DECLARE_INT_HANDLER     uart0_handler                   /* 19: Interrupt 19 */

 

    DECLARE_INT_HANDLER     i2c_handler                     /* 21: Interrupt 21 */

    DECLARE_INT_HANDLER     QSPI0_handler                   /* 22: Interrupt 22 */

    DECLARE_INT_HANDLER     QSPI_handler                    /* 29: Interrupt 29 */

    DECLARE_INT_HANDLER     gpio0_handler                   /* 30: Interrupt 30 */

 

    DECLARE_INT_HANDLER     gpio1_handler                   /* 31: Interrupt 31 */

    DECLARE_INT_HANDLER     gpio2_handler                   /* 32: Interrupt 32 */

    DECLARE_INT_HANDLER     gpio3_handler                   /* 33: Interrupt 33 */

    DECLARE_INT_HANDLER     gpio4_handler                   /* 34: Interrupt 34 */

 

    DECLARE_INT_HANDLER     gpio5_handler                   /* 35: Interrupt 35 */

    DECLARE_INT_HANDLER     gpio6_handler                   /* 36: Interrupt 36 */

    DECLARE_INT_HANDLER     gpio7_handler                   /* 37: Interrupt 37 */

    DECLARE_INT_HANDLER     fpga0_handler                   /* 38: Interrupt 38 */

 

    DECLARE_INT_HANDLER     fpga1_handler                   /* 39: Interrupt 39 */

    DECLARE_INT_HANDLER     fpga2_handler                    /*40: Interrupt 40 */

    DECLARE_INT_HANDLER     fpga3_handler                   /* 41: Interrupt 41 */

    DECLARE_INT_HANDLER     fpga4_handler                   /* 42: Interrupt 42 */

 

    DECLARE_INT_HANDLER     fpga5_handler                   /* 43: Interrupt 43 */

    DECLARE_INT_HANDLER     fpga6_handler                   /* 44: Interrupt 44 */

    DECLARE_INT_HANDLER     fpga7_handler                   /* 45: Interrupt 45 */

    DECLARE_INT_HANDLER     fpga8_handler                   /* 43: Interrupt 43 */

 

    DECLARE_INT_HANDLER     fpga9_handler                   /* 44: Interrupt 44 */

    DECLARE_INT_HANDLER     fpga10_handler                   /* 45: Interrupt 45 */

    DECLARE_INT_HANDLER     fpga11_handler                   /* 44: Interrupt 44 */

    DECLARE_INT_HANDLER     fpga12_handler                   /* 45: Interrupt 45 */

    DECLARE_INT_HANDLER     fpga13_handler                   /* 44: Interrupt 44 */

    DECLARE_INT_HANDLER     fpga14_handler                   /* 45: Interrupt 45 */

    DECLARE_INT_HANDLER     fpga15_handler                   /* 45: Interrupt 45 */

 

搜索vector_base

 

可以看到后面正是设置该地址为用户中断向量基地址

    /*

     * Intialize ECLIC vector interrupt

     * base address mtvt to vector_base

     */

    la t0, vector_base

csrw CSR_MTVT, t0

 

 

启动代码

 

   .globl vector_base

vector_base:

#if defined(DOWNLOAD_MODE) && (DOWNLOAD_MODE != DOWNLOAD_MODE_FLASH)

  //  j _start                                                /* 0: Reserved, Jump to _start when reset for ILM/FlashXIP mode.*/

    la ra,_start    // fix according to suggestion of S.W

ret

 

如果是DOWNLOAD_MODE模式跳转到_start


 

   .section .init

 

 

    .globl _start

    .type _start,@FUNCTION

    .option norvc

/**

 * Reset Handler called on controller reset

 */

_start:

 

 

和链接脚本对应,放在了.init段 

.init           :

  {

    *(.vtable)

    KEEP (*(SORT_NONE(.init)))

  } >flash AT>flash

 

后面就是中断 栈指针等初始化,不再赘述,可以参照RISC-V的文章理解指令。

 

后面重点关注下,code data段的加载bss段的初始化,_data等变量都是在链接脚本中定义的地址,

1:

    /* Load code section if necessary */

    lw t0, (a0)

    sw t0, (a1)

    addi a0, a0, 4

    addi a1, a1, 4

    bltu a1, a2, 1b

2:

    /* Load data section */

    la a0, _data_lma

    la a1, _data

    la a2, _edata

    bgeu a1, a2, 2f

1:

    lw t0, (a0)

    sw t0, (a1)

    addi a0, a0, 4

    addi a1, a1, 4

    bltu a1, a2, 1b

2:

    /* Clear bss section */

    la a0, __bss_start

    la a1, _end

    bgeu a0, a1, 2f

1:

    sw zero, (a0)

    addi a0, a0, 4

    bltu a0, a1, 1b

2:

 

然后是调用SystemInit初始化systick定时器

call SystemInit

 

最后进入main

#ifdef RTOS_RTTHREAD

    // Call entry function when using RT-Thread

    call entry

#else

    call main

#endif

 

 

 

代码框架

anlogic_sdk下是芯片相关代码,主要关注启动代码,中断处理代码,链接脚本

 

 

application下是用户代码

 

 

总结

以上介绍了代码框架,主要是启动流程,方便对SDK有一个整体上的理解。

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表