Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / IoT

Setting Up a New VisionFive 2 RISC-V SBC

5.00/5 (3 votes)
27 Nov 2023CPOL39 min read 13.4K  
The VisionFive 2 RISC-V SBC is an alternative to the Raspberry Pi 4, however its software has some rough edges. I decided to write about my experience working with a series of Raspberry Pi 3 hobby experiments using the VisionFive.
Looking at alternatives to the Raspberry Pi 4, I decided to purchase a VisionFive 2 RISC-V SBC and try to replicate the same IoT hobby projects that I had done with a Raspberry Pi 3.

Contents

Introduction

There are several alternative Small Board Computers (SBC) to the Raspberry Pi 3/4/5. Most of these SBCs have a physical size similar to the Raspberry Pi 3/4 and offer similar capabilities such as a 40 pin connector for IoT along with HDMI, USB, and RJ-45 connectors. These connectors allow the device to be used as a desktop computer with a display, keyboard, mouse, and Ethernet connection. Most of these also have some provision for WiFi and Bluetooth though doing so may require a dongle whether USB or, as in the case of the Orange Pi 5 Plus, an M.2 connector. Some alternatives have not only a microSD card drive but an M.2 connector suitable for an NVMe solid state drive. Most can access a USB solid state drive as well.

Some alternatives, such as the Orange Pi 5, are based on ARM processors which are well supported with various Linux distros. Microsoft now offers an ARM version of Windows which isn't available as a separate purchase like the x86 version but does come on some notebook type devices. And there is the WoR Project that offers a way to build a Window for ARM installer for the Raspberry Pi as well as an experimental version for the Orange Pi 5 or other SBC with the Rockchip 3588.

Another alternative are RISC-V SBCs such as the VisionFive 2 and the Lichee Pi 4. The ecosystem for these devices are not as well developed. Both hardware and software are more of a work in progress which means that working with these alternatives require some degree of expertise as well as persistence in the face of failure.

Background

Since the VisionFive 2 has an appearance similar to the Raspberry Pi 3, I decided to go with that. AliExpress and Amazon both have various offerings and bundles. I decided on a GeekPi bundle that I purchased through Amazon.

The goal of this exercise was to try to replicate the IoT project experiments that I had done with a Raspberry Pi 3. The code for the experiments is located in my Github repository at https://github.com/RichardChambers/raspberrypi.

As I've worked on this project, I am beginning to wonder if I will need to change from the WiringPi library that works with both Raspberry Pi and Orange Pi to some other library such as libgpiod, a standard Linux library. When I tried a couple of the Raspberry Pi 3 projects on an Orange Pi 5 Plus, there was a port of the WiringPi library to the Orange Pi and the only change to the source code needed was the GPIO pin numbers, which differed from the Raspberry Pi 3. It does not appear that there is a RISC-V version of the WiringPi library for the VisionFive 2. On the other hand, my impression is that the libgpiod library is available and usable on Raspberry Pi and Orange Pi using an up-to-date Linux kernel with the support for the libgpiod library built in. However libgpiod does not provide all of the functionality of the WiringPi library as libgpiod is really about the GPIO pins only.

There appear to be several hardware versions of the VisionFive 2. The hardware release is silk printed on the PCB next to the processor and where the StarFive logo is printed. It seems that both release 1.2 and release 1.3 boards are being shipped.

An Important Note About Tools

During my time thus far working with the VisionFive 2, I found that having a PC with Linux available was a key resource. In my case I've been using a Dell with an older i7 processor and a home built PC with an 11th generation i5 processor. The Dell is running Windows 10 Pro and the home build is running Windows 11 Pro and both have Windows Subsystem for Linux (WSL) with Ubuntu as the WSL distro. There have been several problems that having the Linux system available were fairly easily resolved.

I have also used tools that come with Windows 10 and Windows 11 along with the Raspberry Pi Imager application downloaded from Introducing Raspberry Pi Imager, our new imaging utility - Raspberry Pi. It looks like the Raspberry Pi Imager is also available for Ubuntu x86 and MacOS.

This Dell has a normal sized SD slot as well as a couple of USB ports on the front whereas the home build doesn't have an SD slot. When working with the microSD card used in the VisionFive 2 with Windows, I have used both a microSD to SD adaptor and a microSD to USB adapter. Both have worked fine with both PCs.

In addition to a microSD card to USB adapter, another tool is a TTY to USB adapter cable. This cable allows you to connect a PC running a terminal emulator such as PuTTY or gtkterm to the UART pins on the VisionFive 2 40 pin connector. This can be helpful if you are unable to use a graphical desktop environment with a monitor connected via HDMI along with USB keyboard and mouse for some reason. This cable is especially useful if you are debugging Linux kernel builds and boot problems. Note that the TTY to USB converter in these cables may vary in quality and Windows may reject some cables that Linux will accept. Also some cables may have pin connectors labeled and others not which may make connecting the cable TTY leads to the proper UART pins on the 40 pin connector a bit of a guess.

Unboxing and Setup

The bundle I purchased had the following components:

  • 8 GB VisionFive 2 SBC board, mine is a 1.2A version board
  • Type C connector power supply, output 5v and 3.6 amps
  • WiFi dongle
  • 64GB microSD card
  • microSD to USB adapter
  • TTL to USB cable
  • acrylic baseplate with standoffs
  • heatsink for the CPU

The initial problem I ran into was a lack of documentation on the VisionFive 2 board in English. through the StarFive website. The StarFive website is a bit slow and difficult to navigate and somewhat confusing. I did find several articles posted by people doing experiments with the VisionFive 2 which helped somewhat though mostly inducing in me a feeling of dread that I had just blown more than $100 on what was looking to be a desk decoration.

Then I found this article, which helped get me started. However, my experience was a bit easier since the software has had a few months to become better and more stable. As I have continued to work with the device, I appear to have gotten better at searching the internet or perhaps I have learned enough to ask intelligent questions. At any rate, I am beginning to find helpful resources and have been making steady progress in my understanding of the VisionFive 2 SBC and its software.

Lately, I have have found the RVspace forums and the RVspace wiki. The RVspace wiki has this list, Available PDF Documentation -> English Document, that has a number of pieces of documentation about the board as well as application notes for various projects.

I decided to use the Debian distro located on the StarFive website which has two different links Baidu Cloud Disk and OneDrive. There is also a StarFive Github repository which I have not yet investigated other than to see what looks to be the Linux kernel source and build area.

I tried each of these links, both of which appeared to want me to authenticate initially. The Baidu Cloud Disk link displayed an anime style backdrop with what appeared to be a sign-in page but as it was all in Chinese, I wasn't sure. However, the anime girl figures were impressively large breasted. The OneDrive wanted me to authenticate with my Microsoft OneDrive credentials so I refused to do that.

Since that initial attempt, when I have gone back to these links with the same PC and browser, there is no request to authenticate and I see a file hierarchy in my browser that I can navigate.

I decided to use the OneDrive repository to obtain the Debian image. Navigating down the folder hierarchy, I came to a list of folders whose names were dates. I picked the most recent which for me was 202310 and in the folder were release notes as well as several different folders which seemed to be different images for different storage devices such as SD card, NVMe drive or EMMC.

When I tried going to the site again on a different day using a different PC and selected the Baidu Cloud Disk link, I noticed that it appeared that a username, csx2, was auto filled into the edit box on the left side above a button with Chinese text. I just clicked the button and it took me right into the storage area. Afterwards, when I went back to the site with the same PC and browser, I was taken directly to the storage area and did not have to do any kind of authentication.

However, when I tried to download from Baidu Cloud Disk, I was prompted to install an app which I declined. I then navigated to the OneDrive link which wanted me to authenticate, I backed out then went back in and there was no request to authenticate. Download from OneDrive worked fine with no prompt about installing additional software.

As I was using a microSD card for storage, I used the starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img.bz2 file, a zip file containing the actual image.

Creating a Bootable microSD Card

I used the Raspberry Pi Imager application on a Windows 10 PC to create the bootable microSD card. This is the same application that I have used for a Raspberry Pi 4 and an Orange Pi 5 Plus to create a bootable microSD card. I used 7zip to extract the image file into a folder. I inserted the microSD card into the microSD to USB adapter which came with my bundle. I assume that any other SD drive would work though you may need a microSD to SD card adapter for some types of drives.

The microSD card that came with my bundle appears to have been formatted for Windows and when I inserted the USB adapter, Windows immediately saw the new drive and it worked easily with the Raspberry Pi Imager application.

As a note, when doing the same with my Orange Pi 5 Plus using a microSD card from that bundle, Windows refused to display the drive. I used the Disk Management utility in Windows which allowed me to see the Disk device, Disk 3 in my PC, and I was able to format it after which Windows then displayed the device and I was able to use the Raspberry Pi Imager application successfully.

Booting the Device

I connected an HDMI display, keyboard, and mouse. I did not try to connect Ethernet nor WiFi on this first boot attempt. I then inserted the bootable microSD card into the drive and turned it on. I waited for something to appear on the HDMI display and after giving it several minutes, nothing appeared. I powered off the device and went back to the article I had found helpful to see if I could determine the issue.

Near the USB Type C power connector are two LEDs, one red and one green and a small power button momentary pushbutton switch next to the red LED. The red LED turned on, however nothing showed on the display. After reading the above article again, I saw mentioned that there were boot jumper switches that needed to be set appropriately.

After changing the boot switches for booting from an SD card, I powered on the device. The red LED lit followed several seconds later by the green LED starting to blink and a normal Linux boot scrolling text appeared on the display. After a minute or so, I was able to log into my VisionFive 2 for the first time.

Image 1

Here is a closeup image of the boot jumper right below the 40 pin connector in the silkscreened, white line drawn box which has two small sliding switches. In this photo, RGPIO_1 is the top jumper switch and RGPIO_0 is the bottom jumper switch. As is noted in the silkscreen to the right of the boot jumper switch, to boot from a microSD card requires that RGPIO_1 be set to 0 or L (low), switch moved to right in this photo, and RGPIO_0 be set to 1 or H (high), switch moved to left in this photo. My board out of the box had both jumper switches set to L.

Image 2

First Impressions

The desktop is unusual to me who is used to the default Ubuntu desktop and who isn't that familiar with the various Linux desktops available. There is a button at the top labeled Activities which then causes a toolbar to appear at the bottom center when it is clicked. The toolbar at the bottom allows for a couple of applications to be launched: terminal window, FireFox, VLC Media Player, and a File Manager GUI.

After the device booted successfully and I logged in, I used the terminal window application to navigate around a bit. The default user has the standard folder hierarchy with a Documents folder.

Next, I inserted the WiFi dongle that came with my bundle and the OS saw the device and I set up the WiFi credentials. The WiFi dongle of the bundle seems to only support 2.4 GHz as I did not see the 5 GHz WiFi access node also listed. I don't know if this is a hardware or a software limitation. I tried a different USB WiFi dongle later and that dongle did not seem to function properly with the VisionFive 2 so I'm using the dongle from the bundle. I don't know if the malfunctioning dongle was a driver problem or some kind of hardware incompatibility though the dongle did work with Windows PC.

Trying Out Software

After setting up WiFi, I tried the FireFox application which appears to work though it initially displays an all black window before displaying an actual page. I was able to navigate to various websites including YouTube. YouTube videos display. I had intermittent problems with a dance video however a news interview video seemed to display fine. It is a bit slow but that is probably due to a combination of microSD card for storage and the 2.4 GHz WiFi.

I then tried using the vi editor to create a simple HelloWorld C source code file and that worked allowing me to enter the C text and save it. When I tried to compile the C source file, I found that the image did not have a C compiler. I used sudo apt install gcc to install a C compiler and was able to compile my HelloWorld program and to run it.

In addition to gcc, I have also had to apt install git and make in order to setup a working environment for my Raspberry Pi repository experiments. Using git, I successfully cloned my Raspberry Pi repository on the microSD storage and was able to run make on Project01 of the repository after doing the sudo apt install make. However, there is a dependency on the WiringPi library which I will need to address since that library is missing from the VisionFive 2.

I'm leaving porting the WiringOP library to the VisionFive 2 for another day as a brief perusal of the code indicates I have some learning to do first. And it may be that changing to a different library such as libgpiod may be preferable.

I used apt-cache search {package-name} to check for a few other pieces of software that I might be interested in using. A recent version of the Apache2 Web Server was available as were recent versions of Gimp and Subversion and the Java Runtime Environment (package default-jre). Php is also available as are several database engines including MySQL and Postgres.

After working out a way to extend the file system partition to have all of the 64 GB microSD card available, I used apt install to set up a VisionFive 2 hosted web site with Apache2 web server along with PHP and Postgres. I've put together a small test web site using PHP and am about to work on a simple web accessed database application using Postgres and PHP as well.

I had a bit of a problem getting the Postgres database engine configured and working but that was due to my lack of experience and inability to find the appropriately useful documentation. Part of the problem I had was an ambitious attempt to use PEAR. After failing with PEAR, which seemed to have PHP 4/5 components mixed in with the PHP 8.1, I just apt removed it.

After spending an hour or so trying to get Postgres user roles set up and a test PHP database application failing to work, I just used apt remove to remove the various Postgres packages, used apt autoremove to clean up things a bit, rebooted the device, and then tried again to install Postgres after which the setup went much more smoothly. I have another CodeProject article documenting that experience in draft to be published soon.

Python3 is available and part of the Debian image. You do need to type python3 to start the application as just python will display -bash: python: command not found. Python3 reports it is Python 3.10.9.

You should check the list of directories on the PATH environment variable as the list may not include all directories you may need. For instance, when trying to use the resize2fs command, I discovered that the directory in which it is located along with a number of other administrative tools, /sbin, was not included in the list of PATH directories.

Storage Size Limits with MicroSD Card Image

After several days of experiments using a 64 GB microSD card, I've ran into insufficient disk space when trying to install some other, large applications after installing Gimp and a couple of small Github repositories. I was wanting to try the Apache2 web server and some other bits but have to wait for the new microSD card I have on order. The new card should be faster than the 64 GB card that came with my bundle and larger as well, a 256 GB U3 V30 card targeting game devices and 4K video recording devices.

Here's what df was reporting when I ran into insufficient disk space (the size of the partition /dev/mmcblk1p4 is what matters):

Shell
user@starfive:~$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev             1716100       0   1716100   0% /dev
tmpfs             396776    3444    393332   1% /run
/dev/mmcblk1p4   3840592 3795624     28584 100% /
tmpfs            1983868       0   1983868   0% /dev/shm
tmpfs               5120      12      5108   1% /run/lock
tmpfs             396772      88    396684   1% /run/user/1000
user@starfive:~$

Later, I looked at the df report again and I realized that the numbers did not add up to 64 GB. Shutting down the device, I removed the microSD card, and took a look at the disk using the Disk Management tool of Windows 10 Pro on my Windows PC. It showed that the disk had some 55 GB of unallocated space!

I tried using the Disk Management tool to extend the Linux filesystem partition however it would not let me do that. After a bit of reading, I decided that some experimentation and research was going to be needed to figure out how to get some of that unallocated space.

My first approach was to just use the Disk Management tool to create a new, large volume in that unallocated space. When I inserted the modified 64 GB microSD card into the VisionFive 2, it found the new space and automatically mounted it. I now had access to the additional space but I did not like that it was a separate volume.

Increasing the Disk Space Try 2

Using a different, 32 GB microSD card, I did some experiments and researched possibilities. The approach I finally used is described in this Superuser StackExchange post, Can I expand the size of a file based disk image?

I made my changes using Windows Subsystem for Linux to use the Linux commands described with the following procedure:

  • startup WSL on my Windows PC
  • copy the image file, starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img, into the WSL storage area
  • used the Linux commands described in the post, dd and parted, to increase the size of the image file by 2 GB and increase the size of the root partition by 2 GB
  • used the Raspberry Pi Imager tool to put the modified image onto the 32 GB microSD card
  • inserted the 32 GB microSD card with the modified image into the VisionFive 2 and started it up by turning on the power and pressing the start button next to the red LED on the board
  • opened up a terminal window on the device after logging in
  • used the df command to check the file size which it reported as still 3.8 GB then used the command sudo /sbin/resize2fs /dev/mmcblklp4 to resize the files space then check again with df which then reported 5.8 GB of storage

The two Linux commands used in WSL were:

Shell
dd if=/dev/zero bs=1M count=2000 >> ./starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img
parted ./starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img 

Here is a log of what I did. The first log is what I did in WSL to modify the image.

Shell
rick@DESKTOP-GFSP7AC:~/Documents$ dd if=/dev/zero bs=1M count=2000 >> ./starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img
2000+0 records in
2000+0 records out
2097152000 bytes (2.1 GB, 2.0 GiB) copied, 3.8399 s, 546 MB/s
rick@DESKTOP-GFSP7AC:~/Documents$ parted starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img
WARNING: You are not superuser.  Watch out for permissions.
GNU Parted 3.4
Using /home/rick/Documents/starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model:  (file)
Disk /home/rick/Documents/starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img: 6291MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name   Flags
 1      2097kB  4194kB  2097kB               spl
 2      4194kB  8389kB  4194kB               uboot
 3      8389kB  113MB   105MB   fat16        image  boot, esp
 4      113MB   4193MB  4080MB  ext4         root   legacy_boot

(parted) print free
Model:  (file)
Disk /home/rick/Documents/starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img: 6291MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name   Flags
        17.4kB  2097kB  2080kB  Free Space
 1      2097kB  4194kB  2097kB               spl
 2      4194kB  8389kB  4194kB               uboot
 3      8389kB  113MB   105MB   fat16        image  boot, esp
 4      113MB   4193MB  4080MB  ext4         root   legacy_boot
        4193MB  6291MB  2098MB  Free Space

(parted) resizepart 4
End?  [4193MB]? 6291
(parted) print
Model:  (file)
Disk /home/rick/Documents/starfive-jh7110-VF2_515_v3.8.2-66-SD-minimal-desktop-wayland.img: 6291MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name   Flags
 1      2097kB  4194kB  2097kB               spl
 2      4194kB  8389kB  4194kB               uboot
 3      8389kB  113MB   105MB   fat16        image  boot, esp
 4      113MB   6291MB  6178MB  ext4         root   legacy_boot

(parted) quit

Next after imaging the 32 GB microSD card with the modified image file using Raspberry Pi Imager, and using it to boot the VisionFive 2, I did the following: check the current size with df, resize the filesystem with /sbin/resize2fs, and check the result with df again. The log looks like:

Shell
user@starfive:~$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev             1716100       0   1716100   0% /dev
tmpfs             396776    3416    393360   1% /run
/dev/mmcblk1p4   3840592 3176936    647272  84% /
tmpfs            1983868       0   1983868   0% /dev/shm
tmpfs               5120      12      5108   1% /run/lock
tmpfs             396772     128    396644   1% /run/user/1000
user@starfive:~$ sudo resize2fs /dev/mmcblk1p4
[sudo] password for user:
resize2fs 1.46.6-rc1 (12-Sep-2022)
Filesystem at /dev/mmcblk1p4 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/mmcblk1p4 is now 1508240 (4k) blocks long.
user@starfive:~$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev             1716100       0   1716100   0% /dev
tmpfs             396776    3420    393356   1% /run
/dev/mmcblk1p4   5872420 3192504   2663532  55% /
tmpfs            1983868       0   1983868   0% /dev/shm
tmpfs               5120      12      5108   1% /run/lock
tmpfs             396772     128    396644   1% /run/user/1000
user@starfive:~$

After all of this tinkering, I then realized that I did not have to change the size of the image file that I used to image the microSD card. I could just directly change the disk partition using the parted and resize2fs commands in a terminal window on the VisionFive 2 because the file space was in the last partition next to the unallocated space on the disk.

Final Approach to Increasing Disk Space

The final approach I used was to change the size of the partition on the 64 GB microSD card using the tools on the VisionFive 2 itself, the /sbin/parted utility and the resize2fs utility to increase the size of the file space partition from around 3.2 GB to 63 GB, leaving a tiny amount of unallocated space to be conservative.

I've since discovered that the StarFive Git repository for VisionFive 2 has a README.md file documenting the procedure for building the Linux kernel and BusyBox then creating an SD card image. The procedure Generate SD Card Image File describes using fdisk and resize2fs to extend the /dev/mmcblk1p4 partition in a similar fashion.

However, the first step was for me to use the Windows Disk Management utility to delete the volume that I had created in the unallocated space. This resulted in providing the space that I could then extend the file space partition to the end of the disk using all the space available.

The resulting microSD card disk seems to be working fine.

The log of the procedure I used to change the partition size on the 64 GB microSD card is below. Notice that some commands require the device name, /dev/mmcblk1, and other commands require the partition name, /dev/mmcblk1p4.

Shell
user@starfive:~$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev             1716100       0   1716100   0% /dev
tmpfs             396776    3440    393336   1% /run
/dev/mmcblk1p4   3840592 3817668      6540 100% /
tmpfs            1983868       0   1983868   0% /dev/shm
tmpfs               5120      12      5108   1% /run/lock
/dev/mmcblk1p3    102156   22986     79170  23% /boot
tmpfs             396772     128    396644   1% /run/user/1000
user@starfive:~$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
mtdblock0    31:0    0  256K  0 disk 
mtdblock1    31:1    0   64K  0 disk 
mtdblock2    31:2    0    3M  0 disk 
mtdblock3    31:3    0    1M  0 disk 
mmcblk1     179:0    0 59.4G  0 disk 
├─mmcblk1p1 179:1    0    2M  0 part 
├─mmcblk1p2 179:2    0    4M  0 part 
├─mmcblk1p3 179:3    0  100M  0 part /boot
└─mmcblk1p4 179:4    0  3.8G  0 part /
user@starfive:~$ sudo /sbin/parted /dev/mmcblk1
[sudo] password for user: 
GNU Parted 3.5
Using /dev/mmcblk1
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print                                                            
Model: SD SD64G (sd/mmc)
Disk /dev/mmcblk1: 63.8GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name   Flags
 1      2097kB  4194kB  2097kB               spl
 2      4194kB  8389kB  4194kB               uboot
 3      8389kB  113MB   105MB   fat16        image  boot, esp
 4      113MB   4193MB  4080MB  ext4         root   legacy_boot

(parted) resizepart 4 63000                                               
Warning: Partition /dev/mmcblk1p4 is being used. Are you sure you want to continue?
Yes/No? y                                                                 
(parted) print                                                            
Model: SD SD64G (sd/mmc)
Disk /dev/mmcblk1: 63.8GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name   Flags
 1      2097kB  4194kB  2097kB               spl
 2      4194kB  8389kB  4194kB               uboot
 3      8389kB  113MB   105MB   fat16        image  boot, esp
 4      113MB   63.0GB  62.9GB  ext4         root   legacy_boot

(parted) quit                                                             
Information: You may need to update /etc/fstab.

user@starfive:~$ sudo resize2fs /dev/mmcblk1p4                            
resize2fs 1.46.6-rc1 (12-Sep-2022)
Filesystem at /dev/mmcblk1p4 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 8
The filesystem on /dev/mmcblk1p4 is now 15353211 (4k) blocks long.

user@starfive:~$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
udev             1716100       0   1716100   0% /dev
tmpfs             396776    3452    393324   1% /run
/dev/mmcblk1p4  60399460 3842552  56540524   7% /
tmpfs            1983868       0   1983868   0% /dev/shm
tmpfs               5120      12      5108   1% /run/lock
tmpfs             396772     136    396636   1% /run/user/1000
user@starfive:~$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
mtdblock0    31:0    0  256K  0 disk 
mtdblock1    31:1    0   64K  0 disk 
mtdblock2    31:2    0    3M  0 disk 
mtdblock3    31:3    0    1M  0 disk 
mmcblk1     179:0    0 59.4G  0 disk 
├─mmcblk1p1 179:1    0    2M  0 part 
├─mmcblk1p2 179:2    0    4M  0 part 
├─mmcblk1p3 179:3    0  100M  0 part 
└─mmcblk1p4 179:4    0 58.6G  0 part /
user@starfive:~$  

Remote Access via PuTTY

I have the PuTTY toolset installed on my Windows 10 PC. I'm able to use the PuTTY terminal application to remotely connect to my VisionFive 2 located on the dining room table from a PC in my home office or a Windows laptop from the media room couch. I'm also able to use the PSFTP tool that comes with the PuTTY package to connect to the device and navigate the file hierarchy as well as to upload and download files.

The default hostname for my VisionFive 2 with the Debian image is starfive which can be used with PuTTY or with ping to find the device's IP address. I did find that after the device had been running for a day the ability to find the device using its hostname seemed to stop working. Pinging the IP address would result in a Destination host unreachable error. I then did a Restart on the VisionFive 2 after which ping would then work and I was able to use PuTTY to connect to the device and log in.

Remote access allows me to use the familiar tools of Windows 10/11 along with large displays, a 32 inch 4K monitor in my lab and a 46 inch 4k LG TV in the media room, and fast processors with fast and larger solid state storage. The speed difference and visual quality when doing research between using FireFox on the microSD storage VisionFive 2 with a 27 inch 1k display and Chrome on an NVMe storage Intel i5 with an NVIDIA RTX3070 with a 46 inch 4k display is very dramatic. At some point, I expect to get into building the kernel and plan to use Windows Subsystem for Linux with the RISC-V cross compiler toolchain when doing so.

Using a TTY to USB Adapter with the UART

There are cases when it is necessary to access the VisionFive 2 through the UART interface rather than through the standard graphical desktop type of interface. One such case is when debugging problems with Linux booting especially should you start to build your own Linux kernel and image.

This requires a piece of equipment called a TTY to USB adapter which can convert the TTY signals from three pins on the 40 pin connector - pins 6, 8, and 10 - to a USB device connector that is plugged into a PC or laptop running a terminal emulation program.

There are various constructions and quality levels of TTY to USB adapters. The most common are composed of a cable with four wires with female connectors at one end and a large USB connector on the other end. The large USB connector has the TTY to USB converter inside along with a UBS-A male connector. If you are lucky, the TTY wires are labeled. If not, see below.

The USB-A connector is plugged into a PC or laptop running a serial terminal program that allows you to connect to the USB device. The most common program for Windows PCs seems to be the PuTTY application which can be downloaded and installed for free. For Linux PCs the most common programs appear to be minicom, screen, or gtkterm.

See this article from RVspace about setting up and using a TTY to USB adapter.

Here are a couple of hints from my experience thus far:

  • Windows can be picky about recognizing the USB converter and may refuse to set it up. Linux is much more forgiving.
  • gtkterm is much easier to use than minicom and can be installed with sudo apt install gtkterm.
  • If the TTY connector pins on the TTY to USB adapter cable are not labeled, most commonly the black wire goes to pin 6, the white wire goes to pin 8 and the green wire goes to pin 10 with the red wire, if there, unused.
  • The GPIO pins on the VisionFive 2 are 3.3v so make sure the TTY to USB converter will work with 3.3v on the TTY side.
  • The default baud rate appears to be 115200 with No parity, 8 data bits, 1 stop bit so set your terminal emulator with those settings for the connection. I use Xon/Xoff handshaking but I'm unsure if it matters at that baud rate.
  • Which USB port you plug the USB-A into on your PC will usually determine the COM port created under Windows, check Device Manager, or the /dev/ttyUSB device created on Linux, ls /dev/ttyUSB* will provide a list.

This image shows the pins and TTY end leads used to connect the TTY to USB adapter to the VisionFive 2 board. The even numbered pins are on the outside edge and the odd numbered pins are on the inside edge of the 40 pin connector. The pin 2 is on the outside bottom and above that is pin 4. Both pins are 5v so don't connect the TTY leads to those pins. The black goes on pin 6 then white on pin 8 and then green on pin 10. My cable also had a red lead which isn't used.

Image 3

A Brief Investigation into libgpiod

I found a Github repository with several examples of using the libgpiod library, https://github.com/starnight/libgpiod-example. I git cloned the repository to my VisionFive 2 to perform some investigation.

The first things I did was to obtain the libgpiod library with sudo apt install gpiod libgpiod-dev. I then took a look at the example project libgpiod-led from the repository. This example used pin number 23 in the source which I changed to 37. I then used a breadboard to put together a simple LED circuit with using a resistor and an LED with a couple of leads to connect one side to a ground pin, pin 34, on the VisionFive 2 40 pin connector and the other to pin 37.

I then ran make in the libgpiod-led folder to compile the example program successfully. When I tried to run the executable, I received an error.

Open chip failed.

:  Permission denied.

I took this to mean I needed to run it with the sudo command. I tried again with a sudo command line and the LED began blinking.

The following image shows the VisionFive 2 40 pin connector pin out. This is a screenshot from the StarFive document, that is in Chinese but does have this lovely diagram.

Image 4

Configuring Hardware Access for IoT without sudo

To implement Internet of Things (IoT) applications typically requires hardware access to board devices such as the 40 Pin Connector, using the GPIO pins, I2C, SPI, PWM, and other hardware features.

The example of using the libgpiod library to build a simple blinking LED project requires the use of sudo to run the resulting application. Otherwise, the application did not have the necessary permission to access the GPIO pins and issued an error.

Let's take a look at how other boards do it with examples coming from the Raspberry Pi.

The first thing to do is to check on what group owns the hardware interface in /dev that we are wanting to use. This is as simple as using the command ls -l /dev/gpio* to see all devices that are concerned with the GPIO pins. On the VisionFive 2, there are two such devices, /dev/gpiochip0 and /dev/gpiochip1, and both of these devices are owned by root which is why sudo is needed to run our libgpiod-led program.

Shell
user@starfive:~$ ls -l /dev/gpio*
crw------- 1 root root 254, 0 Nov  8 23:59 /dev/gpiochip0
crw------- 1 root root 254, 1 Nov  8 23:59 /dev/gpiochip1

The default is for the GPIO pins to be owned by both user root and the group root. What the above articles suggest is that there should be another group named gpio which should own these hardware bits and then any user in that group can run a GPIO using application that does not require sudo and being a member of group root. However, the VisionFive 2 version of Debian does not seem to come with such a group which you can check by seeing the list of groups using the command getent group.

The first step is to create the gpio group and to then add the user user , the default user that comes with the Debian OS image we are using, to the list of users that are members of the group. We use usermod -a -G so that we will append the specified group to the user's already existing group list rather than replacing that list with what we specify in the command.

Shell
sudo groupadd gpio
sudo usermod -a -G gpiod user

What I found is that it can take a minute or two before the group data is updated and using the groups command to list the user's existing groups may not show the added group for a few minutes.

Next, we need to create a new rule for /dev/gpiochip0 and /dev/gpiochip1 to allow access to the GPIO pins to anyone who is a member of the group gpio.

Create a new rules file using a text editor such as the old but good standby vi to create a new rules file in /etc/udev/rules.d/, sudo vi /etc/udev/rules.d/60-gpio.rules. Insert the following lines into the file.

Shell
# udev rules for gpio port access through libgpiod
SUBSYSTEM=="gpio", KERNEL=="gpiochip[0-4]", GROUP="gpio", MODE="0660"

After making these changes, I restarted the VisionFive 2 and after it came up, I logged in as user user and after navigating to the folder with the built version of libgpiod-led, I ran the program without having to use sudo.

I have not yet done any testing of the I2C interface. I don't know if there will be a similar problem with accessing that hardware or not. However, if I use the command ls -l /dev/i2*, I see the following output which implies that I will not have a problem with access.

Shell
user@starfive:~$ ls -l /dev/i2*
crw-rw-rw- 1 root root 89, 0 Nov  9 19:59 /dev/i2c-0
crw-rw-rw- 1 root root 89, 2 Nov  9 19:59 /dev/i2c-2
crw-rw-rw- 1 root root 89, 5 Nov  9 19:59 /dev/i2c-5
crw-rw-rw- 1 root root 89, 6 Nov  9 19:59 /dev/i2c-6
crw-rw-rw- 1 root root 89, 7 Nov  9 19:59 /dev/i2c-7
user@starfive:~$

Looking at I2C

The standard set of command line tools for I2C are in the i2c-tools package which must be installed with sudo apt install i2c-tools in the terminal window. However after doing so, when I attempted to use i2cdetect -l to get a list of my I2C devices, I received an error of command not found. I then used the find command to locate the install location, sudo find / -name 'i2c*', which reported the utilities had been installed in /usr/sbin. Using echo $PATH, I discovered that the location was not on my path. I tried the command again, using a full path as in /usr/sbin/i2cdetect -l and it worked giving me a list of I2C devices.

I used the vi editor to edit my .profile to add /usr/sbin to the PATH environment variable in order to not require the entire path name of the I2C tools, vi .profile. I added the following lines at the end of the file and then used the source command to check that it worked.

Shell
# set PATH so it includes /usr/sbin if it exists
if [ -d "/usr/sbin" ] ; then
    PATH="$PATH:/usr/sbin"
fi

The i2cdetect -l command displays the following output.

Shell
user@starfive:~$ i2cdetect -l
i2c-0   i2c             Synopsys DesignWare I2C adapter         I2C adapter
i2c-2   i2c             Synopsys DesignWare I2C adapter         I2C adapter
i2c-5   i2c             Synopsys DesignWare I2C adapter         I2C adapter
i2c-6   i2c             Synopsys DesignWare I2C adapter         I2C adapter
i2c-7   i2c             Inno HDMI                               I2C adapter
user@starfive:~$

Looking at PWM

I have spent a number of hours looking into using PWM. I have not yet been able to create a working example of a PWM driven LED project. I've put up a StackOverflow question, how to blink an LED using a PWM pin on Debian with C and have someone who has given me some direction. If you, the reader, has anything you can contribute to either the posted SO question or in the comments below, I would appreciate it.

There is this document, JH7110 PWM Developing Guide, which describes the PWM system. I tried to work with the functions described but was unsuccessful.

One problem that I ran into working with the PWM functionality with a C program was header files that were missing from the image. I used sudo apt install linux-libc-dev to try to install them. The install worked however these newly installed headers went into a file tree of /usr/src/linux-headers-6.0.0-6-common/ and /usr/src/linux-headers-6.0.0-6-riscv64/ and there still appear to be missing headers. I've come to the conclusion the source code described is for building Linux device drivers rather than a user space PWM program.

Something else that is strange is that I do not see any devices with "pwm" in the name in /dev. It's as if the PWM devices don't exist. The gpiochip devices are there as are I2C devices but I don't see PWM devices.

In a later section, "4.1 Sysfs Interface Example", there is an example of accessing the PWM drivers through the Sysfs interface in /sys/class/pwm/. When I attempted to use the procedure as described, it did not work displaying an error message of -bash: export: Permission denied.

Then I discovered this SO post, Permission denied with sudo, which explained the problem and the work around needed, using sudo sh -c 'echo 0 > export' rather than just echo 0 > export.

Shell
user@starfive:/sys/class/pwm/pwmchip0$ sudo sh -c 'echo 0 > export'
[sudo] password for user:
user@starfive:/sys/class/pwm/pwmchip0$ ls -l
total 0
lrwxrwxrwx 1 root root    0 Nov 13 23:41 device -> ../../../120d0000.pwm
--w------- 1 root root 4096 Nov 13 23:44 export
-r--r--r-- 1 root root 4096 Nov 13 23:41 npwm
drwxr-xr-x 2 root root    0 Nov 13 23:41 power
drwxr-xr-x 3 root root    0 Nov 13 23:44 pwm0
lrwxrwxrwx 1 root root    0 Dec 31  2000 subsystem -> ../../../../../../class/pwm
-rw-r--r-- 1 root root 4096 Dec 31  2000 uevent
--w------- 1 root root 4096 Nov 13 23:41 unexport
user@starfive:/sys/class/pwm/pwmchip0$ ls pwm0
capture  duty_cycle  enable  period  polarity  power  uevent
user@starfive:/sys/class/pwm/pwmchip0$

With the PWM device exported and usable, I was then able to drive a blinking LED using the Sysfs interface to the PWM drivers with the following settings which indicates the VisionFive 2 does have functioning PWM drivers in the Debian OS build.

Shell
user@starfive:/sys/class/pwm/pwmchip0/pwm0$ sudo sh -c 'echo 1 >enable'
[sudo] password for user:
user@starfive:/sys/class/pwm/pwmchip0/pwm0$ sudo sh -c 'echo 1000000000 >period'
user@starfive:/sys/class/pwm/pwmchip0/pwm0$ sudo sh -c 'echo 50000000 >duty_cycle'
user@starfive:/sys/class/pwm/pwmchip0/pwm0$ sudo sh -c 'echo 0 >enable'

Looking at some user space libraries such as the WiringPi library, there seems to be some kind of userspace access to device memory. See this article, The Userspace I/O HOWTO for details about userspace drivers.

A Brief Comparison with Orange Pi 5 Plus

My experience with the Orange Pi 5 Plus was significantly easier than with the VisionFive 2. I initially used a microSD card with the Orange Pi using the Raspberry Pi Imager to put Ubuntu, one of several operating system alternatives, onto the bootable microSD card. The Orange PI had all the necessary tools for building Project01 from my Raspberry Pi repository including a version of the WiringPi library, WiringOP which I assume means Wiring Orange Pi. I have looked for version of the WiringPi library for RISC-V and have not been able to find one.

I installed Ubuntu on an NVMe drive and have been impressed with the speed difference between using the Orange Pi with the new drive versus using the Pi with a microSD card. To create the bootable NVMe drive for the Orange Pi 5 Plus, I inserted the drive into a NVMe to USB adapter and then used the Raspberry Pi Imager to put the Ubuntu image to that drive. I assume something similar would work with the VisionFive 2 however I'm reading in posts on the internet that the microSD card approach is more stable.

Cross Compile RISC-V on x86 Linux

After seeing an article about cross compiling, the Linux kernel for the VisionFive 2, I decided to look into being able to do so with Windows Subsystem for Linux using the default Ubuntu distro under Windows 10 Pro.

The first step was to turn on Windows Subsystem for Linux using the command wsl --install in the command line terminal application. This required a restart in order for the wsl terminal window to be available. After restarting, a command line terminal window with Ubuntu Linux appeared.

I first tried using the apt command line mentioned below in Points of Interest for setting up the cross compile environment for cross compiling the Linux kernel for RISC-V. I received an error message that package gcc-riscv64-linux-gnu was not available. I then double checked with the command apt-cache search --names-only 'riscv64' to see a list of all RISC-V related packages and only a couple showed up.

That seemed strange so then I realized that I may need to update the cache first to retrieve an updated list of packages especially since this was the first use of WSL after doing the install. I used the sudo apt update command to update the cache and then tried the search command again and this time a lot of packages displayed.

I then retried the apt command to install the cross compile packages and it finished successfully.

Next, I created a Documents folder and in that created a risc-v folder. I then wrote a simple HelloWorld.c source file and compiled it with the command riscv64-linux-gnu-gcc helloworld.c which produced an output file of a.out.

I then inserted a USB thumb drive that had some room on it. Using the technique with the Windows File Manager described in this Stackoverflow post, I navigated to the directory containing the file by changing the file path to \\wsl.localhost\Ubuntu\home\rick\Documents\risc-v and then dragging the a.out file from the WSL folder to the thumb drive. What I found during this procedure was that I could enter a network name of \\wsl$ in the directory path of File Explorer and it would show the Ubuntu virtual machine.

I then ejected the drive from Windows, pulled the drive, and carried it to the VisionFive 2 and plugged it into a USB port. I opened up the File Manager application which showed the USB drive and did a copy and paste of the a.out file to the VisionFive 2. Next I used chmod +x a.out to make it executable and then ran it successfully.

One of my expectations was that I would be able to build my own Linux kernel. I have worked with the StarFive Git repository to do a build of the Linux Kernel source they have. I have run into a number of missing software components I needed to install into my WLS Ubuntu VM however I have finally been able to build a new Linux kernel and am now working on a problem with building and booting the SD card image. I have an additional article I'm working on documenting what I have run into and how I addressed it. A TTY to USB adapter with a Windows or Linux device that can act as a terminal has been essential for this work.

Helpful Websites

Points of Interest

The VisionFive 2 seems to be on the bleeding edge for an SBC. This means that if you buy one, you must be prepared for a few problems here and there. GPU support appears to be one of those areas which affects FireFox and other graphical interfaces.

The desktop and the applications available in the Debian image are a bit sparse. A number of tools that I expected such as a C compiler and make were missing and had to be installed. Do not expect the same variety of software as for an x86 or ARM Ubuntu distro.

Looking about, it appears that a number of vendors are supporting Linux on RISC-V processors with their software. There also appear to be cross compile tool chains that run on x86 Linux and target RISC-V processors. This Linux kernel source repository, mentions the following apt command to set up the cross-compile toolchain for building the Linux kernel under Debian/Ubuntu.

Shell
sudo apt-get install libncurses-dev libssl-dev bc flex bison make gcc gcc-riscv64-linux-gnu

I did try doing a cross compile using Windows Subsystem for Linux, Ubuntu, on a Windows 10 x86 PC and was able to install the RISC-V cross compile tools and build a simple HelloWorld program on the VisionFive 2.

I can't find a VisionFive 2 version of the WiringPi library which means that I will either have to port WiringPi to the VisionFive 2 or use the standard libgpiod library and modify the projects in my Raspberry Pi repository.

I'm having problems with using the PWM functionality. I'm not sure what I'm missing or not understanding so that is still a work in progress. The PWM devices that I expect to see in /dev aren't there. I was able to install the tools for I2C however I have not yet tried to implement the Raspberry Pi I2C project that I built on the VisionFive 2. I've gotten a bit distracted with other tasks.

I'm curious if other WiFi USB dongles are supported and whether I can switch out the dongle that came with the bundle I purchased for a WiFi USB dongle that supports both 2.4 GHz and 5 GHz. I did try a quick test with a dongle from Tenda that I had lying around and it did not seem to work.

After several days of experiments using a 64 GB microSD card, I ran into insufficient disk space when trying to install additional applications. After some thinking and some research, I realized that the problem was due to the small size of the image and the size of the partition created on the microSD card when I imaged it. After a number of experiments and false starts, I developed a simple procedure using the parted and resize2fs utilities on the VisionFive 2 to add what amounted to some 55 GB of unallocated space into my original 3.2 GB partition with the user file space.

There are a number of useful applications available for the VisionFive 2. I've tried a simple test with Gimp after installing it and now that I have the insufficient file space issue addressed, I plan to look at a number of others such as LibreOffice, the Apache2 web server, Subversion, and others.

I have installed Apache2 along with Php and the PostgreSQL database engine. The web server appears to be working fine and I have a simple Php generated web page that pulls data from a PostgreSQL database and displays it. I'm working on another article to describe that effort.

I'm also looking forward to learning the basics of Linux device drivers and doing my first successful Linux build on x86 Ubuntu with WSL using the cross compiler tools. When I first tried to build the Linux kernel using the source code and components from the StarFive Git repository, the build failed due to an incorrect SHA checksum on the Third Party GPU drivers. I've found on RVspace forums there are other people having a similar problem.

Upon further investigation, I found that the Git Large File System that I thought I had installed was not yet installed. Once I completed that step, the GPU driver blobs were downloaded properly during cloning of the repository to my WSL Ubuntu PC and the SHA checksum problem disappeared. I have been able to successfully build the Linux kernel but am running into problems generating the SD card image. There appears to be a problem with building BusyBox which may have to do with my using WSL. I'm working on another article to describe that effort.

History

  • 9th November, 2023: Initial version
  • 10th November, 2023: Added section titled "Configuring Hardware Access for IoT without sudo"
  • 13th November, 2023: Added several new sections (1) working environment and tools, (2) overcoming a file space limitation due to the StarFive Linux image size, (3) explorations into PWM and I2C which have been somewhat fruitless
  • 17th November, 2023: Edited and improved the PWM section with new findings and added to the software section discussing briefly Apache2 with PHP and Postgres installed with a functioning though limited web site on the VisionFive 2 as well my initial failed attempts at building a Linux kernel from the StarFive Git repository
  • 21st November, 2023: Added section about TTY to USB adapter, added mention of RVspace forum and wiki, added table of contents

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)