Software testing in embedded — unit tests on host, HIL testing
5.5.20· Coding › Embedded Systems & Real-Time Software
Hum Kya Solve Kar Rahe Hain
Embedded systems mein teen testing challenges hain:
- Slow iteration: Hardware pe firmware flash karne mein seconds/minutes lagte hain
- Limited observability: No console, tiny MCUs pe limited debugging
- Hardware dependencies: Code sensors, timers, interrupts pe depend karta hai jo aapki dev machine pe exist nahi karte
Hum isko ek two-tier testing strategy se solve karte hain:
- Unit tests on host (fast, isolated logic-focused)
- Hardware-in-the-loop (HIL) testing (real hardware, real-time verification)
Unit Tests on Host
Yeh Kyun Kaam Karta Hai
Key Insight: Zyaadatar embedded logic pure computation hai jise real hardware ki zaroorat nahi:
- Sensor data processing algorithms (Kalman filters, PID controllers)
- Protocol parsing (UART frames, CAN messages)
- State machines aur business logic
- Data structure operations
Hum kya mock karte hain: Hardware-specific I/O—GPIO reads, ADC conversions, timer interrupts.
Host Testing Ke Liye Structure Kaise Karein
1. Hardware Abstraction Layer (HAL)
Hardware access ko logic se alag karo:
// ❌ BAD: Direct hardware access
void update_motor(void) {
uint16_t adc_value = ADC1->DR; // Direct register read
int pwm = compute_pwm(adc_value);
TIM2->CCR1 = pwm; // Direct register write
}
// ✅ GOOD: Abstracted through HAL
void update_motor(void) {
uint16_t adc_value = hal_adc_read(ADCHANNEL_1);
int pwm = compute_pwm(adc_value); // Pure logic!
hal_pwm_set(PWM_CHANNEL_1, pwm);
}Yeh step kyun? Saari hardware access ko hal_* functions ke through route karke, hum implementations swap kar sakte hain: production ke liye real hardware, testing ke liye mocks.
2. Host Ke Liye Mock Implementation
// mock_hal.c (compiled only for tests)
static uint16_t mock_adc_values[4] = {0};
void mock_hal_set_adc(int channel, uint16_t value) {
mock_adc_values[channel] = value;
}
uint16_t hal_adc_read(int channel) {
return mock_adc_values[channel];
}Ab aapka test inputs inject kar sakta hai:
// test_motor_control.c
void test_motor_pwm_limits(void) {
mock_hal_set_adc(ADC_CHANNEL_1, 4095); // Max ADC value
update_motor();
assert(hal_pwm_get(PWM_CHANNEL_1) == 1000); // Check PWM cap
}Yeh kyun kaam karta hai: Logic function compute_pwm() host CPU pe mock data ke saath chalta hai. Koi hardware nahi chahiye.
3. Build System Setup
Aapko do compilation targets chahiye:
# Target: ARM Cortex-M4
firmware.elf: main.c motor_control.c hal_stm32.c
arm-none-eabi-gcc -mcpu=cortex-m4 -o firmware.elf $^
# Host: x86_64 Linux
test_runner: test_motor_control.c motorc mock_hal.c
gcc -DUNIT_TEST -o test_runner $^ -lunity
./test_runnerAlag builds kyun? Different compilers, different HAL implementations, different entry points (main vs test framework).
Hardware-in-the-Loop (HIL) Testing
HIL Kya Test Karta Hai Jo Host Tests Nahi Kar Sakta
- Real-time behavior: ISR latency, task scheduling, race conditions
- Hardware quirks: ADC noise, GPIO bounce, clock drift
- Integration: Multiple peripherals ka interaction (SPI + UART + Timers)
- Electrical characteristics: Signal rise times, voltage thresholds
HIL Test Setup Architecture

Components:
- Device Under Test (DUT): Aapka embedded board jo firmware chala raha hai
- Test Controller: PC ya automation system jo test scripts chala raha hai
- Stimulus Generation: DACs, signal generators sensors simulate karne ke liye
- Response Capture: ADCs, logic analyzers DUT outputs padhne ke liye
- Communication Bus: UART/CAN/Ethernet command/telemetry ke liye
Example: Motor Control HIL Test
Scenario: Test karo ki motor PWM, ADC input changes pe sahi respond karta hai.
Setup:
- Test controller DAC ke zariye analog voltage bhejta hai (throttle simulate karta hai)
- DAC output → DUT ADC input
- DUT PWM output → Test controller pe Counter/Timer
Test script (Python pseudocode):
def test_motor_response_time():
# Set throttle to 50%
test_rig.set_dac_voltage(ADC_THROTTLE, 1.65) # 1.65V = 50% of 3.3V
time.sleep(0.01) # Allow settling
# Measure PWM duty cycle
pwm_duty = test_rig.measure_pwm(PWM_MOTOR)
# Verify mapping: 50% throttle → 50% PWM (within 2%)
assert abs(pwm_duty - 50.0) < 2.0
# Measure response time
start = time.perf_counter()
test_rig.set_dac_voltage(ADC_THROTTLE, 0.0) # Throttle to 0
while test_rig.measure_pwm(PWM_MOTOR) > 5.0: # Wait for PWM to drop
pass
response_time = time.perf_counter() - start
assert response_time < 0.010 # Must respond within 10msHar step kyun?
- Set DAC: Repeatable analog input create karo (real sensor vary karta)
- Measure PWM: Verify karo ki control law math reality se match karta hai
- Time measurement: Timing regressions pakdo (e.g., slow I²C read add ho gayi)
CI/CD Ke Saath Automated HIL
Modern approach: Jenkins/GitLab runner pe HIL test rig
# .gitlab-ci.yml
hil-tests:
stage: test
tags:
- hil-runner # Runner with testrig attached
script:
- make flash_dut # Flash firmware to DUT
- python3 hil_tests/run_all.py
artifacts:
reports:
junit: hil_tests/results.xmlAutomate kyun? Regression detection—naya commit timing tod de, test fail ho, merge block ho jaaye.
Recall Ek 12-Saal Ke Bachche Ko Samjhao
Socho tum ek robot bana rahe ho jo ek light sensor pe respond karta hai:
Apne computer pe testing (host tests): Tum pretend karte ho ki sensor keh raha hai "bahut roshan hai!" aur check karte ho ki tumhara code sahi motor speed calculate karta hai. Yeh super fast hai—tum ek minute mein 100 ideas test kar sakte ho. Lekin tum sirf apni math aur logic test kar rahe ho, yeh nahi ki real sensor kaam karta hai ya nahi.
Real robot ke saath testing (HIL): Tum real sensor pe actual flashlight maarte ho aur real motors ko spin karte dekho. Yeh slower hai—tumhe robot ke paas jaana padta hai, light maaro, cheezein measure karo. Lekin ab tum sab kuch ek saath test kar rahe ho: sensor, wires, microchip ki speed, yahan tak ki motors zyaada hilaate hain ya nahi.
Smart strategy: Pehle fast computer tests karo 90% bugs fix karne ke liye. Phir real robot tests karo ensure karne ke liye ki yeh real world mein actually kaam karta hai. Yeh aisa hai jaise pehle paper pe apna math homework check karo (fast) aur uske baad science fair project banao (slow but proves it works).
Connections
- Hardware Abstraction Layer (HAL) Design - Testability ke liye structure
- Mocking and Stubbing in C - Host tests ke liye techniques
- Real-Time Operating Systems (RTOS) - Timing guarantees jo HIL verify karta hai
- Continuous Integration for Embedded - Dono tiers automate karna
- Logic Analyzers and Oscilloscopes - HIL debugging ke tools
- Fault Injection Testing - Advanced HIL technique
#flashcards/coding
Embedded software testing ke do tiers kya hain? :: Host-based unit tests (fast, logic-focused) aur Hardware-in-the-Loop (HIL) testing (real hardware, real-time verification)
Host unit tests se real-time behavior kyun test nahi ho sakta?
Embedded testing mein Hardware Abstraction Layer (HAL) kya hai?
Embedded host tests ke liye 80% coverage rule kya hai?
HIL ka matlab kya hai aur yeh kya test karta hai?
HIL testing host testing se slower kyun hai?
Host tests aur HIL tests ka sahi ratio kya hai?
HIL testing mein Device Under Test (DUT) kya hota hai? :: Embedded board/system jo aapka firmware chala raha hai jise tum external stimulus aur measurement equipment se test kar rahe ho