Applied Projects route · TFA-403

Worked Solution: Debugging & Verification

Compare your investigation with a reference solution that explains why each defect occurs, how the design is corrected, which tests demonstrate the change and which product claims remain open.

Worked solution11 min reading + 35 min practiceWorked example

← Back to the learning library

Before you begin: Attempt TFA-402 before using this page. The goal is to compare reasoning and evidence—not merely copy the corrected implementation.

Reading time and practice time are estimates. Examples use fictional products and illustrative engineering values, not approved product limits.

Learning objectives

By the end of this module, you should be able to:

  • Explain the causal chain for each of the four planted defects.
  • Review corrected state supervision, coherent sample transfer, inhibited restart and progress-based watchdog servicing.
  • Interpret six passing reference host tests without overstating them.
  • Identify target integration and HIL evidence needed before a real release decision.

Lesson 1

1. Read the result as an evidence set

The reference correction is one defensible answer under the exercise assumptions. It is not the only implementation. A target with atomic 32-bit access and a supported interrupt-masking API might use a bounded critical section; another might publish immutable queue entries. The essential result is that the interface contract becomes explicit and testable.

The reference host suite contains six cases: nominal start, the exact timeout boundary, rejection of an update-in-progress snapshot, inhibited watchdog restart, proof that timer interrupts cannot service the watchdog, and proof that one completed main step can. All six passed during validation of this learning page. That result applies to the reference C sources compiled for the host; no target or physical test is claimed.

Lesson 2

2. Defect 1 — timeout coupled to the awaited event

In the starter, timeout evaluation is inside if (mode == MODE_STARTING && new_sample). When sensor acquisition stops, the condition is false and the deadline is never checked. The comparison also uses greater-than, making 100 ms behave differently from the stated boundary.

The correction checks elapsed time whenever the controller is STARTING, before accepting a late success event, and uses greater-than-or-equal. SOL-002 observes STARTING at 99 ms and FAULT with output off at exactly 100 ms. The test controls the clock so the result is deterministic. On target, scheduling delay and physical output response still need an allocated timing budget and measurement.

Lesson 3

3. Defect 2 — a volatile structure is not a transaction

The sensor interrupt writes temperature, timestamp and validity as separate operations. Main processing copies the structure while an interrupt may be part-way through publication. volatile requires accesses to occur but does not make the group atomic or prove memory ordering.

The reference solution uses an illustrative sequence counter. The publisher makes the counter odd, writes all fields, then makes it even. The reader accepts a snapshot only if the counter was even and unchanged across the copy. SOL-003 rejects an odd sequence and accepts one completed snapshot with matching fields. A production design must use target-supported atomic and ordering rules; an 8-bit sequence may wrap during an unusually long read, so bounded execution assumptions and counter width require analysis.

Lesson 4

4. Defect 3 — restart resumes authority it no longer has

The starter treats a retained “was running” indication as authority to resume the output after a watchdog reset. Retained state may be stale or corrupt, and the watchdog reset itself indicates loss of controlled execution. The output can energise before prerequisites, sensor validity and user intent have been re-established.

The reference boot path ignores retained active state for actuation and always establishes IDLE with output off. SOL-004 injects a watchdog reset with retained-running information and confirms inhibition. A real design may preserve diagnostic context, but restart permission should come from an explicit system requirement and revalidation sequence. Target tests must observe the actual pin and power stage from reset assertion through initialisation.

Lesson 5

5. Defect 4 — the watchdog observes the wrong heartbeat

The timer interrupt continues to run even when main processing is deadlocked or trapped. Servicing the watchdog from that interrupt therefore proves only interrupt activity and masks the failure the watchdog was intended to detect.

The reference removes service from the timer interrupt and refreshes only after a completed main processing step. SOL-005 advances 250 timer interrupts and observes zero watchdog kicks; SOL-006 completes one controller step and observes one. A larger design should supervise independent progress tokens from every critical function and refresh only when the required set advances within its deadline. Long legitimate operations need explicit supervision rather than an unconditional bypass.

Lesson 6

6. Review the corrected reference implementation

The corrected source below makes the four design changes visible. Notice that it remains a teaching core: it has no real watchdog registers, interrupt-control primitives, output driver or persistent diagnostic store.

#include "firmware.h"

#define START_TIMEOUT_MS UINT32_C(100)

volatile uint32_t g_tick_ms;
volatile uint32_t g_watchdog_kicks;
volatile uint8_t g_sample_sequence;
volatile struct sensor_sample g_sensor_sample;

void timer_interrupt(void)
{
    ++g_tick_ms;
}

void sensor_interrupt(int16_t centi_c, bool valid)
{
    ++g_sample_sequence;
    g_sensor_sample.centi_c = centi_c;
    g_sensor_sample.captured_ms = g_tick_ms;
    g_sensor_sample.valid = valid;
    ++g_sample_sequence;
}

bool try_sensor_snapshot(struct sensor_sample *out)
{
    const uint8_t before = g_sample_sequence;
    if ((before & UINT8_C(1)) != 0U) return false;
    out->centi_c = g_sensor_sample.centi_c;
    out->captured_ms = g_sensor_sample.captured_ms;
    out->valid = g_sensor_sample.valid;
    const uint8_t after = g_sample_sequence;
    return before == after && (after & UINT8_C(1)) == 0U;
}

void controller_boot(struct controller *c, enum reset_reason reason,
                     bool retained_running)
{
    (void)reason;
    (void)retained_running;
    c->mode = MODE_IDLE;
    c->output_on = false;
    c->state_entered_ms = g_tick_ms;
    c->last_sample_ms = 0;
    c->progress_count = 0;
}

void controller_start(struct controller *c)
{
    if (c->mode == MODE_IDLE) {
        c->mode = MODE_STARTING;
        c->state_entered_ms = g_tick_ms;
    }
}

void controller_step(struct controller *c)
{
    struct sensor_sample sample = {0};
    const bool coherent = try_sensor_snapshot(&sample);

    if (c->mode == MODE_STARTING &&
        (uint32_t)(g_tick_ms - c->state_entered_ms) >= START_TIMEOUT_MS) {
        c->mode = MODE_FAULT;
        c->output_on = false;
    } else if (c->mode == MODE_STARTING && coherent && sample.valid &&
               sample.captured_ms != c->last_sample_ms &&
               sample.centi_c >= 3000) {
        c->last_sample_ms = sample.captured_ms;
        c->mode = MODE_RUNNING;
        c->output_on = true;
    }

    ++c->progress_count;
    ++g_watchdog_kicks;
}

The sequence-counter reader is non-blocking: an in-progress update causes the step to proceed without a new coherent sample. The controller's timeout remains independent of that result. This composition prevents a stalled or busy publisher from suppressing state supervision.

Lesson 7

7. Interpret evidence and remaining limitations

A concise verification record would identify the requirement revision, original failing test, source baseline, compiler flags, observed output and repaired result. It would also state that the host suite does not demonstrate interrupt atomicity, worst-case timing, watchdog independence, startup electrical state or the final physical output.

ClaimReference evidenceRemaining work
100 ms start timeoutSOL-002 passes at 99 / 100 ms on controlled host clock.Measure target scheduling and output response.
Coherent sampleSOL-003 rejects an odd publication sequence and accepts a completed one.Confirm target atomic access, barriers and worst-case publication/read timing.
Inhibited restartSOL-004 returns IDLE / off after simulated watchdog reset.Observe real reset cause, pin state and power stage.
Progress watchdogSOL-005 / 006 separate interrupt activity from main progress.Configure the independent watchdog and inject a real processing stall.

The reference solution therefore supports closure of the four host-level logic findings while leaving target actions open. That is the correct evidence outcome—not a weaker pass, but a bounded claim.

Decision guide

Is a defect ready to close?

QuestionClose only whenKeep open when
Was it reproduced?A controlled test demonstrates the original failure.The explanation is plausible but no observation exists.
Was the cause corrected?Design ownership or contract is repaired and reviewed.A delay, retry or test change only hides the symptom.
Was regression shown?The original test passes and relevant neighbours are rerun.Only the nominal path was checked.
Are evidence limits clear?Target and HIL actions are assigned or explicitly unnecessary.Host results are being used as physical product evidence.

Worked example

Worked example — watchdog evidence

Problem

A unit test shows that the timer ISR still increments while the main loop is not called, but the existing watchdog counter also continues to increment.

Engineering approach

The test is retained as the failing observation. Watchdog service is removed from the interrupt and placed after defined main-loop progress. One test confirms 250 interrupts produce no kick; another confirms one completed step produces one kick. Target fault injection is added to the verification plan.

Result

The host evidence demonstrates the corrected ownership rule, while the target action remains visible for peripheral configuration and reset behaviour.

Engineering evidence

What should the work produce?

Four corrected requirements

Approved wording defines boundaries, states, outputs and progress.

Failing observations

EX-003 to EX-006 preserve the original defect evidence.

Reference regressions

SOL-001 to SOL-006 pass against the corrected host implementation.

Review record

Explains the concurrency mechanism, reset policy and watchdog ownership.

Open target actions

Atomicity, timing, watchdog and physical-output tests remain allocated.

Common failure patterns

What goes wrong?

  • Copying the reference code without validating the target memory model.
  • Calling the sequence counter lock-free without bounding publication and read timing.
  • Allowing a successful watchdog reboot to re-enable the output.
  • Recording only the repaired pass and discarding the original failing observation.
  • Closing target-specific claims from host execution.

Applied exercise · approximately 35 minutes

Challenge the reference solution

Review the correction as if it were proposed for your own target. Identify assumptions that could invalidate it and strengthen the verification plan.

  1. Determine whether reads and writes of the sequence counter are atomic on your chosen target.
  2. Add one test for timer rollover at the 100 ms boundary.
  3. Define which critical progress tokens a larger application would require before watchdog refresh.
  4. Specify the physical observations needed from reset assertion to output inhibition.
Review a suggested approach

A strong answer names the processor and compiler memory rules, bounds the snapshot operation and avoids assuming that volatile supplies ordering. Rollover testing should initialise the start time near the counter maximum and use unsigned subtraction across wrap. The progress set should cover the functions whose loss could leave unacceptable behaviour, not every low-value task. Reset testing should observe the reset line or cause, firmware state, output command and harmless physical output on a shared timebase.

Completion criteria

  • Target assumptions are concrete and reviewable.
  • The rollover test preserves the exact inclusive boundary.
  • Watchdog progress represents critical system work.
  • The reset test observes physical behaviour, not only a variable.

This is a self-directed engineering exercise, not an accredited examination. Compare the rationale as well as the final answer.

Practical check

Questions for your next design review

  • Can each correction be traced to its requirement and original failure?
  • Is the snapshot mechanism valid for the actual processor and compiler?
  • Does reset establish an inhibited physical output before normal operation?
  • Can a stalled critical task prevent watchdog service?
  • Are open target and HIL actions visible in the release decision?
Key takeaway

A worked solution is credible when it preserves the defect evidence, repairs the causal design decision and limits every verification claim to what was actually observed.

References and further reading

Educational guidance only. Apply the authorised standards editions, regulations and approved procedures relevant to your product and market. Linked publications support further study; the fictional exercises do not demonstrate compliance.