@@ -544,3 +544,63 @@ def memoryview_to_hex_spaced(mv: memoryview) -> str:
544544 'parse_manifest' : parse_manifest , # for launcher apps
545545 '__name__' : "__main__"
546546}
547+
548+
549+
550+ import lvgl as lv
551+
552+ # Buffer to store FPS
553+ fps_buffer = [0 ]
554+
555+ # Custom log callback to capture FPS
556+ def log_callback (level , log_str ):
557+ global fps_buffer
558+ # Convert log_str to string if it's a bytes object
559+ log_str = log_str .decode () if isinstance (log_str , bytes ) else log_str
560+ # Log message format: "sysmon: 25 FPS (refr_cnt: 8 | redraw_cnt: 1), ..."
561+ if "sysmon:" in log_str and "FPS" in log_str :
562+ try :
563+ # Extract FPS value (e.g., "25" from "sysmon: 25 FPS ...")
564+ fps_part = log_str .split ("FPS" )[0 ].split ("sysmon:" )[1 ].strip ()
565+ fps = int (fps_part )
566+ fps_buffer [0 ] = fps
567+ except (IndexError , ValueError ):
568+ pass
569+ # Optional: Print for debugging
570+ #print(f"Level: {level}, Log: {log_str}")
571+
572+ # Register log callback
573+ lv .log_register_print_cb (log_callback )
574+
575+ # Function to get FPS
576+ def get_fps ():
577+ return fps_buffer [0 ]
578+
579+ fps = get_fps ()
580+ if fps > 0 : # Only print when FPS is updated
581+ print ("Current FPS:" , fps )
582+
583+ # Main loop
584+ for _ in range (10 ):
585+ fps = get_fps ()
586+ if fps > 0 : # Only print when FPS is updated
587+ print ("Current FPS:" , fps )
588+ time .sleep (1 )
589+
590+
591+
592+ # crash:
593+
594+ label = lv .label (lv .screen_active ())
595+ label .delete ()
596+ gc .collect ()
597+ label .set_text ("Crash!" ) # This will crash
598+ label .set_text (None )
599+ label .set_size (100000 , 1000000 )
600+
601+ buf = lv .draw_buf_create (10 , 10 , lv .COLOR_FORMAT .RGB565 , 1 )
602+ buf .data [1000000 ] = 0xFF # Write way beyond buffer size
603+
604+ # this works to crash it:
605+ from machine import mem32
606+ mem32 [0 ] = 0xDEADBEEF
0 commit comments