diff --git a/scripts/gdb/README.md b/scripts/gdb/README.md
new file mode 100644
index 0000000000..2f5eb59e85
--- /dev/null
+++ b/scripts/gdb/README.md
@@ -0,0 +1,20 @@
+# lvglgdb
+
+lvglgdb is a GDB script for LVGL.
+
+# Structure
+
+```mermaid
+graph TD
+ lvgl["lvgl
(mem→python object)"]
+ gdb_cmds["gdb_cmds
(gdb commands)"]
+ lvglgdb["lvglgdb"]
+
+ lvglgdb --> lvgl
+ lvglgdb --> gdb_cmds
+ gdb_cmds --> lvgl
+
+ classDef pkg fill:white,stroke:gray
+ classDef core fill:white,stroke:gray
+ class lvglgdb,lvgl,gdb_cmds pkg
+```
diff --git a/scripts/gdb/lvglgdb/__init__.py b/scripts/gdb/lvglgdb/__init__.py
index f8b7bbe888..d861c390a3 100644
--- a/scripts/gdb/lvglgdb/__init__.py
+++ b/scripts/gdb/lvglgdb/__init__.py
@@ -1,22 +1,13 @@
-from .value import *
-from .lvgl import *
-from .lv_global import set_lvgl_instance
-from .core.lv_obj import DumpObj
-from .display.lv_display import DumpDisplayBuf
-from .draw.lv_draw import InfoDrawUnit
-from .misc.lv_style import InfoStyle
-from .debugger import *
+from .value import Value
+from .lvgl import curr_inst, LVDisplay, LVDrawBuf, LVList, LVObject, dump_style_info
+from . import cmds as cmds
-# Debugger
-Debugger()
-
-# Dumps
-DumpObj()
-DumpDisplayBuf()
-
-# Infos
-InfoStyle()
-InfoDrawUnit()
-
-# Set instance
-set_lvgl_instance(None)
+__all__ = [
+ "curr_inst",
+ "LVDisplay",
+ "LVDrawBuf",
+ "LVList",
+ "LVObject",
+ "dump_style_info",
+ "Value",
+]
diff --git a/scripts/gdb/lvglgdb/cmds/__init__.py b/scripts/gdb/lvglgdb/cmds/__init__.py
new file mode 100644
index 0000000000..aecc4e97aa
--- /dev/null
+++ b/scripts/gdb/lvglgdb/cmds/__init__.py
@@ -0,0 +1,27 @@
+import gdb
+
+from .core import DumpObj
+from .display import DumpDisplayBuf
+from .draw import InfoDrawUnit
+from .misc import InfoStyle
+from .debugger import Debugger
+
+__all__ = []
+
+# Set pagination off and python print-stack full
+gdb.execute("set pagination off")
+gdb.write("set pagination off\n")
+gdb.execute("set python print-stack full")
+gdb.write("set python print-stack full\n")
+
+
+# Debugger
+Debugger()
+
+# Dumps
+DumpObj()
+DumpDisplayBuf()
+
+# Infos
+InfoStyle()
+InfoDrawUnit()
diff --git a/scripts/gdb/lvglgdb/cmds/core/__init__.py b/scripts/gdb/lvglgdb/cmds/core/__init__.py
new file mode 100644
index 0000000000..854d087a70
--- /dev/null
+++ b/scripts/gdb/lvglgdb/cmds/core/__init__.py
@@ -0,0 +1,5 @@
+from .lv_obj import DumpObj
+
+__all__ = [
+ "DumpObj",
+]
diff --git a/scripts/gdb/lvglgdb/cmds/core/lv_obj.py b/scripts/gdb/lvglgdb/cmds/core/lv_obj.py
new file mode 100644
index 0000000000..9b98d58730
--- /dev/null
+++ b/scripts/gdb/lvglgdb/cmds/core/lv_obj.py
@@ -0,0 +1,63 @@
+import argparse
+import gdb
+
+from lvglgdb.lvgl import curr_inst
+from lvglgdb.lvgl import LVObject, dump_obj_info
+
+
+class DumpObj(gdb.Command):
+ """dump obj tree from specified obj"""
+
+ def __init__(self):
+ super(DumpObj, self).__init__(
+ "dump obj", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION
+ )
+
+ def dump_obj(self, obj: LVObject, depth=0, limit=None):
+ if not obj:
+ return
+
+ # dump self
+ print(" " * depth, end="")
+ dump_obj_info(obj)
+
+ if limit is not None and depth >= limit:
+ return
+
+ # dump children
+ for child in obj.children:
+ self.dump_obj(child, depth + 1, limit=limit)
+
+ def invoke(self, args, from_tty):
+ parser = argparse.ArgumentParser(description="Dump lvgl obj tree.")
+ parser.add_argument(
+ "-L",
+ "--level",
+ type=int,
+ default=None,
+ help="Limit the depth of the tree.",
+ )
+ parser.add_argument(
+ "root",
+ type=str,
+ nargs="?",
+ default=None,
+ help="Optional root obj to dump.",
+ )
+ try:
+ args = parser.parse_args(gdb.string_to_argv(args))
+ except SystemExit:
+ return
+
+ if args.root:
+ root = gdb.parse_and_eval(args.root)
+ root = LVObject(root)
+ self.dump_obj(root, limit=args.level)
+ else:
+ # dump all displays
+ depth = 0
+ for disp in curr_inst().displays():
+ print(f"Display {hex(disp)}")
+ for screen in disp.screens:
+ print(f'{" " * (depth + 1)}Screen@{hex(screen)}')
+ self.dump_obj(screen, depth=depth + 1, limit=args.level)
diff --git a/scripts/gdb/lvglgdb/debugger.py b/scripts/gdb/lvglgdb/cmds/debugger.py
similarity index 93%
rename from scripts/gdb/lvglgdb/debugger.py
rename to scripts/gdb/lvglgdb/cmds/debugger.py
index 235ecdcddb..b29b65d9e2 100644
--- a/scripts/gdb/lvglgdb/debugger.py
+++ b/scripts/gdb/lvglgdb/cmds/debugger.py
@@ -57,7 +57,9 @@ class Debugger(gdb.Command):
print("pydevd_pycharm module not found. Please install it using pip.")
return
- pydevd_pycharm.settrace(self.__host, port=self.__port, stdoutToServer=True, stderrToServer=True)
+ pydevd_pycharm.settrace(
+ self.__host, port=self.__port, stdoutToServer=True, stderrToServer=True
+ )
def connect_to_vscode(self):
try:
diff --git a/scripts/gdb/lvglgdb/cmds/display/__init__.py b/scripts/gdb/lvglgdb/cmds/display/__init__.py
new file mode 100644
index 0000000000..43360b4a2f
--- /dev/null
+++ b/scripts/gdb/lvglgdb/cmds/display/__init__.py
@@ -0,0 +1,5 @@
+from .lv_display import DumpDisplayBuf
+
+__all__ = [
+ "DumpDisplayBuf",
+]
diff --git a/scripts/gdb/lvglgdb/display/lv_display.py b/scripts/gdb/lvglgdb/cmds/display/lv_display.py
similarity index 51%
rename from scripts/gdb/lvglgdb/display/lv_display.py
rename to scripts/gdb/lvglgdb/cmds/display/lv_display.py
index c203c80b85..0009134ca9 100644
--- a/scripts/gdb/lvglgdb/display/lv_display.py
+++ b/scripts/gdb/lvglgdb/cmds/display/lv_display.py
@@ -1,52 +1,8 @@
import argparse
import gdb
-from ..core.lv_obj import LVObject
-from ..draw.lv_draw_buf import LVDrawBuf
-from ..value import Value
-from .. import lv_global
-
-
-class LVDisplay(Value):
- """LVGL display"""
-
- def __init__(self, disp: Value):
- super().__init__(disp)
-
- @property
- def hor_res(self) -> int:
- """Get horizontal resolution in pixels"""
- return int(self.super_value("hor_res"))
-
- @property
- def ver_res(self) -> int:
- """Get vertical resolution in pixels"""
- return int(self.super_value("ver_res"))
-
- @property
- def screens(self):
- screens = self.super_value("screens")
- for i in range(self.screen_cnt):
- yield LVObject(screens[i])
-
- # Buffer-related properties
- @property
- def buf_1(self):
- """Get first draw buffer (may be None)"""
- buf_ptr = self.super_value("buf_1")
- return LVDrawBuf(buf_ptr) if buf_ptr else None
-
- @property
- def buf_2(self):
- """Get second draw buffer (may be None)"""
- buf_ptr = self.super_value("buf_2")
- return LVDrawBuf(buf_ptr) if buf_ptr else None
-
- @property
- def buf_act(self):
- """Get currently active draw buffer (may be None)"""
- buf_ptr = self.super_value("buf_act")
- return LVDrawBuf(buf_ptr) if buf_ptr else None
+from lvglgdb.lvgl import curr_inst
+from lvglgdb.lvgl import LVDrawBuf
class DumpDisplayBuf(gdb.Command):
@@ -80,7 +36,7 @@ class DumpDisplayBuf(gdb.Command):
except SystemExit:
return
- display = lv_global.g_lvgl_instance.disp_default()
+ display = curr_inst().disp_default()
if not display:
print("Error: Invalid display pointer")
return
diff --git a/scripts/gdb/lvglgdb/cmds/draw/__init__.py b/scripts/gdb/lvglgdb/cmds/draw/__init__.py
new file mode 100644
index 0000000000..9c31c8a938
--- /dev/null
+++ b/scripts/gdb/lvglgdb/cmds/draw/__init__.py
@@ -0,0 +1,5 @@
+from .lv_draw import InfoDrawUnit
+
+__all__ = [
+ "InfoDrawUnit",
+]
diff --git a/scripts/gdb/lvglgdb/draw/lv_draw.py b/scripts/gdb/lvglgdb/cmds/draw/lv_draw.py
similarity index 93%
rename from scripts/gdb/lvglgdb/draw/lv_draw.py
rename to scripts/gdb/lvglgdb/cmds/draw/lv_draw.py
index 42befeab3b..9530a1ef59 100644
--- a/scripts/gdb/lvglgdb/draw/lv_draw.py
+++ b/scripts/gdb/lvglgdb/cmds/draw/lv_draw.py
@@ -1,7 +1,7 @@
import gdb
-from .. import lv_global
-from ..value import Value
+from lvglgdb.value import Value
+from lvglgdb.lvgl import curr_inst
class InfoDrawUnit(gdb.Command):
@@ -46,5 +46,5 @@ class InfoDrawUnit(gdb.Command):
)
def invoke(self, args, from_tty):
- for unit in lv_global.g_lvgl_instance.draw_units():
+ for unit in curr_inst().draw_units():
self.dump_draw_unit(unit)
diff --git a/scripts/gdb/lvglgdb/cmds/misc/__init__.py b/scripts/gdb/lvglgdb/cmds/misc/__init__.py
new file mode 100644
index 0000000000..d8370d743a
--- /dev/null
+++ b/scripts/gdb/lvglgdb/cmds/misc/__init__.py
@@ -0,0 +1,5 @@
+from .lv_style import InfoStyle
+
+__all__ = [
+ "InfoStyle",
+]
diff --git a/scripts/gdb/lvglgdb/misc/lv_style.py b/scripts/gdb/lvglgdb/cmds/misc/lv_style.py
similarity index 83%
rename from scripts/gdb/lvglgdb/misc/lv_style.py
rename to scripts/gdb/lvglgdb/cmds/misc/lv_style.py
index 73ee0ee21b..5d86772713 100644
--- a/scripts/gdb/lvglgdb/misc/lv_style.py
+++ b/scripts/gdb/lvglgdb/cmds/misc/lv_style.py
@@ -1,8 +1,9 @@
import argparse
import gdb
-from ..value import Value
-from ..core.lv_obj import LVObject
+from lvglgdb.value import Value
+from lvglgdb.lvgl import LVObject
+from lvglgdb.lvgl import dump_style_info
class InfoStyle(gdb.Command):
@@ -37,9 +38,3 @@ class InfoStyle(gdb.Command):
for style in LVObject(obj).styles:
print(" ", end="")
dump_style_info(style)
-
-
-def dump_style_info(style: Value):
- prop = int(style.prop)
- value = style.value
- print(f"{prop} = {value}")
diff --git a/scripts/gdb/lvglgdb/display/__init__.py b/scripts/gdb/lvglgdb/display/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/scripts/gdb/lvglgdb/draw/__init__.py b/scripts/gdb/lvglgdb/draw/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/scripts/gdb/lvglgdb/lv_global.py b/scripts/gdb/lvglgdb/lv_global.py
deleted file mode 100644
index e19f41c4d4..0000000000
--- a/scripts/gdb/lvglgdb/lv_global.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from typing import Union
-import gdb
-
-from .value import Value
-
-g_lvgl_instance = None
-
-
-def set_lvgl_instance(lv_global: Union[gdb.Value, Value, None]):
- global g_lvgl_instance
-
- if not lv_global:
- try:
- lv_global = Value(gdb.parse_and_eval("lv_global").address)
- except gdb.error as e:
- print(f"Failed to get lv_global: {e}")
- return
-
- if not isinstance(lv_global, Value):
- lv_global = Value(lv_global)
-
- inited = lv_global.inited
- if not inited:
- print(
- "\x1b[31mlvgl is not initialized yet. Please call `set_lvgl_instance(None)` later.\x1b[0m"
- )
- return
-
- from .lvgl import LVGL
- g_lvgl_instance = LVGL(lv_global)
diff --git a/scripts/gdb/lvglgdb/lvgl.py b/scripts/gdb/lvglgdb/lvgl.py
deleted file mode 100644
index 41799fc000..0000000000
--- a/scripts/gdb/lvglgdb/lvgl.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from typing import Iterator
-
-import gdb
-
-from .display.lv_display import LVDisplay
-from .misc.lv_ll import LVList
-
-from .value import Value
-
-gdb.execute("set pagination off")
-gdb.write("set pagination off\n")
-gdb.execute("set python print-stack full")
-gdb.write("set python print-stack full\n")
-
-
-class LVGL:
- """LVGL instance"""
-
- def __init__(self, lv_global: Value):
- self.lv_global = lv_global.cast("lv_global_t", ptr=True)
-
- def displays(self) -> Iterator[LVDisplay]:
- ll = self.lv_global.disp_ll
- if not ll:
- return
-
- for disp in LVList(ll, "lv_display_t"):
- yield LVDisplay(disp)
-
- def disp_default(self):
- disp_default = self.lv_global.disp_default
- return LVDisplay(disp_default) if disp_default else None
-
- def screen_active(self):
- disp = self.lv_global.disp_default
- return disp.act_scr if disp else None
-
- def draw_units(self):
- unit = self.lv_global.draw_info.unit_head
-
- # Iterate through all draw units
- while unit:
- yield unit
- unit = unit.next
diff --git a/scripts/gdb/lvglgdb/lvgl/__init__.py b/scripts/gdb/lvglgdb/lvgl/__init__.py
new file mode 100644
index 0000000000..ac043bfbd5
--- /dev/null
+++ b/scripts/gdb/lvglgdb/lvgl/__init__.py
@@ -0,0 +1,14 @@
+from .core import LVObject, curr_inst, dump_obj_info
+from .display import LVDisplay
+from .draw import LVDrawBuf
+from .misc import LVList, dump_style_info
+
+__all__ = [
+ "LVObject",
+ "LVDisplay",
+ "LVDrawBuf",
+ "curr_inst",
+ "LVList",
+ "dump_style_info",
+ "dump_obj_info",
+]
diff --git a/scripts/gdb/lvglgdb/lvgl/core/__init__.py b/scripts/gdb/lvglgdb/lvgl/core/__init__.py
new file mode 100644
index 0000000000..fa320a7fad
--- /dev/null
+++ b/scripts/gdb/lvglgdb/lvgl/core/__init__.py
@@ -0,0 +1,8 @@
+from .lv_obj import LVObject, dump_obj_info
+from .lv_global import curr_inst
+
+__all__ = [
+ "LVObject",
+ "curr_inst",
+ "dump_obj_info",
+]
diff --git a/scripts/gdb/lvglgdb/lvgl/core/lv_global.py b/scripts/gdb/lvglgdb/lvgl/core/lv_global.py
new file mode 100644
index 0000000000..e62739725a
--- /dev/null
+++ b/scripts/gdb/lvglgdb/lvgl/core/lv_global.py
@@ -0,0 +1,107 @@
+import gdb
+from typing import Optional, Union, Iterator, TYPE_CHECKING
+
+from lvglgdb.value import Value
+from ..misc.lv_ll import LVList
+
+"""
+LVGL global instance
+
+Note:
+ lv_global is the global instance of LVGL.
+ It will contain other components like display, draw unit, etc.
+ So if you want add a new component, please add it in this class.
+ And just import your component when you need it. Not expose to the whole file.
+"""
+
+__all__ = ["curr_inst"]
+
+"""
+Type hint for IDE, just imported at typechecking phase not in runtime.
+"""
+if TYPE_CHECKING:
+ from ..display.lv_display import LVDisplay
+
+
+class LVGL:
+ """LVGL instance"""
+
+ def __init__(self, lv_global: Value):
+ self.lv_global = lv_global.cast("lv_global_t", ptr=True)
+
+ def displays(self) -> "Iterator[LVDisplay]":
+ ll = self.lv_global.disp_ll
+ if not ll:
+ return
+
+ from ..display.lv_display import LVDisplay
+
+ for disp in LVList(ll, "lv_display_t"):
+ yield LVDisplay(disp)
+
+ def disp_default(self):
+ from ..display.lv_display import LVDisplay
+
+ disp_default = self.lv_global.disp_default
+ return LVDisplay(disp_default) if disp_default else None
+
+ def screen_active(self):
+ disp = self.lv_global.disp_default
+ return disp.act_scr if disp else None
+
+ def draw_units(self):
+ unit = self.lv_global.draw_info.unit_head
+
+ # Iterate through all draw units
+ while unit:
+ yield unit
+ unit = unit.next
+
+
+class _LVGLSingleton:
+ __slots__ = ("_lvgl", "_ready")
+
+ def __init__(self) -> None:
+ self._lvgl: Optional[object] = None
+ self._ready = False
+
+ def ensure_init(self, lv_global: Union[gdb.Value, Value, None] = None) -> bool:
+ if self._ready:
+ return True
+
+ if lv_global is None:
+ try:
+ lv_global = Value(gdb.parse_and_eval("lv_global").address)
+ except gdb.error as e:
+ print(f"Failed to get lv_global: {e}")
+ return False
+ elif not isinstance(lv_global, Value):
+ lv_global = Value(lv_global)
+
+ if not lv_global.inited:
+ print(
+ "\x1b[31mlvgl is not initialized yet. "
+ "Please call `ensure_init()` later.\x1b[0m"
+ )
+ return False
+
+ self._lvgl = LVGL(lv_global)
+ self._ready = True
+ return True
+
+ def __getattr__(self, name: str):
+ if not self._ready and not self.ensure_init():
+ raise RuntimeError("LVGL singleton not ready")
+ return getattr(self._lvgl, name)
+
+ def reset(self) -> None:
+ self._lvgl = None
+ self._ready = False
+
+
+__curr_inst = _LVGLSingleton()
+
+
+def curr_inst() -> _LVGLSingleton:
+ """Get the global instance of LVGL"""
+ return __curr_inst
diff --git a/scripts/gdb/lvglgdb/core/lv_obj.py b/scripts/gdb/lvglgdb/lvgl/core/lv_obj.py
similarity index 50%
rename from scripts/gdb/lvglgdb/core/lv_obj.py
rename to scripts/gdb/lvglgdb/lvgl/core/lv_obj.py
index 74524ecfbb..7fbaccaedc 100644
--- a/scripts/gdb/lvglgdb/core/lv_obj.py
+++ b/scripts/gdb/lvglgdb/lvgl/core/lv_obj.py
@@ -1,8 +1,4 @@
-import argparse
-import gdb
-
-from ..value import Value
-from .. import lv_global
+from lvglgdb.value import Value
class LVObject(Value):
@@ -70,64 +66,6 @@ class LVObject(Value):
return self.spec_attr.children[index] if self.spec_attr else None
-class DumpObj(gdb.Command):
- """dump obj tree from specified obj"""
-
- def __init__(self):
- super(DumpObj, self).__init__(
- "dump obj", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION
- )
-
- def dump_obj(self, obj: LVObject, depth=0, limit=None):
- if not obj:
- return
-
- # dump self
- print(" " * depth, end="")
- dump_obj_info(obj)
-
- if limit is not None and depth >= limit:
- return
-
- # dump children
- for child in obj.children:
- self.dump_obj(child, depth + 1, limit=limit)
-
- def invoke(self, args, from_tty):
- parser = argparse.ArgumentParser(description="Dump lvgl obj tree.")
- parser.add_argument(
- "-L",
- "--level",
- type=int,
- default=None,
- help="Limit the depth of the tree.",
- )
- parser.add_argument(
- "root",
- type=str,
- nargs="?",
- default=None,
- help="Optional root obj to dump.",
- )
- try:
- args = parser.parse_args(gdb.string_to_argv(args))
- except SystemExit:
- return
-
- if args.root:
- root = gdb.parse_and_eval(args.root)
- root = LVObject(root)
- self.dump_obj(root, limit=args.level)
- else:
- # dump all displays
- depth = 0
- for disp in lv_global.g_lvgl_instance.displays():
- print(f"Display {hex(disp)}")
- for screen in disp.screens:
- print(f'{" " * (depth + 1)}Screen@{hex(screen)}')
- self.dump_obj(screen, depth=depth + 1, limit=args.level)
-
-
def dump_obj_info(obj: LVObject):
clzname = obj.class_name
coords = f"{obj.x1},{obj.y1},{obj.x2},{obj.y2}"
diff --git a/scripts/gdb/lvglgdb/lvgl/display/__init__.py b/scripts/gdb/lvglgdb/lvgl/display/__init__.py
new file mode 100644
index 0000000000..136d6ea665
--- /dev/null
+++ b/scripts/gdb/lvglgdb/lvgl/display/__init__.py
@@ -0,0 +1,5 @@
+from .lv_display import LVDisplay
+
+__all__ = [
+ "LVDisplay",
+]
diff --git a/scripts/gdb/lvglgdb/lvgl/display/lv_display.py b/scripts/gdb/lvglgdb/lvgl/display/lv_display.py
new file mode 100644
index 0000000000..e6643c572d
--- /dev/null
+++ b/scripts/gdb/lvglgdb/lvgl/display/lv_display.py
@@ -0,0 +1,45 @@
+from ..core.lv_obj import LVObject
+from ..draw.lv_draw_buf import LVDrawBuf
+from lvglgdb.value import Value
+
+
+class LVDisplay(Value):
+ """LVGL display"""
+
+ def __init__(self, disp: Value):
+ super().__init__(disp)
+
+ @property
+ def hor_res(self) -> int:
+ """Get horizontal resolution in pixels"""
+ return int(self.super_value("hor_res"))
+
+ @property
+ def ver_res(self) -> int:
+ """Get vertical resolution in pixels"""
+ return int(self.super_value("ver_res"))
+
+ @property
+ def screens(self):
+ screens = self.super_value("screens")
+ for i in range(self.screen_cnt):
+ yield LVObject(screens[i])
+
+ # Buffer-related properties
+ @property
+ def buf_1(self):
+ """Get first draw buffer (may be None)"""
+ buf_ptr = self.super_value("buf_1")
+ return LVDrawBuf(buf_ptr) if buf_ptr else None
+
+ @property
+ def buf_2(self):
+ """Get second draw buffer (may be None)"""
+ buf_ptr = self.super_value("buf_2")
+ return LVDrawBuf(buf_ptr) if buf_ptr else None
+
+ @property
+ def buf_act(self):
+ """Get currently active draw buffer (may be None)"""
+ buf_ptr = self.super_value("buf_act")
+ return LVDrawBuf(buf_ptr) if buf_ptr else None
diff --git a/scripts/gdb/lvglgdb/lvgl/draw/__init__.py b/scripts/gdb/lvglgdb/lvgl/draw/__init__.py
new file mode 100644
index 0000000000..3cb93d1c11
--- /dev/null
+++ b/scripts/gdb/lvglgdb/lvgl/draw/__init__.py
@@ -0,0 +1,5 @@
+from .lv_draw_buf import LVDrawBuf
+
+__all__ = [
+ "LVDrawBuf",
+]
diff --git a/scripts/gdb/lvglgdb/core/__init__.py b/scripts/gdb/lvglgdb/lvgl/draw/lv_draw.py
similarity index 100%
rename from scripts/gdb/lvglgdb/core/__init__.py
rename to scripts/gdb/lvglgdb/lvgl/draw/lv_draw.py
diff --git a/scripts/gdb/lvglgdb/draw/lv_draw_buf.py b/scripts/gdb/lvglgdb/lvgl/draw/lv_draw_buf.py
similarity index 96%
rename from scripts/gdb/lvglgdb/draw/lv_draw_buf.py
rename to scripts/gdb/lvglgdb/lvgl/draw/lv_draw_buf.py
index 2dad2d530b..a587bc5ffe 100644
--- a/scripts/gdb/lvglgdb/draw/lv_draw_buf.py
+++ b/scripts/gdb/lvglgdb/lvgl/draw/lv_draw_buf.py
@@ -5,7 +5,7 @@ import gdb
import numpy as np
from PIL import Image
-from ..value import Value
+from lvglgdb.value import Value
class LVDrawBuf(Value):
@@ -143,7 +143,7 @@ class LVDrawBuf(Value):
return False
def _convert_to_image(
- self, pixel_data: bytes, width: int, height: int, color_format: int
+ self, pixel_data: bytes, width: int, height: int, color_format: int
) -> Optional[Image.Image]:
"""
Convert raw pixel data to PIL Image based on color format.
@@ -162,14 +162,18 @@ class LVDrawBuf(Value):
# Convert RGB565 to RGB888
arr = np.frombuffer(pixel_data, dtype=np.uint8)
arr = arr.reshape((height, width, 2))
- rgb565 = np.frombuffer(pixel_data, dtype=np.uint16).reshape((height, width))
+ rgb565 = np.frombuffer(pixel_data, dtype=np.uint16).reshape(
+ (height, width)
+ )
r = (((rgb565 & 0xF800) >> 11) << 3).astype(np.uint8)
g = ((rgb565 & 0x07E0) >> 3).astype(np.uint8)
b = ((rgb565 & 0x001F) << 3).astype(np.uint8)
return Image.fromarray(np.dstack((r, g, b)), "RGB")
elif color_format == self._color_formats["RGB888"]:
- arr = np.frombuffer(pixel_data, dtype=np.uint8).reshape(height, width, 3)
+ arr = np.frombuffer(pixel_data, dtype=np.uint8).reshape(
+ height, width, 3
+ )
rgb_arr = arr[:, :, [2, 1, 0]] # BGR -> RGB
return Image.fromarray(rgb_arr, "RGB")
diff --git a/scripts/gdb/lvglgdb/lvgl/misc/__init__.py b/scripts/gdb/lvglgdb/lvgl/misc/__init__.py
new file mode 100644
index 0000000000..bce06ebf31
--- /dev/null
+++ b/scripts/gdb/lvglgdb/lvgl/misc/__init__.py
@@ -0,0 +1,7 @@
+from .lv_ll import LVList
+from .lv_style import dump_style_info
+
+__all__ = [
+ "LVList",
+ "dump_style_info",
+]
diff --git a/scripts/gdb/lvglgdb/misc/lv_ll.py b/scripts/gdb/lvglgdb/lvgl/misc/lv_ll.py
similarity index 97%
rename from scripts/gdb/lvglgdb/misc/lv_ll.py
rename to scripts/gdb/lvglgdb/lvgl/misc/lv_ll.py
index 3f68c64743..abb038c88c 100644
--- a/scripts/gdb/lvglgdb/misc/lv_ll.py
+++ b/scripts/gdb/lvglgdb/lvgl/misc/lv_ll.py
@@ -1,7 +1,7 @@
from typing import Union
import gdb
-from ..value import Value
+from lvglgdb.value import Value
class LVList(Value):
diff --git a/scripts/gdb/lvglgdb/lvgl/misc/lv_style.py b/scripts/gdb/lvglgdb/lvgl/misc/lv_style.py
new file mode 100644
index 0000000000..eb621c3a37
--- /dev/null
+++ b/scripts/gdb/lvglgdb/lvgl/misc/lv_style.py
@@ -0,0 +1,7 @@
+from lvglgdb.value import Value
+
+
+def dump_style_info(style: Value):
+ prop = int(style.prop)
+ value = style.value
+ print(f"{prop} = {value}")
diff --git a/scripts/gdb/lvglgdb/misc/__init__.py b/scripts/gdb/lvglgdb/misc/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/scripts/gdb/lvglgdb/value.py b/scripts/gdb/lvglgdb/value.py
index 9fad1bab20..e215feab31 100644
--- a/scripts/gdb/lvglgdb/value.py
+++ b/scripts/gdb/lvglgdb/value.py
@@ -4,7 +4,7 @@ from typing import Optional, Union
class Value(gdb.Value):
- def __init__(self, value: Union[gdb.Value, 'Value']):
+ def __init__(self, value: Union[gdb.Value, "Value"]):
super().__init__(value)
def __getitem__(self, key):
@@ -19,14 +19,18 @@ class Value(gdb.Value):
return Value(super().__getattribute__(key))
return Value(super().__getitem__(key))
- def cast(self, type_name: Union[str, gdb.Type], ptr: bool = False) -> Optional['Value']:
+ def cast(
+ self, type_name: Union[str, gdb.Type], ptr: bool = False
+ ) -> Optional["Value"]:
try:
- gdb_type = gdb.lookup_type(type_name) if isinstance(type_name, str) else type_name
+ gdb_type = (
+ gdb.lookup_type(type_name) if isinstance(type_name, str) else type_name
+ )
if ptr:
gdb_type = gdb_type.pointer()
return Value(super().cast(gdb_type))
except gdb.error:
return None
- def super_value(self, attr: str) -> 'Value':
+ def super_value(self, attr: str) -> "Value":
return self[attr]