📝 29 Nov 2020
Pine64 is graciously giving away the PineCone BL602 RISC-V Evaluation Board to folks participating in the PineCone Nutcracker Challenge.
(PineCone is now available for purchase)
Let's learn about the PineCone Board... And how it helps the RISC-V Open Source Ecosystem.
PineCone is based on the BL602 combo chipset made by Nanjing-based Bouffalo Lab...
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
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.
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 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)
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.
How does BL602 compare with ESP32?
BL602 is a General Purpose Microcontroller that supports Bluetooth LE and WiFi
ESP32 is more of a Bluetooth LE + WiFi Controller that supports Embedded Programs
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)
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?
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...
Peripherals and Input/Output Ports are implemented differently: Timer, GPIO, UART, I2C, SPI, ...
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.
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...
SiFive FE310 (Released 2017)
GigaDevice GD32 VF103 (Released 2019)
BL602 (Released 2020)
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!
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
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.
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 (left) vs SiFive FE310 (right): Totally different
(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)
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.
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.
The WiFi Drivers that we wish to grok are located here...
...Inside the files
Here is a sample BL602 app that calls the WiFi Functions in
The PineCone Community has helpfully generated the GCC Linker Map for the
bl602_demo_at firmware (which includes
I have loaded the
bl602_demo_at.map Linker Map into a Google Sheet for analysis...
Click here to open the Google Sheet: PineCone BL602 AT Demo Linker Map
Filter Views ➜
Filter Views ➜
All Objects By Size
It takes a while to sort the objects... Be patient
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
sdk_app_ble_sync are here: Google Sheet for
bl602_demo_wifi, Google Sheet for
Remember that Wireless RAM starts at address
0x4203 0000? I have highlighted in yellow the 19 largest variables in Wireless RAM...
__bss_start __wifi_bss_start rx_dma_hdrdesc _data_load ram_heap ...
(The addresses of the variables are shown in the
These are likely the WiFi Buffers that our WiFi Driver uses to send and receive WiFi packets, also to control the WiFi operation.
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
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.
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.
More about the BL602 WiFi Controller
How can we get a PineCone BL602 Evaluation Board?
Join the PineCone Nutcracker Challenge!
Contribute to the community-driven Reverse Engineering of the BL602 Bluetooth LE / WiFi Drivers.
Or contribute docs and code that will help others adopt BL602 quickly. (This includes porting Mynewt / RIOT / Zephyr to 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)...
More docs and tools for PineCone BL602 may be found here...
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
Watch on YouTube
Flashing PineCone with Dev Cube
We flash RISC-V firmware to the PineCone board through the USB Serial Connection using the Dev Cube Tool...
Set the PineCone Jumper to the
H Position (Like this)
Connect PineCone to our computer's USB port
Download the PineCone Sample Firmware images from GitHub Actions. See the next section "Building Firmware"
Unzip the files in
Or download this Hello World sample firmware:
Download the PineCone SDK
git clone --recursive https://github.com/pine64/bl_iot_sdk
Launch Dev Cube for Windows, located in the PineCone SDK at
Select Chip Type
We should see
Simple Flasher. If not, click
View ➜ IoT
Set the following...
COM Port: Select the Serial COM port for PineCone
✅ Factory Params
✅ Partition Table: Click
Browse and select from the PineCone SDK...
✅ Boot2 Bin: Click
Browse and select from the PineCone SDK...
✅ Firmware Bin: Click
Browse and select from the PineCone Sample Firmware
This is the "Hello World" sample firmware that we'll be flashing.
The three files selected should NOT have any spaces in their pathnames.
Create & Program
This flashes the firmware to PineCone. We should see...
Verify success Program Finished
See the screenshot
Disconnect PineCone from the USB port.
Set the PineCone Jumper to the
L Position (Like this)
Reconnect PineCone to the USB port.
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...
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)
We may use Linux, Windows or macOS to build the BL602 firmware...
If we haven't done so, download the PineCone BL602 SDK
git clone --recursive https://github.com/pine64/bl_iot_sdk cd bl_iot_sdk
Follow the build instructions for Linux, Windows and macOS like so...
# Change this to the full path of bl_iot_sdk export BL60X_SDK_PATH=/Users/Luppy/pinecone/bl_iot_sdk export CONFIG_CHIP_NAME=BL602 make
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 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...
Download the built firmware from GitHub Actions:
(Requires login to GitHub)
All Workflows ➜ Results, click the first row
customer_app.zip (Like this)
The built firmware images in the downloaded ZIP have the extension
Modified GitHub Actions Workflow that builds the firmware
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)
The development tools supported for BL602 are...
SiFive Freedom Studio
(Because BL602 is based on SiFive's E21 or E24 RISC-V Core)
(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)
There's an entire article about debugging PineCone Firmware with OpenOCD and JTAG...
"Connect PineCone BL602 to OpenOCD"
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!)
How shall we learn about writing RISC-V firmware for BL602?
Check out the "Hello World" sample firmware...
Start by reading the C source file:
Then browse the other firmware samples in the BL602 SDK...
Some of the firmware samples are documented here
Getting involved with the PineCone Nutcracker Challenge is a great way to learn about RISC-V... Especially for Embedded Engineers exploring Arm alternatives.
And you might earn a free PineCone Evaluation Board!
(PineCone is now available for purchase)
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!
More about PineCone...
Got a question, comment or suggestion? Create an Issue or submit a Pull Request here...
Besides PineCone, there are other dev boards based on BL602. However it's not clear whether the firmware is 100% compatible with these boards.
Can we flash firmware to PineCone via a Web Browser through the Web Serial API? That would be really interesting.