Quick Peek of PineCone BL602 RISC-V Evaluation Board

PineCone BL602 RISC-V Evaluation Board

đź“ť 29 Nov 2020

(UPDATE: PineCone is now available for purchase)

Pine64 is graciously giving away the PineCone BL602 RISC-V Evaluation Board to folks participating in the PineCone Nutcracker Challenge.

Let’s learn about the PineCone Board… And how it helps the RISC-V Open Source Ecosystem.

1 PineCone BL602: Why does it matter?

PineCone is based on the BL602 combo chipset made by Nanjing-based Bouffalo Lab…

  1. Low Cost: BL602 is a General Purpose 32-bit Microcontroller. (Think STM32 Blue Pill, Nordic nRF52)

    But BL602 supports Bluetooth LE AND 2.4 GHz WiFi… At the low low price of an ESP8266.

    That’s a game changer!

    BL602 as a drop-in replacement for ESP8266

  2. Power Efficient: BL602 is perfect for wearables and other power-constrained devices. (Maybe even PineTime!)

    By performance, BL602 belongs to the same class of microcontrollers as Nordic nRF52832. BL602 won’t run Linux, but neither does PineTime.

  3. CPU is based on RISC-V, not Arm: Yep this scares most people, because BL602 will NOT run code compiled for Arm processors. Instead we need to use the 32-bit RISC-V version of the GCC compiler to recompile our programs.

    FreeRTOS + AliOS has been ported to BL602. (More details) But other Real Time Operating Systems (like Zephyr, RIOT and Mynewt) have been slow to adopt RISC-V. (We’ll learn why in a while)

    Rust runs perfectly fine on RISC-V microcontrollers. (Here’s the proof)

    UPDATE: Check out Zephyr for BL602

It’s great that Pine64 is reaching out to the Open Source Community through the PineCone Nutcracker initiative… Because it takes A Humongous Village to get BL602 ready for real-world gadgets.

1.1 BL602 vs ESP32

How does BL602 compare with ESP32?

To folks who are familiar with Arm microcontrollers (STM32 Blue Pill, Nordic nRF52), BL602 looks like another microcontroller… Except that it runs on the RISC-V Instruction Set instead of Arm.

Hope this addresses the confusion over BL602, as discussed here and here

(There’s a new ESP32 based on RISC-V, but the hardware is not available yet so we’ll wait and see. Compare BL602 with ESP32-C3)

1.2 RISC-V vs Arm

Why not stick with Arm? Why get adventurous with RISC-V?

Nintendo Switch (the #1 gaming console) runs on Arm. iPhone and the new M1 Macs also run on Arm. Most of our gadgets are powered by Arm today.

Before Arm gets too successful and locks us in… Shouldn’t we explore alternatives like RISC-V?

2 The Thing About RISC-V and PineCone BL602

32-bit RISC-V microcontrollers all run on the same core instruction set.

So the same firmware should run on different brands of RISC-V microcontrollers… Right?

Nope! Because across different brands of RISC-V microcontrollers…

  1. Peripherals and Input/Output Ports are implemented differently: Timer, GPIO, UART, I2C, SPI, …

  2. Exceptions and Interrupts also work differently on various RISC-V microcontrollers.

    (FYI: Arm microcontrollers all handle Exceptions and Interrupts the same way)

It’s not so straightforward to port existing RISC-V firmware to BL602.

2.1 BL602 vs Other RISC-V Microcontrollers

How bad is the RISC-V firmware portability problem?

Let’s compare BL602 with the two most popular models of 32-bit RISC-V microcontrollers…

  1. SiFive FE310 (Released 2017)

  2. GigaDevice GD32 VF103 (Released 2019)

  3. BL602 (Released 2020)

    UPDATE: Check out Zephyr for BL602

    UPDATE: Check out Apache NuttX operating system for BL602

As we can see, firmware support is not so great for newer RISC-V microcontrollers.

Firmware created for Pinecil will NOT run on PineCone… Even the simplest firmware for blinking the LED!

2.2 Hardware Abstraction Layer

How do we create portable firmware for RISC-V?

We’ll have to isolate the differences with a layer of low-level firmware code known as the Hardware Abstraction Layer (HAL).

So when we port the firmware from, say, Pinecil to PineCone, we need to replace the HAL for GD32 VF103 by the HAL for BL602.

Check out the BL602 HAL

2.3 Embedded Operating Systems

Sounds like a lot of tedious repetitive work. Is there a sustainable way to create portable firmware for RISC-V?

Yes, by adopting a modern Embedded Operating System like Mynewt, RIOT and Zephyr.

These operating systems expose a high-level API for various Peripherals (Timers, GPIO, I2C, SPI, …) that works across multiple microcontrollers (for both Arm and RISC-V).

But first we need to port Mynewt, RIOT and Zephyr to BL602.

The PineCone Nutcracker initiative helps to accelerate the porting process. We’ll pool together the necessary skills and software from the Open Source Community, to make this work.

UPDATE: Check out Zephyr for BL602

Is there hope for Mynewt / RIOT / Zephyr on BL602?

I shall be porting Mynewt + Rust to BL602, and documenting the porting process.

Why? Because it’s an educational exercise that helps us better understand the BL602 internals.

And it will be a helpful reference for porting other Embedded Operating Systems to BL602.

Let’s talk about the harder PineCone Nutcracker Challenge: Reverse engineering the Bluetooth LE and WiFi drivers for BL602…

BL602 Memory Map vs SiFive FE310: Totally different

BL602 Memory Map (left) vs SiFive FE310 (right): Totally different

3 Reverse Engineer the Bluetooth LE and WiFi Drivers

(This section gets deeply technical about Reverse Enginnering… You may skip to the next section if you’re not working on Bluetooth LE and WiFi)

BL602 feels exciting. The mass market RISC-V microcontrollers never had onboard Bluetooth LE and WiFi… Until now!

Unfortunately we don’t have complete documentation about the implementation of BLE and WiFi on BL602. (And I totally understand if there are commercial reasons for this omission)

But we have the compiled RISC-V libraries that we may Reverse Engineer to understand the BLE and WiFi implementation.

That’s the crux of the PineCone Nutcracker Challenge… Decompile the Bluetooth LE and WiFi driver code, understand how the RISC-V code operates the wireless hardware.

Then reimplement the wireless functions the open source way. Perhaps by adapting the wireless drivers from Mynewt (NimBLE), RIOT and Zephyr.

Let’s walk through one possible approach for Reverse Engineering the WiFi Driver. (I’m sure there are many other ways to do this, like this)

UPDATE: Check out this article on the Reverse Engineering of BL602 WiFi…

3.1 How does our WiFi Driver talk to the WiFi Controller?

From the BL602 Reference Manual (Page 17), we see that our RISC-V CPU talks to the WiFi Controller via the WRAM Wireless RAM at address 0x4203 0000 onwards.

PineCone BL602 Wireless RAM

Our WiFi Driver probably reads and writes WiFi packets to/from that 112 KB chunk of Shared Memory. The WiFi Control Registers may be inside too.

Let’s find out which WiFi Driver functions use that chunk of RAM.

3.2 Analyse the Linker Map

The WiFi Drivers that we wish to grok are located here…

…Inside the files libatcmd.a and libbl602_wifi.a

Here is a sample BL602 app that calls the WiFi Functions in libatcmd.a and libbl602_wifi.a…

The PineCone Community has helpfully generated the GCC Linker Map for the bl602_demo_at firmware (which includes libatcmd.a and libbl602_wifi.a)…

I have loaded the bl602_demo_at.map Linker Map into a Google Sheet for analysis…

  1. Click here to open the Google Sheet: PineCone BL602 AT Demo Linker Map

  2. Click the Symbols Sheet

  3. Click Data âžś Filter Views âžś None

  4. Click Data âžś Filter Views âžś All Objects By Size

  5. It takes a while to sort the objects… Be patient

PineCone BL602 AT Demo Linker Map

Here we see the list of functions, global variables and static variables defined in bl602_demo_at.map, sorted by size.

Let’s look at the first page of functions and variables.

(FYI: The Linker Maps loaded into Google Sheet for bl602_demo_wifi and sdk_app_ble_sync are here: Google Sheet for bl602_demo_wifi, Google Sheet for sdk_app_ble_sync)

3.3 Find the WiFi Buffers

Remember that Wireless RAM starts at address 0x4203 0000? I have highlighted in yellow the 19 largest variables in Wireless RAM…


(The addresses of the variables are shown in the Offset column)

These are likely the WiFi Buffers that our WiFi Driver uses to send and receive WiFi packets, also to control the WiFi operation.

3.4 Identify the WiFi Functions

rx_dma_hdrdesc looks interesting. It could be the DMA buffer for receiving WiFi packets. Let’s find out which WiFi Function in the WiFi Driver uses rx_dma_hdrdesc…

We’ll scan for rx_dma_hdrdesc (and other interesting variables) in the Decompiled RISC-V Assembly Code (*.s) that the PineCone Community has generated…

Hopefully we’ll be able to understand the Assembly Code and figure out how the WiFi Buffers are used to send and receive WiFi packets.

3.5 Is there a Blob for the WiFi Controller?

What’s really inside the WiFi Controller?

Could there be some low-level chunk of executable code (non RISC-V) that runs inside the WiFi Controller to control the WiFi operations?

By studying the WiFi Buffers and the associated WiFi Functions, we may uncover the Code Blob that runs inside the WiFi Controller.

UPDATE: Check out this article on the Reverse Engineering of BL602 WiFi…

PineCone BL602 Evaluation Board

4 Hands On with PineCone BL602

The BL602 docs are located in the BL602 Docs Repo…

BL602’s RISC-V Core seems to be based on either SiFive E21 or SiFive E24 (to be confirmed, though the SDK source code suggests E21 here and here)…

More docs and tools for PineCone BL602 may be found here…

Which dev boards are supported by the BL602 IoT SDK?

Firmware built with the BL602 IoT SDK will work fine on…

  1. Pine64 PineCone

  2. Pine64 Pinenut

  3. DOIT DT-BL10

  4. MagicHome BL602 WiFi LED Controller

  5. Sipeed BL602 EVB

The programs published on this site (in the “PineCone” series of articles) will run on any of these boards.

Just note that the boards have different jumpers, buttons and LEDs.

4.1 Form Factor

The PineCone BL602 Evaluation Board has a similar form factor to other wireless dev boards, like EBYTE E73-TBB (which is based on nRF52832)

The PineCone board comes with a USB-C Connector. When connected to our computer via USB, the BL602 board is recognised as a Serial Device, ready to be flashed.

(PineCone’s USB Vendor ID is 0x1A86, Product ID is 0x7523)

Watch on YouTube

Flashing PineCone with Dev Cube

Flashing PineCone with Dev Cube

4.2 Flashing Firmware

We flash RISC-V firmware to the PineCone board through the USB Serial Connection using the Dev Cube Tool…

  1. Set the PineCone Jumper to the H Position (Like this)

    Connect PineCone to our computer’s USB port

  2. Download the PineCone Sample Firmware images from GitHub Actions. See the next section “Building Firmware”

    Unzip the files in customer_app.zip

    Or download this Hello World sample firmware: sdk_app_helloworld.bin

  3. Download the PineCone SDK bl_iot_sdk…

    git clone --recursive https://github.com/pine64/bl_iot_sdk
  4. Launch Dev Cube for Windows, located in the PineCone SDK at bl_iot_sdk/tools/flash_tool/BLDevCube.exe

  5. Select Chip Type BL602/604, click Finish

    We should see Simple Flasher. If not, click View âžś IoT

  6. Set the following…

  7. Click Create & Program

    This flashes the firmware to PineCone. We should see…

    Verify success
    Program Finished

    See the screenshot

  8. Disconnect PineCone from the USB port.

    Set the PineCone Jumper to the L Position (Like this)

    Reconnect PineCone to the USB port.

  9. Click Open UART

    Press the RST button on PineCone (Look here)

    Our firmware starts to run. We should see…

    [helloworld]   start
    [helloworld]   helloworld
    [helloworld]   end

    See the screenshot

In case of problems, check the instructions in…

4.2.1 Other Flashing Tools

Are there command-line tools for flashing firmware to PineCone on Linux, macOS and Windows?

Check out the article…

Is JTAG supported for flashing firmware to the PineCone Board?

JTAG works for loading firmware into PineCone’s Cache Memory (similar to RAM). But not to PineCone’s Internal Flash ROM (XIP Flash).

So we must flash firmware to PineCone over UART.

Are SWD and ST-Link supported for flashing firmware to the PineCone board?

Sorry no. SWD is available only on Arm Microcontrollers. (SWD was created by Arm)

The UART flashing protocol for PineCone is described in the BL602 Flash Programming doc.

(The BL602 Flash Programming doc seems to suggest that BL602 may also be flashed from an SD Card via Secure Digital Input/Output)

4.3 Building Firmware

We may use Linux, Windows or macOS to build the BL602 firmware…

On Windows, MSYS2 is required. Alternatively, we may use Windows Subsystem for Linux (WSL). (Some USB Devices don’t work under WSL… Beware!)

The built firmware includes FreeRTOS + AliOS for handing Bluetooth LE and WiFi operations in the background. More details

Can we download the firmware without building it ourselves?

The firmware is built automatically in the cloud by GitHub Actions…

If we have trouble building the firmware on our own, just download the built firmware images from above.

The downloaded firmware images *.bin may be flashed to PineCone with the BLFlashEnv Tool on Linux and Windows. (No need for MSYS2)

4.4 Development Tools

The development tools supported for BL602 are…

  1. SiFive Freedom Studio

    (Because BL602 is based on SiFive’s E21 or E24 RISC-V Core)

  2. Eclipse

(For the BL602 port of Mynewt: I’ll be using VSCode as the development tool. Firmware build will be supported on plain old Windows (without MSYS2 / WSL), macOS, Linux, GitHub Actions and GitLab CI. More about porting Mynewt to RISC-V and how it got stuck)

4.5 Debugging Firmware

There’s an entire article about debugging PineCone Firmware with OpenOCD and JTAG…

“Connect PineCone BL602 to OpenOCD”

4.6 Testing the Firmware

When we port to BL602 a sizeable piece of firmware (or an Embedded Operating System like Mynewt), testing the firmware can get challenging.

For embedded gadgets like PineTime, the sensors and display are connected. Which makes it easier to test the Input/Output Ports (like I2C and SPI).

PineCone is a bare board with no sensors and actuators, so we need to wire up additional components to test the firmware. (I’ll probably use Bus Pirate to test my BL602 port of Mynewt + Rust)

(FYI: SiFive’s Doctor Who HiFive Inventor is an educational RISC-V board with onboard sensors and LED display. Would be great if Pine64 could add sensors and a display to BL602 for easier testing!)

4.7 Learning RISC-V and BL602

How shall we learn about writing RISC-V firmware for BL602?

5 What’s Next

Getting involved with the PineCone Nutcracker Challenge is a great way to learn about RISC-V… Especially for Embedded Engineers exploring Arm alternatives.

We’re in the middle of a pandemic. Why not take the time to learn some RISC-V… And contribute to the RISC-V Open Source Ecosystem!

Got a question, comment or suggestion? Create an Issue or submit a Pull Request here…


6 Notes

  1. I’m not a Pine64 employee and I’m not paid by Pine64 to write these articles on BL602.

    Pine64 sponsors my coffee (as a GitHub Sponsor) and they send me samples (of gadgets, not coffee) for evaluation and experimentation.

    (I’m not connected to Bouffalo Lab either)

  2. Besides Pine64 PineCone, there are other dev boards based on BL602…

    They are based on the same BL602 IoT SDK, so the same firmware should work on the various boards.

    The programs published on this site (in the “PineCone” series of articles) will run on any of these boards.

    Just note that the boards have different jumpers, buttons and LEDs.

  3. BL602 Bluetooth LE and WiFi are working … But we need help to reverse engineer the blobs! 🙏

  4. Here are the Bluetooth LE and WiFi demo apps and source code…

    The WiFi Source Code is explained in this article…

  5. Can we flash firmware to PineCone via a Web Browser through the Web Serial API? That would be really interesting.

    The Web Serial API works OK for sending commands to the BL602 Command Line Interface. (See this)

  6. Took me a while to realise that BL602 IoT SDK is built with AliOS (with FreeRTOS underneath)

    See this Twitter Thread