
The DE10-Nano SoC FPGA (DE10-Nano)
Why I picked up the DE10-Nano Cyclone V SoC FPGA after a whole series on the BeagleBone Black — an ARM Cortex-A9 running Linux paired with FPGA fabric you program yourself.
Read More →A 22-part series. ← All Posts

Why I picked up the DE10-Nano Cyclone V SoC FPGA after a whole series on the BeagleBone Black — an ARM Cortex-A9 running Linux paired with FPGA fabric you program yourself.
Read More →
Cataloguing every onboard peripheral on the DE10-Nano straight from the official User Manual — FPGA-side buttons, switches, ADC, and HDMI; HPS-side UART, accelerometer, Ethernet, and more — before writing a single line of project code.
Read More →
The newest-dated file on Terasic's DE10-Nano download page isn't an OS image at all — it's a reference-design bundle. Here's where the real bootable Angstrom Linux image actually lives, and what's inside it.
Read More →
Your laptop is x86, the DE10-Nano's ARM. Here's a full working setup — Makefile, tasks.json, launch.json, settings.json — that cross-compiles a C program, ships it to the board over SSH, and lets you set breakpoints and step through it live from VS Code.
Read More →
Stop juggling an LED, a button, and a socket in one giant loop. Here's the Start/loop/Stop task pattern on POSIX threads I now build first on every embedded Linux project, including the DE10-Nano.
Read More →
Typing a long ARM gcc command every time I changed a file got old fast. Here's the small Makefile I wrote before my first real feature: the right cross-compiler, the right flags, and only rebuilding what changed.
Read More →
Before automating deploy and debug, I put the toolchain path, board IP, user, and GDB port into .vscode/settings.json so every task reads the same seven values from one file.
Read More →
The first link in a build, deploy, and debug chain: a tasks.json build task that runs make, puts compiler errors in the Problems panel, and runs on Ctrl+Shift+B.
Read More →
A tasks.json deploy task that builds first, then uses scp to copy the binary to the DE10-Nano, with every address and path pulled from settings.json.
Read More →
The last link in the chain: a background tasks.json task that SSHes into the DE10-Nano, starts gdbserver, and tells VS Code it's ready when it sees
Read More →
The payoff for the whole setup series: a launch.json that builds, deploys, starts gdbserver, and drops you into VS Code's debugger at main() on the DE10-Nano, all from F5.
Read More →
Before the first task, one tiny shared header: types.h, which gives the project INT32, UINT32, and BOOLEAN names built on stdint.h so every file agrees on exactly how big each value is.
Read More →
The first real task in the project: swalive.h, the header for a heartbeat thread that proves the software is still running, explained line by line, from the include guard to the volatile running flag.
Read More →
swalive.c, the code behind the heartbeat header: a pthread that prints a cycle counter and HH:MM:SS uptime every five seconds, uses CLOCK_MONOTONIC so NTP can't break it, line-buffers stdout so it never goes quiet in a log, and shuts down in about a second.
Read More →
hwalive.h, the header for a heartbeat you can see: a pthread task that blinks HPS_LED0 on the DE10-Nano through sysfs, with a one-second interval, a cached file descriptor, and cleanup that leaves the LED off.
Read More →
hwalive.c, the code behind the LED heartbeat: a pthread that blinks HPS_LED0 once a second through sysfs, with write() instead of buffered streams, an lseek before every write, and start and stop paths that always leave the LED off and the file closed.
Read More →
frame.h and frame.c: a 16-byte packet built from four UINT32 fields, a header marker and control codes that identify it on the wire, and a mutex-protected shared copy that the network tasks read and write as one piece.
Read More →
udptx.c, the task that puts the frame on the network: a UDP socket with SO_BROADCAST, a pthread that copies the shared frame, converts it to network byte order with htonl, and sends it with sendto, plus two bugs I left in and will fix next.
Read More →
A Wireshark demo for the UDPTx task: capture on the PC, filter on port 5001, and read the 16-byte frame byte by byte to confirm the header, control code, big-endian order, broadcast destination, and send interval.
Read More →
udprx.c, the task that lets the board listen: bind to port 5001, block in recvfrom, accept WRITE frames from any PC, update control_reg with ntohl and get, change, set, hand it to TODO FPGA hooks, and stop a blocked thread cleanly with shutdown().
Read More →
send.py, the host-app side of the UDPRx task: build a 16-byte WRITE frame with struct.pack, send it unicast to the board's IP on port 5001, confirm it in listen.py and Wireshark, send from a second PC, and fix it when nothing happens.
Read More →
Adding GoogleTest to an Embedded Linux C project: test frame.c on the PC with a separate CMake test folder, FetchContent, extern "C", a fixture that resets the shared frame, CMake presets, and a one-click VS Code test task.
Read More →