Close
0%
0%

A RISCy move

Moving development to the RISC-V series of MCUs

Similar projects worth following
After the 8042/8, 8051, STM8, AVR families what next? And why I am getting Rusty.

Time to progress with my exploration of microcontroller platforms. I'll be focusing on the RISC-V 32 MCUs which are now commodity chips, in particular the WCH 32V series. To be sure, I've already made initial forays in this area.

Instead of writing a long detail document, I'll spin off digressions into logs instead of boring everybody to tears with constant updates where it's hard to discern what has been updated.

First off, a history of the MCU families that I've delved into.

Next, an exploration of candidate MCU families.

A brief survey of the toolchain scene.

The WCH 32V series of MCUs

Now we get to the actual hardware that I've decided to develop for. The CH32V003 family is one of the offerings of the Nanjing Qingheng Microelectronics company. These MCU ICs got the attention of developers and hobbyists for their low price. This family of 20 pin and below MCUs aims to capture some of the base functionality MCU market, which coincidentally or not, have 003 somewhere in the model name, e.g. STM8F003, STM32F003. Higher members of the CH32V family offer more peripherals and more pins.

If you go shopping in the usual bazaars, this is a module you will commonly see:

Another variant has a TSSOP-20 package instead of the QFP-20 package in the middle. Notice the 3 pins to the programming dongle.

I've decided to go for the module shown in the topmost picture, one of the BTE series made by a different factory. It doesn't have the USB-C connector but has an onboard 24 MHz crystal which could come in handy for more precise timing.

I've decided to not attempt to design around the bare MCU but use the BTE module as a component. They pack more on the module than I could with my SMD soldering skills and sell it cheaper than I could buy the components for. You can see how small it is, about the size of a 20 pin 0.6 inch DIP IC. A price of tens of cents for the bare MCU is tempting, but so is the price of only a dollar or two, quantity 10 shipping included, for the module. Tested working too. The drawback is that these module will raise the height of the entire assembly if pulgged into Dupont pin sockets, unless I'm willing to solder them more or less permanently onto the base PCB.

RISC-V IDE and compiler toolchains

The toolchain suggested by the manufacturer is MounRiver Studio. There are secondary sites, as the original site isn't the fastest. Arduino also supports the WCH chips now, but of course with their HAL. The actual compiler tools are available separately if you want to develop from the CLI and use automated build tools, a prebuilt one being the xPack tools. And of course you can also build the compiler tools from the gcc sources, but you need to know which compiler flags to use for the ISA of the WCH chips. Things move quickly in this world, so check that the information you have is current. For example for a long time MounRiver Studio was at 1.92, but now I see that 2.40 has been out for a few months, and it seems it's not based on Eclipse any more but on the VSCode editor.

Rust HAL and libraries

One option I didn't mention in the toolchain survey is the programming language Rust. Writing in C or C++ has got boring so I want to challenge myself with something new. Rust will generate larger binaries than C due to the layers of abstraction so it's just as well that my intended MCU target the WCH32V003 has 16kB flash memory. So I wrote a log entry about installing a Rust toolchain. I'll start with a text editor and the CLI interface and think about IDEs later.

Next thing is to write a simple Rust program, maybe blinky. As explained in the log, versions for several MCU targets can be generated with a single toolchain.

(To be continued.)

  • Installing a Rust toolchain

    Ken Yap6 days ago 0 comments

    This log will be amended as I fill in details that I may have missed.

    Your OS may have Rust available in their package repositories. But due to the rapid pace of development it's best to install a Rust toolchain outside of the package system. Rust developers have streamlined this task.

    You need two important programs: rustup which is a toolchain installer (and maintainer), and cargo, installed by rustup, which is a project manager. The other programs like rustc, the compiler, will be installed by rustup.

    Before you install rustup, you need to decide if you accept the standard location for the software, in the case of Linux, under your home directory in ~/.cargo, as explained here. If like me, you dislike lots of package files under home (unfortunately this is the norm these days with Arduino, PlatformIO, etc. etc.), you can change the directories. There are two environment variables, and I've set them thus:

    export RUSTUP_HOME=/usr/local/lib/rustup CARGO_HOME=/usr/local/lib/cargo
    

    If you choose to change them, edif your ~/.bash_profile to export these environment variables. Also put this command in ~/.bash_profile after so that the correct executables are found.

    . "$CARGO_HOME/env"

    Logout and login again if necessary to ensure that these settings are in place before you install rustup following the instructions at the website.

    The help text for rustup indicates what it does:

    $ rustup --help
    rustup 1.29.0 (28d1352db 2026-03-05)
    
    The Rust toolchain installer
    
    Usage: rustup[EXE] [OPTIONS] [+toolchain] [COMMAND]
    
    Commands:
      install      Install or update the given toolchains, or by default the active toolchain
      uninstall    Uninstall the given toolchains
      toolchain    Install, uninstall, or list toolchains
      default      Set the default toolchain
      show         Show the active and installed toolchains or profiles
      update       Update Rust toolchains and rustup
      check        Check for updates to Rust toolchains and rustup
      target       Modify a toolchain's supported targets
      component    Modify a toolchain's installed components
      override     Modify toolchain overrides for directories
      run          Run a command with an environment configured for a given toolchain
      which        Display which binary will be run for a given command
      doc          Open the documentation for the current toolchain
      man          View the man page for a given command
      self         Modify the rustup installation
      set          Alter rustup settings
      completions  Generate tab-completion scripts for your shell
      help         Print this message or the help of the given subcommand(s)
    
    Arguments:
      [+toolchain]  Release channel (e.g. +stable) or custom toolchain to set override
    
    Options:
      -v, --verbose  Set log level to 'DEBUG' if 'RUSTUP_LOG' is unset
      -q, --quiet    Disable progress output, set log level to 'WARN' if 'RUSTUP_LOG' is unset
      -h, --help     Print help
      -V, --version  Print version
    
    Discussion:
      Rustup installs The Rust Programming Language from the official
      release channels, enabling you to easily switch between stable,
      beta, and nightly compilers and keep them updated. It makes
      cross-compiling simpler with binary builds of the standard library
      for common platforms.
    
      If you are new to Rust consider running `rustup doc --book` to
      learn Rust.
    
    Common commands:
    
      Update Rust toolchains and rustup
    
        $ rustup update
        
      Install the current stable release of Rust for your host platform
    
        $ rustup toolchain install stable
    

    Toolchain means a release channel, e.g. default, nightly. If you are thinking about MCU targets, then the term is target.

    Here's a relevant fact: gcc requires a different toolchain for each MCU family. That's why the toolchain for the classic Arduino starts with avr-, that for the STM32 starts with arm-, and for the WCH32V series riscv-. LLVM however uses the same compiler for all targets, and you can install a new target without installing another compiler. Here are the targets I have installed:

    $ rustup target list | grep installed
    riscv32i-unknown-none-elf (installed)
    thumbv6m-none-eabi (installed)
    x86_64-unknown-linux-gnu (installed)...
    Read more »

  • Toolchains

    Ken Yap06/17/2026 at 02:34 0 comments

    Microcontrollers need firmware and toolchains used to develop them. This is an overview and will undergo revision as I will no doubt overlook some concepts at the time of writing.

    Assemblers

    Unless you have one of those educational kits where you toggle switches (or the equivalent thereof) to program the hardware, it's assumed the basic requirement is an assembler which will take assembly code and turn it into bits to be loaded into the MCU.

    This is the case for the 8048/8042 MCUs I have mentioned. The toolchain is the ASxxxx cross assembler and linker. The MCU is too weak to support a HLL like C. Wikipedia claims that a PL/M compiler existed for the 8048 but I am dubious because the architecture is severely limited.

    Compilers

    I consider the basic requirement for a MCU toolchain to be a C compiler toolchain. This true of all the MCUs I have used from the 8051 onwards, although early PIC models had very restrictive architectures like for example a two-level stack which forces one to flatten out function calls.

    CLI Development Environments

    The first step up from a compiler is something to automate the repeated steps of a embedded app edit and build. You could do it with scripts, but I started off with a text editor and a Makefile which is very familiar from the desktop Linux environment..

    This can be elaborated with any number of improved build tools like CMake, meson + ninja, etc.

    It's worthwhile retaining CLI build facilities even if one is using an IDE, to have a reproducible means of creating production artifacts.

    Integrated Development Environments

    A great boon of a GUI IDE is multiple views. In one window you could be editing source code, another could be a command window, and of course you could have output and debugging windows. When editing, the IDE can help the programmer by suggesting completions for library calls, sparing having to look up the programming manual.

    Many of IDEs are front-ends to traditional CLI programs, simply because that's how the tools are invoked. For example, when you use the Arduino IDE, possibly the best known, you can see the compile commands launched in response to firing off a build. Some IDEs like the Microchip MPLAB X even generate Makefiles to control the build process.

    IDEs can be specific to a platform, e.g. Window, or could be cross-platform. The preference these days is for cross-platform IDEs to capture a large audience. Traditionally cross-platform IDEs relied technology like Java e.g. in the form of the Eclipse platform. Many IDEs, for example Moun River are based on this. But these days cross-platform GUI toolkits are not a big deal, so an IDE like Arduino has support for the main OSes. Java GUIs these days look square and quaint.

    IDEs can also be multi-target. Arduino started off supporting the AVR MCUs, but these days the Espressif, ARM, and RISC-V MCUs are transparently supported. The compiler toolchains moved from the Arduino application package to optional library packages.

    But one great aid that IDEs provide is configuration for multiple models of MCUs. Unlike desktop CPUs where generations of processors can be accomodated in the kernel and runtime libraries, and it's all hidden from you, a Linux app works the same whether you are using a 10 year-old processor, or this year's, MCUs come in a huge variety of models targeted for various fields, e.g. consumer, automotive, instrumentation, with differences in peripherals. It's expensive and unnecessary to make embedded programs work on many models, so builds are configured for just the intended target. You can see this in the Arduino IDE where you have to select the board you are working with.

    This customisation is extensive in IDEs like the ARM CubeMX IDE for STMicro's line of STM32 processors. A separate GUI program takes you through the selection of the company's MCU models and generates a configuration file which is used to influence build configuration.

    Another dimension of IDEs is...

    Read more »

  • Which 32-bit MCU family should I pick?

    Ken Yap05/27/2026 at 14:55 2 comments

    My early attempt at a 32-bit CPU. No, just kidding.

    Having decided to move on from the MCUs I am using, now that 32-bit MCUs are cheap commodities what are the candidates?

    Before that, one advantage is clear: going to 32-bit gets decent HLL support. You can have a gcc/g++ toolchain, or one based on the up and coming rival, LLVM. You can also have other languages like Rust.

    ARM

    ARM is everywhere. A lot of hobbyists got introduced to ARM via Raspberry Pi. But the range extends from small MCU boards like the STM32 Blue Pill, to smartphones and tablets, to desktops, and to 64-bit servers in the datacentres. The PlasticARM project put a minimal Cortex-M0 on a flexible substrate, providing more areas for IoT to colonise.

    ARM will be around for a long time. It should be noted here that the core architecture is licensed but the MCU chip manufacturer has absorbed that cost for you.

    In practical terms, I could develop with the STM32 family or the RP series. I probably will for high performance uses.

    RISC-V

    RISC-V is an open architecture, there is no licensing to deploy it, so it has become attractive to chip makers as an alternative to ARM. I have a GigaDevice 32V dev board, but it's really the WCH series of 32V chips that are challenging the low-end uses of ARM. This makes them attractive to me.

    Xtensa

    Xtensa is the MCU architecture that Espressif Systems used in their popular series of WiFi and Bluetooth capable modules, such as the ESP8266 and ESP32. It's very popular due to the wireless capabilities, just look at the number of projects on Hackaday. I have several Espressif modules that badly need a few round tuits from me, so I will also develop with these.

    But here's the rub: Espressif is shifting their product lines to RISC-V cores. The Xtensa based MCUs will be around for a while, if only because there's so much stock around.

    Also the RP2350 has an interesting design: two ARM cores and two RISC-V cores, the first use of RISC-V in the RP series.

    Which will it be?

    Actually, with a good toolchain, I don't have to stick exclusively to one family. I'll just let the project, the available MCUs, and my wallet provide the decision parameters. More about toolchains in another log.

  • My personal history with MCUs

    Ken Yap05/25/2026 at 11:26 0 comments

    This project #Restoring a Beckman neon display clock is what got me started on MCUs several years ago. It contained an 8048 family MCU and I wrote code to replace the original firmware. I managed to live within the limitations of assembly language, 1kB code space, 64B RAM, and 13 I/O pins, several lost to using external ROM. Definitely no high level language.

    As it turned out I had quite a few of the 8048 family, and the related 8041/2 family chips in my junk box. I think the '48s came from full height 5¼ inch floppy drives, and the '42s came from PC keyboard controllers. I put them to use in projects like #8042 clock #8042 metronome and 8048 clock. No that last link is not a mistake, the instruction set is almost the same for the '48 and the '42 so the code is usable for both.

    Well that was a good way to use up those chips. I have to say there are quite hardy and resisted many accidents. But boy were they power hogs.

    As we know Intel came out with the 8051, the successor to the 8048. The breakthrough improvement was putting peripherals in the I/O address space rather than having specific instructions for each I/O port. The '51 has gone on to be probably the most durable MCU family and descendants live on as programmable cores for many chips.

    It actually is a fairly decent MCU to learn on. The hardware and instruction set are easy to understand and there is even C language support in the form of the GPL Small Device C Compiler (SDCC) and commercial offerings. Descendants have increased the clock rate to be tens of times faster than the original. Some are one-chip wonders only needing a handful of passives for a working system like this. The one above is a STC89C52 workalike for the 8052 with flash ROM for code, but otherwise a drop-in equivalent, used in #89C52 clock board. I used this dev board with them: #Adventures with a STC89C52 development board. Other projects using a '51 include #Ancient 12 hour display and #Modularnixie.

    But ultimately, it's an 8-bit MCU with all the attendant limitations. (Some expanded architectures like the '251 were developed.) So I used up the handful of MCUs and dev boards I bought and bade them farewell.

    Next cab off the rank was the STM8 which I got interested in thanks to #eForth for cheap STM8S gadgets. They appear in the millions if not billions in small gadgets. You probably have a few around the house. (An interesting development was that 8051 derivatives started to muscle in on the STM8 based gadgets by coming out with pin (but not architecture) compatible models, presumably because the '51 core architecture was free to reimplement.) Modules are readily available from AliExpress and the per MCU price was between 10 and 20¢, although it was a while before my SMD soldering skills were up to doing TSSOP-20.

    This has a decent architecture and is also well supported by SDCC. It has a good selection of on-chip peripherals including standards like I2C which wasn't in the '51 descendants until well into its reign. The GPIO pins can do true bidirectional and true push-pull in addition to other modes like hi-Z and open drain, unlike the 8051's weak pullup. The HAL takes a bit of getting used to but it is worth it.

    I liked this MCU and used it in #Repurposing an old nixie thermometer, #Third life for a radio alarm clock, and the driver for #Vertical LED digit display boards. I still have a few chips but won't be starting any new projects with them.

    The AVR family is represented by the Arduino models I have. Strangely I haven't done any projects with them because I think of them as test equipment which I used frequently, as a driver in the above photo. One drawback is that they have 5 V GPIO which means I have to turn to the ESP32 Arduino lookalikes that work with 3.3 V logic.

    I did have a couple of early DIP AVR chips for which I managed to nut out the details of to use in this project, and this project. The architecture is decent, it manages to get gcc support...

    Read more »

View all 4 project logs

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates