最小系统实现

概述

本章节介绍如何在芯片上运行起最小系统。

最小系统开发

最小系统开发关键点如下: 1、搭建yoc开发环境

2、建立自己的芯片组件

3、CPU类型选择

4、链接脚本中的地址空间定义

5、printf功能移植

第一步、建立yoc开发环境

YoC 开发平台提供芯片SDK的模板工程,以RISCV CPU e907fp芯片为例,通过模板工程快速建立 SDK工程环境。

mkdir sdk_xxxchip
cd sdk_xxxchip
yoc init
yoc search dummy_demo

显示如下:

  arm_dummy_demo                            - YoC dummy demo for arm.
  csky_dummy_demo                           - YoC dummy demo for csky.
  riscv_dummy_demo                          - YoC dummy demo for riscv.

YoC 开发平台提供了3种不同类型的芯片模板工程:

arm_dummy_demo/csky_dummy_demo/riscv_dummy_demo:

最小系统的芯片SDK模板工程,包括 aos、console、kv、csi等组件,及demo示例。

开发者根据芯片特性,选择适当的SDK模板工程,创建芯片SDK。以RISCV CPU为例,选择riscv_sdk_dummy模板工程。

下载dummy模板工程

示例:

yoc install riscv_dummy_demo

编译 riscv_dummy_demo

编译完成之后,正确显示结果如下:

AR yoc_sdk/lib/libchip_riscv_dummy.a
CC out/riscv_dummy_demo/app/src/main.o
ranlib yoc_sdk/lib/libchip_riscv_dummy.a
AR yoc_sdk/lib/libriscv_dummy_demo.a
ranlib yoc_sdk/lib/libriscv_dummy_demo.a
LINK out/riscv_dummy_demo/yoc.elf
Generating yoc.bin
riscv64-unknown-elf-objdump -d out/riscv_dummy_demo/yoc.elf > yoc.asm
INSTALL yoc.elf
scons: done building targets.
YoC SDK Done

第二步、建立自己的芯片组件

套件中自带 board_riscv_dummy 开发板组件与 chip_riscv_dummy 组件,需要根据自己芯片型号(名称)更名,例如:

yoc rename board_riscv_dummy board_cb8888
yoc rename chip_riscv_dummy chip_ch8888
make clean && make

根据以上几步,完成了开发工程的搭建,接下进入到芯片的 bring up 阶段。

第三步、CPU类型选择

修改components/chip_ch8888/package.yaml文件中的arch_name和cpu_name字段,如下:

hw_info:
  arch_name: riscv                          # <可选项> cpu架构:csky、arm、riscv
  cpu_name: e907fp                          # <可选项> cpu型号:e902、e906、e90fd...

第四步、链接脚本

程序的内存划分主要由链接脚本完成。 用户可以根据chip_ch8888下的链接脚本(gcc_xip.ld)进行修改。(如果是64BIT的CPU请参考gcc_xip_rv64.ld进行修改。)

链接脚本修改

指定链接脚本

链接脚本存放在 chip_ch8888 目录下。 链接时使用哪个链接脚本描述在chip_ch8888/package.yaml文件中,如下例:

hw_info:
  arch_name: riscv
  cpu_name: e907fp
  ld_script: gcc_xip.ld     # 链接脚本指定
指定内存空间

如下定义ISRAM起始地址为0x00000000,长度为0x20000

MEMORY
{
    ISRAM : ORIGIN = 0x00000000 , LENGTH = 0x40000   /* ISRAM 256KB*/
    DSRAM : ORIGIN = 0x20000000 , LENGTH = 0x20000   /* DSRAM 128KB*/
}
指定 HEAP 的分配
动态方式指定

如下例,定义 __heap_start__heap_end,即可指定堆区的起始和结束地址,用户只需要修改这两个符号即可。

下例中:__heap_start 从 .bss 段结束开始;__heap_end 指定为 ram 的结束地址

...
PROVIDE (__heap_end = __ram_end);        # 指定 heap 结束

 ._user_heap : {
  . = ALIGN(0x4) ;
  __heap_start = .;                      # 指定 heap 开始,从.bss结束起划为heap
  . += __min_heap_size;
  . = ALIGN(0x4) ;
 } > REGION_BSS AT > REGION_BSS
 ...
静态方式指定

用户也可以使用绝对地址定义 __heap_start__heap_end,该方法需要特别小心避免和其它内存段冲突,如下:

PROVIDE (__heap_start = 0x10000000);
PROVIDE (__heap_end   = 0x10010000);

点击学习更多链接脚本知识

第五步、printf 功能实现

使用UART口打印,需要满足以下条件:

1、依赖UART驱动中的csi_uart_putc接口(在chip_riscv_dummy/drivers/uart.c文件中)

2、需要在boards/<board_name>/include/board.h中定义如下宏定义

#define CONSOLE_UART_IDX                (0)               //控制器编号
#define CONFIG_CLI_USART_BAUD           (115200)          //串口波特率
#define CONFIG_CONSOLE_UART_BUFSIZE     (128)             //控制台缓存大小

#define CONSOLE_TXD                 PA10                  //TX引脚名字
#define CONSOLE_RXD                 PA11                  //RX引脚名字
#define CONSOLE_TXD_FUNC            PA10_UART0_TX         //TX引脚复用值
#define CONSOLE_RXD_FUNC            PA11_UART0_RX         //RX引脚复用值

3、UART驱动编写,请参考CSI驱动编写例程中的UART驱动编写章节。

第六步、最小系统运行

参考riscv_dummy_demo/README.md文件进行编译以及运行。 运行最小系统,出现如下打印说明运行成功。

###Welcom to YoC###
[Sep 20 2022,09:25:18]
[   0.000]<I>[INIT]<app_task>Build:Sep 20 2022,09:25:18
[   0.010]<D>[app]<app_task>Hello world! YoC
(cli-uart)# [   3.010]<D>[app]<app_task>Hello world! YoC
[   6.010]<D>[app]<app_task>Hello world! YoC
[   9.010]<D>[app]<app_task>Hello world! YoC
[  12.010]<D>[app]<app_task>Hello world! YoC
[  15.010]<D>[app]<app_task>Hello world! YoC

results matching ""

    No results matching ""