5.5.20 · D3 · HinglishEmbedded Systems & Real-Time Software

Worked examplesSoftware testing in embedded — unit tests on host, HIL testing

3,726 words17 min read↑ Read in English

5.5.20 · D3 · Coding › Embedded Systems & Real-Time Software › Software testing in embedded — unit tests on host, HIL testi

Yeh page ek drill hall hai. Parent note ne tumhe ideas bataye the — host unit tests versus HIL testing. Yahan hum har tarah ke scenario ko walk through karte hain jo un ideas se bante hain, ek worked example per "cell". Pehle answer guess karo (yahi Forecast line hai), phir numbered reasoning se khud ko check karo.

Koi bhi numbers aane se pehle, chote arithmetic pieces aur har symbol ko pin down karte hain jo examples reuse karte hain, taaki koi bhi notation unexplained na lage.

Bas itna hi toolbox hai. Neeche sab kuch inhi lines plus careful case-splitting hai. Do pictures inhe concrete banati hain:

Figure — Software testing in embedded — unit tests on host, HIL testing
Figure — Software testing in embedded — unit tests on host, HIL testing

The scenario matrix

Is topic ka har testing question in cells mein se ek mein aata hai. Neeche aane wale examples un cells ke saath labelled hain jo woh cover karte hain, aur saath mein woh sab ko hit karte hain.

Axis Cell What could go wrong / what it tests Example
Signal sign Positive input mid-range mapping, rounding Ex 2
Signal sign Zero input 0 count → 0 V → 0% duty, off-by-one at bottom rail Ex 1a
Signal sign Saturated-high input clipping / cap at the top rail Ex 1
Degenerate input dt = 0 divide-by-zero → +inf Ex 3
Degenerate input Empty buffer length 0 → divide-by-zero in an average Ex 3b
Limiting value 0% and 100% duty rounding at both rails Ex 1, Ex 1a
Where to test Pure logic vs hardware timing choosing host vs HIL Ex 4
Real-time deadline vs ISR latency, missed deadline Ex 5
Mock correctness Mock returns wrong / stale value false green test Ex 6
Real-world word problem Throttle → motor mapping end to end full HIL loop Ex 7
Coverage / strategy 80% host-coverage target test-budget maths Ex 8
Exam-style twist "This test passes — why is it worthless?" flaky/tautological tests Ex 9

Har cell covered hai. Chalo shuru karte hain.


Forecast: voltage guess karo (3.3 V se thoda kam? exactly 3.3 V?) aur duty (99.9%? 100%?) padhne se pehle.

  1. Max count nikalo. 12-bit → counts , toh max count . Yeh step kyun? Rail wahin hai jahan off-by-one bugs rehte hain; hume use karna chahiye, nahi.
  2. Voltage mein convert karo. . Yeh step kyun? Confirm karta hai ki top count exactly par map karta hai — ruler-end property.
  3. CCR, phir duty. , par capped, toh . Yeh step kyun? Saturated input ko saturated output dena chahiye; ek bug jo produce karta (CCR ) timer overflow kar deta.

Verify: Voltage V reference hi hai ✓ (units: count/count × V = V). Duty physical maximum hai; isse upar kuch impossible hai, toh cap apna kaam kar raha hai ✓.


Forecast: kya voltage exactly 0 V hai ya thoda positive offset? Kya duty exactly 0% hai, ya rounding ek stray count mein sneaks in karta hai?

  1. Min count nikalo. 12-bit ADC ka bottom rail count hai. Yeh step kyun? Zero end ka apna off-by-one danger hai (ek bug jo return karta ki jagah ek tiny always-on PWM leak karta).
  2. Voltage mein convert karo. . Yeh step kyun? Confirm karta hai ki bottom count exactly V par map karta hai — ruler ka start.
  3. CCR, phir duty. , toh . Yeh step kyun? Zero input ko ek dead motor dena chahiye. Agar rounding CCR produce karta, motor creep karta — exactly woh bug jo ek host test count par pakadta hai.

Verify: V ✓; ✓. Dono rails (Ex 1 = 100%, Ex 1a = 0%) ab bounded hain, toh linear map dono ends par pinned hai ✓.


Forecast: kya count exactly , , ya hai? Kya CCR hai? Kya duty exactly hai?

  1. Voltage → count. . Yeh step kyun? ek integer nahi hai — ADC ko round karna hoga. Half-scale voltage exactly half-scale count nahi deta; yeh asymmetry (0…4095 ek even span hai, toh iska exact middle nahi) ek classic surprise hai.
  2. Count → CCR (woh step jo formula pehle demand karta hai). . Yeh step kyun? Hume duty se pehle integer CCR compute karna hai — timer sirf whole numbers hold kar sakta hai, toh yahan rounding real hardware behaviour hai, shortcut nahi.
  3. CCR → duty. . Yeh step kyun? CCR ke par round hone ke baad, duty exact par land karti hai — integer rounding actually step 1 ke half-count offset ko cancel kar deta hai. Yeh tabhi visible hota hai jab CCR ko separate step rakho.

Verify: count ✓; ✓; , ek tolerance ke andar ✓. CCR step ko honor karna stated formula follow karta hai aur dikhata hai ki do roundings interact karte hain.


Forecast: crash? NaN? ek bada number? Kaun sa output field result ko poison karta hai?

  1. Derivative term literally compute karo. . Yeh step kyun? C floating-point mein, ek crash nahi hai — yeh +inf yield karta hai. Yeh ek silent poison hai, crash se bhi bura.
  2. Sum mein propagate karo. Output . Yeh step kyun? Infinity mein koi bhi finite term add karne se infinity hi rehti hai — poora controller output meaningless ho jaata hai.
  3. Host-test fix. Ek unit test host par microseconds mein cheaply inject kar sakta hai aur isfinite(output) assert kar sakta hai. HIL par tum sirf ek motor ko full power par slam karte dekh sakte ho. Yeh step kyun? Yahi poora reason hai ki degenerate inputs host tier mein jaate hain: fast, safe, repeatable.

Verify: IEEE-754 kehta hai aur ; isfinite(+inf) false hai ✓. Toh ek assertion isfinite(pid_update(...)) correctly fail hota hai, bug ko host par pakadta hai.


Forecast: kya ek empty buffer deta hai, ya kuch aur bura?

  1. Degenerate size substitute karo. . Yeh step kyun? Zero terms par hai, aur se divide karne par milta hai — sabse bura float result, NaN (Not-a-Number), jo khud se bhi equal nahi hai.
  2. Poison trace karo. NaN ke saath koi bhi comparison false hai, toh baad mein if (avg > threshold) silently wrong branch leta hai — koi crash nahi, koi warning nahi. Yeh step kyun? Dikhata hai ki empty buffer Example 3 se alag hazard hai: dt=0 ne +inf diya, lekin 0/0 se NaN milta hai, jo comparisons mein differently behave karta hai.
  3. Host-test fix. Host par ek empty buffer inject karo aur assert karo ki function ise guard karta hai (ek defined default return karta hai, jaise , jab ho) divide karne ki jagah. Yeh step kyun? Empty-collection edge cases HIL par real startup tak invisible hote hain — host par force karna cheap hai.

Verify: NaN hai; NaN == NaN false hai (defining property) ✓. Ek guarded implementation jo return kare jab ho test pass karati hai; naive wali NaN produce karti hai aur fail hoti hai ✓.


Forecast: kaun se do pure maths hain, kaun se do real silicon chahiye?

  1. (a) CRC calculator → host. Kyun? Bytes par pure computation — x86 par result wahi hoga jo MCU par hoga. Kuch mock karne ki zaroorat nahi.
  2. (b) UART ISR latency → HIL. Kyun? Latency real time hai; host tests clock ko mock karte hain, toh woh actual response ke microseconds measure nahi kar sakte. Response pin par ek logic analyzer chahiye.
  3. (c) Kalman update → host. Kyun? Linear algebra with no I/O. Sensor reads ko HAL se route karo aur mock data feed karo.
  4. (d) GPIO rises to 3.0 V → HIL. Kyun? Voltage level ek electrical property hai; sirf real hardware aur ek scope ise confirm kar sakti hai.

Verify: Rule hai "kya answer real timing ya real voltage ke saath badlega?" — (b) aur (d) haan → HIL; (a) aur (c) nahi → host. Do/do split parent ke "logic on host, physics on hardware" principle se match karta hai ✓.


Forecast: pass ya fail? margin µs mein aur percent mein?

  1. Worst case ko deadline se compare karo. pass. Yeh step kyun? Real-time correctness worst case se decide hoti hai, average se kabhi nahi — ek bhi missed deadline failure hai.
  2. Absolute margin compute karo. . Yeh step kyun? Margin batata hai ki tum kitna future code (ek added RTOS context switch, ek slow I²C read) afford kar sakte ho deadline break hone se pehle.
  3. Relative margin compute karo. . Yeh step kyun? Teams aksar ≥ 20% headroom require karti hain; isse clear karta hai.

Verify: ✓; margin , yani deadline ka ✓ (timeline figure dekho). Kyunki humne 5000 runs ka max measure kiya (mean nahi), pass verdict jitter ke liye robust hai.

Figure — Software testing in embedded — unit tests on host, HIL testing

Forecast: green ya red? aur kya yahan ek green achi khabar hai?

  1. Compute karo ki mock actually kya return karta hai. Buggy mock → count , toh duty . Yeh step kyun? Hume woh value trace karni hai jo mock logic ko feed karta hai, nahi woh value jo test inject karna chahta tha.
  2. Assertion evaluate karo. Test assert karta hai duty == 0, aur duty hai → assertion passes. Yeh step kyun? Ek passing assertion worthless hai agar woh galat reason se pass hoti hai — input logic tak kabhi pahuncha hi nahi.
  3. Self-checking mock design karo. Ek read-back assertion add karo: set_adc(1, 3000) ke baad, assert karo hal_adc_read(1) == 3000. Yeh stale mock ko duty value par trust karne se pehle pakad leta hai. Yeh step kyun? Tests ko apni khud ki plumbing verify karni chahiye; warna har "green" suspicious hai.

Verify: Correct mock ke saath, count duty deta hai , jo ke kareeb kahin nahi hai. Toh read-back check hal_adc_read(1) == 3000 buggy mock par fail hogi, ise expose karegi ✓.


Forecast: 49.8% kitna 50% se off hai, aur kya yeh ±2% clear karta hai?

  1. Intended input confirm karo. V hai of full scale → throttle genuinely half par hai. Yeh step kyun? "Expected" number establish karta hai jis se assertion compare karti hai.
  2. Error compute karo. . Yeh step kyun? Spec ek absolute-percent tolerance hai, toh hum directly subtract karte hain.
  3. Tolerance se compare karo. pass. Yeh step kyun? gap real hardware reality hai — ADC noise, DAC settling, integer rounding — aur yeh budget ke andar aaram se fit hai.

Verify: , aur ✓. Sanity: sub-1% error Ex 2 ke integer-rounding ke saath consistent hai, toh number physically believable hai, too-good-to-be-true nahi ✓.


Forecast: kaun sa denominator matter karta hai — saare 10 000 lines, ya sirf testable logic?

  1. Testable population identify karo. Vendor drivers tested maane gaye hain, toh meaningful denominator logic + HAL glue lines hai. Yeh step kyun? Denominator mein untestable vendor code count karna score ko unfairly punish karega aur real gaps hide karega.
  2. Logic-focused coverage. custom logic ka. Yeh step kyun? Yahi woh number hai jo parent ka formula actually care karta hai — bugs tumhari logic mein chhupte hain.
  3. Whole-image coverage. . Yeh step kyun? Dikhata hai ki ek naive denominator ek achhe test suite ko bura kaise dikhata hai; hamesha state karo ki tumne kaun sa denominator use kiya.

Verify: ✓ (logic target met). , jo ek naive whole-image target par fail ho jaata — proving denominator choice matters ✓.


Forecast: ek duty CCR kabhi bhi kya smallest aur largest ho sakta hai?

  1. Asserted quantity ko bound karo. Ek PWM CCR hamesha ek non-negative integer hota hai: by construction. Yeh step kyun? Assertion >= 0 ek tautology hai — yeh har possible input ke liye true hai, including ek totally broken compute_pwm jo return kare.
  2. Dikhao ki yeh bug se correct ko distinguish nahi kar sakta. Max ADC should give CCR (Ex 1 se). Lekin ek bug jo CCR return karta hai woh bhi >= 0 satisfy karta hai, toh test green hai jabki motor dead hai. Yeh step kyun? Ek achha assertion falsifiable hona chahiye — yeh kam se kam ek wrong output ke liye fail karna chahiye.
  3. Fix karo. Expected value se replace karo: assert(hal_pwm_get(1) == 1000);. Yeh step kyun? Ab return karne wala bug test fail karata hai, jo poori baat hai.

Verify: 0 >= 0 true hai, toh ka ek broken CCR weak assertion pass kar leta hai ✓ (yeh worthless hai). Corrected == 1000 deta hai 0 == 1000false, bug par correctly fail hota hai ✓.


Recall Quick self-check

Zero ADC count on a 3.3 V, TOP=1000 system kya voltage aur duty deta hai? ::: V aur — dono bottom rails exactly pinned. Half-scale voltage (1.65 V on a 3.3 V, 12-bit ADC) kaun sa count, CCR (TOP=1000), aur duty deta hai? ::: count , phir CCR , phir duty . PID mein dt = 0 +inf kyun deta hai lekin empty buffer average NaN kyun deta hai? ::: (nonzero over zero), lekin indeterminate hai → NaN, jo khud se bhi equal nahi hai. 100 µs deadline ke against 73 µs worst-case ISR latency kitna margin chhodti hai? ::: 27 µs, yani 27% headroom. assert(duty >= 0) worthless kyun hai? ::: Ek duty by construction non-negative hoti hai, toh assertion ek tautology hai — yeh kabhi fail nahi ho sakti, even ek broken output par.