In short
Embedded Linux is a full Linux kernel plus a minimal, purpose-built root filesystem running on a resource-constrained device rather than a desktop. It is chosen when an application needs networking, a filesystem, a display stack, multiple processes or large libraries - things a bare-metal 8051 or small ARM Cortex-M build cannot carry. Single-board computers (SBCs) such as the Raspberry Pi, BeagleBone Black and India's own boards are complete computers on one PCB and are the standard teaching and prototyping platform for it. University syllabi examine the boot sequence, cross-compilation toolchain, device tree, build systems (Yocto/Buildroot) and GPIO/driver access; placement rounds at Bosch, Tata Elxsi, L&T Technology Services, HCLTech, Qualcomm, Texas Instruments India, KPIT, ISRO/DRDO labs and C-DAC ask these as standard screening questions.
Explained
Why Linux on an embedded device, and when not to
- Application processor vs microcontroller: Linux needs a memory management unit (MMU), tens of MB of RAM and non-volatile storage. Cortex-A class SoCs (Broadcom BCM2711, TI AM335x, NXP i.MX, Rockchip, Allwinner) have an MMU; Cortex-M microcontrollers generally do not.
- Rough practical floor: a usable headless Linux needs on the order of 8-16 MB RAM and a few MB of flash for a stripped BusyBox system; real products typically ship 256 MB-4 GB RAM. (Figures vary with configuration - treat as orders of magnitude, not specifications.)
- Choose Linux when you need TCP/IP and TLS, a filesystem, USB/Wi-Fi/Bluetooth stacks, a GUI or camera pipeline, Python/Qt/OpenCV, multi-process software, field software updates.
- Choose bare metal or an RTOS when you need microsecond-deterministic response, instant boot, battery life measured in years, very low BOM cost, or safety certification of a small codebase.
- No-MMU option: uClinux-style builds (
CONFIG_MMU=n) run on MMU-less parts, but without memory protection orfork()(onlyvfork()). - Licensing: the kernel is GPLv2 - modifying and shipping it obliges you to offer the modified kernel source; user-space applications linking to glibc/musl are not thereby GPL'd. Many SBC projects also publish hardware designs; a company's legal/compliance team usually keeps a bill of licences.
Software stack, layer by layer
- Boot ROM inside the SoC: fixed, mask-programmed code; reads boot-mode pins/eFuses and loads a small first-stage loader from SD, eMMC, NAND, SPI flash, USB or Ethernet.
- First-stage loader / SPL (MLO): initialises DDR controller, clocks and a minimum of pin muxing, then loads the full bootloader. (On the Raspberry Pi this role is taken by the VideoCore GPU firmware -
bootcode.bin/start.elfon older models, SPI EEPROM on Pi 4/5.) - Bootloader - U-Boot (most common; alternatives: barebox, GRUB/EFI on x86 SBCs): brings up console, storage and network, loads the kernel image (
zImage/Image/uImage), the device tree blob and optionally an initramfs, then jumps to the kernel passing a kernel command line. Useful U-Boot commands:printenv,setenv,saveenv,tftpboot,fatload mmc 0:1 0x82000000 zImage,bootz. - Linux kernel: decompresses, parses the device tree, probes drivers, mounts the root filesystem given by
root=/dev/mmcblk0p2. - init: PID 1 -
systemd(most distributions), SysV init scripts, or BusyBoxinitwith/etc/inittabon small systems. It mounts/proc,/sys,/dev(devtmpfs + udev/mdev), brings up networking and starts the application service. - Root filesystem:
/bin /sbin /lib /etc /dev /proc /sys /var /tmp /home /opt. BusyBox provides hundreds of shell utilities as one multi-call binary (symlinks point to it). - Kernel command line example:
console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait rw rootfstype=ext4 quiet.
Device tree, drivers and user-space hardware access
- Device tree (DT): a hardware description passed to the kernel so one kernel binary serves many boards. Source
.dts+ reusable.dtsiincludes, compiled by dtc into a.dtb. Nodes carrycompatible,reg(address/size),interrupts,clocks,status,pinctrl-0. - **Overlays (
.dtbo):** patches applied at boot to enable optional hardware - on the Raspberry Pi they are listed in/boot/firmware/config.txtasdtoverlay=i2c-rtc,ds3231. - A driver's
of_match_tablelistscompatiblestrings; the kernel binds driver to node when they match. Mismatchedcompatibleis the classic "my device never probes" bug. - Driver types: character (most sensors,
/dev/ttyS0,/dev/i2c-1), block (storage), network; built in-kernel or as a loadable module (.ko) managed byinsmod,modprobe,rmmod,lsmod,depmod. - Kernel space vs user space: kernel code runs privileged with no libc and no floating-point convenience; crossing the boundary costs a system call. User space is preferred wherever a standard interface exists.
- Pseudo-filesystems:
/proc(process and kernel information:/proc/cpuinfo,/proc/interrupts,/proc/meminfo,/proc/devices),/sys(device model:/sys/class/gpio,/sys/bus/i2c/devices),/dev(device nodes, major/minor numbers). - GPIO: the old
/sys/class/gpiosysfs interface is deprecated; current practice is the character-device ABI/dev/gpiochipNwith libgpiod tools (gpiodetect,gpioinfo,gpioset,gpioget) or Pythongpiod. Pi-specific libraries: RPi.GPIO (legacy),gpiozero,pigpio,lgpio. - Bus access from user space: I2C via
/dev/i2c-Nwithi2cdetect/i2cget/i2csetorioctl; SPI via/dev/spidevB.Cwithspi_ioc_transfer; UART via/dev/ttyS*,/dev/ttyAMA0,/dev/ttyUSB0configured withtermios/sttyorpyserial; PWM and IIO sensors via/sys/class/pwmand/sys/bus/iio. - Memory-mapped access:
mmap()on/dev/memor a UIO device gives direct register access - fast, but unsafe and non-portable; a proper driver or overlay is the examinable "right answer".
Cross-development: toolchain, build systems, debugging
- Cross-compilation builds on an x86-64 host for an ARM target because the target is slow and storage-poor. Toolchain name is a triplet:
arm-linux-gnueabihf-gcc(32-bit hard-float),aarch64-linux-gnu-gcc(64-bit). - Typical kernel build:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2711_defconfigthenmake menuconfig,make -j8 zImage dtbs modules,make modules_install INSTALL_MOD_PATH=<rootfs>. - Sysroot holds target headers and libraries; C library choice: glibc (full, large), musl (small, static-friendly), uClibc-ng (legacy small systems).
- Buildroot:
make menuconfig→ produces a kernel, toolchain and a complete rootfs image in one tree. Simple, fast, rebuilt wholesale; no binary package manager. Good for fixed-function devices and for lab work. - Yocto Project / OpenEmbedded: recipes (
.bb), layers (meta-*),bitbakebuilds; produces an SDK and reproducible, versioned distributions with package feeds. Steeper learning curve, used by most product companies (and by Automotive Grade Linux). - Other paths: Debian/Ubuntu/Armbian/Raspberry Pi OS images +
apt(fastest to a working system, largest footprint);debootstrapfor a custom Debian rootfs. - Deploying and debugging: serial console on UART (115200 8N1, USB-TTL adapter - never connect a 5 V adapter to 3.3 V pins);
ssh/scp/rsync; NFS root for fast edit-test cycles; TFTP for kernel;gdbserveron target with cross-gdbon host; JTAG/SWD with OpenOCD for bootloader bring-up;dmesg,journalctl,strace,ltrace,perf,top,free,lsof. - Field updates: A/B (dual-slot) partitions or RAUC/SWUpdate/Mender, with rollback on failed boot - examined as "how do you update firmware safely in the field".
Real time, storage, power and reliability
- Standard Linux is not hard real-time: it is a throughput-fair, preemptible kernel with unbounded worst-case latency from locks and interrupt handling.
- PREEMPT_RT (mainlined into Linux 6.12 in 2024) makes most kernel code preemptible and converts spinlocks to sleeping locks, giving typical worst-case latencies in the tens to low hundreds of microseconds on good hardware - versus milliseconds on a stock kernel. Measured with
cyclictest. - Other determinism tools: CPU isolation (
isolcpus,taskset),chrtwithSCHED_FIFO/SCHED_RR,mlockall()to prevent paging, IRQ affinity, and offloading hard timing to a coprocessor - the BeagleBone's PRU (200 MHz programmable real-time unit) or an on-chip Cortex-M4 in i.MX/STM32MP1 parts. - Storage: raw NAND/NOR needs flash-aware filesystems UBIFS/JFFS2; managed flash (SD, eMMC, USB) has an internal FTL so ext4 is used. Reduce wear with
noatime,tmpfsfor/tmpand/var/log, a read-only root with an overlay, and a journal-less ordata=writebackoption where safe. - Power loss corrupts SD cards - the single most common field failure of Pi-based products; remedies are read-only root, supercapacitor/UPS HAT and clean shutdown on a power-fail GPIO.
- Watchdog:
/dev/watchdogwith a user-space daemon petting it; the SoC resets the board if the application hangs. - Boot time reduction: smaller kernel config, skip initramfs,
quiet, disable unused drivers,systemd-analyze blame, keep heavy services lazy. A tuned system boots in 1-3 s; a stock desktop-style image takes 20-40 s. - Security: change default credentials, disable unused services, dm-verity / secure boot chains,
iptables/nftables, and treat any internet-facing SBC as an IT asset. India's CERT-In 2022 directions require reporting of cyber incidents (including IoT incidents) within 6 hours, and the DPDP Act, 2023 governs personal data a device collects; BIS compulsory registration (CRS) under the Electronics and IT Goods order applies to many SBC/adapter products sold in India - check the current CRS product list, which is revised often.
Popular SBCs and how they are used in the lab
- Raspberry Pi 4 / 5: BCM2711/BCM2712 quad Cortex-A72/A76, 1-16 GB RAM (Pi 4: 1-8 GB; Pi 5: 2-16 GB), 40-pin header (28 GPIO lines, of which 26 are freely usable - GPIO0/GPIO1 are reserved for HAT ID EEPROM - all 3.3 V, no analog input), I2C/SPI/UART/PWM/I2S, Gigabit Ethernet, Wi-Fi/BT, CSI camera, HDMI. Boots Raspberry Pi OS from microSD; Pi 5 adds PCIe and a separate RP1 south-bridge.
- BeagleBone Black: TI AM335x Cortex-A8 1 GHz, 512 MB DDR3, 4 GB eMMC, 65 GPIO on two 46-pin headers, 7 on-board 12-bit ADC channels (1.8 V max), 2× PRU - the board of choice when you need both Linux and hard real-time I/O. Beagle Y-AI / BeaglePlay are the newer TI boards.
- Others: Orange Pi, Banana Pi, Rock Pi/Radxa, NVIDIA Jetson Nano/Orin (CUDA for edge AI), ODROID, Intel-based UP boards, and Indian options - Arduino-/RPi-compatible boards from Indian vendors, C-DAC's PARAM-related and VEGA RISC-V processors (Thejas32 SBC), and the Shakti RISC-V family from IIT Madras.
- Microcontroller-class "Pi" boards - Raspberry Pi Pico (RP2040/RP2350) - run bare metal or MicroPython, not Linux: a very common interview trap.
- Industrial form factors: SoM/CoM (system-on-module) such as Variscite, Toradex Colibri/Verdin, PHYTEC, plus an application-specific carrier board - the standard way a prototype on an SBC becomes a product.
Key points
- Embedded Linux - a configured Linux kernel plus a minimal purpose-built rootfs on constrained hardware; needs an MMU except in uClinux builds.
- SBC - a complete computer (SoC, RAM, storage, I/O) on one board; Raspberry Pi and BeagleBone are the exam standards.
- Boot chain - Boot ROM → SPL/first-stage → U-Boot → kernel + DTB (+ initramfs) → init → application.
- U-Boot - loads and hands over the kernel, DTB and command line;
bootargs/bootcmdin its environment decide the boot. - Device tree -
.dts/.dtsicompiled bydtcinto.dtb;compatiblestring binds hardware node to driver; overlays (.dtbo) enable optional peripherals. - Root filesystem - supplied by
root=on the command line; BusyBox packs the common utilities into one multi-call binary. - init - PID 1: systemd, SysV init or BusyBox init; starts services and the application.
- Kernel module -
.koloaded withinsmod/modprobe; lets drivers ship separately from the kernel image. - /proc, /sys, /dev - process/kernel info, device model attributes, device nodes; the user-space windows onto hardware.
- GPIO today -
/dev/gpiochipNwith libgpiod;/sys/class/gpiois deprecated. - Bus device files -
/dev/i2c-N,/dev/spidevB.C,/dev/ttyS*; no analog input on the Pi, 7 ADC channels on BeagleBone Black. - Cross-compilation - host-built binaries for the target using a triplet toolchain (
arm-linux-gnueabihf-,aarch64-linux-gnu-) and a sysroot. - Buildroot vs Yocto - Buildroot is simple and rebuilt wholesale; Yocto uses layers/recipes/bitbake and gives versioned, package-managed distributions.
- Not real-time - stock Linux gives soft real-time only; PREEMPT_RT (mainline since 6.12) plus
SCHED_FIFO,mlockall(), CPU isolation reduce worst-case latency to tens of microseconds. - PRU / companion core - the way to get hard microsecond timing alongside Linux.
- Flash filesystems - UBIFS/JFFS2 for raw NAND; ext4 for SD/eMMC; read-only root and
noatimeprotect against corruption and wear. - GPLv2 - shipping a modified kernel obliges you to offer its source; user-space applications are unaffected by that obligation.
- Watchdog and A/B updates -
/dev/watchdogrecovers hangs; dual-slot images with rollback make field updates safe.
Formulas and examples
Boot time T_boot = t_ROM + t_SPL + t_U-Boot + t_kernel + t_init + t_app (sum of measured stages, seconds)
SD/eMMC transfer time t = bytes / sustained throughput (B ÷ B·s⁻¹ = s)
Flash wear: write-amplified lifetime ≈ (capacity × P/E cycles) / (daily write bytes × WAF) days; WAF = write amplification factor (dimensionless)
Baud rate to byte rate: bytes/s = baud / bits-per-frame (8N1 → 10 bits per byte, so 115200 baud ≈ 11,520 B/s)
Serial latency per byte at 8N1 = 10 / baud seconds
CPU load of a periodic task: U = C / T, C = execution time, T = period; the task is feasible only if ΣU ≤ 1 (and worst-case latency ≪ T)
I2C sensor sample rate limit ≈ bus clock / (bits per transaction), bits ≈ 9 × (bytes + address bytes) including ACKs
GPIO power: I = (V_supply − V_f) / R, series resistor R in Ω, LED forward drop V_f in V
1. A/B update partition budget on a 4 GB eMMC
- Kernel 6 MB + DTB 0.06 MB + rootfs 420 MB = ~426 MB per slot.
- Two slots = 852 MB; boot/U-Boot partition 8 MB; leave 5% eMMC spare.
- 4 GB eMMC ≈ 3,820 MB usable → data partition = 3,820 − 852 − 8 − 191 (5%) ≈ 2,769 MB.
- Conclusion: A/B updates are comfortably affordable here; on a 512 MB flash they would not be, and a single-slot update with a recovery initramfs would be used.
2. Boot-time budget
| Stage | Stock image (s) | Tuned (s) |
|---|---|---|
| Boot ROM + SPL | 0.25 | 0.25 |
| U-Boot (3 s autoboot delay) | 3.20 | 0.20 |
| Kernel (full config, initramfs) | 4.50 | 1.10 |
| systemd to multi-user | 18.00 | 0.90 |
| Application start | 2.00 | 0.35 |
| Total | 27.95 | 2.80 |
- Savings come from
bootdelay=0, dropping the initramfs, a trimmed kernel config and replacing most systemd units with a single application service - a 10× reduction, which is the usual order of improvement.
3. SD-card wear on a logging device
- Device writes a 2 kB record every second: 2,048 × 86,400 = 176,947,200 B/day ≈ 168.8 MiB/day.
- Card 32 GB, assume 1,000 P/E cycles and a write-amplification factor of 10 (small random writes on 512 kB erase blocks).
- Endurance ≈ 32,768 MiB × 1,000 / (168.8 × 10) ≈ 19,412 days ≈ 53 years - so wear is *not* the limit; the limit is power-fail corruption. Repeat with WAF 100 and 300 P/E cycles (cheap card): 32,768 × 300 / (168.8 × 100) ≈ 582 days ≈ 1.6 years, which is a real product risk. Hence: buy industrial/pSLC cards, batch writes, and mount logs on
tmpfswith periodic flush.
4. Can a user-space loop read a sensor at 1 kHz?
- I2C sensor, 400 kHz fast mode, read of 6 bytes + 1 address byte + register byte = 8 bytes ≈ 8 × 9 = 72 bit-slots ≈ 72/400,000 = 180 µs bus time.
- Add two
ioctlsyscalls and scheduler jitter: on a stock kernel, worst-case wake-up jitter is commonly 1-10 ms, far more than the 1 ms period. - With
SCHED_FIFOpriority 80,mlockall(), a PREEMPT_RT kernel and an isolated CPU, jitter falls to tens of µs and 1 kHz becomes reliable. - Verdict: 1 kHz is achievable only with RT configuration; 10 kHz needs a PRU, an on-chip M4 or a hardware FIFO.
5. Console throughput check
- Logging 200 bytes per line at 10 lines/s over a 115200 8N1 serial console: required = 2,000 B/s; available = 115,200/10 = 11,520 B/s → 17% utilisation, fine.
- At 921600 baud with 1,000 lines/s of 200 bytes: required 200,000 B/s vs available 92,160 B/s → impossible; printing from an interrupt-heavy path would also block the kernel, so logs must go to a ring buffer or the network.
| Bare metal / RTOS on MCU | Embedded Linux on SBC/SoC | |
|---|---|---|
| Hardware | Cortex-M, no MMU, kB of RAM | Cortex-A with MMU, MB-GB of RAM |
| Boot time | µs-ms | 1-30 s |
| Determinism | Hard real-time, µs | Soft; tens of µs with PREEMPT_RT |
| Networking/filesystem | Added as libraries, limited | Full TCP/IP, TLS, ext4, USB, Wi-Fi |
| Development | Single binary, JTAG debug | Toolchain + rootfs + kernel + userland |
| Power | µA sleep modes | mA to W; suspend is harder |
| Unit cost | ₹50-₹500 class | ₹1,500-₹10,000 class |
| Typical use | Motor control, metering, sensing | Gateway, HMI, camera, edge AI |
| Buildroot | Yocto / OpenEmbedded | Debian-based image | |
|---|---|---|---|
| Configuration | make menuconfig, Kconfig | layers + .bb recipes, bitbake | ready image + apt |
| Output | kernel + rootfs image | distribution + SDK + package feed | general-purpose distro |
| Build time (first) | tens of minutes | hours | minutes |
| Package manager on target | none by default | opkg/rpm/deb | apt |
| Best for | fixed-function devices, teaching | products, long-lived product lines | prototypes, fastest start |
Where it is used
- Automotive and ADAS: infotainment, instrument clusters and telematics on Linux/Android Automotive at Bosch, Continental, Visteon, Harman, KPIT, Tata Elxsi and L&T Technology Services - roles titled "BSP engineer", "Linux device driver engineer", "Yocto build engineer".
- Networking and telecom CPE: routers, ONTs and 5G CPE from Sterlite, Tejas Networks, HFCL and Reliance Jio run OpenWrt/Yocto Linux; BSP and bring-up work on Qualcomm, Broadcom and MediaTek SoCs.
- Industrial and energy: edge gateways, SCADA RTUs, PLC HMIs and smart-meter data concentrators (IS 15959 / IS 16444 define India's smart-meter data exchange and meter specifications), machine-vision inspection on Jetson boards.
- Medical, retail and kiosks: patient monitors, Aadhaar-enabled e-KYC and biometric kiosks, UPI-capable POS terminals and billing devices, digital signage - typically an i.MX or Rockchip SoM running Yocto Linux.
- Space, defence and research: ISRO, DRDO, BEL and C-DAC use Linux on ARM/PowerPC/RISC-V targets; C-DAC's VEGA (Thejas32) and IIT Madras's Shakti RISC-V cores are the indigenous-processor track under the Digital India RISC-V (DIR-V) programme.
- Education and prototyping: Raspberry Pi/BeagleBone labs in AICTE-aligned microprocessor and IoT courses, final-year projects, Smart India Hackathon entries, and Atal Tinkering Labs in schools.
Interview questions
- Q: Why can't Linux run on an 8051 or a Cortex-M microcontroller? A: Standard Linux requires an MMU for virtual memory and process isolation, plus tens of MB of RAM; such microcontrollers have neither, so bare metal or an RTOS is used instead (uClinux is a no-MMU exception without process protection).
- Q: Describe the boot sequence of an ARM Linux SBC. A: SoC boot ROM loads the SPL, which initialises DDR and loads U-Boot; U-Boot loads the kernel image, device tree blob and optional initramfs with a command line; the kernel probes drivers from the device tree, mounts the root filesystem given by
root=, and starts PID 1 (init/systemd), which starts the application. - Q: What problem does the device tree solve? A: It moves board-specific hardware description out of the kernel into a data file, so one kernel binary supports many boards and a new board needs a new
.dtsrather than kernel source changes. - Q: How does a driver get bound to a device-tree node? A: The node's
compatiblestring is matched against the driver'sof_match_table; on a match the kernel calls the driver'sprobe()with that node's resources. - Q: Difference between Buildroot and Yocto? A: Buildroot is a Kconfig-driven tree that builds one complete rootfs image quickly and is rebuilt wholesale; Yocto is a layered recipe-and-bitbake system that produces a maintainable distribution with package feeds and an SDK, at the cost of complexity.
- Q: Is Linux a real-time operating system? A: No - stock Linux offers soft real-time with millisecond-scale worst-case latency; PREEMPT_RT (mainlined in 6.12) with
SCHED_FIFO,mlockall()and CPU isolation brings worst-case latency to tens of microseconds, and hard microsecond timing is offloaded to a PRU or companion Cortex-M. - Q: Why cross-compile instead of building on the board? A: The target has far less CPU, RAM and storage; a host x86-64 machine builds a kernel in minutes rather than hours, and keeps the target image free of compilers and headers.
- Q: What is the current correct way to toggle a GPIO from user space? A: Use the
/dev/gpiochipNcharacter-device ABI through libgpiod (gpioset, orgpiodin Python); the/sys/class/gpiosysfs interface is deprecated. - Q: Why does the Raspberry Pi have no analog input, and what do you do about it? A: The BCM SoC includes no ADC; add an external ADC over SPI or I2C (MCP3008, ADS1115) or use a board that has one, such as the BeagleBone Black with 7 channels of 12-bit ADC.
- Q: Why do SD cards fail in deployed Pi-based products, and how do you prevent it? A: Unclean power-down during a write corrupts the filesystem, and small frequent writes wear the flash; fixes are a read-only root with an overlay, logs on
tmpfs,noatime, industrial/pSLC cards, and a controlled shutdown on power-fail detection. - Q: When would you choose a loadable module over a built-in driver? A: When the driver is optional or field-updatable, to keep the kernel small and boot fast, or while developing - a module can be reloaded without rebooting; the driver must be built in if it is needed to mount the root filesystem.
- Q: What are your GPLv2 obligations when shipping an embedded Linux product? A: You must make the source of the kernel and other GPL components you distribute (including your modifications) available to recipients; your own user-space applications linking only to the C library are not required to be released under GPL.
- Q: How would you debug "kernel panic - not syncing: VFS: unable to mount root fs"? A: Check the
root=device and partition, whether the rootfs driver (MMC, ext4) is built in rather than a module, therootfstype/rootwaitarguments, and the filesystem itself - read the serial console log to see which stage failed.
Common mistakes
- Confusing microcontroller boards with SBCs - saying the Raspberry Pi Pico or an Arduino "runs embedded Linux"; they run bare metal or MicroPython.
- Claiming Linux is real-time, or quoting PREEMPT_RT latency as hard determinism without naming the measurement (
cyclictest) and the configuration. - Compiling with the host
gccand wondering why the binary will not execute, or mixing a glibc binary with a musl rootfs. - Editing kernel source for board specifics instead of writing a device-tree node or overlay; or writing an overlay whose
compatibledoes not match any driver. - Connecting 5 V sensors or a 5 V USB-TTL adapter to 3.3 V GPIO/UART pins, and omitting the common ground - a reliable way to kill an SBC.
- Pulling the power instead of
shutdown, then blaming the SD card; and leaving default credentials and open SSH on an internet-facing board. - Forgetting
make modules_install/depmod, so a built module never loads, or assuming a module can mount the root filesystem it is stored on. - In exams, writing the boot sequence without the device tree and the kernel command line, or omitting the SPL/DDR-initialisation stage.
Related topics
- ARM and embedded C · Real-time operating systems · Embedded interfaces: UART, SPI and I2C · Internet of Things basics · Microcontroller peripherals: timers, ADC, PWM and interrupts · Sensors and actuators for embedded systems