A good code and UI store methods separately

The LVGL version I’m currently using is 7.4
Because images and fonts take up a lot of Flash space.
As a result, it takes a lot of time to download the program to the MCU every time.
My Flash has 2M to store enough code and UI, no need for extranet storage, no need for a file system.
Now I want to store the code and UI separately in a separate partition of storage, and can be downloaded separately to the MCU.
UI resources in.c format generated by LVGL tools cannot be stored and downloaded separately because they cannot specify pointer locations separately.
The.bin file generated by LVGL tool needs to be used with the file system to open the file, but I prefer to directly use the address pointer of UI resources to operate UI resources, which is faster and more convenient.
I do not know any better Suggestions to complete this function, thank you.

Although it is a solution released by TouchGFX, a similar method may work for LVGL. See link at https://support.touchgfx.com/docs/development/scenarios/using-non-memory-mapped-flash

This can be done with some minor changes to the font declaration. It is not difficult to implement, but a little time consuming to set up and get going. I’ll give you an outline but I’m not going to give every little detail.

The main complexity is that lv_font_t is not designed to be const. There are fields in lv_font_t that are dynamic. eg get_glyph_bitmap and get_glyph_dsc are pointers to functions, so if we have a const lv_font_t declaration then the function pointers will be invalid. To get around this you need to make a RAM copy of lv_font_t and at run time re-link the function pointers.

  1. Place all your font files (as generated) into a separate project. Change the lv_font_t declaration at the end of the font file to const. I also place other resoures (like strings) in the project.

  2. Write a script/program to parse the resource files and project headers and product a header file which will list all the resources and their memory locations. You can do this so the linker updates the sizes and locations.

  3. Compile the resource project and upload to your resource segment.

  4. In the main application you need to declare RAM based lv_font_t structures and then update at run time.

The main task is to add headers to the resource file that get updated when compiling the resource in such a way that you can re-link at run time. eg In the resource project I have a header like this:

typedef struct {
	uint32_t /*t_spifi_resource_type*/ res_type;
	uint32_t hash;
	const void * address;
	uint32_t size;
	uint32_t checksum;
} t_spifi_resource_header;

And the resource list is declared like

extern lv_font_t font_mono16_lv;
const t_spifi_resource_header font_mono16_header = { SRT_FONT, 0xEDBB9E14, &font_mono16_lv, 0, 0 };

The main application has a header too like this

{ SRT_FONT, 0xEDBB9E14, &font_mono16_lv, 0 },

But also a RAM based list of fonts

static lv_font_t ram_font_list[RESOURCE_FONT_COUNT];

And the run time linking is something like

memcpy(&ram_font_list[s], p, sizeof(lv_font_t));
ram_font_list[s].get_glyph_bitmap = lv_font_get_bitmap_fmt_txt;
ram_font_list[s].get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt;
memcpy(&ram_font_dsc[s], ram_font_list[s].dsc, sizeof(lv_font_fmt_txt_dsc_t));
ram_font_list[s].dsc = &ram_font_dsc[s];

Where s = the index into the ram font list and p is the pointer into the const font list. There’s more complexity I am not showing because I match on the hash so that the font resources can move around between versions and the run time linking will still work. This way I can do OTA updates of the resources.

1 Like