rt-smart 实时操作系统是 rt-thread 面向带MMU,中高端应用的芯片,例如ARM Cortex-A系列芯片,MIPS芯片,带MMU的RISC-V芯片等。rt-smart 在 RT-Thread 操作系统的基础上启用独立、完整的进程方式,同时以混合微内核模式执行。
rt-thread 官网:https://www.rt-thread.org/
rt-smart 官方文档中心:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-smart/introduction/rt-smart-intro/rt-smart-intro
注:文档中心相关文档可能并未及时更新
milkv-duo 系列开发板包括 duo、duo256、duos 均已支持 rt-thread 标准版、rt-smart 版本运行。
支持开发板以及集成 SoC 芯片信息如下:
- milk-v duo: https://milkv.io/duo,SoC 采用 CV1800B。
- milk-v duo256m: https://milkv.io/duo256m,SoC 采用 SG2002(原 CV181xC)。
- milk-v duos: https://milkv.io/duos,SoC 采用 SG2000(原 CV181xH)。
Duo 家族开发板采用 CV18xx 系列芯片。芯片的工作模式总结如下:
- CV1800B,支持一种工作模式:
- 大核(RISC-V C906@1GHz)+ 小核(RISC-V C906@700MHz)。
- SG2002(原 CV181xC),支持两种工作模式,通过管脚 GPIO_RTX 的外围电路控制进行切换:
- 大核(RISC-V C906@1GHz)+ 小核(RISC-V C906@700MHz)。
- 大核(ARM Cortex-A53@1GHz)+ 小核(RISC-V C906@700MHz)。
- SG2000(原 CV181xH),支持两种工作模式,通过管脚 GPIO_RTX 的外围电路控制进行切换:
- 大核(RISC-V C906@1GHz)+ 小核(RISC-V C906@700MHz)。
- 大核(ARM Cortex-A53@1GHz)+ 小核(RISC-V C906@700MHz)。
异构芯片有大小核多个不同核的存在,以及不同 SoC 下不同工作模式的存在,bsp/cvitek
提供了三种不同 BSP/OS,需要单独编译。
BSP 名称 | 大小核 | 芯片架构 | 默认串口控制台 | 备注 |
---|---|---|---|---|
cv18xx_risc-v | 大核 | RISC-V C906 | uart0 | 支持 MMU,支持 RT-Thread 标准版 和 RT-SMART 模式,默认运行 RT-SMART 版本 |
c906-little | 小核 | RISC-V C906 | uart1 | 无 MMU,运行 RT-Thread 标准版 |
cv18xx_aarch64 | 大核 | ARM Cortex A53 | uart0 | 支持 MMU, 支持 RT-Thread 标准版 和 RT-SMART 版,默认运行 RT-Thread 标准版本 |
由于开发板默认运行的大核为 “cv18xx_risc-v”, 所以本文将主要介绍 cv18xx_risc-v
和 c906-little
的构建和使用。
代码下载
目前 rt-thread 官方仓库 master 已支持 rt-smart 运行模式,按照以下方式下载代码:
$ git clone https://github.com/rt-thread/rt-thread
milkv-duo 系列开发板对应的 bsp 位于 bsp/cvitek
目录结构如下:
├── board_env.sh
├── c906_little # risc-v c906 小核
├── combine-fip.sh
├── cv18xx_aarch64 # arm Cortex-A53 核
├── cv18xx_risc-v # risc-v c906 大核
├── drivers # 驱动
├── mkimage
├── mksdimg.sh
└── README.md
目前只支持 Linux 环境下的开发,推荐 ubuntu 22.04。不支持 Windows 环境,在 Windows 环境下,可使用 WSL 进行开发。
环境搭建
依赖安装
RT-Thread 实时操作系统采用 SCons 作为构建工具。
$ sudo apt-get install -y scons python3 python3-pip libncurses5-dev device-tree-compiler
rt-thread 使用 kconfiglib 作为 menuconfig 工具,使用以下命令安装:
$ pip3 install kconfiglib
milkv-duo 系列开发板会自动下载包括 opensbi、u-boot 等相关依赖代码包,并自动编译,需安装以下依赖:
$ sudo apt-get install -y wget bison flex
toolchain 下载
-
rt-smart 运行使用专用 musl gcc 编译器,下载地址 https://github.com/RT-Thread/toolchains-ci/releases/download/v1.7/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2
下载完成后使用如下命令解压:
$ sudo tar -xvf riscv64-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2 -C /opt
-
rt-thread 标准版使用 xuantie newlib gcc 编译器,下载地址 https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1705395512373/Xuantie-900-gcc-elf-newlib-x86_64-V2.8.1-20240115.tar.gz
下载完成后使用如下命令解压:
$ sudo tar -zxvf Xuantie-900-gcc-elf-newlib-x86_64-V2.8.1-20240115.tar.gz -C /opt
编译
小核编译
小核相关操作均在 bsp/c906_little
目录下进行。
- 配置 toolchain 地址(配置方法任选一种)
-
手工修改
rt-thread toolchain 可通过bsp/cvitek/c906_little/rtconfig.py
文件中的EXEC_PATH
变量手工设置,请根据上诉 newlib gcc 地址正确设置。if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' EXEC_PATH = r'/opt/Xuantie-900-gcc-elf-newlib-x86_64-V2.8.1/bin' else: print('Please make sure your toolchains is GNU GCC!') exit(0)
-
环境变量设置
$ export RTT_CC_PREFIX=riscv64-unknown-elf- $ export RTT_EXEC_PATH=/opt/Xuantie-900-gcc-elf-newlib-x86_64-V2.8.1/bin
-
在编译命令中通过参数传入 toolchain 路径,方法见
3. 编译
。
-
选择对应的开发板
c906_little 默认开发板为 milkv-duo256m sd卡版本,可通过 menuconfig 进入修改选择$ scons --menuconfig RT-Thread Kernel ---> RT-Thread Components ---> RT-Thread Utestcases ---> RT-Thread online packages ---> General Drivers Configuration ---> Board Type (milkv-duo256m) ---> ( ) milkv-duo ( ) milkv-duo-spinor (X) milkv-duo256m ( ) milkv-duo256m-spinor ( ) milkv-duos
同时也可以在修改 RT-Thread Kernel、Components 等相关配置选择。修改完成后,保存并退出。
-
编译
使用如下命令编译:$ scons # 或 $ scons --exec-path=/opt/Xuantie-900-gcc-elf-newlib-x86_64-V2.8.1/bin
小核首次编译会自动下载 opensbi、u-boot 等相关依赖代码包,并自动编译后与 c906_little 目录下的 rtthread.bin 合并成 fip.bin 文件。该文件位于
bsp/cvitek/output/milkv-duo256m/fip.bin
成功编译打包后会显示如下信息:
[LS] -rw-r--r-- 1 root root 456704 Nov 2 11:47 /home/share/samba/rt-thread/bsp/cvitek/cvitek_bootloader/fsbl/build/cv1812cp_milkv_duo256m_sd/fip.bin make[1]: Leaving directory '/home/share/samba/rt-thread/bsp/cvitek/cvitek_bootloader/fsbl' cp /home/share/samba/rt-thread/bsp/cvitek/cvitek_bootloader/fsbl/build/cv1812cp_milkv_duo256m_sd/fip.bin /home/share/samba/rt-thread/bsp/cvitek/cvitek_bootloader/install/soc_cv1812cp_milkv_duo256m_sd/ cp /home/share/samba/rt-thread/bsp/cvitek/cvitek_bootloader/fsbl/build/cv1812cp_milkv_duo256m_sd/fip.bin /home/share/samba/rt-thread/bsp/cvitek/cvitek_bootloader/install/soc_cv1812cp_milkv_duo256m_sd/fip_spl.bin /home/share/samba/rt-thread/bsp/cvitek scons: done building targets.
注: 路径名会根据编译环境不同而变化。
大核编译
大核相关操作均在 bsp/cv18xx_risc-v
目录下进行。
编译前须确认当前大核运行 rt-thread 标准版还是 rt-smart 版,默认为 rt-smart 版。标准版编译流程同c906_little
,下面介绍 rt-smart 编译方法。
- 配置 toolchain 地址(配置方法任选一种)
-
手工修改
rt-smart toolchain 可通过bsp/cvitek/cv18xx_risc-v/rtconfig.py
文件中的EXEC_PATH
变量手工设置,请根据上诉 musl gcc 地址正确设置。if CROSS_TOOL == 'gcc': PLATFORM = 'gcc' EXEC_PATH = r'/opt/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin' else: print('Please make sure your toolchains is GNU GCC!') exit(0)
-
环境变量设置
$ export RTT_CC_PREFIX=riscv64-unknown-linux-musl- $ export RTT_EXEC_PATH=/opt/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin
-
在编译命令中通过参数传入 toolchain 路径,方法见
4. 编译
。
-
rt-smart 功能开启与内核虚拟地址确认
大核 cv18xx_risc-v 默认运行 rt-smart 版,也可以运行 rt-thread 标准版,可通过 menuconfig 进入
RT-Thread Kernel
修改选择。$ scons --menuconfig RT-Thread Kernel ---> [*] Enable RT-Thread Smart (microkernel on kernel/userland)
开启
Enable RT-Thread Smart
选项后,在 menuconfig 主页面下可看到内核虚拟地址,该地址必须为0xFFFFFFC000200000
。$ scons --menuconfig RT-Thread Kernel ---> (0xFFFFFFC000200000) The virtural address of kernel start RT-Thread Components ---> RT-Thread Utestcases ---> RT-Thread online packages ---> General Drivers Configuration ---> (8192) stack size for interrupt Board Type (milkv-duo256m) ---> rootfs type (Disk FileSystems, e.g. ext4, fat ...) --->
-
选择对应的开发板
cv18xx_risc-v 默认开发板为 milkv-duo256m sd卡版本,可通过 menuconfig 进入Board Type
修改选择。$ scons --menuconfig RT-Thread Kernel ---> (0xFFFFFFC000200000) The virtural address of kernel start RT-Thread Components ---> RT-Thread Utestcases ---> RT-Thread online packages ---> General Drivers Configuration ---> (8192) stack size for interrupt Board Type (milkv-duo256m) ---> ( ) milkv-duo ( ) milkv-duo-spinor (X) milkv-duo256m ( ) milkv-duo256m-spinor ( ) milkv-duos rootfs type (Disk FileSystems, e.g. ext4, fat ...) --->
同时也可以在修改 RT-Thread Kernel、Components 等相关配置选择。修改完成后,保存并退出。
-
编译
使用如下命令编译:$ scons # 或 $ scons --exec-path=/opt/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin
编译完成
编译成功后,会在 bsp/cvitek/output
对应开发板型号目录下自动生成 fip.bin
和 boot.sd
文件,其中大核运行文件在 boot.sd
中,小核的运行文件在 fip.bin
中。
- fip.bin:fsbl、opensbi、uboot、小核运行文件打包后的 bin 文件
- boot.sd:大核打包后的 bin 文件
运行
-
将 SD 卡分为 2 个分区,第 1 个分区用于存放 bin 文件,分区格式为
FAT32
。第 2 个分区可用于作为根文件系统,具体分区格式需与对应根文件系统移植(见 #根文件系统挂载 )。 -
将
bsp/cvitek
目录下 output 对应开发板下的fip.bin
和boot.sd
复制到 SD 卡第一个分区中。两个固件文件可以独立修改更新,譬如后续只需要更新大核,只需要重新编译 “cv18xx_risc-v” 并复制boot.sd
文件即可。 -
更新完固件文件后,重新上电可以看到串口的输出信息。
大小核串口输出分别为:
-
大核: uart0(GP12/GP13)
U-Boot 2021.10 (Nov 02 2024 - 11:47:01 +0000) cvitek_cv181x DRAM: 254 MiB gd->relocaddr=0x8b0c8000. offset=0xaec8000 MMC: cv-sd@4310000: 0 Loading Environment from nowhere... OK In: serial Out: serial Err: serial Net: Warning: ethernet@4070000 (eth0) using random MAC address - 82:f7:c4:27:98:16 eth0: ethernet@4070000 Hit any key to stop autoboot: 0 Boot from SD ... switch to partitions #0, OK mmc0 is current device 170180 bytes read in 11 ms (14.8 MiB/s) ## Loading kernel from FIT Image at 81800000 ... Using 'config-cv1812cp_milkv_duo256m_sd' configuration Trying 'kernel-1' kernel subimage Description: cvitek kernel Type: Kernel Image Compression: lzma compressed Data Start: 0x818000d8 Data Size: 143686 Bytes = 140.3 KiB Architecture: RISC-V OS: Linux Load Address: 0x80200000 Entry Point: 0x80200000 Hash algo: crc32 Hash value: 194b3f87 Verifying Hash Integrity ... crc32+ OK ## Loading fdt from FIT Image at 81800000 ... Using 'config-cv1812cp_milkv_duo256m_sd' configuration Trying 'fdt-cv1812cp_milkv_duo256m_sd' fdt subimage Description: cvitek device tree - cv1812cp_milkv_duo256m_sd Type: Flat Device Tree Compression: uncompressed Data Start: 0x8182333c Data Size: 24599 Bytes = 24 KiB Architecture: RISC-V Hash algo: sha256 Hash value: fca09bd9678df89606a7d31d37d033745f23ef47701ba482f4637fc0ddbb0715 Verifying Hash Integrity ... sha256+ OK Booting using the fdt blob at 0x8182333c Uncompressing Kernel Image Decompressing 398856 bytes used 44ms Loading Device Tree to 000000008a777000, end 000000008a780016 ... OK Starting kernel ... [I/drv.pinmux] Pin Name = "UART0_RX", Func Type = 281, selected Func [0] [I/drv.pinmux] Pin Name = "UART0_TX", Func Type = 282, selected Func [0] heap: [0x80292618 - 0x81200000] \ | / - RT - Thread Smart Operating System / | \ 5.2.0 build Nov 2 2024 12:02:13 2006 - 2024 Copyright by RT-Thread team lwIP-2.1.2 initialized! [I/sal.skt] Socket Abstraction Layer initialize success. Hello RT-Smart! msh />
-
小核: uart1(GP0/GP1)
运行日志如下:
RT_HW_HEAP_BEGIN:8fe33900 RT_HW_HEAP_END:90000000 size: 1885952
\ | /
- RT - Thread Operating System
/ | \ 5.2.0 build Nov 2 2024 11:37:57
2006 - 2024 Copyright by RT-Thread team
Hello, RISC-V!
msh >
```
波特率均为:115200
可通过大核串口日志确认运行的是 rt-smart 系统,小核运行 rt-thread系统。
根文件系统挂载
大核启用 rt-smart 后可以在启动阶段挂载根文件系统。目前支持 ext4, fat 文件格式,内核默认支持 fat,下面介绍 fat 格式文件系统流程。
驱动配置
- 根文件系统依赖 SD 卡驱动和 RTC 驱动,可通过 menuconfig 进入
General Drivers Configuration
修改开启。 - 使能
BSP_ROOTFS_TYPE_DISKFS
,可通过 menuconfig 进入rootfs type (Disk FileSystems, e.g. ext4, fat ...)
开启
$ scons --menuconfig
RT-Thread Kernel --->
(0xFFFFFFC000200000) The virtural address of kernel start
RT-Thread Components --->
RT-Thread Utestcases --->
RT-Thread online packages --->
[X] Enable RTC
[X] Enable Secure Digital Host Controller
General Drivers Configuration --->
(8192) stack size for interrupt
Board Type (milkv-duo256m) --->
rootfs type (Disk FileSystems, e.g. ext4, fat ...) --->
(X) Disk FileSystems, e.g. ext4, fat ...
根文件系统构建
RT-Thread 官方的 userapps 工具制作文件系统。
userapps 仓库地址: https://github.com/RT-Thread/userapps。具体操作参考 《介绍与快速入门》。
制作根文件系统步骤如下,供参考:
- xmake的安装
$ sudo add-apt-repository ppa:xmake-io/xmake
$ sudo apt update
$ sudo apt install xmake
- 根文件系统编译
$ git clone https://github.com/RT-Thread/userapps.git
$ cd userapps
$ source ./env.sh
$ cd apps
$ xmake f -a riscv64gc
$ xmake -j$(nproc)
$ xmake smart-rootfs
$ xmake smart-image -f fat -s 512M
在 userapps/apps/build
路径下生成根文件系统镜像文件 fat.img
。
如果是制作 ext4 格式的文件系统 image,则最后一步换成:
$ xmake smart-image -f ext4
生成根文件系统镜像文件 ext4.img
。
根文件系统写入 SD 卡
将已经打包完成的 fat.img
文件写入上诉 SD 卡第二个分区,请确认当前 SD 卡第二分区为 FAT32,当前步骤在 Ubuntu下进行。
-
将 SD 卡插入 PC ,通过 fdisk 命令获取设备号。
$ sudo fdisk -l Disk /dev/sdb: 7.21 GiB, 7742685184 bytes, 15122432 sectors Disk model: Storage Device Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xc2aebb63 Device Boot Start End Sectors Size Id Type /dev/sdb1 * 1 262144 262144 128M c W95 FAT32 (LBA) /dev/sdb2 264192 15120383 14856192 7.1G c W95 FAT32 (LBA)
SD 卡第二分区为
/dev/sdb2
。 -
将 SD卡第二分区挂载到
~/sd-card
。$ mkdir ~/sd-card $ sudo mount /dev/sdb2 ~/sd-card
-
将
fat.img
$ mkdir ~/tmp $ sudo mount -o loop fat.img ~/tmp $ cd ~/tmp $ ls bin dev etc lib mnt proc root run sbin services tc tmp usr var
-
复制
~/tmp
下的所有文件至~/sd-card
$ cp -a ~/tmp/* ~/sd-card
-
卸载 SD 卡分区
$ sudo umount ~/sd-card $ sudo umount ~/tmp
根文件系统运行
将写入根文件系统的 SD 卡插入开发板,上电运行后,会显示如下日志
Starting kernel ...
[I/drv.pinmux] Pin Name = "UART0_RX", Func Type = 281, selected Func [0]
[I/drv.pinmux] Pin Name = "UART0_TX", Func Type = 282, selected Func [0]
heap: [0x0xffffffc000300110 - 0x0xffffffc000b00110]
\ | /
- RT - Thread Smart Operating System
/ | \ 5.2.0 build Dec 28 2024 14:06:17
2006 - 2024 Copyright by RT-Thread team
lwIP-2.1.2 initialized!
[I/sal.skt] Socket Abstraction Layer initialize success.
[I/drivers.serial] Using /dev/ttyS0 as default console
[I/SDIO] SD card capacity 7561216 KB.
[I/SDIO] sd: switch to High Speed / SDR25 mode
found part[0], begin: 512, size: 128.0MB
found part[1], begin: 135266304, size: 7.86GB
[I/app.filesystem] device 'sd1' is mounted to '/' as FAT
Hello RT-Smart!
msh />
/ #
/ #
可以看到日志中显示 / #
,表示文件系统已经启动,输入 help
命令可以查看当前支持的命令:
/ # help
Built-in commands:
------------------
. : [ [[ alias bg break cd chdir command continue echo eval exec
exit export false fg getopts hash help history jobs kill let
local printf pwd read readonly return set shift source test times
trap true type ulimit umask unalias unset wait [ [[ add-shell
addgroup adduser adjtimex ar arch arp arping ascii ash awk base32
base64 basename bash bbconfig bc blkid bootchartd bunzip2 busybox
bzcat bzip2 cal cat chat chattr chgrp chmod chown chpasswd chpst
chroot chrt chvt cksum clear cmp comm cp cpio crc32 crond crontab
cryptpw cttyhack cut date dc dd deallocvt delgroup deluser depmod
devfsd devmem devmem2 df dhcprelay diff dirname dmesg dnsd dnsdomainname
dos2unix dpkg dpkg-deb du dumpkmap dumpleases echo ed egrep env
envdir envuidgid expand expr factor fakeidentd fallocate false
fatattr fbset fdflush fdformat fdisk fgconsole fgrep find findfs
flock fold free freeramdisk fsck fsck.minix fsfreeze fstrim fsync
ftpd ftpget ftpput fuser getopt getty grep groups gunzip gzip
halt hd head hexdump hexedit hostid hostname httpd hush hwclock
id ifconfig ifdown ifup inetd init inotifyd insmod install iostat
ipcalc ipcrm ipcs kill killall killall5 klogd less link linux32
linux64 ln loadkmap logger login logname logread losetup lpd
lpq lpr ls lsattr lsmod lsof lspci lsscsi lsusb lzcat lzma lzop
lzopcat makedevs makemime man md5sum mesg microcom mim minips
mkdir mkfifo mkfs.minix mknod mkpasswd mkswap mktemp modinfo
modprobe more mount mountpoint mpstat mt mv nc netcat netstat
nice nl nmeter nohup nologin nproc nsenter nslookup ntpd nuke
od partprobe passwd paste patch pgrep pidof ping pipe_progress
pivot_root pkill pmap popmaildir poweroff powertop printenv printf
ps pscan pstree pwd pwdx rdate rdev readahead readlink readprofile
realpath reboot reformime remove-shell renice reset resize resume
rev rm rmdir rmmod route rpm rpm2cpio rtcwake run-parts runsv
runsvdir rx script scriptreplay sed sendmail seq setarch setconsole
setfattr setkeycodes setlogcons setserial setsid setuidgid sh
sha1sum sha256sum sha3sum sha512sum shred shuf sleep smemcap
softlimit sort split ssl_client start-stop-daemon stat strings
stty su sulogin sum sv svc svlogd svok swapoff swapon switch_root
sync sysctl syslogd tac tail tar taskset tcpsvd tee telnet telnetd
test tftp tftpd time timeout top touch tr traceroute true truncate
ts tty ttysize tune2fs udhcpd udpsvd umount uname uncompress
unexpand uniq unix2dos unlink unlzma unlzop unshare unxz unzip
uptime usleep uudecode uuencode vconfig vi volname watch wc wget
which whoami whois xargs xxd xz xzcat yes zcat
FAQ
-
如遇到不能正常编译,请先使用
scons --menuconfig
重新生成配置。 -
错误:./mkimage: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
可在 http://security.ubuntu.com/ubuntu/pool/main/o/openssl 下载
libssl1.1_1.1.1f-1ubuntu2_amd64.deb
文件后安装即可解决。
或使用以下命令下载安装:$ wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2_amd64.deb $ sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb
-
如发现切换开发板编译正常,但无法正常打包,请切换至自动下载的
cvi_bootloader
目录,并手工运行git pull
更新,或删除该目录后重新自动下载。
参考文档
- 【参考 1】CV1800B/CV1801B Datasheet(中文版):https://github.com/milkv-duo/duo-files/blob/main/duo/datasheet/CV1800B-CV1801B-Preliminary-Datasheet-full-zh.pdf
- 【参考 2】SG2002/SG2000 技术参考手册(中文版):https://github.com/sophgo/sophgo-doc/releases。官方定期发布 pdf 形式。可以下载下载最新版本的中文版本技术参考手册:
sg2002_trm_cn.pdf
或者sg2000_trm_cn.pdf
。