前言
- 经过这两天的折腾,在 qemu-virt64-riscv上,终于把 RT-Thread Smart(简称 rt-smart)跑起来了,这里做个记录,记录下整个流程的搭建,遇到问题的解决
- rt-smart 当前支持的 bsp 不多,经过尝试,可以在 qemu 上运行,这方便了一些简单软件的开发与调试
- rt-smart 开发,分为两个部分:内核态与用户态,内核态注重设备驱动开发,用户态注重实际的开发应用功能的实现
- 前面文章:RT-Thread BSP qemu-virt64-riscv 的编译环境搭建 已经把 rt-smart 跑起来了,本篇继续把 用户态 userapps 跑起来。
userapps 的获取
- 下载地址 https://github.com/RT-Thread/userapps,可以使用
git clone https://github.com/RT-Thread/userapps.git
- rt-smart 上,为了实现用户态与内核态的分离,使用了【系统调用】,这个系统调用可以认为是个
sdk
,当前userapps
提供了arm
与riscv
的 sdk(编译好的二进制)文件与头文件,所以用户态的程序开发,只需要开发 app 即可。
userapps 的编译环境
- 编译
userapps
的方法:下载userapps
后,进入 tools 目录,然后把 运行平台的 交叉编译工具链拉取下来,qemu-virt64-riscv
使用的是riscv64
,在 ubuntu 20.04 shell 中运行:$ python3 get_toolchain.py riscv64
即可拉取riscv64
的 gcc 交叉编译工具链riscv64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2
,并解压到userapps/tools/gnu_gcc/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu
- 设置
riscv64
gcc 交叉编译链的 环境变量:ubuntu 20.04 下,在userapps
目录下,直接运行$ source smart-env.sh riscv64
即可
zhangsz@zhangsz:~/rtt/smart/userapps$ source smart-env.sh riscv64
/home/zhangsz/rtt/smart/userapps
Arch => riscv64
CC => gcc
PREFIX => riscv64-unknown-linux-musl-
EXEC_PATH => /home/zhangsz/rtt/smart/userapps/tools/gnu_gcc/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin
- 可以运行
$ riscv64-unknown-linux-musl-gcc -v
验证riscv64
gcc 交叉编译工具链生效
userapps 的编译
- 编译
userapps
,可以在userapps
目录直接使用scons
进行编译,也可以进入userapps/apps/xxx
目录下,单独编译某个 app。 - 如单独编译
userapps/apps/hello
的方法,进入userapps/apps/hello
,运行scons
编译,生成hello.elf
文件,这个 elf 就是用户态的可执行文件,可以放进rt-smart
文件系统中,运行执行。
zhangsz@zhangsz:~/rtt/smart/userapps/apps/hello$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: building associated VariantDir targets: build/hello
CC build/hello/main.o
LINK hello.elf
scons: done building targets.
- 在
userapps
目录下,默认是全部编译,生成的产物在userapps/root/bin
zhangsz@zhangsz:~/rtt/smart/userapps$ cd root/bin/
zhangsz@zhangsz:~/rtt/smart/userapps/root/bin$ ls
hello.elf ping.elf pong.elf umailbox.elf vi.elf webclient.elf webserver.elf
zhangsz@zhangsz:~/rtt/smart/userapps/root/bin$
- 可以把
userapps
的编译产物userapps/root/bin
目录下的所有 elf 文件等,全部 拷贝到qemu-virt64-riscv
的 sd.bin 镜像文件中
sd.bin 镜像文件
- ubuntu 20.04 下,有各种文件系统镜像文件的制作工具,如
fat
、ext4
等文件系统类型 - 如当前 RT-Thread 支持
elm
文件系统,也就是fat
文件系统,制作方法如下: - 进入
qemu-virt64-riscv
的内核目录,注意userapps
和qemu-virt64-riscv
是独立的
$ dd if=/dev/zero of=sd.bin bs=1024 count=65536 /* 64MB 大小,可以根据需要更改大小 */
$ mkfs.fat sd.bin /* 格式化为 fat 文件类型 */
$ mkdir sdcard /* 镜像文件 sd.bin mount 挂载目录,挂载后可往镜像文件里面拷贝或删除文件 */
$ sudo mount sd.bin sdcard/ /* 挂载到 sdcard 目录下,这样就可以拷贝文件了 */
$ sudo cp -r /home/zhangsz/rtt/smart/userapps/root/bin sdcard/ /* userapps 产物拷贝到 镜像文件 */
$ ls sdcard/ /* 文件拷贝进去了 */
bin
$ sudo umount sdcard /* 取消镜像文件 sd.bin 的挂载, userapps 的产物已经在里面了 */
运行 qemu
-
qemu-virt64-riscv
下 运行$ ./qemu-nographic.sh
即可
zhangsz@zhangsz:~/rtt/smart/rtt_qemu_aarch64/qemu-virt64-riscv$ ./qemu-nographic.sh
OpenSBI v1.2
____ _____ ____ _____
/ __ \ / ____| _ \_ _|
| | | |_ __ ___ _ __ | (___ | |_) || |
| | | | '_ \ / _ \ '_ \ \___ \| _ < | |
| |__| | |_) | __/ | | |____) | |_) || |_
\____/| .__/ \___|_| |_|_____/|____/_____|
| |
|_|
Platform Name : riscv-virtio,qemu
Platform Features : medeleg
Platform HART Count : 1
Platform IPI Device : aclint-mswi
Platform Timer Device : aclint-mtimer @ 10000000Hz
Platform Console Device : uart8250
Platform HSM Device : ---
Platform PMU Device : ---
Platform Reboot Device : sifive_test
Platform Shutdown Device : sifive_test
Firmware Base : 0x80000000
Firmware Size : 212 KB
Runtime SBI Version : 1.0
Domain0 Name : root
Domain0 Boot HART : 0
Domain0 HARTs : 0*
Domain0 Region00 : 0x0000000002000000-0x000000000200ffff (I)
Domain0 Region01 : 0x0000000080000000-0x000000008003ffff ()
Domain0 Region02 : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address : 0x0000000080200000
Domain0 Next Arg1 : 0x000000008fe00000
Domain0 Next Mode : S-mode
Domain0 SysReset : yes
Boot HART ID : 0
Boot HART Domain : root
Boot HART Priv Version : v1.12
Boot HART Base ISA : rv64imafdch
Boot HART ISA Extensions : time,sstc
Boot HART PMP Count : 16
Boot HART PMP Granularity : 4
Boot HART PMP Address Bits: 54
Boot HART MHPM Count : 16
Boot HART MIDELEG : 0x0000000000001666
Boot HART MEDELEG : 0x0000000000f0b509
heap: [0x802e7078 - 0x842e7078]
\ | /
- RT - Thread Smart Operating System
/ | \ 5.0.0 build Mar 19 2023 20:34:47
2006 - 2022 Copyright by RT-Thread team
lwIP-2.0.3 initialized!
[I/sal.skt] Socket Abstraction Layer initialize success.
[I/utest] utest is initialize success.
[I/utest] total utest testcase num: (0)
file system initialization done!
Hello RISC-V
msh />
msh />ls
Directory /:
bin <DIR>
msh />cd bi
msh />cd bin/
msh /bin>ls
Directory /bin:
hello.elf 341224
ping.elf 347336
pong.elf 342152
umailbox.elf 357440
vi.elf 517448
webclient.elf 393016
webserver.elf 489320
msh /bin>./h
msh /bin>./hello.elf
msh /bin>hello world!
- 可以进入 /bin 目录下,运行
elf
用户态的程序了
进程间通信例程
- 当前用户态程序
ping.elf
pong.elf
,可以用于验证 线程通信 - 首先后台方式运行
pong.elf
,运行命令:./pong.elf &
,注意后面的&
代表后台线程,这样 shell 不会被占用,否则无法再运行其他的elf
文件
msh /bin>./pong.elf &
msh /bin>
Pong: wait on the IPC channel: 3
- 接下来运行
ping.elf
,看下效果./ping.elf
- 用户态的线程可以正常的运行
小结
- rt-smart 的内核态与用户态分离,与 嵌入式Linux开发方法相似, rt-smart 在不断的完善,后期会适配到更多的平台上
- 除了运行 RT-Thread
userapps
下的app,用户可以根据需要,设计自己的 app,当前如果需要内核设备驱动支持,还需要在 内核部分编写设备驱动等。