GD32VW553K-START
The GD32VW553K-START is the GigaDevice evaluation board for the GD32VW553KMQ (Nuclei N307, Wi-Fi 6 + BLE 5.3). It carries an on-board GD-Link debug probe which also provides the USB serial console.
The GD32VW553K-START, carrying the GD32VW553-MINI module.
Features
GD32VW553-MINI module with the GD32VW553KMQ (QFN32, 4096 KB flash, 320 KB SRAM) and a PCB antenna
On-board GD-Link probe: SWD/JTAG plus a USB CDC virtual COM port, both over the single USB Type-C connector
Two test pin headers (J1, J2) breaking out the GPIOs
BOOT0/BOOT1 jumpers, a power jumper and a reset button (NRST)
Three user LEDs on GPIOC
Serial Console
The console is UART2 (PA6 TX / PA7 RX), wired to the GD-Link virtual COM port.
It shows up on the host as /dev/ttyACM0 at 115200 8N1.
LEDs
Three LEDs sit on GPIOC and are driven push-pull, active HIGH. In the vendor SDK they are named LED_RUN, LED_SLEEP and LED_RX.
LED |
Pin |
Meaning in the vendor SDK |
|---|---|---|
LED1 |
PC0 |
CPU running |
LED2 |
PC1 |
CPU sleeping |
LED3 |
PC2 |
Reception |
With CONFIG_USERLED they belong to the application and are exposed as
/dev/userleds. With CONFIG_ARCH_LEDS the OS takes them over instead
and uses them to show its state: LED1 comes on once NuttX has started, LED2
joins it when the idle stack exists, and LED3 signals an assertion or a
panic. The two modes are mutually exclusive.
Pin headers
The user I/O of the module is broken out on two 2x8 test-pin headers, J1 and
J2. The tables below follow the board silkscreen (AN154 Figure 1-1) top to
bottom: the first two columns are the left row of the header, the last two the
right row. Several positions are wired to nothing (NC); the alternate
functions listed are the ones this port uses or reserves, and every other line
is a plain GPIO. The silkscreen abbreviates the port letter (A0 is PA0,
B15 is PB15, C15 is PC15).
Signal |
Function |
Signal |
Function |
|---|---|---|---|
PA0 |
GPIO |
PA1 |
GPIO |
PA2 |
GPIO |
PA3 |
GPIO |
PA4 |
GPIO |
PA5 |
GPIO |
PA6 |
UART2_TX (console) |
PA7 |
UART2_RX (console) |
PB0 |
GPIO |
NC |
– |
NC |
– |
NC |
– |
NC |
– |
PB15 |
GPIO |
GND |
ground |
+5V |
power in/out |
Signal |
Function |
Signal |
Function |
|---|---|---|---|
PC15 |
GPIO |
PC14 |
GPIO |
NC |
– |
PA15 |
JTDI |
PA14 |
JTCK |
PA13 |
JTMS |
PB4 |
JNTRST |
PB3 |
JTDO |
PA12 |
GPIO |
NC |
– |
NC |
– |
NC |
– |
PA8 |
GPIO |
GND |
ground |
+3V3 |
3.3V power test |
GND |
ground |
Note
PA13/PA14/PA15/PB3/PB4 on J2 are the chip’s JTAG pins, wired to the on-board GD-Link through the J4 shorting caps. Use them as plain GPIO only after removing those caps, or the debug probe and the application will fight over the lines.
Flashing
The board is programmed with OpenOCD through the GD-Link probe. The GigaDevice OpenOCD fork (shipped with the vendor SDK) is required:
$ openocd -f openocd_gdlink.cfg \
-c "program nuttx.bin 0x08000000 verify reset exit"
NuttX is linked at 0x08000000, bypassing the vendor MBL bootloader.
Note
The chip mask ROM uses the first 0x200 bytes of SRAM. The linker script starts the application at 0x20000200 for that reason; do not move it.
Flash layout
The full map is in the chip documentation. What matters when flashing this board:
Range |
Size |
Purpose |
|---|---|---|
0x08000000 – 0x083db000 |
3948 KiB |
Available to the firmware. This is what the linker script gives out; overflowing it is a link error |
0x083db000 – 0x083fb000 |
128 KiB |
progmem / LittleFS |
0x083fb000 – 0x08400000 |
20 KiB |
Wi-Fi NVDS – do not erase |
For reference, the configurations use a small part of that budget: nsh
135 KiB (3%), periph 154 KiB (4%), littlefs 195 KiB (5%), wapi
610 KiB (15%) and sta_softap 613 KiB (16%). The ble config (BLE on top
of wapi) brings the image to about 971 KiB (25%).
Warning
The last pages of the flash are not free: the Wi-Fi NVDS holds the RF calibration data and the MAC address, and erasing it breaks the radio. The progmem region ends exactly where the NVDS begins.
The region handed to progmem is set with
CONFIG_GD32VW55X_PROGMEM_START_ADDR and CONFIG_GD32VW55X_PROGMEM_SIZE;
nothing outside it is ever erased or written.
Configurations
Each configuration is built with:
$ ./tools/configure.sh gd32vw553k-start:<config>
$ make
nsh
Basic NuttShell configuration over the UART2 console. No radio.
wapi
NSH plus the Wi-Fi station support. The interface is registered as wlan0
with the MAC address read from the chip eFuse, and is driven with the standard
network tools:
nsh> wapi scan wlan0
nsh> wapi psk wlan0 <passphrase> 3
nsh> wapi essid wlan0 <ssid> 1
nsh> ifup wlan0
nsh> renew wlan0
nsh> ifconfig
nsh> ping 8.8.8.8
Note
Use ifup wlan0, not ifconfig wlan0 up: ifconfig interprets its
second argument as an IP address.
Note
The station is WPA2-only. A WPA3-transition network (WPA2/WPA3 mixed
mode) associates through WPA2-PSK; a WPA3(SAE)-only network is refused
up front with ENOTSUP and a console message naming the unsupported
AKM, instead of letting the prebuilt supplicant attempt the SAE
handshake (which faults).
The RTC and the SNTP client are enabled, so the clock can be set from the network:
nsh> ntpcstart
nsh> date
periph
NSH plus every peripheral driver (DMA, GPIO/EXTI, SPI, I2C, ADC, PWM, input
capture, both watchdogs, progmem, TRNG and CRC), registered as /dev/i2c0,
/dev/spi0, /dev/adc0, /dev/pwm0, /dev/capture0,
/dev/watchdog0 and /dev/watchdog1. No radio.
littlefs
NSH with the last 128 KiB of usable flash (below the Wi-Fi NVDS) exposed as an
MTD device, /dev/gd32flash, and mounted as LittleFS on /data.
Note
The erase page is 4 KiB, so the LittleFS size factors must be left at 1
(CONFIG_FS_LITTLEFS_PROGRAM_SIZE_FACTOR and friends). With the default
factor of 4 the program size becomes 16 KiB on a 4 KiB block: littlefs then
writes past the page it erased, and the filesystem corrupts in confusing
ways (ENAMETOOLONG on a short name, ENOSPC on an empty volume).
Build and flash it:
$ ./tools/configure.sh gd32vw553k-start:littlefs
$ make
$ openocd -f openocd_gdlink.cfg \
-c "program nuttx.bin 0x08000000 verify reset exit"
The partition is formatted on the first boot (the board mounts it from
gd32_bringup()), so it is ready to use as soon as NSH comes up:
nsh> mount
/data type littlefs
/proc type procfs
nsh> df -h
Filesystem Size Used Available Mounted on
littlefs 128K 8K 120K /data
procfs 0B 0B 0B /proc
Write and read a file back:
nsh> echo "NuttX on GD32VW553" > /data/hello.txt
nsh> cat /data/hello.txt
NuttX on GD32VW553
nsh> ls -l /data
/data:
drwxrwxrwx 0 .
dr--r--r-- 0 ..
-rw-rw-rw- 19 hello.txt
The contents survive a reset, since they are in flash:
nsh> reboot
NuttShell (NSH) NuttX-13.0.0
nsh> mount
/data type littlefs
/proc type procfs
nsh> cat /data/hello.txt
NuttX on GD32VW553
Note
The NSH command is reboot (there is no reset command). It needs
CONFIG_BOARDCTL_RESET, which every configuration of this board enables;
the board resets the core through the Nuclei SysTimer software reset
request, the same way the vendor SDK does.
To start from a clean volume, erase the region with the debug probe and let the next boot format it again:
$ openocd -f openocd_gdlink.cfg \
-c "init; halt; flash erase_address 0x083db000 0x20000; reset; exit"
Warning
Erase only the progmem region. The Wi-Fi NVDS lives immediately above it,
at 0x083fb000; wiping it takes the RF calibration and the MAC address with
it. After using the filesystem, wapi scan wlan0 in the wapi
configuration is a quick way to confirm the radio is still healthy.
sta_softap
NSH plus the Wi-Fi softAP: the board becomes an access point and a DHCP server. The single-VIF firmware does station or AP at a time (not both at once), so this is a softAP, not the simultaneous STA+AP of some other parts.
Bring it up with the standard tools:
nsh> wapi mode wlan0 3 # 3 = master (softAP)
nsh> wapi psk wlan0 12345678 3 # WPA2-PSK
nsh> wapi essid wlan0 nuttxwifi 1 # start the AP
nsh> dhcpd_start wlan0 # DHCP server, in the background
A client then sees nuttxwifi, associates with WPA2, and gets an address
from the 10.0.0.0/24 pool (the AP is 10.0.0.1).
Note
Use WPA2, not WPA3. The SAE (WPA3) handshake on the AP side is deep on the
stack; with the default task stacks it overflows inside the elliptic-curve
crypto and faults. This configuration raises CONFIG_INIT_STACKSIZE to
8192 and CONFIG_DEFAULT_TASK_STACKSIZE to 4096 for the same reason – the
radio tasks need the headroom.
Note
dhcpd_start spawns the server as a background task and returns. The
plain dhcpd command, confusingly, runs the server blocking in the
foreground.
ble
wapi plus BLE (CONFIG_GD32VW55X_BLE) and the demo GATT service
(CONFIG_GD32VW55X_BLE_GATT_DEMO). The board advertises a connectable set
named NuttX and registers a minimal “transparent UART” service (16-bit
UUIDs 0xffe0 / RX 0xffe1 / TX 0xffe2). Advertising restarts on
every disconnection, so the device stays discoverable across connections. A
central connects, discovers the service, and a write to the RX characteristic
is logged on the board console:
nsh> BLE RX (11): Hello world
Note
The central -> board write is exercised with a write command
(write-without-response), which is reliable. The prebuilt vendor
controller does not complete a write-request (write-with-response) or the
CCCD subscribe issued by a Linux BlueZ host, so the TX notification echo
(board -> central) is best exercised from a phone app such as nRF Connect.
This is why BLE keeps CONFIG_EXPERIMENTAL.
ostest
nsh plus the NuttX OS test suite (CONFIG_TESTING_OSTEST). Run it from
the shell to exercise the scheduler, synchronisation primitives and the FPU
context switch:
nsh> ostest
...
ostest_main: Exiting with status 0
The rr_test (round-robin with a 30000-prime workload) makes the full run
take a couple of minutes on this core; every sub-test reports nerrors=0.
Status
All seven configurations were validated on hardware:
nsh: boots, console, heap and task list are healthy.littlefs: the partition is formatted on the first boot, files are written and read back, and they survive both arebootand a re-flash.periph: every driver registers (/dev/i2c0,/dev/spi0,/dev/adc0,/dev/pwm0,/dev/capture0,/dev/watchdog0,/dev/watchdog1,/dev/userleds,/dev/random). The TRNG returns fresh entropy on each read, and the three LEDs work.wapi: full station path over a live AP –wapi scanlists the nearby networks, WPA2 associates through the four-way handshake, DHCP obtains an address, andpingreaches the internet.sta_softap: the board’s own AP – a client sees the SSID, associates with WPA2, gets an address from the board’s DHCP server, and pings the board.ble: advertisesNuttX, a central connects, the demo GATT service enumerates, and a write to the RX characteristic is received on the board console (central -> board).ostest: the OS test suite runs to completion (every sub-test reportsnerrors=0and it ends withostest_main: Exiting with status 0).
BLE (CONFIG_GD32VW55X_BLE) is marked EXPERIMENTAL and off by default. The
prebuilt libble is an all-in-one controller plus RivieraWaves host with no
HCI transport, so the port drives the vendor host directly (it does not
register a NuttX bt_driver_s). The ble configuration enables it along
with a demo GATT service; see that section above for what is validated and the
notification caveat. A reusable test tool for this is kept with the
out-of-tree port notes.
Note
CONFIG_ARCH_LEDS must stay off on this board. With the OS driving the
LEDs, the serial console dies in the Wi-Fi configurations (the console UART
shares the work queue path); the LEDs belong to the application
(CONFIG_USERLED), and every defconfig here disables ARCH_LEDS
explicitly.