M5Stack(ESP32)学习笔记(9)—— 编译并烧写M5Stack的MicroPython固件

      UIFlow是个挺不错的编程环境,适合新手学习。它基于MicroPython(Lobo版本),也可以脱离UIFlow的IDE来用Python编程。但是把玩了几天后,我发现M5Stack的原配UIFlow/MicroPython有如下问题:

  1. 系统带的东西不少,启动后运行的东西比较多,也有很多令我不明白的地方,而且官方文档也没有说清楚
  2. 我的M5Stack Fire有16M的Flash ROM,但是UIFlow启动后只有700k左右 ( https://blog.csdn.net/zhufu86/article/details/91049171 )
  3. 没有支持PSRAM(M5Stack Fire自带4M的PSRAM),相信我,对于MicroPython来说4M的RAM和520K的RAM有天壤之别
  4. UIFlow不适合希望深入研究MicroPython的人,而且,没有UIFlow的纯MicroPython更适合生产环境

那么,我来自己编译一个可以发挥M5Stack Fire的优势的MicroPython版本吧。

编译环境

首先,需要有一个编译环境。 按照Lobo MicroPython的wiki的说法,编译环境用各种平台都可以。乐鑫也说可以在win系统下用MSYS2环境来编译。 然而我尝试了一圈(Win&macOS),似乎都不太顺利。算了,还是用Linux吧。因为我没有安装了Linux的主机,所以只能用虚拟机。 为了不让安装的Linux占太多空间,我选择了Debian 9.9。

在macOS下使用VirtualBox安装Debian 9.9

详细安装过程省略……

  • 下载debian-9.9.0-amd64-xfce-CD-1.iso
  • VirtualBox设置:
    内存设置2048MB
    硬盘设置为16GB
  • 安装过程
    选择文本安装界面
    语言选择英语
    国家选择中国
    locale选择en_US.UTF-8
    Use a network mirror? 选择No
    安装的组件,取消选择 Debian desktop environment 和 … Xfce,只选standard system utilities
  • 安装完成后,用root登录。为了避免权限问题,所有的命令都使用root登录执行
  • 为了方便执行命令,开启ssh-server
    apt-get install openssh-server
  • 修改sshd_config文件,命令为:vi /etc/ssh/sshd_config
  • 将#PasswordAuthentication yes的注释去掉
  • 将#PermitRootLogin prohibit-password的注释去掉,并把prohibit-password改为yes
  • 启动SSH服务,命令为:/etc/init.d/ssh start// 或者service ssh start
  • 已经启动的话,/etc/init.d/ssh resetart
  • 验证SSH服务状态,命令为:/etc/init.d/ssh status
  • 添加开机自启动 update-rc.d ssh enable应该不需要,系统已经把ssh设为自启动了
  • VirtualBox设置端口转发,把Host的2222端口转发到Guest的22端口
  • 这样就可以在macOS的命令行用ssh -p2222 [email protected]登录到Debian Linux了
  • 登录后修改apt源为国内源,参考:
    http://mirrors.ustc.edu.cn/help/debian.html
    http://mirrors.ustc.edu.cn/help/debian-security.html

下载MicroPython的源码

我选择了M5Stack放出的Lobo版本,地址在:
https://github.com/m5stack/M5Stack_MicroPython

点Clone or download直接下载zip包。 当然也可以git clone,但是我这边太慢。

下载完成后,从macOS拷贝到Debian Linux。

scp -P2222 M5Stack_MicroPython.zip [email protected]:/root/

准备编译环境

  • 安装必要的包
apt-get install git wget make libncurses-dev flex bison gperf python python-serial g++ libfuse-dev picocom unzip
  • 解压缩M5Stack_MicroPython.zip
unzip M5Stack_MicroPython.zip
  • 把M5Stack插入USB口,并且在USBSettings里面增加Filter,让VirtualBox自动捕捉Silcon Labs CP2104 USB to UART Bridge Controller连接到Debian Linux。

  • 在Debian里面查看M5Stack串口连接对应的设备名称

root@debian:~# ls /dev/ttyU*
/dev/ttyUSB0

多半可能是/dev/ttyUSB0

编译和烧写

编译

  • 执行如下命令,会进入配置界面
root@debian:~# cd M5Stack_MicroPython/MicroPython_BUILD/
root@debian:~/M5Stack_MicroPython/MicroPython_BUILD# ./BUILD.sh menuconfig
  • 其实我也没弄清所有的配置,以下是我觉得比较重要的地方:(如果发现编译烧写后不对,可以./BUILD.sh clean./BUILD.sh menuconfig重新配置)
  • Bootloader config
       —> Bootloader log verbosity设为Verbose
  • Serial flasher config
       —> Default serial port设置为(/dev/ttyUSB0
       —> Flash SPI mode (DIO)
       —> Flash SPI speed (80 MHz)
       —> Flash size (16 MB)
  • MicroPython
       —> (CST-8) Time zone
       —> System settings
          ------> (24) MicroPython stack size (KB)
          ------> (2560) MicroPython heap size (KB) (你需要先打开ESP32-specific -> Support for external, SPI-connected RAM,否则会无法设置)
       —> Modules
          ------> [*] Use Websockets
          ------> [*] Use Display module
          ------> [*] Use GSM module
          ------> [*] Use GPS module
          ------> [*] Use mDNS module
          ------> [*] Use requests module
          ------> [*] Use Curl module
          ------> [*] Enable TLS in Curl module (NEW)
          ------> [*] FTP support in Curl module
          ------> [*] Use SSH module
          ------> [*] Use Mqtt module
       —> File systems
          ------> Set internal filesystem type (SPIFFS)
       —> SD Card configuration
          ------> SD Card mode (SPI Mode)
          ------> [ ] Allow hispeed in SPI mode
          ------> (18) CLK pin
          ------> (23) MOSI pin
          ------> (19) MISO pin
          ------> (4) CS pin
  • Partition Table
       —> Partition Table (Custom partition table CSV)
       —> (partitions.csv) Custom partition CSV file (NEW)
  • Component config
       —> Bluetooth 打开
       —> ESP32-specific
          ------> [*] Support for external, SPI-connected RAM
          ------> SPI RAM config
             ---------> SPI RAM access method (Make RAM allocatable using heap_caps_malloc)
             ---------> Set RAM clock speed (40MHz clock speed) 设为80MHz会导致SD卡不能挂载,不知道为什么。
          ------> FAT Filesystem support
             ---------> OEM Code Page (Simplified Chinese (DBCS) (CP936))

其他未列出的,我保留默认了(其实是不知道怎么改。是时候深入学习一下ESP32了。)

  • Save然后Exit

  • 新建一个文件 partitions.csv ,文件内容如下:

# -------------------------------------------------------
# -    Partition layout generated by BUILD.sh script    -
# -------------------------------------------------------
# Name,         Type, SubType, Offset,  Size,       Flags
# -------------------------------------------------------
nvs,            data, nvs,     0x9000,  24K,
phy_init,       data, phy,     0xf000,  4K,
MicroPython,    app,  factory, 0x10000, 2304K,
internalfs,     data, spiffs,  0x250000, 12288K,
  • 运行 ./BUILD.sh编译,如果./BUILD.sh -v会打印出比较“啰嗦的”编译过程信息,选择哪种,要看个人口味。

  • 几分钟(取决于你的PC有多快)后,看到如下内容应该就是编译成功了

--------------------------------
Build complete.
You can now run ./BUILD.sh flash
to deploy the firmware to ESP32
--------------------------------

烧写

  • 强烈建议无论如何先擦除Flash
root@debian:~/M5Stack_MicroPython/MicroPython_BUILD# ./BUILD.sh erase

----------------------------------------
MicroPython for ESP32 with psRAM support
----------------------------------------

======================
Erasing ESP32 Flash...
======================
Erasing entire flash...
esptool.py v2.5.0
Serial port /dev/ttyUSB0
Connecting.....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse
MAC: ……
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Erasing flash (this may take a while)...
Chip erase completed successfully in 31.3s
Staying in bootloader.
OK.

root@debian:~/M5Stack_MicroPython/MicroPython_BUILD#
  • 如果擦除或者烧写开始的时候,出现连接串口的困难,或者Timeout,需要在试图连接串口的过程中按一下M5Stack左侧的复位按键,如果不行的话,需要反复尝试按键。
  • 然后烧写
root@debian:~/M5Stack_MicroPython/MicroPython_BUILD# ./BUILD.sh flash

----------------------------------------
MicroPython for ESP32 with psRAM support
----------------------------------------

=========================================
Flashing MicroPython firmware to ESP32...
=========================================
AR build/libnmea/liblibnmea.a
LD build/MicroPython.elf
esptool.py v2.5.0
Flashing binaries to serial port /dev/ttyUSB0 (app at offset 0x10000 )...
esptool.py v2.5.0
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32D0WDQ6 (revision 1)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse
MAC: ……
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 921600
Changed.
Configuring flash size...
Auto-detected Flash size: 16MB
Compressed 24896 bytes to 14040...
Wrote 24896 bytes (14040 compressed) at 0x00001000 in 0.2 seconds (effective 1071.0 kbit/s)...
Hash of data verified.
Compressed 144 bytes to 69...
Wrote 144 bytes (69 compressed) at 0x0000f000 in 0.0 seconds (effective 236.7 kbit/s)...
Hash of data verified.
Compressed 2322400 bytes to 1419457...
Wrote 2322400 bytes (1419457 compressed) at 0x00010000 in 19.6 seconds (effective 947.4 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 127...
Wrote 3072 bytes (127 compressed) at 0x00008000 in 0.0 seconds (effective 3884.4 kbit/s)...
Hash of data verified.

Leaving...
Staying in bootloader.
OK.

root@debian:~/M5Stack_MicroPython/MicroPython_BUILD#
  • 检查是否烧写成功,执行 ./BUILD.sh monitor可以看到M5Stack的启动过程 (Ctrl+] 可以退出
    启动过程中可以看到Flash Size
I (55) boot: SPI Speed      : 80MHz
I (60) boot: SPI Mode       : DIO
I (64) boot: SPI Flash Size : 16MB

Partition Table

I (84) boot: Partition Table:
I (87) boot: ## Label            Usage          Type ST Offset   Length
D (94) boot: load partition table entry 0x3f408000
D (99) boot: type=1 subtype=2
I (102) boot:  0 nvs              WiFi data        01 02 00009000 00006000
D (110) boot: load partition table entry 0x3f408020
D (115) boot: type=1 subtype=1
I (118) boot:  1 phy_init         RF data          01 01 0000f000 00001000
D (126) boot: load partition table entry 0x3f408040
D (131) boot: type=0 subtype=0
I (134) boot:  2 MicroPython      factory app      00 00 00010000 00240000
D (141) boot: load partition table entry 0x3f408060
D (146) boot: type=1 subtype=82
I (149) boot:  3 internalfs       Unknown data     01 82 00250000 00c00000
I (157) boot: End of partition table

第一次启动可以看到internalfs分区会被格式化

W (1073) SPIFFS: mount failed, -10025. formatting...

Internal FS (SPIFFS): Mounted on partition 'internalfs' [size: 12582912; Flash address: 0x250000]
----------------
Filesystem size: 11558656 B
           Used: 512 B
           Free: 11558144 B
----------------

然后启动就完成了

MicroPython ESP32_LoBo_v3.2.24 - 2018-09-06 on ESP32 board with ESP32
Type "help()" for more information.
>>>

验收成果

好了,编译和烧写过程看上去是顺利的。 下面来看看新烧写的系统有什么不同吧。

  • 检查RAM
>>> import micropython, machine
>>> micropython.mem_info()
stack: 752 out of 23552
GC: total: 2561344, used: 7712, free: 2553632
No. of 1-blocks: 17, 2-blocks: 7, max blk sz: 440, max free sz: 159592
>>> machine.heap_info()
Heap outside of MicroPython heap:
---------------------------------
             Free: 158208
        Allocated: 45484
     Minimum free: 154436
     Total blocks: 85
Largest free block: 113804
 Allocated blocks: 79
      Free blocks: 6

SPIRAM info:
------------
             Free: 1572804
        Allocated: 2621456
     Minimum free: 1572804
     Total blocks: 2
Largest free block: 1572804
 Allocated blocks: 1
      Free blocks: 1
>>>
>>> a = ['esp32'] * 200000
>>>
>>> a[123456]
'esp32'
>>>
>>> micropython.mem_info()
stack: 752 out of 23552
GC: total: 2561344, used: 808176, free: 1753168
No. of 1-blocks: 31, 2-blocks: 13, max blk sz: 50000, max free sz: 109564

分配了一个很大数组后,还有1.7M左右的可用RAM

  • 检查ROM
>>> import os
>>> statvfs_fields = ['bsize','frsize','blocks','bfree','bavail','files','ffree',]
>>> info = dict(zip(statvfs_fields, os.statvfs('/flash')))
>>> info
{'files': 0, 'ffree': 0, 'bsize': 256, 'bfree': 45149, 'frsize': 256, 'bavail': 45149, 'blocks': 45151}
>>> info['bsize'] * info['bfree']
11558144
>>>

剩余空间 11 558 144字节

  • 挂载SD卡
>>> import uos
>>> uos.mountsd()
---------------------
 Mode: SPI
     Name: SU08G
     Type: SDHC/SDXC
    Speed: default speed (25 MHz)
SPI speed: 20 MHz
     Size: 7580 MB
      CSD: ver=1, sector_size=512, capacity=15523840 read_bl_len=9
      SCR: sd_spec=2, bus_width=5

>>> uos.listdir('/sd/')
[……, ……]
>>>
  • Wifi
>>> import network
>>> wlan=network.WLAN(network.STA_IF)
>>> wlan.wifiactive()
False
>>> wlan.active(True)
W (421208) phy_init: failed to load RF calibration data (0x1102), falling back to full calibration   (啥?)
True
>>> wlan.wifiactive()
True
>>> wlan.scan()
[扫描结果略]
>>> wlan.connect('ssid','password')
>>> wlan.isconnected()
True
  • TFT display
>>> import display
>>> tft = display.TFT()
>>> tft.init(tft.M5STACK, width=240, height=320, rst_pin=33, backl_pin=32, miso=19, mosi=23, clk=18, cs=14, dc=27, bgr=True, backl_on=1)
>>> tft.println('Hello world!')
>>>
  • RTC
>>> import machine,time
>>> time.gmtime()
(1970, 1, 1, 0, 14, 32, 5, 1)
>>> rtc = machine.RTC()
>>> rtc.ntp_sync(server = "ntp.aliyun.com",tz='CST-8')
>>> rtc.synced()
True
>>> time.gmtime()
(2019, 6, 16, 6, 25, 13, 1, 167)
>>> time.localtime()
(2019, 6, 16, 14, 25, 22, 1, 167)
>>> time.strftime('%Y/%m/%d %H:%M:%S',time.localtime())
'2019/06/16 14:25:32'
  • 不过有些原来M5Stack UIFlow可以用的库也不能用了,比如
>>> import units

Device ID:240ac4a65958
LCD initializing...Done!
>>> env0 = units.ENV(units.PORTA)
Traceback (most recent call last):
  File "", line 1, in <module>
  File "m5flow/units.py", line 20, in __init__
ImportError: no module named 'dht12'
>>>

不过我想应该可以用其他方法实现。
[Update 20190616 16:43] 要想使用units.ENV,在/flash/lib文件夹下上传bmp280.mpy和dht12.mpy即可。

结束

好了,编译和烧写成功。

【参考资料】
https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/wiki
https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/wiki/build
https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/wiki/filesystems
https://zhuanlan.zhihu.com/p/37940795
https://wiki.ai-thinker.com/esp32/docs/esp32_idf_menuconfig
https://www.esp32.com/viewtopic.php?t=2446
https://www.arduino.cn/thread-84654-1-1.html
http://forum.m5stack.com/topic/307/gui-for-m5stack-micropython
http://forum.m5stack.com/topic/892/solved-trouble-burning-micropython-firmware/3
http://forum.m5stack.com/category/15/micropython
https://forum.micropython.org/viewtopic.php?t=6042
https://appelsiini.net/2018/m5stack-esp32-firmware-cli/
https://github.com/m5stack/M5Stack_MicroPython
https://docs.espressif.com/projects/esp-idf/en/latest/get-started/windows-setup.html
https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo/blob/master/MicroPython_BUILD/components/micropython/esp32/modules_examples/tft/tftdemo.py
http://iot-bits.com/customizing-esp32-partitions-table/
https://randomnerdtutorials.com/solved-failed-to-connect-to-esp32-timed-out-waiting-for-packet-header/

你可能感兴趣的:(M5Stack(ESP32)学习笔记(9)—— 编译并烧写M5Stack的MicroPython固件)