Product Validation¶
These tutorials assume Connected Subsystems is comfortable territory. You can bring up a peripheral, connect it to middleware, and you have already seen at least one coexistence problem firsthand. This track focuses on the work that separates a working demo from a product you can ship: measured power, safe OTA, custom hardware bring-up, crash analysis, multi-connection Bluetooth, and reusable drivers.
Product-validation work is less about copying a single example and more about building evidence. For each tutorial, keep notes: board revision, SDK version, example base, test setup, expected result, observed result, and what changed.
Use this series when your responsibility extends beyond a feature working once: you need measurable power behavior, recoverable updates, repeatable custom-hardware bring-up, and evidence for failures that happen outside the happy path.
Tune Low-Power Modes and Wake Sources¶
Goal: get real battery-life evidence instead of assuming firmware is low power because it calls a sleep function.
Time: 2+ hours, plus measurement setup
Start from: example/pm/classical, example/pm/raise_wrist
- Set up current measurement as described in the Low-Power Overview.
- Record a baseline for boot, active, connected idle, display-off idle, and deep sleep if available.
- Start from the classical PM example and identify where a driver votes for a power state and releases it.
- Move to the raise-to-wake example and study how an interrupt-driven accelerometer event gates display and application-processor wakeup.
- Apply the same pattern to your own product: replace unnecessary timers and polling loops with interrupts or event-driven work.
- Re-measure after each change.
- If deep sleep is not as deep as expected, use
list_thread,list_device, PM logs, and wake-source instrumentation to find the subsystem still active.
Success criteria: the firmware reaches the expected low-power state, current is repeatable across runs, and wake sources are intentional rather than accidental.
Troubleshooting: if power looks good once and bad later, check error paths, reconnect paths, display teardown, audio session teardown, and any timer created after startup.
What you learned: how to move from "should be low power" to measured low power, and how to track down a PM vote that is quietly being left open.
Add OTA Firmware Updates over BLE¶
Goal: update firmware in the field without a wired connection.
Time: 2 hours
Start from: example/ble/peripheral_with_ota
- Build and flash the OTA-enabled peripheral example.
- Confirm normal BLE peripheral behavior still works before attempting an update.
- Trigger an OTA update and confirm the device boots the new image.
- Interrupt an OTA transfer by disconnecting mid-update, losing power if safe for the board, or moving out of range.
- Confirm the device falls back to the previous valid image instead of bricking.
- Test OTA after stale bond, phone-side forget-device, and device reboot.
- If your product already uses PAN for data, evaluate the PAN OTA path as a separate design choice.
Success criteria: successful OTA updates boot the new image, failed OTA attempts recover cleanly, and the user-facing state is understandable after either result.
Troubleshooting: check partition layout, image signing or integrity checks if used, rollback markers, connection parameters during transfer, and whether bond or storage changes survive update.
What you learned: partition and rollback design, and why "OTA works once" is not the same as "OTA is safe to ship."
Bring Up a Custom Display Module¶
Goal: port a new LCD, AMOLED, EPD, or memory display instead of using a pre-supported reference panel.
Time: 3+ hours
Start from: the closest existing display driver in the SDK, adapted for your panel
- Collect the panel datasheet, initialization sequence, timing parameters, interface type, reset requirements, and power sequence.
- Confirm the selected SF32 device and package support the required interface and pinout.
- Copy the closest existing display driver and replace the panel-specific init sequence and register map.
- Bring up solid-color fills first. Do not debug LVGL widgets until the panel can display simple patterns.
- Verify color order, byte order, orientation, address window, and partial update behavior.
- Add LVGL back from Connected Subsystems, exercise 2.
- Enable DMA, partial refresh, and ePicasso acceleration one at a time.
- Test display-off, sleep, wake, and reinitialization paths.
Success criteria: the panel initializes reliably after cold boot and reset, renders known patterns correctly, and survives sleep/wake without corruption.
Troubleshooting: if fills are wrong, check pixel format, MADCTL/orientation bits, byte order, command/data wiring, reset timing, and power-rail sequencing before changing UI code.
What you learned: how to separate electrical/sequence correctness from UI-framework configuration.
Profile CPU Usage and Analyze a Crash¶
Goal: debug problems that do not reproduce conveniently under a live debugger.
Time: 2 hours
Start from: example/system/cpu_usage_profiler, example/system/coredump
- Run the CPU usage profiler example against one of your Connected Subsystems combined workloads.
- Identify which task is consuming CPU time and whether it matches your expectation.
- Add a controlled fault in a practice branch or disposable example and capture a core dump.
- Use the SDK's dump-analysis tooling to locate the faulting function and call stack.
- Compare the crash context with
list_thread, logs, and recent events. - Remove the deliberate fault and repeat the flow with a real intermittent issue if you have one.
Success criteria: you can explain both a performance problem and a crash using captured evidence rather than guesses.
Troubleshooting: make sure symbols match the flashed binary, logs include firmware version, and optimization level is understood before interpreting call stacks.
What you learned: proactive profiling for slow paths and postmortem dump analysis for failures that are hard to catch live.
Build a Multi-Connection BLE Product¶
Goal: support more than one simultaneous BLE role or connection.
Time: 2 hours
Start from: example/ble/central_and_peripheral, example/ble/multi_connection
- Start from the peripheral behavior you already have from Connected Subsystems, exercise 3.
- Add a central role alongside it, such as acting as a peripheral to a phone while acting as a central to a sensor accessory.
- Extend to multiple concurrent connections.
- Record connection intervals, slave latency, supervision timeout, and notification rate for each link.
- Add a throughput baseline using the SDK throughput example before blaming application code.
- Test reconnect, phone sleep, accessory loss, and simultaneous notification bursts.
Success criteria: all intended roles connect, disconnect, and reconnect reliably, and connection-parameter choices remain stable under combined activity.
Troubleshooting: look for incompatible parameter requests, too much notification traffic, blocking application callbacks, and power policy that wakes the main CPU for every link event.
What you learned: peripheral and central roles are not mutually exclusive on SF32, and connection-parameter tradeoffs compound once multiple links share the radio schedule.
Write a Custom RT-Thread Device Driver¶
Goal: integrate a peripheral that does not have an existing SDK driver as a proper RT-Thread device rather than a one-off application hack.
Time: 3+ hours
Start from: SDK application-development guidance plus the closest existing driver
- Review how the SDK organizes board definitions, pin mux, clocks, and peripheral drivers.
- Start from the existing driver that is architecturally closest to your peripheral.
- Keep bus access, device registration, configuration, and application logic separated.
- Register the device and confirm it appears under
list_device. - Exercise it the same way you exercised ADC, PWM, I2C, and storage devices in earlier tutorials.
- Add error handling for missing hardware, invalid arguments, timeouts, and suspend/resume.
- If the driver is reusable, package it as an SDK component instead of copy-pasting it between products.
Success criteria: application code can find and use the driver through the normal RT-Thread device model, and the driver behaves predictably across init, use, error, and sleep/wake paths.
Troubleshooting: if the driver works only from one application file, it is probably bypassing the device model. Refactor until it feels like the built-in devices.
What you learned: how to extend the SDK ecosystem cleanly rather than creating a maintenance liability.
Product-Validation Release Checklist¶
- Power numbers are measured, repeatable, and tied to named test scenarios.
- OTA survives interruption and can roll back to a known-good image.
- Custom display bring-up is validated with patterns before LVGL complexity.
- Profiling and coredump workflows are documented for the team.
- Multi-connection Bluetooth is tested across reconnect and phone/accessory edge cases.
- Custom drivers use the RT-Thread device model and handle sleep/wake.
- Combined-load tests include display, Bluetooth, storage, audio, sensors, and AI as applicable.
Where to Go Next¶
At this point you have the full toolkit: peripherals, middleware, coexistence awareness, power discipline, OTA, custom hardware bring-up, postmortem debugging, and driver integration. From here, the Examples catalog and Graphics Overview are ongoing references. Pull from them per feature rather than working through them linearly.
Auto-generated content
This page was compiled/drafted without an existing source document. Verify technical claims against SiFli's official documentation before relying on them.