2022年2月9日 星期三

顯示 ESP32/ESP8266 開發板記憶體使用情形的方法

最近這幾天忙著將手邊幾款 ESP8266/ESP32 開發板的 MicroPython 版本升到 v1.18, 想說 esp 或 micropython 模組裡面是否有查詢檔案空間與 SRAM 記憶體耗用情形的函式, 發現似乎只有 micropython.mem_info() 可以顯示 SRAM 記憶體使用情形, 例如 : 

>>> import micropython   
>>> micropython.mem_info()    
stack: 704 out of 15360
GC: total: 111168, used: 4192, free: 106976   
 No. of 1-blocks: 87, 2-blocks: 31, max blk sz: 18, max free sz: 6660

其中 GC 後面的 total: 111168 表示此板 SRAM 記憶體約 111KB, 而 free: 106976 表示可用記憶體還有 107 KB 左右, 兩者相除就可以得到可用記憶體之百分比=106976/111168=96%. 

我在MicroPython 討論區找到了解決辦法, 參考下面這篇 : 


作者 devnull 寫了兩個自訂程式 df() 與 free() 來分別顯示 Flash 與 SRAM 記憶體可用空間, 原始程式碼引用如下 :

import gc
import os

def df():
  s = os.statvfs('//')     
  return ('{0} MB'.format((s[0]*s[3])/1048576))

def free(full=False):
  F = gc.mem_free()   
  A = gc.mem_alloc()     
  T = F+A
  P = '{0:.2f}%'.format(F/T*100)
  if not full: return P
  else : return ('Total:{0} Free:{1} ({2})'.format(T,F,P))

可見檢查 Flash 檔案空間容量是使用 os.statvfs(), 而檢查 SRAM 記憶體空間則是使用 gc.mem_free() 與 gc_mem_alloc() 來計算. 

以下是在 WROOM ESP32S 開發板測試的結果 :

>>> import os
>>> import gc
>>> def df():    
...       s = os.statvfs('//')
...       return ('{0} MB'.format((s[0]*s[3])/1048576))
...
...
...
>>> df()               # 顯示檔案系統可用容量
'1.988281 MB'

可見 4MB 的 Flash 記憶體燒完 MicroPython 韌體後只剩一半約 2MB 可用. 

>>> def free(full=False):
...       F = gc.mem_free()        # 可用之 SRAM 記憶體大小
...       A = gc.mem_alloc()      # 已可用之 SRAM 記憶體大小
...       T = F+A
...       P = '{0:.2f}%'.format(F/T*100)
...       if not full: return P
...       else : return ('Total:{0} Free:{1} ({2})'.format(T,F,P))
...
...
...
>>> free()            # 預設顯示可用記憶體百分比
'96.65%'
>>> free(True)    # 指定顯示可用記憶體完整資訊
'Total:111168 Free:107296 (96.52%)'

可見剛燒完韌體還沒有跑程式, SRAM 記憶體可用率為 96.52%. 

下面是在 Witty Cloud ESP8266 機智雲開發板上的測試結果 :

MicroPython v1.18 on 2022-01-17; ESP module with ESP8266
Type "help()" for more information.
>>> import os
>>> import gc
>>> def df():
...       s = os.statvfs('//')
...       return ('{0} MB'.format((s[0]*s[3])/1048576))
...
...
...
>>> def free(full=False):
...       F = gc.mem_free()
...       A = gc.mem_alloc()
...       T = F+A
...       P = '{0:.2f}%'.format(F/T*100)
...       if not full: return P
...       else : return ('Total:{0} Free:{1} ({2})'.format(T,F,P))
...
...
...
>>> df()
'2.96875 MB'    
>>> free(True)
'Total:37952 Free:35136 (92.58%)'

Witty Cloud ESP8266 開發板剛燒完韌體 Flash 還有近 3MB, 比上面 WROOM ESP32S (同樣是 4MB Flash) 足足多出 1MB, 可見 ESP32 的 MicroPython 較吃空間. 

D1 mini 開發板在同樣情況下測試結果為 :

>>> df()
'2.96875 MB'   
>>> free(True)
'Total:37952 Free:35008 (92.24%)'

可見 D1 mini 與 Witty Cloud 結果差不多 (都是 4MB 的 ESP8266).

沒有留言 :