Embedded Engineers: Don’t Miss These 20 GitHub Repositories!

Embedded Engineers_ Don't Miss These 5 GitHub Repositories!
Embedded Engineer’s GitHub Shelf
Firmware field guide20 repositories~14 min read

Top 20 GitHub repos for embedded engineers

Real code from the RTOS kernels, vendor HALs, bootloaders, test frameworks and debuggers that ship inside millions of devices. Read them in the right order and they teach you the whole firmware stack.

Why source beats tutorialsRead the code that already ships

Most embedded courses stop at blinking an LED. Production firmware has to boot securely, schedule dozens of tasks, survive a power cut halfway through a flash write, talk over a radio, draw a UI on a 320×240 display, and still be testable on a laptop before anyone touches a board. Nobody learns all of that from a textbook. You learn it by reading code that has already solved it.

The twenty repositories below are that code. Some are kernels you will run directly in products. Some are thin hardware layers that show how a register write becomes a GPIO toggle. Others are tools that make the work survivable: unit-test frameworks, an on-chip debugger, and two full-system simulators. Together they cover every layer between the silicon and the application.

Each entry below explains what the project is, what it will teach you, and the one file or folder to open first. The links point to the official repositories.

MapWhere each repo sits in the firmware stack

Before diving in, it helps to see how these projects relate. Firmware is built in layers. Hardware abstraction code sits right above the silicon. An RTOS or scheduler sits above that. Middleware such as file systems, serialization and graphics sits above the OS. Tooling runs alongside all of it on your development machine.

YOUR APPLICATION BOOT & UPDATE MCUboot MIDDLEWARE LVGL · LittleFS nanopb · ETL RTOS / OPERATING SYSTEM FreeRTOS · Zephyr NuttX · RIOT · Mbed OS ESP-IDF (FreeRTOS based) HARDWARE ABSTRACTION CMSIS · STM32CubeF4 libopencm3 · ArduinoCore MCU SILICON TOOLING on your PC Unity Ceedling Renode QEMU OpenOCD talks to chip via SWD/JTAG
Fig. 1 The firmware stack. Read bottom-up to understand how hardware becomes an application; the tooling column runs on your development machine.

Quick referenceAll 20 repositories at a glance

The table keeps the original ranking. The Layer column tells you which part of Fig. 1 each repo belongs to, so you can jump straight to the gap in your own knowledge.

No.RepositoryWhat you can learnLayerGitHub link
01FreeRTOSRTOS, tasks, queues, semaphoresRTOS
02Zephyr ProjectModern RTOS, drivers, Bluetooth, IoTRTOS
03ArduinoCore-avrAVR microcontrollers, GPIO, timersHAL
04CMSIS_5ARM Cortex-M, DSP, embedded librariesHAL
05libopencm3Low-level ARM Cortex-M developmentHAL
06ESP-IDFESP32 firmware, Wi-Fi, Bluetooth, IoTSDK + RTOS
07STM32CubeF4STM32 drivers, peripheral examplesHAL
08Apache NuttXRTOS, POSIX APIs, embedded systemsRTOS
09Mbed OSRTOS, connectivity, IoT developmentRTOS
10RIOT OSIoT operating systems, networkingRTOS
11LVGLEmbedded GUI, displays, touch interfacesMiddleware
12LittleFSFlash file systems for microcontrollersMiddleware
13MCUbootSecure bootloaders and firmware updatesBoot
14nanopbProtocol Buffers for embedded CMiddleware
15UnityUnit testing for embedded CTooling
16CeedlingAutomated testing for C projectsTooling
17OpenOCDJTAG/SWD debugging and flashingTooling
18RenodeEmbedded hardware and firmware simulationTooling
19QEMUSystem emulation and firmware testingTooling
20Embedded Template Library (ETL)C++ data structures for embedded systemsMiddleware

Layer 1 · Operating systemsThe RTOS kernels

An RTOS is the first big leap after bare-metal loops. Instead of one while(1) that polls everything, you split work into tasks with priorities and let a scheduler decide who runs. These six projects show very different answers to the same problem.

01

FreeRTOS

CMITKernel

FreeRTOS is the most widely deployed small RTOS. The kernel is only a handful of C files, which makes it the best place to learn how a scheduler really works. You will see how a context switch saves registers on the stack, how the ready list is sorted by priority, and how a queue blocks a task until data arrives.

Once you understand tasks.c and queue.c, every other RTOS on this list becomes easier to read, because they all solve the same scheduling and synchronization problems.

Start hereRead tasks.c around vTaskSwitchContext(), then portable/GCC/ARM_CM4F/port.c to see the PendSV handler that actually swaps tasks.
github.com/FreeRTOS/FreeRTOS-Kernel
READY RUNNING BLOCKED SUSPENDED scheduled preempted vTaskDelay / xQueueReceive event / timeout Suspend Resume Only the highest-priority READY task runs
Fig. 2 The four task states in FreeRTOS. A task that waits on a queue or delay moves to Blocked and costs no CPU time until its event or timeout arrives.
02

Zephyr Project

CApache-2.0Linux Foundation

Zephyr is a full RTOS ecosystem rather than a bare kernel. It supports hundreds of boards and borrows Devicetree and Kconfig from Linux, so the same driver code runs on boards from Nordic, NXP, ST, Espressif and many others. It also ships a complete Bluetooth Low Energy stack, networking, and power management.

Reading Zephyr teaches you how large firmware projects stay portable. You will learn how a board file describes hardware, how drivers bind to that description at build time, and how a professional project organizes tests and CI.

Start hereBuild samples/basic/blinky, then trace how DT_ALIAS(led0) resolves through the board’s .dts file to a real GPIO pin.
github.com/zephyrproject-rtos/zephyr
06

ESP-IDF

CApache-2.0Espressif

ESP-IDF is Espressif’s official framework for the ESP32 family. It wraps a modified FreeRTOS with Wi-Fi, Bluetooth, TLS, OTA updates, and a component-based CMake build system. It is the fastest way to learn connected-device firmware on cheap, widely available hardware.

Pay attention to how it runs FreeRTOS on dual-core chips and how its event loop decouples Wi-Fi events from application code. Those patterns carry over to any IoT product.

Start hereRun examples/wifi/getting_started/station, then read components/esp_event to see how events are posted and dispatched.
github.com/espressif/esp-idf
08

Apache NuttX

CApache-2.0POSIX

NuttX aims to be a small Unix. It implements POSIX and ANSI interfaces, so code that uses open(), read(), pthread_create() and file descriptors runs on a microcontroller. It even has a shell, NuttShell, and a virtual file system where drivers appear under /dev.

It is a great bridge for Linux developers moving into firmware. It is also the operating system underneath the PX4 drone autopilot, which shows it can handle demanding real-time work.

Start hereBuild the sim:nsh configuration and run NuttX as a process on your PC, no board required.
github.com/apache/nuttx
09

Mbed OS

C++Apache-2.0Legacy

Mbed OS combined an RTOS (built on Keil RTX), a clean C++ driver API and connectivity stacks for Cortex-M boards. Its DigitalOut, Thread and EventQueue classes are still a tidy example of how to wrap hardware in object-oriented C++ without heavy overhead.

Arm announced that Mbed would reach end of life in July 2026. Read it as a well-designed reference codebase, but choose Zephyr or FreeRTOS for new products.
Start hereRead events/ to see how EventQueue defers work out of interrupt context.
github.com/ARMmbed/mbed-os
10

RIOT OS

CLGPL-2.1IoT networking

RIOT targets very constrained IoT nodes, devices with a few kilobytes of RAM running on batteries for years. Its strength is networking: it includes a full IPv6 stack with 6LoWPAN, CoAP, and support for low-power radios.

Study RIOT to learn how a network stack fits into tiny memory, and how a tickless scheduler lets the CPU sleep between events to save power.

Start hereRun examples/gnrc_networking on the native board to try IPv6 networking from a Linux terminal.
github.com/RIOT-OS/RIOT

CompareChoosing between the RTOS options

The kernels overlap, so here is how they differ in practice. Scroll the table sideways on a phone.

ProjectAPI styleFootprintBuilt-in networkingBest for
FreeRTOSOwn C APIVery smallAdd-on librariesLearning schedulers, simple products
ZephyrOwn C API, DevicetreeSmall to mediumBLE, IPv4/IPv6, ThreadMulti-board professional products
ESP-IDFFreeRTOS + Espressif APIsMediumWi-Fi, BLE, TLSESP32 IoT devices
NuttXPOSIXSmall to mediumTCP/IP, USBLinux-style code, drones
RIOTPOSIX-like CVery small6LoWPAN, CoAPBattery-powered sensor nodes
Mbed OSC++ classesMediumEthernet, cellular, LoRaStudy only (end of life)

Layer 2 · Hardware abstractionClose to the registers

These repositories sit directly above the silicon. They are where a line like digitalWrite(13, HIGH) turns into a single store to a memory-mapped port register. Reading them removes the magic from microcontrollers.

03

ArduinoCore-avr

C / C++LGPL-2.1AVR

This is the code behind every Arduino Uno sketch. It is short and readable, which makes it ideal for a first look under the hood. You will see how millis() is driven by a Timer0 overflow interrupt, how analogWrite() configures hardware PWM, and how the serial port uses a ring buffer filled from an interrupt.

Start hereOpen cores/arduino/wiring.c for timers and wiring_digital.c for GPIO. Then compare it with the ATmega328P datasheet.
github.com/arduino/ArduinoCore-avr
04

CMSIS_5

CApache-2.0Arm

CMSIS is Arm’s standard interface for Cortex-M processors. Every vendor HAL for Cortex-M builds on it. It defines how the core registers (NVIC, SysTick, SCB) are named and accessed, provides the startup code pattern, and includes CMSIS-DSP for filters and FFTs plus CMSIS-RTOS as a portable RTOS API.

Arm now develops CMSIS 6 in separate repositories. CMSIS_5 remains a complete, readable reference, and most existing projects still use it.
Start hereRead CMSIS/Core/Include/core_cm4.h to see exactly how NVIC_EnableIRQ() writes to hardware.
github.com/ARM-software/CMSIS_5
05

libopencm3

CLGPL-3.0Open source HAL

libopencm3 is a community firmware library for many Cortex-M families, including STM32, NXP LPC, and others. It is thinner than vendor HALs, so each function maps almost one-to-one onto register writes. That makes it an excellent study companion while you read a reference manual.

Start hereLook at lib/stm32/common/gpio_common_f0234.c and match each line with the GPIO chapter of an STM32F4 reference manual.
github.com/libopencm3/libopencm3
07

STM32CubeF4

CBSD-3 / ST termsVendor HAL

This is ST’s official MCU package for the STM32F4 series. It contains the HAL and LL (low-layer) drivers, board support packages, middleware such as USB and FatFS, and hundreds of example projects for real evaluation boards.

Comparing the HAL and LL drivers side by side is one of the best lessons in abstraction cost: the HAL is portable and safe, while LL is lean and close to the metal.

Start herePick a board under Projects/ and open a UART DMA example. Follow the call into stm32f4xx_hal_uart.c.
github.com/STMicroelectronics/STM32CubeF4

Layer 3 · Boot and updateGetting new firmware onto a device safely

13

MCUboot

CApache-2.0Secure boot

MCUboot is a secure bootloader used by Zephyr, NuttX, ESP-IDF, and many commercial products. It checks a cryptographic signature on the application image before running it, and handles over-the-air updates by keeping two image slots in flash.

It teaches the most important rule of field updates: a device must never be left without a working image, even if power fails mid-update. The swap-and-confirm flow in Fig. 3 is how MCUboot guarantees that.

Start hereRead boot/bootutil/src/loader.c and the design document docs/design.md.
github.com/mcu-tools/mcuboot
FLASH LAYOUT MCUboot Primary slot running image v1 Secondary slot new image v2 1 App downloads v2 → secondary 2 Reset · MCUboot verifies signature 3 Swap slots · boot v2 as “test” app OK crash / no confirm 4a Confirm v2 becomes permanent 4b Revert next reset restores v1 The device always has one known-good image
Fig. 3 MCUboot’s test-and-confirm update. If the new image never marks itself as good, the bootloader swaps the old image back on the next reset.

Layer 4 · MiddlewareGraphics, storage, data and C++

Middleware turns a running kernel into a product. These four libraries are portable, so you can drop them into almost any project on this list.

11

LVGL

CMITGraphics

LVGL (Light and Versatile Graphics Library) builds smartphone-style interfaces with buttons, charts, sliders, animations and anti-aliased fonts on microcontrollers with as little as tens of kilobytes of RAM. It only needs two things from you: a function that pushes pixels to the display and a function that reads touch input.

The source teaches partial screen redraws, dirty-area tracking and draw buffers, which are the techniques that make smooth UIs possible without a GPU.

Start hereRun LVGL in the PC simulator, then read src/core/lv_refr.c to see how invalidated areas are redrawn.
github.com/lvgl/lvgl
12

LittleFS

CBSD-3File system

LittleFS is a small file system built for raw NOR and NAND flash. It is power-loss resilient, so a sudden reset never corrupts the file system, and it spreads writes across blocks to avoid wearing out one area of flash. Its RAM usage is bounded and does not grow with the size of the storage.

The design notes are some of the best writing on copy-on-write data structures for flash. Read them even if you never use the library.

Start hereRead DESIGN.md first, then the 5-line block-device config in README.md.
github.com/littlefs-project/littlefs
14

nanopb

CzlibSerialization

nanopb implements Google Protocol Buffers in plain C, with no dynamic memory allocation. You write a .proto file, a generator produces C structs, and the library encodes them into a compact binary format that a phone app or cloud server can decode in any language.

It teaches you how to design firmware messages that can evolve over time without breaking older devices in the field.

Start hereBuild examples/simple and read the generated .pb.h file. Use a .options file to set fixed array sizes.
github.com/nanopb/nanopb
20

Embedded Template Library (ETL)

C++MITHeader-only

The C++ standard library containers allocate memory from the heap, which many safety and real-time projects forbid. ETL provides fixed-capacity replacements such as etl::vector, etl::string, etl::queue and etl::map whose maximum size is set at compile time, so memory use is fully predictable.

It is a good way to learn modern C++ techniques like templates and constexpr applied to embedded constraints.

Start hereReplace one std::vector in a project with etl::vector<T, 16> and check the map file to see memory move from heap to static.
github.com/ETLCPP/etl

Layer 5 · ToolingTest, debug and simulate

Strong embedded teams find most bugs before firmware ever reaches a board. These five tools make that possible: two for unit testing on your PC, one for debugging real hardware, and two for running firmware on simulated hardware.

15

Unity

CMITUnit test

Unity is a unit-test framework for C made of a single source file and two headers. It runs on a PC or directly on a microcontroller, and offers assertions built for embedded work, such as checking integers in hex, bit masks and memory arrays.

Start hereRead examples/example_1. Write one test for a ring buffer before you write the ring buffer.
github.com/ThrowTheSwitch/Unity
16

Ceedling

RubyMITTest runner

Ceedling is the build system that makes Unity practical at scale. It finds test files, generates test runners, and uses CMock to create mocks from your header files automatically. With mocks you can test a driver’s logic by faking the HAL calls underneath it, so you never need the real chip for unit tests.

Start hereRun ceedling new myproject, then add #include "mock_gpio.h" to a test and watch the mock appear.
github.com/ThrowTheSwitch/Ceedling
17

OpenOCD

CGPL-2.0Debugger

OpenOCD (Open On-Chip Debugger) connects your PC to a microcontroller through a debug probe such as ST-LINK, J-Link or a CMSIS-DAP adapter. It speaks JTAG and SWD to the chip, programs flash, and exposes a GDB server so you can set breakpoints and inspect memory from your editor.

Reading its target and flash drivers shows exactly how a debugger halts a core and writes flash through the debug port.

Start hereRun openocd -f interface/stlink.cfg -f target/stm32f4x.cfg, then connect with arm-none-eabi-gdb and target extended-remote :3333.
github.com/openocd-org/openocd
YOUR PC GDB / IDE breakpoints, step, watch TCP :3333 OpenOCD target + flash drivers USB Debug probe ST-LINK · J-Link · CMSIS-DAP SWDIO · SWCLK MCU Debug Access Port → core + flash
Fig. 4 How OpenOCD sits between your debugger and the chip. Only two wires (SWDIO and SWCLK) plus ground are needed for SWD.
18

Renode

C#MITSimulator

Renode, from Antmicro, simulates complete embedded systems, including the CPU, peripherals, sensors and even multiple networked nodes. It runs your unmodified firmware binary, so you can test a full Zephyr or FreeRTOS build in CI without any physical boards.

Its Robot Framework integration lets you write tests like “send this UART input, expect this output”, which is how teams catch regressions on every commit.

Start hereRun the bundled STM32F4 Discovery demo script, then read a platform .repl file to see how a board is described.
github.com/renode/renode
19

QEMU

CGPL-2.0Emulator

QEMU is the general-purpose machine emulator used across the industry. For embedded work it emulates Arm, RISC-V and other architectures, with machine models for boards such as the BBC micro:bit and several Cortex-M and Cortex-A platforms. Zephyr and many Linux-based projects use it as a default test target.

Compared with Renode, QEMU is faster and broader in CPU support, while Renode models more peripherals and multi-node systems. Learn both.

Start hereBoot a Zephyr sample with west build -b qemu_cortex_m3 samples/hello_world and west build -t run.
github.com/qemu/qemu

RoadmapA 12-week order for reading these repos

Twenty codebases is a lot. The order below builds each skill on the previous one, and every stage ends with something you can run.

1 WEEKS 1–3 · REGISTERS ArduinoCore-avr → CMSIS_5 → libopencm3 → STM32CubeF4 2 WEEKS 4–6 · SCHEDULING FreeRTOS → Zephyr + OpenOCD for debugging 3 WEEKS 7–9 · PRODUCT FEATURES ESP-IDF · LittleFS · nanopb LVGL · MCUboot 4 WEEKS 10–12 · QUALITY Unity · Ceedling · Renode · QEMU then explore NuttX · RIOT · ETL
Fig. 5 Suggested reading order. Stage 1 removes the magic from hardware; stage 4 makes your firmware testable without a board.
  1. 1

    Registers first. Blink an LED with ArduinoCore-avr, then do it again on a Cortex-M board using only CMSIS register definitions. Finish by comparing libopencm3 with the STM32 HAL for the same peripheral.

  2. 2

    Then scheduling. Write two FreeRTOS tasks that share a queue, and step through a context switch with OpenOCD and GDB. Port the same idea to Zephyr to see Devicetree in action.

  3. 3

    Then product features. Build an ESP32 sensor that stores readings in LittleFS, sends them as nanopb messages over Wi-Fi, shows them on an LVGL screen, and updates itself through MCUboot.

  4. 4

    Then quality. Move your driver logic under Ceedling tests with mocked hardware, and run the whole firmware image in Renode or QEMU inside a CI pipeline.

How to readGetting value from a large codebase

Opening a repository with thousands of files can feel overwhelming. A few habits make it manageable.

Start from a sample, not from the root. Every project here ships examples. Build one, flash it or run it in a simulator, then follow the function calls inward. You will learn the architecture by tracing one real path through it.

Keep the datasheet open. HAL code only makes sense next to the reference manual that describes each register bit. When you see a write to RCC->AHB1ENR, look up what that bit enables.

Read the tests and CI files. Zephyr’s tests/ folder, LittleFS’s test suite and the GitHub Actions workflows in these repos show you how professional firmware is verified, which interviewers often ask about.

Read the issue tracker and pull requests. Closed bugs explain why odd-looking code exists. A race condition fixed in a FreeRTOS port or a flash wear issue in LittleFS teaches more than any tutorial.

Contribute something small. Fix a typo in documentation, add a board definition, or improve an example. Your first merged pull request to Zephyr or LVGL is a strong signal on an embedded résumé.

Wrap-upThe short version

If you only have time for three repositories, read FreeRTOS to understand scheduling, CMSIS to understand Cortex-M hardware access, and MCUboot to understand safe updates. Those three cover the core of what makes firmware different from application software.

With time for more, follow the 12-week roadmap above. By the end you will have touched every layer of a modern embedded product, from the register write that toggles a pin to the CI pipeline that tests a full firmware image on simulated hardware. That breadth is exactly what separates someone who can write a driver from someone who can ship a device.

Licenses and project status reflect each repository’s own README as of late 2026; check the repo before relying on them in a product.