Skip to content

Commit 22072d3

Browse files
memtest: add warning
1 parent c7fec9a commit 22072d3

2 files changed

Lines changed: 139 additions & 1 deletion

File tree

internal_filesystem/apps/com.example.memtest/assets/memtest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,12 @@ def test_allocation(buffer_size, n):
7373
return count
7474

7575
def stress_test_thread():
76-
summary = "Running RAM memory tests...\n\n"
76+
summary = "Running RAM memory tests...\n"
77+
summary += "This might hang on desktop/unix.\n\n"
7778
summary += "Buffer Size (bytes) | Max Allocated\n"
7879
summary += "-----------------------------------\n"
7980
lv.async_call(lambda l: status.set_text(summary), None)
81+
time.sleep_ms(500)
8082
# Test buffer sizes of 2^n, starting from n=1 (2 bytes)
8183
n = 1
8284
while keep_running:
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Example results for ESP32-S3 with 8MB SPIRAM:
2+
#
3+
#=== Memory Allocation Test Summary ===
4+
#Buffer Size (bytes) | Max Buffers Allocated
5+
#----------------------------------------
6+
# 2 | 25762
7+
# 4 | 25760
8+
# 8 | 25771
9+
# 16 | 25759
10+
# 32 | 35541
11+
# 64 | 11276
12+
# 128 | 6517
13+
# 256 | 3521
14+
# 512 | 1832
15+
# 1024 | 932
16+
# 2048 | 466
17+
# 4096 | 232
18+
# 8192 | 115
19+
# 16384 | 56
20+
# 32768 | 26
21+
# 65536 | 12
22+
# 131072 | 9
23+
# 262144 | 4
24+
# 524288 | 2
25+
# 1048576 | 1
26+
# 2097152 | 0
27+
#=====================================
28+
#
29+
# On desktop, this hangs while outputting, for some reason...
30+
31+
import gc
32+
import time
33+
import _thread
34+
35+
# Configuration
36+
ALLOCATION_TIMEOUT_MS = 100 # Timeout for a single allocation (in milliseconds)
37+
keep_running = True
38+
summary = ""
39+
40+
def test_allocation(buffer_size, n):
41+
"""Test how many buffers of a given size can be allocated with a timeout."""
42+
print(f"\nTesting buffer size: {buffer_size} bytes (2^{n})")
43+
buffers = []
44+
count = 0
45+
46+
try:
47+
while keep_running:
48+
# Measure time for allocation
49+
start_time = time.ticks_ms()
50+
# Allocate a new buffer
51+
buffer = bytearray(buffer_size)
52+
allocation_time = time.ticks_diff(time.ticks_ms(), start_time)
53+
54+
# Check if allocation took too long
55+
if allocation_time > ALLOCATION_TIMEOUT_MS:
56+
print(f"\nStopped after allocating {count} buffers of {buffer_size} bytes: Allocation timeout ({allocation_time}ms > {ALLOCATION_TIMEOUT_MS}ms)")
57+
break
58+
59+
buffers.append(buffer)
60+
count += 1
61+
# Print progress every 100 allocations to avoid flooding serial
62+
if count % 100 == 0:
63+
print(f"Allocated {count} buffers of {buffer_size} bytes", end="\r")
64+
except MemoryError as e:
65+
buffers.clear()
66+
print(f"\nStopped after allocating {count} buffers of {buffer_size} bytes: MemoryError")
67+
except Exception as e:
68+
buffers.clear()
69+
print(f"\nStopped after allocating {count} buffers of {buffer_size} bytes: {e}")
70+
71+
# Free allocated buffers
72+
buffers.clear()
73+
gc.collect()
74+
return count
75+
76+
def update_status(timer):
77+
global status, summary
78+
status.set_text(summary)
79+
80+
def stress_test_thread():
81+
global summary
82+
summary += "Running RAM memory tests...\n"
83+
summary += "This might hang on desktop/unix.\n\n"
84+
summary += "Buffer Size (bytes) | Max Allocated\n"
85+
summary += "-----------------------------------\n"
86+
time.sleep(1)
87+
#lv.async_call(lambda l: update_status(), None)
88+
# Test buffer sizes of 2^n, starting from n=1 (2 bytes)
89+
n = 1
90+
while keep_running:
91+
buffer_size = 2 ** n
92+
summary += f"{buffer_size:>12} | "
93+
#lv.async_call(lambda l: status.set_text(summary), None)
94+
# Run allocation test
95+
gc.collect()
96+
max_buffers = test_allocation(buffer_size, n)
97+
# Check if we allocated 0 buffers (indicates we can't allocate this size)
98+
if max_buffers == 0:
99+
print(f"Cannot allocate buffers of size {buffer_size} bytes. Stopping test.")
100+
summary += f"{max_buffers:>14}\n"
101+
#lv.async_call(lambda l: status.set_text(summary), None)
102+
break
103+
# Clean up memory before next test
104+
gc.collect()
105+
n += 1
106+
summary += f"{max_buffers:>14}\n"
107+
#lv.async_call(lambda l: update_status(), None)
108+
time.sleep_ms(200) # Brief delay to stabilize system
109+
# Print summary report
110+
summary += "\n"
111+
summary += "===================================\n"
112+
summary += "Test completed.\n"
113+
#lv.async_call(lambda l: update_status(), None)
114+
115+
116+
117+
def janitor_cb(timer):
118+
global keep_running
119+
if lv.screen_active() != appscreen:
120+
print("memtest.py backgrounded, cleaning up...")
121+
janitor.delete()
122+
keep_running = False
123+
update_status_timer.delete()
124+
125+
appscreen = lv.screen_active()
126+
status = lv.label(appscreen)
127+
status.align(lv.ALIGN.TOP_LEFT, 5, 10)
128+
status.set_style_text_color(lv.color_hex(0xFFFFFF), 0)
129+
status.set_style_text_font(lv.font_unscii_8, 0)
130+
131+
_thread.stack_size(12*1024)
132+
_thread.start_new_thread(stress_test_thread, ())
133+
134+
update_status_timer = lv.timer_create(update_status, 750, None)
135+
janitor = lv.timer_create(janitor_cb, 400, None)
136+

0 commit comments

Comments
 (0)