Your prototype works on your desk. A teammate installs the firmware on a second board, and the buttons appear without their icons. For a team building a branded controller or an interactive exhibit, that can turn a planned user test into a search for missing files.
The handoff needs to include the artwork, where the device expects to find it, and the firmware that can read it. This matters most when the images live outside the program. A successful firmware upload does not tell you whether those files arrived with it.
This note looks at the file interface that LVGL 9.0 uses to load images from storage, as seen from a MicroPython build, and turns it into a handoff check. It is based on reading the interface definitions, not on a recorded image-loading run, so treat the test steps at the end as checks to perform on your own hardware.
Decide what travels with the firmware
A fixed set of icons can be built into a firmware image. External files become useful when artwork needs to change separately, for example while a designer is trying several labels or themes. That flexibility adds a separate item to the delivery: the asset files. LVGL's 9.0 image documentation describes both storage approaches and notes that file-based images need memory for loading and drawing.
For a prototype handoff, put the firmware build and its matching asset set in one release folder. Include a short list of expected filenames and the storage destination. This is a working practice we recommend, not a release process we have measured. Its purpose is simple: the next person should not have to reconstruct your laptop's directory structure.
Do not assume that naming a file logo.png makes it usable by every build. The image format and decoder still have to match the receiving firmware. An image converter's C output and its binary output also take different routes into the product: one is compiled, while the other is delivered as a file. Keep the converter settings with the asset set.
Give each file a route the device understands
LVGL file paths look like S:images/icon.bin. Here, S identifies a registered LVGL storage driver. It does not automatically mean "SD card," and it is not your computer's drive letter. The adapter receives the part after the prefix and maps it to the underlying storage. Agree on that mapping before copying artwork between machines. The LVGL 9.0 filesystem reference explains the registration and path handling.
Two structures carry this. fs_drv_t describes the driver: its letter, its initialization and registration, and cache-related settings. fs_file_t represents a file opened through that driver, with operations for opening, closing, reading, writing and moving through the file, plus directory-related definitions. In practical terms, one defines the route to storage; the other represents a file being used through that route.
For file-backed image widgets, the version 9.0 reference lists open, close, read, seek and tell operations. An adapter must report failures and actual byte counts correctly. Some descriptions group seek and tell together; treat them as separate operations when reviewing an implementation. Keep the C driver's lifetime rules separate from the details of your MicroPython binding, which must be checked against the firmware actually installed.
Test the handoff on a clean device
First install the exact firmware and asset set another person will receive. Then use the LVGL file interface to open the exact image path, read data, check the result and close the file. Reading an unrelated text file is a useful first check, but it does not establish that the image exists or can be decoded. A 2024 LVGL issue records that distinction: the reporter could read text while the image failed. The visible report does not establish a fix.
Board-specific packaging can fail earlier still. Resource paths, partition configuration and whether filesystem support is enabled in the build all decide whether the files exist where the application looks. The configuration names differ from one SDK to the next. The transferable question is whether the delivered files actually reach the storage that the running application opens.
For your own acceptance test, show one small image after a cold start, then try a deliberately missing file. Decide what the user should see in that case: a readable text label or a clear fallback is often more useful than an unexplained blank space. Run this on the target hardware; an interface reading cannot settle it.
A short checklist for each handoff:
- the firmware build and the asset set, versioned together in one folder;
- the list of expected filenames and the storage path each one is copied to;
- the converter settings used to produce the image files;
- the drive letter and the storage it maps to in this build;
- the result of the cold-start image check and the missing-file check.
Before handing the unit over, record the firmware version, asset version, installation steps and observed result. That gives a designer or tester something concrete to repeat when the next artwork revision arrives.