Keyboard Memory Leak

Using lv_micropython Master (v1.20.0, v9 lvgl)
ESP-IDF 4.4.6


import lvgl as lv
from ili9XXX import ili9341
from xpt2046 import xpt2046
import os, time, sdcard
from machine import SPI, Pin

# Mount SD Card
sd = sdcard.SDCard(SPI(2), Pin(14), baudrate=20_000_000)
os.mount(sd, '/sd')
# Load Graphics Driver
lv.init()
# Load TFT Driver
disp = ili9341(spihost=2, miso=-1, mosi=-1, clk=-1, cs=15, mhz=20, dc=13, rst=-1, power=-1, factor=48, half_duplex=False, backlight=27, backlight_on=1)
# Load Touch Driver
touch = xpt2046(spihost=2, cs=5, mhz=5, half_duplex=False, cal_x0 = 242, cal_x1 = 3783)

# Screen Objects BOOT
scr = lv.scr_act()

# Password textarera
pwd = lv.textarea(scr)
pwd.set_one_line(True)
pwd.set_width(230)
pwd.set_pos(5, 120)

# Keyboard
kb = lv.keyboard(scr)
kb.align(lv.ALIGN.BOTTOM_MID, 0, 0)
kb.set_textarea(pwd)

while True:
	print(f'''
	mem_alloc: {gc.mem_alloc()/1_000_000:.3f}
	mem_free: {gc.mem_free()/1_000_000:.3f}
	''')
	time.sleep(1)

output…

mem_alloc: 0.034
mem_free: 4.064

mem_alloc: 0.051
mem_free: 4.047

mem_alloc: 0.075
mem_free: 4.023

mem_alloc: 1.273
mem_free: 2.825

mem_alloc: 1.293
mem_free: 2.805

What could cause this ??

import gc
import time

while True:
    print(f"mem_alloc: {gc.mem_alloc()/1_000_000:.3f} 
              mem_free: {gc.mem_free()/1_000_000:.3f}")
    time.sleep(1)

# OUTPUT:
# mem_alloc: 0.020 mem_free: 2.029
# mem_alloc: 0.021 mem_free: 2.029
# mem_alloc: 0.021 mem_free: 2.028
# mem_alloc: 0.022 mem_free: 2.028
# mem_alloc: 0.022 mem_free: 2.027
# mem_alloc: 0.022 mem_free: 2.027

it seems normal in micropython. not lvgl’s keyboard memory leaking.

I have 16 complex screens with full png background images and many of widgets. navigating those screens, corrensponding with mutiple sensors. will be so okay with 2mb memory. of course there is some fragmentations but it is a few kb. I’ve seen that setting gc.threshold() for gc.collect() will be helpful to minimize memory fragmentation. May the force of gc.collect() be with you :slight_smile:

The issue is you guys are not garbage collecting before doing the measurements. You are naturally going to be using dynamic memory because you are printing to a serial buffer. The data may get output but it doesn’t get garbage collected right away so you will see the memory use increase. Make sure you run gc.collect() right before performing ANY memory related tasks.

You guys are correct there is no memory leak !!!
Had isuue with keyboard with button matrix crashig… found issue and corrected.
THANKS !!

no worries m8. Don’t know if we actually helped at all.

DID NOT find the issue…
Running code below, I wait ~ 2min and change map ABC or 1#
Get…

Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.

Core  1 register dump:
PC      : 0x40147810  PS      : 0x00060030  A0      : 0x80147d9d  A1      : 0x3ffd2e30
A2      : 0x3f821140  A3      : 0x3f821600  A4      : 0x00000000  A5      : 0x00000000  
A6      : 0x3f46b149  A7      : 0x3f821600  A8      : 0x00000000  A9      : 0x00000000
A10     : 0x00001f01  A11     : 0x00000000  A12     : 0x00000001  A13     : 0x00000000  
A14     : 0xffffffff  A15     : 0x0000000c  SAR     : 0x0000001f  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00001f01  LBEG    : 0x40096f2d  LEND    : 0x40096f51  LCOUNT  : 0x8014a4cb  


0x4014780d: allocate_btn_areas_and_controls at lv_btnmatrix.c:860
 (inlined by) lv_btnmatrix_set_map at lv_btnmatrix.c:101
0x40147d9a: lv_btnmatrix_set_map at lv_btnmatrix.c:96
0x4014a4b5: lv_keyboard_def_event_cb at lv_keyboard.c:346
0x402397ed: lv_event_send at lv_event.c:76
0x4012bc26: event_send_core at lv_obj_event.c:310
0x4012bce2: lv_obj_send_event at lv_obj_event.c:64
0x401480b1: lv_btnmatrix_event at lv_btnmatrix.c:482
0x402386a5: lv_obj_event_base at lv_obj_event.c:87
0x4012bc15: event_send_core at lv_obj_event.c:307
0x4012bce2: lv_obj_send_event at lv_obj_event.c:64
0x40128dbd: indev_proc_press at lv_indev.c:1072
0x40128fbe: indev_pointer_proc at lv_indev.c:556
 (inlined by) lv_indev_read_timer_cb at lv_indev.c:206
 (inlined by) lv_indev_read_timer_cb at lv_indev.c:166
0x40144334: lv_timer_exec at lv_timer.c:346
 (inlined by) lv_timer_handler at lv_timer.c:114
 (inlined by) lv_timer_handler at lv_timer.c:71
0x400fd2b7: lv_task_handler at lv_api_map.h:42
0x400fbab3: mp_lv_task_handler at lv_mp.c:26471
0x40107935: lv_fun_builtin_var_call at lv_mp.c:103
0x400e4c6a: mp_call_function_n_kw at runtime.c:695
0x400e4dba: mp_call_method_n_kw at runtime.c:711
0x40086621: mp_execute_bytecode at vm.c:1042
0x400de704: fun_bc_call at objfun.c:278
0x400e4c6a: mp_call_function_n_kw at runtime.c:695
0x401223be: mp_call_method_self_n_kw at objboundmeth.c:70
0x401223f1: bound_meth_call at objboundmeth.c:83
0x400e4c6a: mp_call_function_n_kw at runtime.c:695
0x400e4d73: mp_call_function_1 at runtime.c:673
0x400e579e: mp_call_function_1_protected at runtime_utils.c:33
0x400e5928: mp_sched_run_pending at scheduler.c:110
 (inlined by) mp_handle_pending at scheduler.c:239
0x400d8aa5: mp_hal_stdin_rx_chr at mphalport.c:103
0x400f0e2d: readline at readline.c:560
0x400f157e: pyexec_friendly_repl at pyexec.c:610
0x400d8844: mp_task at main.c:181

code used…


LC_MAP = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\n",
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\n",
"a", "s", "d", "f", "g", "h", "j", "k", "l", "\n",
"ABC", "z", "x", "c", "v", "b", "n", "m", lv.SYMBOL.BACKSPACE, "\n",
"1#", lv.SYMBOL.LEFT, " ", lv.SYMBOL.RIGHT, lv.SYMBOL.NEW_LINE, None]
UC_MAP = ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "\n",
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\n",
"A", "S", "D", "F", "G", "H", "J", "K", "L", "\n",
"abc", "Z", "X", "C", "V", "B", "N", "M", lv.SYMBOL.BACKSPACE, "\n",
"1#", lv.SYMBOL.LEFT, " ", lv.SYMBOL.RIGHT, lv.SYMBOL.NEW_LINE, None]
SP_MAP = ["{", "}", "[", "]", "<", ">", "|" , "\\", "\n",
"~", "_", ":", ";", "\"", "'", ",", ".", "\n",
"abc", "/", "*", "-", "+", "=", "?", lv.SYMBOL.BACKSPACE,"\n",
"   ", lv.SYMBOL.LEFT, " ", lv.SYMBOL.RIGHT, lv.SYMBOL.NEW_LINE, None]

CTRL_LC = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4,
6, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 10, 4, 4,]
CTRL_UC = [4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4,
6, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 10, 4, 4,]
CTRL_SP = [4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
5, 4, 4, 4, 4, 4, 4, 4,
lv.btnmatrix.CTRL.HIDDEN | 4, 4, 10, 4, 4,]


def kb_cb(event):
	code = event.get_code()
	obj = event.get_target_obj()
	if code == lv.EVENT.PRESSED:
		id = obj.get_selected_btn()
		txt = obj.get_btn_text(id)
		if txt == lv.SYMBOL.NEW_LINE:
			print('in new line')

# does not work with v9 simulator
scr = lv.scr_act()
# this does
# scr = lv.screen_active()

# Password textarera
pwd = lv.textarea(scr)
pwd.set_one_line(True)
pwd.set_width(230)
pwd.set_pos(5, 120)
pwd.add_state(lv.STATE.FOCUSED)

# Keyboard
kb = lv.keyboard(scr)
kb.align(lv.ALIGN.BOTTOM_MID, 0, 0)
kb.set_map(lv.keyboard.MODE.TEXT_LOWER, LC_MAP, CTRL_LC)
kb.set_map(lv.keyboard.MODE.TEXT_UPPER, UC_MAP, CTRL_UC)
kb.set_map(lv.keyboard.MODE.SPECIAL, SP_MAP, CTRL_SP)
kb.set_mode(lv.keyboard.MODE.TEXT_LOWER)
kb.add_event(kb_cb, lv.EVENT.PRESSED, None)
kb.set_textarea(pwd)

Using lv_micropython Master…
MicroPython v1.20.0-700-g841ece132-dirty on 2023-12-01; ESP32 module 4MB(spiram) with ESP32
cr = lv.scr_act() works for my workstation. but not on v9 simulator
MicroPython v1.20.0-1050-g348432dc1-dirty on 2023-11-27; JS with Emscripten
and scr = lv.screen_active() work for simulator but not workstation?

I hope the backtrace helps… again any thought wecome !!!

lv_micropython master branch has lvgl 9 dev (4 JUL),
at that time lvgl used scr_act(), but the latest lvgl is using
lv.screen_active(). maybe the simulator uses the latest.

there is multi-instance branch on lv_micropython,
it is keep following the latest lvgl with mp1.20.

Do you have any thoughts on why my keyboard code is giving a…
Guru Meditation Error: Core 1 panic’ed (LoadProhibited)
when I change maps after a few minuites.

Using Git how do I switch to… feat/multi-instance branch ?

I’ve posted lv_micropython with latest lvgl 9 dev, feat/multi-instance branch
In my case, I could not initialize the display. (ili9XXXX)

you can clone it with,
git clone --branch feat/multi-instance https://github.com/lvgl/lv_micropython.git
I have compiled successfully only in esp-idf v4.4.4 (v4.4.6 failed)

I’ve only seen Core 1 panic’ed (LoadProhibited) error when I did like below,

>>> import lvgl as lv
>>> lv.init()
>>> o = lv.obj()
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). 
Exception was unhandled.

Core  1 register dump:
PC      : 0x4012adf3  PS      : 0x00060a30  A0      : 0x80129ed5  A1      : 0x3ffd2f40  
A2      : 0x00000000  A3      : 0x3f45d03e  A4      : 0x00000000  A5      : 0x3f45d0a4  
....