赞
踩
在Renode上跑通了一个裸机(baremetal)demo,记录一下过程,为后面的进一步开发做铺垫。
该Demo来自国外一个大神的代码仓库:https://github.com/y2kbugger/baremetal-riscv-renode
有兴趣的同学可以自行下载。
由于我们使用Renode作为仿真平台,因此首先需要完成Renode的安装。以上代码仓库中包含了所有的工程组件,包括Renode源码、RISC-V工具链源码,以及编译所需组件的Makefile,但是实际使用中,可能会出错,所以我选择逐项安装。
Renode的安装在之前的文章里面已经介绍过,在本Demo中可以直接使用,安装方法见之前的博客:初识Renode_牧羊女-CSDN博客
要想在x86平台上编译RISC-V的binaries,首先需要安装交叉编译工具。针对该Demo的需要,我们只需要安装riscv32-unknown-elf-gcc套件即可,之前的文章我们也介绍了riscv32-unknown-elf-gcc的编译安装过程:编译riscv32-unknown-elf-gcc_牧羊女-CSDN博客
该Demo非常简单,堪称嵌入式界的“Hello World”,功能是让一个虚拟LED闪烁。该Demo使用的硬件及软件代码见下面描述。
Demo使用的硬件组成非常简单,包括一块很小的memory、一个RISC-V CPU、一个GPIO以及两个LED,如下面平台描述文件(vexriscv.repl)所示:
- mem: Memory.MappedMemory @ sysbus 0x0
- size: 0x00040000
-
- cpu: CPU.VexRiscv @ sysbus
-
- gpio_out: GPIOPort.LiteX_GPIO @ sysbus 0x60000800
- type: Type.Out
- 0 -> led0@0
- 1 -> led1@0
-
- led0 : Miscellaneous.LED @ gpio_out 0
- led1 : Miscellaneous.LED @ gpio_out 1
关于平台描述文件的介绍,见前面的文章: Renode学习:平台描述文件REPL_牧羊女-CSDN博客
该Demo的软件代码(baremetal.s)为汇编语言,但也很简单,按照我有限的理解加了一点注释,如下:
- #这段有点像C中的宏定义哈
- .equ LED, 0x60000800
- .equ DELAY_COUNT, 9000000
- .equ LED_STATE_INITIAL, 0b00
- .equ LED_STATE_TOGGLE_MASK, 0b01
-
- .section .text #定义文本段
- .global _start #定义_start为外部程序可访问的标签,类似于我们常用的main()函数
- _start:
- li a5, LED # 将上面LED表示的值加载到a5寄存器
- li a4, LED_STATE_INITIAL # 同上,li为加载立即数指令
- li a6, LED_STATE_TOGGLE_MASK
- sw a4, 0x0(a5) # store word,将寄存器一个word大小的值存入堆栈,0x0为offset
- loop:
- li a0, DELAY_COUNT # reset counter
- delay_loop:
- addi a0, a0, -1 # count down
- bnez a0, delay_loop # 条件转移指令,不为0时发生
- toggle_led:
- lw a4, 0x0(a5) # read in old led state
- xor a4, a4, a6 # toggle led state word
- sw a4, 0x0(a5) # write new state
- jump loop, t0
工程的运行需要三个步骤,分别是:
(1) 从源码baremetal.s中编译出目标二进制文件;
(2) 启动由以上REPL平台描述文件定义的硬件模拟环境;
(3) 将步骤(1)中编译出的elf文件加载到平台模拟器的内存中。
目标文件的编译命令行如下:
riscv32-unknown-elf-gcc baremetal.s -ggdb -O0 -o image -ffreestanding -nostdlib
其中,
执行完以上编译命令后,会生成目标ELF文件image:
Renode有一个非常方便的地方,就是可以通过一个RESC脚本将所有的步骤串联起来执行,而无需用户在命令行窗口中逐个输入命令,这就大大简化了我们的仿真操作步骤。
工程的仿真脚本(vexriscv.resc)如下:
- :name: 1_blinky_VexRiscv
- :description: Loader for the baremetal-riscv-renode project example 1 "blinky"
-
- $name?="vexriscv-machine"
-
- using sysbus
- mach create $name
- machine LoadPlatformDescription @vexriscv.repl
-
- sysbus LoadELF @image
-
- machine StartGdbServer 3333
- logLevel -1 sysbus.gpio_out.led0
- logLevel -1 sysbus.gpio_out.led1
-
- start
关于脚本中命令的介绍,见之前的文章:Renode学习:Working with machines_牧羊女-CSDN博客
代码仓库中已经将运行命令也集成到了Makefile文件中,所以我们只需要执行make launch即可使demo运行起来。
Makefile文件如下:
- image: baremetal.s
- riscv32-unknown-elf-gcc baremetal.s -ggdb -O0 -o image -ffreestanding -nostdlib
-
- launch: image
- renode vexriscv.resc
-
- debug:
- riscv32-unknown-elf-gdb -x gdbrc
-
- clean:
- rm image
运行界面如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。