Senior Engineer (7 years) transitioning from automotive application development to embedded systems engineering.
I spent years working above hardware abstractions. Now I'm learning what's below them—by building bare-metal drivers, parsers, and kernels from scratch.
Background: 7 years as Senior Engineer in automotive software (application layer)
Current Focus: Teaching myself embedded systems fundamentals through hands-on hardware projects
Goal: Transition to firmware/embedded roles where I work directly with hardware
Why the switch? After years of promises about "hardware opportunities coming soon," I decided to create my own path. I'm investing my time learning register-level programming, interrupt-driven architecture, and real hardware debugging.
| Category | Skills |
|---|---|
| Microcontrollers | STM32 (G0 series - deep), F4 series (learning) |
| Architecture | Bare-metal C, Register-level programming, Interrupt-driven design |
| Peripherals | UART (deep), GPIO, Timers, SPI (in progress), DMA (learning) |
| Protocols | UART, Custom network protocols, SPI (learning), I2C (learning) |
| RTOS | FreeRTOS (learning), Custom kernel development (completed) |
| Tools | ARM GCC, GDB, OpenOCD, ST-Link, Make, Unity (TDD), Oscilloscope (basic), Logic Analyzer (basic) |
| Debugging | JTAG (learning), Stack analysis, Hardware validation |
| Standards | MISRA C:2012 (learning), Test Driven Development |
| Category | Skills |
|---|---|
| Languages | C (proficient), C++ (familiar), ARM Assembly (learning) |
| Development | Git, Requirements analysis, Testing (unit/integration/system) |
| Domain | Automotive software development |
| Methodologies | Agile, V-Model validation, TDD |
Preemptive Priority-Based RTOS from Scratch
Built a complete Real-Time Operating System for ARM Cortex-M0+ as part of M.Tech dissertation. This was the deep dive—implementing task scheduling, context switching, synchronization primitives, and memory management entirely from first principles.
Core Features Implemented:
- Scheduler: O(1) priority-based preemptive scheduler with 8 priority levels
- Context Switching: Hand-written ARM Cortex-M0+ assembly (measured 4.81 µs @ 16 MHz)
- Synchronization: Semaphores, mutexes with priority inheritance protocol
- IPC: Message queues with blocking send/receive
- Memory Management: Fixed-block allocator with O(1) allocation/deallocation
- Safety: Stack overflow detection with canary values
- Power: Tickless idle mode for low-power operation
- HAL: Hardware abstraction layer for portability
The Hard Parts:
- Debugging context switch corruption (stack alignment issues took 3 days)
- Implementing priority inheritance without deadlock scenarios
- Hand-writing PendSV handler in ARM assembly for Cortex-M0+ constraints
- Managing 36KB RAM budget across 16 tasks with proper stack allocation
- Building comprehensive test suite (13 automated tests covering all features)
Key Learnings:
- Deep understanding of ARM Cortex-M exception model and interrupt priorities
- Stack frame layout and PSP/MSP register management
- Critical section design and interrupt masking strategies
- Trade-offs between O(1) scheduling vs memory overhead
- Hardware timer programming for RTOS tick generation
Performance Metrics:
- Context switch: 4.81 µs (target: <10 µs) ✅
- Memory allocation: O(1) constant time ✅
- Kernel footprint: ~8 KB FLASH ✅
- Stack overhead: 1 KB per task
- Tested with 6 concurrent tasks under stress
Tech: STM32G071RB | Bare-metal C | ARM Assembly | Cortex-M0+ | SysTick | PendSV | 13 automated tests
Bare-Metal Networked File Server (No OS, No TCP/IP)
Collaborative project building a remote file storage node on STM32G0. Replacing heavy IP stacks with "MiniProt", a custom lightweight (<8KB) transport protocol over raw Ethernet frames for SD card file management.
Team Split (Target: Dec 17, 2025):
- My Role: Protocol framing, CRC-16 error detection/correction, bare-metal SPI driver, ENC28J60 integration
- Sathvik: Protocol reliability and security mechanisms
Project Phases:
- Phase 1 (Dec 17): ENC28J60 driver analysis, bare-metal SPI driver, protocol implementation, driver integration
- Phase 2: FatFs integration, Em-CLI for remote operations, SD card file management
- Phase 3: IoT add-on (problem statement TBD)
IoT Use Case:
flowchart TB
subgraph IoT_Sensors["IoT Sensor Network"]
S1[Temperature Sensor]
S2[Humidity Sensor]
S3[Motion Sensor]
S4[Other IoT Devices]
end
subgraph Edge_Device["TinyServe-STM32 (Edge Node)"]
ETH[Ethernet Controller<br/>ENC28J60]
MCU[STM32G0<br/>Protocol Stack]
SD[SD Card Storage<br/>FatFs]
ETH <-->|SPI| MCU
MCU <-->|SPI| SD
end
subgraph Cloud_Backend["Remote System"]
GW[Gateway/Server]
DB[(Database)]
API[REST API]
UI[Web Dashboard]
GW --> DB
DB --> API
API --> UI
end
S1 -->|Sensor Data| MCU
S2 -->|Sensor Data| MCU
S3 -->|Sensor Data| MCU
S4 -->|Sensor Data| MCU
MCU -->|Store Locally| SD
MCU <-->|MiniProt over Ethernet| ETH
ETH <-->|Network| GW
UI -->|Query/Commands| API
API -->|Retrieve Data| GW
GW <-->|File Operations| ETH
style Edge_Device fill:#e1f5ff
style IoT_Sensors fill:#fff4e1
style Cloud_Backend fill:#f0e1ff
classDef storage fill:#c8e6c9
class SD storage
Solving edge data storage + remote accessibility for IoT deployments: local buffering during network outages, lightweight remote file operations, cost-effective Ethernet over cellular/WiFi.
The Hard Parts:
- Designing lightweight protocol with robust framing and error correction
- SPI arbiter for Ethernet Controller + SD Card on shared bus (no mutex)
- MISRA C:2012 compliance with TDD workflow
- 8KB protocol stack budget on 36KB RAM system
Key Learnings:
- Custom protocol design over raw Ethernet frames (no TCP/IP overhead)
- Register-level SPI driver with resource contention management
- TDD for protocol logic validation before hardware deployment
- ENC28J60 Ethernet controller architecture and integration
Tech: STM32G071RB | Bare-metal C | ENC28J60 (Ethernet) | FatFs | Em-CLI | SPI Arbitration | MISRA C | Unity (TDD)
Bare-metal UART driver with JSON parsing
My first real embedded project. Built UART driver from scratch (no HAL), integrated JSON parser, and learned what "memory constraints" actually means.
The Hard Parts:
- Debugged stack overflow that took 2 days (learned to read .map files)
- Built interrupt-driven state machines for concurrent TX/RX
- Handled all hardware errors (overrun, framing, parity, noise)
- Created 3-tier testing strategy (unit, integration, hardware validation)
Key Learnings:
- Register-level UART configuration (read 800+ page reference manual)
- Interrupt service routine design and optimization
- Memory management on resource-constrained systems (36KB RAM)
- Hardware debugging with real tools (not just printf)
Tech: STM32G071RB | Bare-metal C | UART (9600 baud) | JSMN Parser | 18 automated tests
Interactive Command-Line Interface for Embedded Systems
Building on Serial-JSON-Bridge, this project adds human-machine interaction through a full CLI framework. Created extensible command registration system with built-in commands (help, set, get) and JSMN parser integration for future JSON protocol support—serving as the foundation for TinyServe's Em-CLI remote management interface.
The Hard Parts: Designing memory-efficient command registration without dynamic allocation, handling user input edge cases (incomplete commands, buffer overflows), creating clean separation between UART driver layer and CLI parser logic, building extensible framework under STM32G0 constraints.
Key Learnings: User interface design for resource-constrained systems, command parsing and tokenization strategies, building frameworks in bare-metal C with zero malloc, importance of good CLI help systems in embedded tools.
Tech: STM32G071RB | Bare-metal C | UART | Command Parser | JSMN | Extensible Architecture
My approach:
- Start with fundamentals (datasheets, reference manuals)
- Build from scratch (no HAL, no magic)
- Test on real hardware (catch real-world issues)
- Document failures (they teach more than successes)
- Iterate and improve
Current learning pattern:
- UART driver (done) → CLI interface (done) → Custom protocols (in progress) → SPI + Ethernet → I2C
- Build depth in one peripheral before moving to next
- Each project builds on previous learnings
- Now focusing on networking and protocol design
Immediate (Next 2-3 Months):
- Complete custom RTOS kernel (DONE - see Cortex-M0-RTOS-Kernel)
- Complete Interactive CLI (DONE - foundation for TinyServe Em-CLI)
- Complete TinyServe-STM32 Phase 1 (Protocol Stack + Loopback Test)
- Complete TinyServe-STM32 Phase 2 (Full NAS functionality)
- Complete UART driver with DMA
- Build I2C driver + EEPROM interface
Near-term (3-6 Months):
- Multi-peripheral system integration
- Bootloader design and implementation
- Low-power mode optimization
- CAN bus driver (leverage automotive knowledge)
Goal: Build sufficient portfolio depth to transition into firmware/embedded engineering role.
From 7 years in automotive:
- ✅ Professional maturity (meeting deadlines, working in teams)
- ✅ Software engineering discipline (testing, documentation, architecture)
- ✅ Domain knowledge (automotive requirements, safety mindset)
- ✅ Problem-solving methodology (systematic debugging)
From self-teaching embedded:
- ✅ Proven learning ability (projects speak for themselves)
- ✅ Genuine passion for hardware (not just career desperation)
- ✅ Hands-on experience (real hardware, real debugging)
- ✅ Growth mindset (document failures, iterate, improve)
- ✅ Deep dive capability (built complete RTOS from scratch)
- ✅ Protocol design experience (custom networking stack in progress)
What I'm looking for: Entry-level to junior embedded/firmware roles where I can apply software engineering fundamentals to hardware development and learn from experienced embedded engineers.
Currently building a portfolio for transition to embedded systems roles. Open to discussing firmware opportunities, embedded projects, or just talking about hardware.
"After 7 years of working above abstractions, I'm learning what's below them. One register at a time."