2017年5月18日 星期四

MicroPython on ESP8266 (六) : 檔案系統測試

昨晚重建 MicroPython on ESP8266 的檔案系統後就順利搞定 WebREPL 檔案傳送這個重要關卡了, 實在是可喜可賀. 那麼今天就來好好地測試一下檔案系統的功能. 由於 WebREPL client 對於檔案的管理只有上傳與下載檔案的功能而已, 如果要對檔案系統進行管理, 例如新增刪除目錄等等就力有未逮, 必須使用 ampy, mpfshell, 或 rshell 等套件. 在上一篇文章裡只大略測試了 ampy 與 mpfshell 的檔案管理功能, 這裡要來做個詳細測試.

此系列前面五篇測試參考 :


MicroPython 文件參考 :

MicroPython tutorial for ESP8266  (官方教學)
http://docs.micropython.org/en/latest/micropython-esp8266.pdf
http://docs.micropython.org/en/latest/pyboard/library/usocket.html#class-socket
http://docs.micropython.org/en/v1.8.7/esp8266/library/usocket.html#module-usocket
https://gist.github.com/xyb/9a4c8d7fba92e6e3761a (驅動程式)

其實檔案系統最重要的是根目錄 / 下的兩個 python 執行檔 boot.py 與 main.py, 韌體在開機後首先會去根目錄下找尋 boot.py, 有找到的話就先執行此開機檔, 然後再尋找 main.py, 有的話就執行此程式, 一般而言, main.py 裡面主要就是一個執行特定應用邏輯無窮迴圈. 因此通常會在 boot.py 裡面進行系統設定, 例如開啟關閉 debug 或 webrepl 功能等. 一般 boot.py 的內容如下 :

#import esp
#esp.osdebug(None)
import gc
import webrepl
webrepl.start(password="123456")
gc.collect()

首先在 REPL 或 WebREPL 介面上測試 MicroPython 的檔案功能, 注意, 以下測試是在新版 (1MB Flash) 的 ESP-01 模組上進行的, 因為只有 Flash 記憶體超過 1MB 才有足夠空間建立檔案系統, 參考 :

# The internal filesystem

"If your devices has 1Mbyte or more of storage then it will be set up (upon first boot) to contain a filesystem. This filesystem uses the FAT format and is stored in the flash after the MicroPython firmware."

MicroPython 事實上只納入基本的檔案目錄操作功能如檔案與目錄的讀寫而已, 雖有實作 os 模組但卻未實作 os.path 模組, 例如 :

>>> import os                                                                                      
>>> import os.path                                                                                  
Traceback (most recent call last):                                                                  
  File "<stdin>", line 1, in <module>                                                              
ImportError: no module named 'os'

一. 讀寫文字檔 :

Python 的檔案操作是使用內建函數 open() 與 close(), 此函數會開啟指定檔案, 並傳回其檔案物件參考, 語法如下 :

 函數 & 方法 說明
 f=open('filename' [, 'mode']) 開啟檔案 (預設唯讀 mode='r'), 傳回檔案物件參考
 f.close() 關閉參考 f 之所指之檔案物件 (關檔)

其中 filename 為文字檔案名稱如 data.txt, data.log 等, 而 mode 為開啟模式, 有三種模式 :

 開啟模式 說明
 w 寫入模式 (取代原檔案內容)
 a 附加寫入模式 (寫入資料附加於原內容尾端)
 r 唯讀模式 (預設)

開啟檔案後可用下列檔案物件的方法讀寫檔案 :

 方法 說明
 write(string) 將字串 string 寫入檔案 
 read() 傳回全部檔案內容
 readline() 逐列讀取檔案內容, 傳回目前指標所指之列內容
 readlines() 逐列讀取檔案內容, 將各列內容放在串列中傳回

在 w 模式開啟一個不存在的檔案相當於是建立一個空白檔案, 利用傳回的檔案物件參考呼叫 write() 方法就可以寫入文字資料, write() 方法的傳回值是寫入的 byte 數. 如果要開啟的檔案已存在, 則 w 模式下用 write() 寫入的資料將取代檔案內的原資料 (原檔案內容會被刪除); 而在 a 模式下原檔案內容不會消失, 新寫入的資料會附加在原檔案內容後面.

注意, 檔案讀寫完畢務必呼叫 close() 方法關閉檔案, 否則記憶體將無法釋放而造成系統資源浪費, 例如.

>>> f=open('data.txt','w')   #開啟一個空白檔案                                     >>> f.write('Hello!\r\n')     #寫入資料
8                                                         #傳回寫入 byte 數
>>> f.write('World!')         #寫入資料
6                                                         #傳回寫入 byte 數
>>> f.close()                       #關閉檔案

這時用 os.listdir() 就可以看到檔案系統中多出了剛建立的 data.txt :

>>> import os                                                                                         
>>> os.listdir()                                                                                      
['boot.py', 'main.py', 'data.txt']

在 WebREPL 網頁右端的 "Get a file" 框內輸入 data.txt 後按 "Get from device" 鈕即可下載剛剛建立的文字檔 :


開啟所下載之檔案, 其內容為兩列文字 (因為有跳行字元 \r\n 之故) :

Hello!
World!

注意, Windows 跳行須用 \r\n, 若只用 \n 沒有跳行效果. 

如果以 a 模式再次開啟檔案, 並寫入 'MicroPython' 字串, 則此字串將附加於 World! 之後, 例如 :

>>> f=open('data.txt','a') 
>>> f.write('MicroPython') 
11 
>>> f.close()

再次下載 data.txt 開啟後發現內容果然變成如下 :

Hello!
World!MicroPython

讀取檔案內容可使用 read(), readline(), 以及 readlines() 這三個方法. 其中 read() 會一次讀取全部內容後傳回, 例如 :

>>> f=open('data.txt','r')                                                                            
>>> f.read()                                                                                          
'Hello!\r\nWorld!MicroPython'

注意, 以 r 模式開啟檔案時, 該檔案必須已存在, 否則會產生錯誤 :

>>> f=open('data.log','r')                                                                            
Traceback (most recent call last):                                                                    
  File "<stdin>", line 1, in <module>                                                                 
OSError: [Errno 2] ENOEN

其次, readline() 是每次讀取檔案中的一列後傳回 (字串), 讀到檔尾時會傳回空字串 : 

>>> f=open('data.txt','r')
>>> line=f.readline()       #讀第 1 列
>>> line                    
'Hello!\r\n'
>>> line=f.readline()       #讀第 2 列
>>> line
'World!MicroPython'
>>> line=f.readline()       #已到檔尾, 傳回空字串
>>> line
''
>>> f.close()

可以用 while 迴圈逐列讀取, 用傳回值是否為真來控制迴圈是否繼續, 因空字串之布林值為 False, 固可作為迴圈終止條件 :

>>> f=open('data.txt','r')
>>> while True:    #無限迴圈
...     line=f.readline()           #讀取一列
...     if not line:break            #檔尾傳回空字串 (False) 跳出迴圈
...     print(line)
...
Hello!

World!MicroPython
>>> f.close()

readlines() 方法也是一次讀取全部內容, 但它是逐列讀取後放入串列中傳回, 可以使用 for 迭代將串列內容讀出來, 例如 :

>>> f.close()
>>> f=open('data.txt','r')
>>> lines=f.readlines()
>>> type(lines)
>>> for line in lines:
...     print(line)
...
...
...
Hello!

World!MicroPython
>>> f.close()

以上便是 MicroPython 的基本檔案讀寫測試. MicroPython 的檔案系統可以應用在物聯網的 data logger, 例如紀錄溫溼度等環境氣候變化等.


二. 檔案管理套件 :

由於 WebREPL 只有檔案上傳下載功能, 如果需要新增刪除目錄或檔案等檔案管理功能, 需另行安裝 Adafruit-ampy, mpfshell, 或 rshell 等套件才可達到此目的.


1. Adafruit-ampy :

此套件由 Adafruit 發布, 利用串列埠與 ESP8266 模組連線 (沒有 wifi 連線功能) 進行檔案管理, 安裝 ampy 參考 :

Adafruit : Install ampy

利用 pip 指令即可線上安裝此套件 :

D:\<pip3 install adafruit-ampy
Collecting adafruit-ampy
  Downloading adafruit_ampy-1.0.1-py2.py3-none-any.whl
Collecting click (from adafruit-ampy)
  Downloading click-6.7-py2.py3-none-any.whl (71kB)
Collecting pyserial (from adafruit-ampy)
  Downloading pyserial-3.3-py2.py3-none-any.whl (189kB)
Installing collected packages: click, pyserial, adafruit-ampy
Successfully installed adafruit-ampy-1.0.1 click-6.7 pyserial-3.3

可見 ampy 有兩個相依套件 click 與 pyserial, 如果要在無 Internet 環境安裝 ampy, 可在下列網址下載這三個檔案以離線方式安裝 :

https://pypi.python.org/pypi/adafruit-ampy/
https://pypi.python.org/pypi/click
https://pypi.python.org/pypi/pyserial

在命令提示字元視窗下 ampy --help 會列出 ampy 命令格式 :

D:\test>ampy --help
Usage: ampy [OPTIONS] COMMAND [ARGS]...

  ampy - Adafruit MicroPython Tool

  Ampy is a tool to control MicroPython boards over a serial connection.
  Using ampy you can manipulate files on the board's internal filesystem and
  even run scripts.

Options:
  -p, --port PORT  Name of serial port for connected board.  Can optionally
                   specify with AMPY_PORT environemnt variable.  [required]
  -b, --baud BAUD  Baud rate for the serial connection (default 115200).  Can
                   optionally specify with AMPY_BAUD environment variable.
  --version        Show the version and exit.
  --help           Show this message and exit.

Commands:
  get    Retrieve a file from the board.
  ls     List contents of a directory on the board.
  mkdir  Create a directory on the board.
  put    Put a file or folder and its contents on the...
  reset  Perform soft reset/reboot of the board.
  rm     Remove a file from the board.
  rmdir  Forcefully remove a folder and all its...
  run    Run a script and print its output.

這裡很重要的是 OPTION 中的 port, 在 Windows 是用 COMx (慣例是用大寫), 所以要先在裝置管理員中確定 USB-TTL 轉接線是哪一個 COM 埠. 另外因為 ampy 要使用串列埠, 所以如果有使用 PuTTY 開啟該 COM 埠的話, 必須關掉 Putty, 否則 ampy 的指令都會報錯, 例如 :

D:\test>ampy --port COM4 put main.py
Traceback (most recent call last):
  File "c:\python36\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\python36\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Python36\Scripts\ampy.exe\__main__.py", line 9, in
  File "c:\python36\lib\site-packages\click\core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "c:\python36\lib\site-packages\click\core.py", line 697, in main
    rv = self.invoke(ctx)
  File "c:\python36\lib\site-packages\click\core.py", line 1063, in invoke
    Command.invoke(self, ctx)
  File "c:\python36\lib\site-packages\click\core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\python36\lib\site-packages\click\core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "c:\python36\lib\site-packages\ampy\cli.py", line 70, in cli
    _board = pyboard.Pyboard(port, baudrate=baud)
  File "c:\python36\lib\site-packages\ampy\pyboard.py", line 143, in __init__
    raise PyboardError('failed to access ' + device)
ampy.pyboard.PyboardError: failed to access COM4    (因為 PuTTY 也在連線 COM4 導致衝突)

首先來測試目錄的新增 (mkdir) 刪除 (rmdir), 檔案刪除 (rm), 以及檔案與目錄列示 (ls) 等指令 :

D:\test>ampy --port COM4 mkdir test      #建立目錄 test

D:\test>ampy --port COM4 ls                     #列出根目錄下的檔案與目錄
boot.py
main.py
data.txt
data.log
test                                                                      #新增的目錄

D:\test>ampy --port COM4 rmdir test       #刪除目錄 test

D:\test>ampy --port COM4 ls                      #列出根目錄下的檔案與目錄
boot.py
main.py
data.txt
data.log

D:\test>ampy --port COM4 rm data.log     #刪除檔案 data.log

D:\test>ampy --port COM4 ls                      #列出根目錄下的檔案與目錄
boot.py
main.py
data.txt                                                                 #data.log 已被刪除

其次測試 get 指令, 我原以為這與 webrepl 一樣是從 ESP8266 下載檔案, 測試結果卻是讀取檔案內容後直接在命令列, 我覺得應該稱為 cat 才對 :

D:\test>ampy --port COM4 get data.txt      #讀取並顯示檔案內容
Hello!
World!MicroPython

接下來測試檔案上傳 (put) 指令, 為了同時也測試 run 指令, 我先編輯了一個執行檔 hello.py, 就是單純地印出 Hello World! 而已 :

print('Hello World')

然後將此 hello.py 上傳到根目錄

D:\test>ampy --port COM4 put hello.py      #上傳檔案  

D:\test>ampy --port COM4 ls                       #列出根目錄下的檔案與目錄
boot.py
main.py
data.txt
hello.py

D:\test>ampy --port COM4 run hello.py     #執行 hello.py
Hello World

注意, run 指令會等 python 程式執行完才會輸出結果, 這對如下有無限迴圈的程式而言, 用 ampy run 將永遠看不到所執行程式之輸出結果 :

i = 1
while True:  #無限迴圈
    print(i)     #ampy run 永遠無法看到此輸出
    i += 1

解決之道是加上 --no-output 參數 :

D:\test>ampy --port COM4 run endlessloop.py  --no-output   #執行 hello.py

參考 :

Run Code

最後測試重啟指令 reset :

D:\test>ampy --port COM4 reset  

D:\test>

此指令下達後視窗會停住一會兒等系統重置完成才會跳出提示號.

如果不想每次下 ampy 指令都要指定 port, 可以先設定環境參數 AMPY_PORT, 例如 :

D:\test>SET AMPY_PORT=COM4       #設定環境參數 AMPY_PORT
D:\test>ampy ls                                          #不用再指定 --port 參數
boot.py
main.py
data.txt
hello.py

參考 :

Run Code
File Operations

下面是 Adafruit 關於檔案系統的教學影片 :

# Micropython esp8266 Tutorial 4 - Filesystem and ampy part 2



2. mpfshell :

此檔案系統管理套件的功能相當於 ampy 加上 webrepl, 但 mpfshell 在 ESP8266 板子不是透過串列埠來連線, 而是與 webrepl 一樣是透過 WiFi 網路連線 (使用 websocket).

mpfshell 本身須離線安裝, 可由下面網址下載 mpfshell 的 zip 檔 :

https://github.com/wendlers/mpfshell

由於 mpfshell 相依於 colorama 與 websocket-client, 必須先安裝這兩個套件才能安裝 mpfshell, 可以在線安裝 :

D:\test>pip3 install colorama
Collecting colorama
  Downloading colorama-0.3.9-py2.py3-none-any.whl
Installing collected packages: colorama
Successfully installed colorama-0.3.9

D:\test>pip3 install websocket_client
Collecting websocket_client
  Downloading websocket_client-0.40.0.tar.gz (196kB)
B 436kB/s
Requirement already satisfied: six in c:\python36\lib\site-packages (from websoc
ket_client)
Installing collected packages: websocket-client
  Running setup.py install for websocket-client ... done
Successfully installed websocket-client-0.40.0

也可以下載這兩個套件後離線安裝 :

https://pypi.python.org/pypi/colorama
https://pypi.python.org/pypi/websocket-client/

安裝程序如下 :

D:\test>pip3 install d:\python\colorama-0.3.9-py2.py3-none-any.whl
Processing d:\python\colorama-0.3.9-py2.py3-none-any.whl
Installing collected packages: colorama
Successfully installed colorama-0.3.9

D:\test>pip3 install d:\python\websocket_client-0.40.0.tar.gz
Processing d:\python\websocket_client-0.40.0.tar.gz
Requirement already satisfied: six in c:\python36\lib\site-packages (from websoc
ket-client==0.40.0)
Installing collected packages: websocket-client
  Running setup.py install for websocket-client ... done
Successfully installed websocket-client-0.40.0

最後安裝 mpfshell 本身 :

D:\test>pip3 install d:\python\mpfshell-master.zip
Processing d:\python\mpfshell-master.zip
Requirement already satisfied: pyserial in c:\python36\lib\site-packages (from m
pfshell==0.8.0)
Requirement already satisfied: colorama in c:\python36\lib\site-packages (from m
pfshell==0.8.0)
Requirement already satisfied: websocket_client in c:\python36\lib\site-packages
 (from mpfshell==0.8.0)
Requirement already satisfied: six in c:\python36\lib\site-packages (from websoc
ket_client-<mpfshell==0.8.0)
Installing collected packages: mpfshell
  Running setup.py install for mpfshell ... done
Successfully installed mpfshell-0.8.0

安裝完畢後開啟命令提示字元視窗, 輸入 mpfshell 卻無法執行 :

E:\test>mpfshell
'mpfshell' 不是內部或外部命令、可執行的程式或批次檔。

原因是安裝在 Python 的 Scripts 目錄下的 mpfshell 缺少副檔名 .py 之故, 只要手動在其後面加上 .py 即可 :


這樣再次輸入 mpfshell 即可進入 mpfs 介面了 :

D:\test>mpfshell

** Micropython File Shell v0.8.0, sw@kaltpost.de **
-- Running on Python 3.6 using PySerial 3.3 --

mpfs [/]>

按 Ctrl+C 會離開 mpfshell 介面回到命令提示字元.

由於 mpfshell 也是使用 webrepl 連線 ESP8266, 而 webrepl 無法多重連線, 因此若 WebREPL client 還在連線中的話, mpfshell 將連線失敗, 在 WebREPL client 畫面會顯示 :

"Concurrent WebREPL connection from(IP, port) rejected"


只要按 WebREPL client 上方的 "Disconnect" 鈕離線, mpfshell 就能順利連線了 :

D:\test>mpfshell                             #進入 mpfshell 介面

** Micropython File Shell v0.8.0, sw@kaltpost.de **
-- Running on Python 3.6 using PySerial 3.3 --

mpfs [/]> help                                  #指令列表

Documented commands (type help <topic>):
========================================
EOF  cd     exec  get   lcd  lpwd  md    mput  mrm   put  repl
cat  close  exit  help  lls  ls    mget  mpyc  open  pwd  rm

help 後面加上指令可以查看該指令說明, 例如 :

mpfs [/]> help put                            #顯示 put 指令之說明
put <LOCAL FILE> [<REMOTE FILE>]
        Upload local file. If the second parameter is given,
        its value is used for the remote file name. Otherwise the
        remote file will be named the same as the local file.

mpfs [/]> open ws:192.168.2.107    #連線 ESP8266
webrepl passwd:                                     #輸入 webrepl 密碼 123456

Failed to open: ws:192.168.2.107           #因 WebREPL client 連線中著導致 mpfshell 無法連線

mpfs [/]> open ws:192.168.2.107     #將 WebREPL client 離線後 mpfshell 即可順利連線
webrepl passwd:                                     #輸入 webrepl 密碼 123456
Connected to esp8266                             #連線成功
mpfs [/]> ls                                         #顯示檔案與目錄列表

Remote files in '/':

       boot.py
       main.py
       data.txt
       hello.py

mpfs [/]> cat boot.py                          #顯示檔案內容
#import esp
#esp.osdebug(None)
import gc
import webrepl
webrepl.start(password="123456")
gc.collect()

mpfs [/]> md log                                 #新增目錄 log
mpfs [/]> ls                                          #顯示檔案與目錄列表

Remote files in '/':

       boot.py
       main.py
       data.txt
       hello.py

mpfs [/]> cd log                                   #切換到 log 目錄

mpfs [/log]> pwd                                 #顯示目前路徑
/log

mpfs [/log]> help put                          #顯示 put 指令說明
put <LOCAL FILE> [<REMOTE FILE>]
        Upload local file. If the second parameter is given,
        its value is used for the remote file name. Otherwise the
        remote file will be named the same as the local file.

mpfs [/log]> put data.log                     #上傳 data.log 至 ESP8266        
mpfs [/log]> ls                                       #顯示檔案與目錄列表

Remote files in '/log':

 <dir> ..
       data.log                                                 #log 下有剛上傳的 data.log

mpfs [/log]> cat data.log                       #顯示檔案內容
Hello World!

mpfs [/log]> get data.log                       #下載 data.log

mpfs [/log]> rm data.log                       #刪除檔案
mpfs [/log]> cd ..                                    #切換目錄至上一層
mpfs [/]> rm log                                     #刪除目錄  log
mpfs [/]> ls                                             #顯示檔案與目錄列表

Remote files in '/':                                        #已無 log 目錄

       boot.py
       main.py
       data.txt
       hello.py

mpfshell 也有本地端檔案系統操作指令 (L 開頭的除了 ls 外都是本機指令), 不須跳出 mpfshell 也可以切換本機路徑或顯示檔案 :

mpfs [/]> lpwd                                        #顯示本機目前路徑
D:\test

mpfs [/]> lcd ..                                        #切換本機目前路徑至上一層

mpfs [/]> lpwd                                        #顯示本機目前路徑
D:\
mpfs [/]> lcd test                                    #切換本機目前路徑至 test 目錄
mpfs [/]> lpwd                                        #顯示本機目前路徑
D:\test

mpfs [/]> lls                                            #顯示本機目前路徑下之檔案與目錄

Local files:

       boot.py
       data.log
       hello.py
       menutest.java
       pyautogui_1.py
       pyautogui_2.py
       tk1.py

m 開頭的指令 mget, mput, 與 mrm 為使用正規表示法來整批下載, 上傳以及刪除遠端檔案系統中的檔案. 這在需要大量處理遠端檔案時非常有用, 例如下載 ESP8266 所記錄的 log 檔至本機中進一步處理, 或者整批下載後再整批刪除以節省 Flash 空間.

mpfs [/]> help mget      #顯示 mget 指令說明
mget <SELECTION REGEX>
        Download all remote files that match the given regular expression.
        The local files will be named the same as the remote files.

        "mget" does not get directories, and it is note recursive.


mpfs [/]> lls                   #顯示本機目前路徑下檔案目錄

Local files:                          #目前路徑下是空的


mpfs [/]> ls                     #顯示遠端目前路徑下檔案目錄

Remote files in '/':                #有 4 個檔案

       boot.py
       main.py
       data.txt
       hello.py

mpfs [/]> mget .*\.py      #以正規表達式整批下載 .py 檔
 * get boot.py
 * get main.py
 * get hello.py
mpfs [/]> lls

Local files:                            #整批下載了 3 個 .py 檔案

       boot.py
       hello.py
       main.py

mpfshell 的 repl 指令還可以像 Putty 連線那樣進入 REPL 介面 (透過 websocket 連線) :

mpfs [/]> repl
>
*** Exit REPL with Ctrl+Q ***

MicroPython v1.8.7-7-gb5a1a20a3 on 2017-01-09; ESP module with ESP8266
Type "help()" for more information.
>>> print('Hello!')
Hello!
(按 Ctrl+Q)
mpfs [/]>

可見於 REPL 介面按 Ctrl+Q 又回到 mpfshell 介面了. 也就是說有了 mpfshell 後其實就不需要 Putty 了, 這是 mpfshell 比 ampy 以及 webrepl 好用的地方. 我唯一不滿意的是它的文字顏色.


3. rshell :

rshell 與 mpfshell 一樣都具有模擬 REPL 功能

在線安裝 :

E:\test>pip3 install rshell
Collecting rshell
  Downloading rshell-0.0.9.tar.gz
Requirement already satisfied: pyserial in c:\python36\lib\site-packages (from r
shell)
Collecting pyudev>=0.16 (from rshell)
  Downloading pyudev-0.21.0.tar.gz (89kB)
 561kB/s
Requirement already satisfied: six in c:\python36\lib\site-packages (from pyudev
>=0.16->rshell)
Installing collected packages: pyudev, rshell
  Running setup.py install for pyudev ... done
  Running setup.py install for rshell ... done
Successfully installed pyudev-0.21.0 rshell-0.0.9

可見 rshell 有兩個相依套件 pyserial 與 pyudev, 若要離線安裝須先下載安裝這兩個套件 :

https://pypi.python.org/pypi/pyudev
https://pypi.python.org/pypi/pyserial

先安裝 pyudev 套件與 pyserial :

C:\Users\Tony<pip3 install d:\python\pyudev-0.21.0.tar.gz
Processing d:\python\pyudev-0.21.0.tar.gz
Requirement already satisfied: six in c:\python36\lib\site-packages (from pyudev
==0.21.0)
Installing collected packages: pyudev
  Running setup.py install for pyudev ... done
Successfully installed pyudev-0.21.0

C:\Users\Tony>pip3 install d:\python\pyserial-3.3-py2.py3-none-any.whl
Requirement already satisfied: pyserial==3.3 from file:///E:/python/pyserial-3.3
-py2.py3-none-any.whl in c:\python36\lib\site-packages

然後下載 rshell 壓縮檔 :

https://github.com/dhylands/rshell

安裝 rshell :

C:\Users\Tony<pip3 install d:\python\rshell-master.zip
Processing d:\python\rshell-master.zip
Requirement already satisfied: pyserial in c:\python36\lib\site-packages (from r
shell==0.0.9)
Requirement already satisfied: pyudev<=0.16 in c:\python36\lib\site-packages (fr
om rshell==0.0.9)
Requirement already satisfied: six in c:\python36\lib\site-packages (from pyudev
<=0.16-<rshell==0.0.9)
Installing collected packages: rshell
  Running setup.py install for rshell ... done
Successfully installed rshell-0.0.9

但安裝完後輸入 rshell 卻出現錯誤 :

E:\test>rshell           #開啟 rshell
Traceback (most recent call last):
  File "C:\Python36\Scripts\rshell-script.py", line 11, in     load_entry_point('rshell==0.0.9', 'console_scripts', 'rshell')()
  File "c:\python36\lib\site-packages\pkg_resources\__init__.py", line 565, in l
oad_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "c:\python36\lib\site-packages\pkg_resources\__init__.py", line 2631, in
load_entry_point
    return ep.load()
  File "c:\python36\lib\site-packages\pkg_resources\__init__.py", line 2291, in
load
    return self.resolve()
  File "c:\python36\lib\site-packages\pkg_resources\__init__.py", line 2297, in
resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "c:\python36\lib\site-packages\rshell\command_line.py", line 1, in e>
    import rshell.main
  File "c:\python36\lib\site-packages\rshell\main.py", line 65, in     import readline
ModuleNotFoundError: No module named 'readline'

雖然 rshell 功能似乎比 mpfshell 多, 但不知道是啥原因不能跑, 殘念 ~~~.

參考 :

Problems with running MicroPython on ESP8266 with 512K


2017-05-25 補充 :

最近在測試 MicroPython 時發現手上一堆舊版 ESP-01 因為只有 512K Flash 記憶體而用途受限, 看來只能當 Arduino 的 WiFi 模組了. 雖然還是可以灌 512K 韌體, 但因空間太小沒有檔案系統, 只能在 REPL 環境下執行 Python 程式, 沒辦法傳 boot.py 與 main.py 進去, 如果斷電重開機得重新在 REPL 輸入程式, 參考 :

Current _boot.py not compatible with ESP8266-01 #1986

"@doudz : Filesystem on modules with 512K flash is not supported (assuming yours is such). To help us diagnose it, move away _boot.py, build, boot, run "import port_diag", and provide its output."

2017-06-24 補充 :

今天在找 WDT 資料時從下列文章中看到應用程式配置的好方法 :

https://github.com/micropython/micropython/issues/2154

意思是不要把應用程式直接命名為 main.py, 而是取名為較容易辨識的 my_app.py, 然後在 main.py 裡面匯入 my_app, 再呼叫 my_app.main() 來執行應用程式, 例如 :


import my_app 
my_app.main()

參考 :

http://docs.micropython.org/en/latest/esp8266/esp8266/general.html#boot-process

這樣雖然要編輯上傳 main.py 與 my_app.py 兩個檔案, 比較麻煩, 但是在模組化而言, 一個應用可能會拆成好幾個 .py 程式, 這個方式會比較符合結構化原則. 

2017-06-26 補充 :


如果 ampy 突然無法上傳檔案, 且 REPL 中用 os.listdir() 發現有一堆 \x00, 這表示檔案系統已經局部毀損了, 但重灌韌體並無法解決檔案系統受損問題, 必須利用下列程式碼重建檔案系統 :

>>> from flashbdev import bdev
>>> uos.VfsFat.mkfs(bdev)
>>> vfs=uos.VfsFat(bdev)
>>> with open("/boot.py", "w") as f:
...     f.write("""\
...     import gc
...     gc.collect()
...     """)
...     f.close()
...

...

參考 :

MicroPython v1.9.1 版韌體測試

沒有留言 :