Description
I am trying to get LVGL into a Bootloader with limited program size (~240 KB or less). Without LVGL, I was getting a program size of around 131 KB. Now I am asked to add an improved appearance with LVGL. Output is read-only – no user input, and the simplicity of what I need is rendering a single (multi-line) string on a 16-bpp color touch-screen application. Adding LVGL and simply calling lv_init() and initializing and registering a display, with default lv_conf.h I was getting a new program size of 436 KB. All I need to do is display ASCII text on a black (or fixed-color) background. So in lv_conf.h I found the various LV_USE_… macros and set them all to 0 except for LV_USE_LABEL. I also set sub-macros LV_LABEL_TEXT_SELECTION and LV_LABEL_LONG_TXT_HINT to 0.
This helped a great deal. Now I am down to 267 KB. I already have my compiler putting each function into its own section, and having my linker remove unused sections. Normally it is very clever at finding functions – even in a deep call tree – that end up not getting called and removing them. So I normally feel safe including complex libraries, and these two features normally cause the linker to keep ONLY the library features that I actually call (plus the functions they call, of course).
A cursory examination of the output of
nm --print-size --size-sort --reverse-sort <.elf file>
on the resulting .elf file is showing my program still contains these (showing only the largest several LVGL functions).
9d0072a8 0000106c T lv_draw_sw_blend_basic
9d008314 00000e34 T lv_obj_get_scrollbar_area
9d009d68 00000b94 T lv_obj_refr_size
9d00a8fc 00000a9c t refr_area_part
9d00c878 00000960 T lv_draw_label
9d00e334 000007bc T lv_draw_sw_img_decoded
9d00ffa0 000006bc T _lv_disp_refr_timer
9d01065c 000006a8 t lv_obj_event
9d012500 000005c4 T lv_draw_sw_letter
9d013bd8 0000056c t lv_obj_draw
9d0146a8 0000054c t refr_obj
9d01511c 00000510 T lv_obj_refr_pos
9d01562c 000004f0 t scroll_area_into_view
9d015ff8 000004a4 t lv_obj_set_state
9d017208 0000042c T _lv_txt_get_next_line
9d017a44 000003f0 T lv_draw_img
9d017e34 000003e0 T lv_draw_sw_line
9d0185c4 00000380 T _lv_obj_style_state_compare
9d019018 00000368 T lv_obj_init_draw_rect_dsc
9d019380 00000360 t trans_anim_cb
9d019a3c 0000035c t draw_bg_img
What confuses me is that I am not doing anything with images or image decoding, and yet
lv_draw_img
and
draw_bg_img
which then forces things like ‘lv_draw_sw_img_decoded’ and other things about image decoding to be pulled into the program (1.9 KB), which I am not going to be using.
Another example: if I am not using scrolling of any type, why are
lv_obj_get_scrollbar_area() (3.5 KB)
and
scroll_area_into_view() (1.2 KB)
being included?
Notes:
- I have worked with LVGL 6.0.2 extensively in another application, so I have no worries about getting it functioning. I’ve had time to study the flow of control and some of its inner parts that get rendering to take place, and so my worries are NOT about getting it working, but ONLY about reducing program size. Reason: If I can’t get the whole program under about 240 KB (which means LVGL needs to fit inside about 109 KB including the [single] font I am using), then I won’t be able to use LVGL at all.
- All I need to do is display un-editable text (one size) on a black background (labels).
- There is no user input needed.
- I’m not using anything that would need to be scrolled, so everything about scroll bars (e.g. lv_obj_get_scrollbar_area(), which itself has a 3.5 KB footprint) is not going to be needed.
- I’m not using any transformations or functions that should need any Trigonometry functions. (I found transforms can be removed by setting LV_DRAW_COMPLEX to 0.)
- I’m not using any animations (which means several things can be eliminated).
- LV_USE_FS_FATFS, LV_USE_FS_STDIO, LV_USE_FS_POSIX, LV_USE_FS_WIN32 are all defined as 0.
- I have already removed my original text-rendering functions from the program.
What MCU/Processor/Board and compiler are you using?
PIC32MZ1024EFF100 / Production PCB
What LVGL version are you using?
8.3.9 (end of branch ‘release/v8.3’)
NOTE: it is easy for me to switch versions at this point, if doing so makes this easier or more feasible.
What do you want to achieve?
Reduce LVGL program-size footprint considerably. I was hoping to get it down to 70 KB + the size of the font that I am using.
What have you tried so far?
-
Compiler optimization towards size reduction.
-
Setting all the LV_USE_… to 0 except for the one that I actually need: LABELS. (Reduced program size by approx. 170 KB.)
-
In lv_init(), commenting out calls to _lv_anim_core_init() and _lv_img_decoder_init() (reduced program size by only around 5 KB). (Note: this was just a temporary experiment – I haven’t done enough homework yet to determine if this is safe or not.)
-
Verified all conditional compilation in lv_extra_init() is not included.
-
Removed original rendering code (somewhat complex) to reduce program size.
-
Set LV_BUILD_EXAMPLES to 0.
-
Set LV_DRAW_COMPLEX to 0. (gained 35 KB!)
-
Set LV_MEMCPY_MEMSET_STD to 1. (gained 1.1 KB)
Code to reproduce
This is all I have called so far:
/* Initialize LVGL. */
lv_init();
/* Set up display buffer. */
lv_disp_draw_buf_init(&gDisplayBuffer, gclraDrawBuffer, NULL, HOR_PX_COUNT * 40);
/* Set up and register display driver. */
lv_disp_drv_init(&gDisplayDriver);
gDisplayDriver.hor_res = HOR_PX_COUNT ;
gDisplayDriver.ver_res = VER_PX_COUNT;
gDisplayDriver.flush_cb = _UI_FlushBufferToLcdPanel;
gDisplayDriver.draw_buf = &gDisplayBuffer;
lv_disp_drv_register(&gDisplayDriver);
Screenshot and/or video
n/a
So I am hoping that someone has experience on reducing this footprint to < 70-80 KB + font size…
I will continue to hunt down call traces to things I am not using, but any advice from someone experienced along this line would be greatly appreciated!