EmbeddedRelated.com

How to Deploy Local LLMs for Embedded Software Development: Terminology and Motivation

Mohammed BillooMohammed Billoo May 12, 2026

In this blog post series, I walk you through creating a fully local, offline AI pipeline. In this first post, I outline the motivation and relevant terminology that are important before we dive into hardware selection and implementation of the pipeline.


Your architecture was decided before you opened the schematic

Emile DécosterdEmile Décosterd May 7, 2026

Engineering teams often treat requirements as a simple feature checklist, but they actually hold the blueprint for your software architecture. By analyzing constraints collectively rather than in isolation, you can define critical architectural patterns—such as task scheduling and abstraction levels—long before the first schematic is drawn. This proactive approach eliminates wasted complexity, reduces development time, and allows software needs to inform hardware choices early in the cycle. Discover how to shift your design mindset to build lean, purposeful systems that align perfectly with business objectives from day one.


GNU Linker Scripts. Part 1. .data, .bss, and the Startup Contract

Alexey KarelinAlexey Karelin May 5, 2026

Before your first line of C code executes, your system must establish a vital memory contract. Discover how the GNU Linker manages the transition from power-on to a ready-to-run state by deconstructing the roles of .data and .bss sections. Learn how to map Virtual and Load Memory Addresses effectively and decode the startup routines that initialize your global variables. By mastering these fundamental linker script mechanics, you gain total control over your embedded application's memory layout and ensure your startup code performs reliably every time.


Beyond the Packet: Designing Reliable Serial Communication for Embedded Systems

Prabo SemasinghePrabo Semasinghe May 4, 2026

Serial communication between microcontrollers sounds simple until the protocol quietly breaks your system. Prabo Semasinghe walks through the design steps for building a robust communication framework: packet structure, error detection, acknowledgment handling, state machine design, and the failure-mode testing that actually proves it works.


I Stopped Testing Embedded Systems by Hand. Here's What Replaced It.

Everardo GarciaEverardo Garcia April 23, 2026

Everardo Garcia walks through the shift from manual, terminal-based system-level testing to automated tests that run during development. He shows how OpenHTF (a framework originally built at Google for manufacturing lines) plus a laptop, a USB cable, and ~150 lines of Python closes the functional testing gap most embedded teams carry, and how spec-driven prompting with GitHub Copilot makes writing plugs and phases fast enough to keep up.


Finite State Machines (FSM) in Embedded Systems (Part 5) - From One FSM to Many

Massimiliano PaganiMassimiliano Pagani April 21, 20261 comment

Traditionally, complex systems are implemented using multi-threading and mutexes. Trying to scale up this approach usually results in a nightmare of data races and hidden bugs. A single Finite State Machine may bring order to chaos in applications, but cannot be scaled beyond a limit. In this installment, we explore the Actor Model: a shift from shared state to communicating state machines. Discover how treating FSMs as independent, message-passing entities can eliminate concurrency issues, simplify testing, and improve your embedded architecture.


Your Unit Tests Won't Find the Wolves: Why Embedded Developers Should Be Fuzzing

Ryan TorvikRyan Torvik April 18, 2026

You test the happy paths. You check the well-formatted packets and the expected inputs. But real users don't read manuals, and real data doesn't follow your protocol spec. Fuzzing throws millions of randomized inputs at your code to find the crashes you never thought to look for. Here's why it matters for embedded systems.


Quickfire Heuristics: A Fast Usability Evaluation Framework for Lean Hardware Teams

Emmanuel OdunladeEmmanuel Odunlade April 10, 2026

That device with the single LED that requires you to count blink patterns just to understand system status. The button you must hold for 8 seconds, which also performs four other actions depending on hold duration. These are not accidents of negligence; they are the predictable output of development processes that have no rigorous usability evaluation component. Usability tends to slip through the gaps of standard engineering reviews, surfacing late, when design flexibility is already gone. This article introduces a framework that adapts Jakob Nielsen's Ten Usability Heuristics, for hardware and embedded systems, translating each principle into concrete evaluation questions for physical interfaces, firmware state machines, constrained displays, and cross-layer interactions. Using a smartwatch as the running example, it also introduces a structured session format, maps the framework to key lifecycle stages, and extends it to manufacturing, test, and field service contexts.


Debug, visualize and test embedded C/C++ through instrumentation

Pier-Yves LessardPier-Yves Lessard March 24, 2026

Instrumenting a firmware is a highly effective methodology for debugging and testing an embedded softwares. In this article, I will present a way of achieving this using Scrutiny, an open-source software suite developed as a personal initiative, designed to streamline debugging, telemetry, and hardware-in-the-loop (HIL) testing for embedded devices.


Never use Float or Integer

Mark HermelingMark Hermeling March 18, 20264 comments

Ada treats numbers as more than just numbers, and that changes how embedded code fails. This post shows why you should avoid using Float and Integer directly, then demonstrates how distinct types, ranges, and subtypes let the compiler catch unit mix-ups and out-of-range values before runtime. It also shows the same code running on a Raspberry Pi Pico, and briefly introduces SPARK for proving correctness.


Introduction to Microcontrollers - Beginnings

Mike SilvaMike Silva August 20, 201312 comments

Mike Silva's beginner tutorial series walks through core microcontroller concepts and practical steps to get started, from wiring an LED blinky to understanding startup code. He compares embedded and desktop programming, explains why C and assembly matter, and introduces AVR and STM32 Cortex-M3 toolchains and hardware. Expect clear examples, no-nonsense tool advice, and the essential hardware knowledge to move from simulator to a real board.


Analyzing the Linker Map file with a little help from the ELF and the DWARF

Govind MukundanGovind Mukundan December 27, 201524 comments

Running out of Flash or RAM is a familiar pain for firmware engineers, and the linker map only tells part of the story. This post shows how to combine the linker MAP with ELF symbol tables and DWARF debug info to recover static symbols, sizes, and source files that the map omits. It also describes a C# WinForms viewer that automates the parsing with binutils and helps you spot module and symbol-level memory waste.


MSP430 Launchpad Tutorial - Part 2 - Interrupts and timers

Enrico GaranteEnrico Garante June 17, 201342 comments

Interrupts let the MSP430 respond to events without wasting CPU time, and this tutorial walks through using TimerA and Port 1 interrupts on the LaunchPad. Enrico shows how to configure TACTL, CCR0 and CCTL0 to generate a periodic TimerA interrupt, and how to set up P1IE, P1IES and P1IFG to catch a button press. The code toggles LEDs and enters LPM0 while waiting for interrupts.


Chebyshev Approximation and How It Can Help You Save Money, Win Friends, and Influence People

Jason SachsJason Sachs September 30, 201221 comments

Are expensive math libraries or huge lookup tables eating CPU and flash on your microcontroller? In this practical guide Jason Sachs shows how Chebyshev polynomial approximation (with range reduction, splitting, and small interpolated tables) can give near-minimax accuracy while using far less code and runtime. The post compares Taylor series, plain and interpolated tables, and explains how to fit empirical sensor data and evaluate coefficients efficiently.


MSP430 LaunchPad Tutorial - Part 4 - UART Transmission

Enrico GaranteEnrico Garante July 3, 201320 comments

Want to stream sensor or debug data from an MSP430 LaunchPad to a PC or Bluetooth module? Enrico swaps in an MSP430G2553 and shows how to configure SMCLK, P1 pin multiplexing, and UCA0 baud/dividers (with modulation) to approximate 115200 baud. The post also walks through interrupt-driven RX/TX handling and a low-power wait loop that sends a "Hello World" reply on demand.


Understanding and Preventing Overflow (I Had Too Much to Add Last Night)

Jason SachsJason Sachs December 4, 2013

Integer overflow is stealthier than you think, and in embedded systems it can break control loops or corrupt data. Jason Sachs walks through the usual culprits, including addition, subtraction, multiplication, shifting and Q15 fixed-point traps, plus C-specific pitfalls such as undefined signed overflow and INT_MIN edge cases. He then lays out practical defenses: prefer fixed-width types, widen and saturate intermediates, enable wraparound where appropriate, and reason about modular congruence for compound arithmetic.


Adventures in Signal Processing with Python

Jason SachsJason Sachs June 23, 201311 comments

Jason Sachs shows how PyLab (numpy, scipy, matplotlib) can handle many signal-processing and visualization tasks engineers usually reach for MATLAB to do. He walks through practical examples including PWM ripple, two pole RC filters, and symbolic math with SymPy, and shares real-world installation tips and trade-offs. The post closes with pointers to IPython and pandas to speed interactive analysis and data handling.


MSP430 Launchpad Tutorial - Part 1 - Basics

Enrico GaranteEnrico Garante June 14, 201320 comments

A working button-driven LED on the MSP430 LaunchPad is only a few steps away. Enrico Garante walks through creating a CCS project, setting P1.0 as the LED output and enabling P1.3 button interrupts, then shows the interrupt service routine that toggles the LED. The short tutorial covers stopping the watchdog, configuring P1DIR/P1OUT, clearing flags, and launching the code so you can get blinking quickly.


Coroutines in one page of C

Yossi KreininYossi Kreinin August 20, 201315 comments

Yossi Kreinin shows how to get usable coroutines in plain C by combining setjmp/longjmp with a bit of inline assembly. The post walks through a working iterator example, explains why you must allocate and switch a separate stack, and outlines the start/yield/next API. It also flags portability pitfalls like stack growth direction and frame pointers, and points to makecontext and Tony Finch alternatives.


Important Programming Concepts (Even on Embedded Systems) Part I: Idempotence

Jason SachsJason Sachs August 26, 20145 comments

Idempotence is a simple design principle that prevents duplicate effects when operations are retried or repeated. Jason Sachs shows why it matters in embedded systems, from HTTP submit buttons and capacitive touch inputs to garage-door remotes and SPI DAC writes. Read this post to learn three practical idempotent techniques and when redundant writes are a sensible reliability trade-off.