Exercises — Software testing in embedded — unit tests on host, HIL testing
5.5.20 · D4· Coding › Embedded Systems & Real-Time Software › Software testing in embedded — unit tests on host, HIL testi
Shuru karne se pehle do words tumhare apne hone chahiye:
- Host = wo PC jis par tum code likhte ho (x86 laptop).
- Target / DUT = wo microcontroller (MCU) jis par firmware actually run karta hai. DUT = Device Under Test, wo board jo tumhare bench par ek HIL rig mein rakhaa hota hai.
Level 1 — Recognition
Exercise 1.1 (L1)
Har item ko HOST-testable (pure logic, koi real hardware nahi) ya HIL-only (real timing/hardware chahiye) mein classify karo: (a) Ek CRC-16 checksum function jo ek byte array par kaam karta hai. (b) UART receive handler ki interrupt latency. (c) Ek state machine jo booleans se valve OPEN/CLOSED decide karta hai. (d) 12-bit resolution par ADC electrical noise.
Recall Solution
- (a) HOST — ek array par pure arithmetic, koi peripheral nahi. ✅
- (b) HIL — latency ek event aur interrupt service routine (ISR) ke run hone ke beech ka real time elapsed hai; host time ko mock karta hai isliye ise measure nahi kar sakta.
- (c) HOST — booleans in, enum out, koi hardware nahi.
- (d) HIL — noise real analog-to-digital converter ki ek electrical property hai; ek mock exactly wo number return karta hai jo tumne inject kiya, isliye uska noise zero hota hai. Rule of thumb: agar tum use plain numbers ke roop mein inputs de sako aur outputs ko plain numbers ke roop mein check kar sako, to wo host-testable hai.
Exercise 1.2 (L1)
Neeche diye code mein wo ek line batao jo host testing ko block karti hai aur use ek hal_* call se rewrite karo.
void read_sensor(void) {
uint16_t v = ADC1->DR; // line A
store(process(v)); // line B
}Recall Solution
Line A — ADC1->DR ek physical hardware register read karta hai jo tumhare PC par exist hi nahi karta, isliye program host par crash karta hai (ya link bhi nahi hota).
Fix using a HAL seam:
uint16_t v = hal_adc_read(ADC_CHANNEL_1);Ab ek mock host par v supply kar sakta hai. Line B (process) pehle se hi pure logic thi aur isme koi change ki zaroorat nahi.
Level 2 — Application
Exercise 2.1 (L2)
Ek file mein 1000 total lines hain: 120 vendor driver code hain, 80 thin HAL glue hain, aur baaki tumhari custom logic hai. Parent note ka target yeh hai: Yahan "logic code" ka matlab hai tumhari custom logic lines. Kya tum logic par target meet karte ho? Poori file ka kitna fraction logic hai?
Recall Solution
Logic lines . Poori file ka fraction jo logic hai: Toh file ka 80% woh logic hai jise tumhe hard test karna chahiye; baaki 20% (driver + glue) ya to vendor-tested hai ya trivially thin. Agar tum saari 800 logic lines cover karo tum coverage bar comfortably hit karte ho. Target meet hota hai. ✅
Exercise 2.2 (L2)
Throttle ko ek 3.3 V reference par 12-bit ADC se read kiya jaata hai. "12-bit" ka matlab hai ADC se tak ek integer report karta hai. Tumhare HIL rig ka DAC us ADC input mein 1.65 V output karta hai. DUT ko kaun sa raw ADC integer read karna chahiye (ideal, no noise)?
Recall Solution
Max ADC code (yeh full-scale voltage represent karta hai). Conversion linear hai — code voltage ke proportional hai: , toh , floor . (Full scale ka half code 2047 hai, geometric midpoint se ek neeche kyunki hum 0 se count karte hain.)
Exercise 2.3 (L2)
compute_pwm ADC code ko linearly PWM duty (tenths of a percent) par map karta hai, aur caps at 1000. Max ADC input 4095 ke liye, aur code 2047 ke liye yeh kya return karta hai?
Recall Solution
Linear map: , phir clamp to .
- code : → exactly cap hit hota hai. Parent note ke
assert(... == 1000)se match karta hai. - code : .
Level 3 — Analysis
Exercise 3.1 (L3)
Ek UART-receive ISR ko deadline ke andar respond karna hai. Ek HIL run mein, ek logic analyzer capture karta hai: byte par aata hai, response GPIO par rise karta hai. Measured latency compute karo aur pass/fail batao. Ek host unit test yahan failure kabhi kyun nahi pakad sakta?
Recall Solution
Latency = response time − trigger time: Compare: → PASS (margin ). Host kyun nahi pakad sakta: host par, time mocked hota hai — ISR tumhare test harness dwara ek plain function ki tarah call kiya jaata hai, toh "hardware use kab tak run karega" ka koi matlab nahi hota. Real ISR latency CPU clock, higher-priority interrupts, aur cache/pipeline effects par depend karti hai jo sirf real target par exist karte hain.
Exercise 3.2 (L3)
Response-time figure dekho. Ek change motor loop mein ek slow blocking read add karta hai. Change se pehle loop measure karta tha; read leta hai. HIL deadline hai. Kya test ab bhi pass hota hai? Margin kitna shrink hota hai?

Recall Solution
New response time = old + added blocking cost: Deadline hai, aur → FAIL. Old margin tha (slack, green in the figure). New margin hai (overrun, red). Margin exactly utna shrink hua jitna humne add kiya. Yeh ek timing regression hai — HIL isi ko pakadne ke liye exist karta hai.
Exercise 3.3 (L3)
Ek test suite mein 40 host unit tests hain 3 ms each aur 8 HIL tests hain 4 s each. Har tier ka total wall-clock time compute karo. Kaunsa ratio (HIL time : host time) yeh dikhata hai ki tum logic ko host par kyun push karte ho?
Recall Solution
Host total: . HIL total: . Ratio HIL : host . HIL yahan ~267× slower hai. Har logic bug jo tum host par pakad sako ek ~267×-zyada-expensive round trip bachata hai — yahi two-tier strategy ka poora argument hai.
Level 4 — Synthesis
Exercise 4.1 (L4)
Is function ke liye seams design karo taaki yeh host-testable ban jaye, aur batao ki har hal_* mock kya return/record karta hai:
void safety_check(void) {
if (ADC2->DR > 3000) // over-temperature
GPIOB->BSRR = (1u << 5); // set fault LED
else
GPIOB->BRR = (1u << 5); // clear fault LED
}Phir dono branches cover karne ke liye do host test cases likho, aur wo boundary ADC value do jo unhe alag karti hai.
Recall Solution
Seams (mock/stub karo):
hal_adc_read(ADC_TEMP)— ek stub jise tum set karo; injected value return karta hai.hal_led_set(FAULT_LED, on)— ek mock jo last state record karta hai (spy), taaki test ise read back kar sake. Refactored:
void safety_check(void) {
bool over = hal_adc_read(ADC_TEMP) > 3000;
hal_led_set(FAULT_LED, over);
}Boundary: branch code (LED off, > false hai) aur (LED on) ke beech flip hoti hai. Toh separating boundary 3000 aur 3001 ke beech hai.
Do tests (dono branches + boundary cover karo):
// branch 1: below/at threshold -> LED off
mock_set_adc(ADC_TEMP, 3000); safety_check(); assert(mock_led == 0);
// branch 2: above threshold -> LED on
mock_set_adc(ADC_TEMP, 3001); safety_check(); assert(mock_led == 1);3000 aur 3001 choose karna (0 aur 4095 nahi) decision ko test karta hai, jahan bugs rehte hain.
Exercise 4.2 (L4)
Tumhare paas ek Makefile hai jisme do targets hain (ARM ke liye firmware, host ke liye test_runner). Tumhare CI pipeline mein tum chahte ho ki fast tier har commit ko gate kare aur slow tier nightly run kare. Decision flow ko (ek mermaid graph ke roop mein) draw karo aur justify karo ki kaunsa tier commits gate karta hai.
Recall Solution
Host tests har commit ko gate karte hain kyunki yeh ~saikdon guna faster hain (Ex 3.3) aur debuggable hain; HIL nightly shared rig par run hota hai kyunki yeh slow aur hardware-limited hai.
Level 5 — Mastery
Exercise 5.1 (L5)
Full HIL response-time test. Rig throttle DAC ko absolute time par 0 V set karta hai. DUT ka PWM 5% duty se neeche girna chahiye. Logic analyzer dikhata hai PWM par 5% cross karta hai. Deadline 10 ms hai. (a) Response time compute karo. (b) Pass ya fail, aur remaining margin. (c) Ek fault-injection variant ADC line ko stuck-high fault par hold karta hai (throttle hamesha max par appear hota hai). DUT jo PWM drive karta hai uska predict karo aur batao ki kya "drop below 5%" test kabhi pass ho sakta hai. Yeh HIL + fault injection ke combination ke baare mein kya reveal karta hai?
Recall Solution
(a) Response time do edges ka delta hai:
(b) → PASS, margin .
(c) Stuck-high ADC → DUT sochta hai throttle hamesha max code 4095 par hai → compute_pwm cap 1000 tenths = 100% duty return karta hai (Ex 2.3 se). Yeh kabhi 5% se neeche nahi girta, toh while(pwm > 5.0) loop hamesha spin karta rahta hai → test time out / fail hota hai — jo sahi result hai: firmware ke paas frozen sensor detect karne ka koi independent tarika nahi hai.
Insight: host tests control math verify karte hain; plain HIL real hardware par timing verify karta hai; HIL + fault injection broken hardware ke under safety behaviour verify karta hai. Sirf combination yeh expose karta hai ki ek stuck sensor motor ko full power par drive karta hai — teeno mein se sabse dangerous, sabse real-world failure.
Exercise 5.2 (L5)
Ek mixed strategy budget karo. Tumhe 800 logic lines par logic coverage reach karni hai. Host tests 12 lines each cover karte hain; har host test ki cost 3 ms hai. HIL ko additionally 3 timing deadlines verify karni hain 4 s each. Compute karo: (a) minimum host tests needed, (b) host-tier wall-clock time, (c) 3 HIL tests include karte hue total suite time, (d) kya plan per-commit gating ke liye sane hai agar gate budget 2 seconds hai?
Recall Solution
(a) Cover karne wali lines . Tests needed host tests. (b) Host time . (c) HIL time . Total . (d) Gate sirf host tier run karta hai: budget → sane, gate on host. HIL ke 12 s nightly run hote hain, per-commit nahi. Yeh exactly Ex 4.2 wala two-tier split hai, ab quantified.
Recall Quick self-check
12-bit ADC ka full-scale code ::: 4095 (yani , 0 se count karte hue) Host tests ISR latency kyun measure nahi kar sakte ::: host time ko mock karta hai, isliye real elapsed duration ka koi matlab nahi; sirf real hardware ke paas real clock hota hai Do logic-analyzer timestamps se latency ::: response edge minus trigger edge (ek difference, kabhi single stamp nahi) Kaunsa tier har commit gate karta hai aur kyun ::: host unit tests — saikdon guna faster aur debug karna easy Threshold boundary tests kahan place karo ::: threshold ke theek neeche aur theek upar, extremes par nahi