关于ESP8266设备的介绍

ESP8266是由Espressif开发的一种流行的支持wifi的片上系统(SoC)。

ESP8266系统板

为了方便学习应用关于ESP8266的MicroPython,最好使用含有USB转串口TTL电路,自动引导电路与ESP核心模块一起的评估板。

为了实现通用接口我们有如下协定

  • 我们将使用基于ESP8266官方引脚定义名称作为MircoPython中GPIO引脚名称。
  • MicroPython可以控制所有的引脚,但不是所有的引脚你都能使用,这是因为有的引脚可能已经使用了,不能再次使用,例如有SPI flash,你就不能再使用相关联的引脚了。不同的模块可能引出的引脚数量不同,在硬件适配的时候一定注意。
  • 有些电路板可能缺乏外部引脚/内部连接来支持ESP8266 deepsleep模式。

技术规范和SoC数据表

有关ESP8266芯片的数据表和其他参考资料可从供应商网站获得: http://bbs.espressif.com/viewtopic.php?f=67&t=225 . 它们是芯片技术规格、性能、运行方式、内部功能等方面的主要参考。

为了方便,下面提供了一些技术规格:

  • 内核: Xtensa lx106
  • CPU 频率: 80MHz overclockable to 160MHz
  • 可用RAM: 96KB (部分用于系统)
  • BootROM: 64KB
  • 内置 FlashROM: None
  • 外置 FlashROM: 代码和数据, SPI Flash. 通常大小 512KB-4MB.
  • GPIO: 16 + 1 (GPIOs与其他功能进行多路复用, 包括外置 FlashROM, UART,深度睡眠唤醒,等等)
  • UART: 一路 RX/TX UART (没有硬件握手), 一路 只发 UART.
  • SPI: 2 SPI 接口 (1路用于FlashROM).
  • I2C: 没有固定的引脚,软件方式任何可用引脚都可以用.
  • I2S: 1.
  • 编程: 通过UART使用引导下载到使用 BootROM 也可以是外部flash中 ,不论如何都是引导到 BootROM bootloader永远可用,不至于ESP32变砖.

运行时资源有限性说明

ESP8266的资源非常有限(首先是RAM内存)。因此,请避免分配太大的容器对象(列表、字典)和缓冲区。也没有成熟的操作系统来跟踪资源并自动清理它们,所以这是用户/用户应用程序的任务:请确保在使用后尽快关闭打开的文件、套接字等。

引导过程

在引导时,如果MicroPython在EPS8266烧录好则模块将读取执行``_boot.py`` 脚本。 在FlashROM安装系统文件, or if it’s not available, performs first-time setup of the module and creates the filesystem. This part of the boot process is considered fixed, and not available for customization for end users (even if you build from source, please refrain from changes to it; customization of early boot process is available only to advanced users and developers, who can diagnose themselves any issues arising from modifying the standard process).

Once the filesystem is mounted, boot.py is executed from it. The standard version of this file is created during first-time module set up and has commands to start a WebREPL daemon (disabled by default, configurable with webrepl_setup module), etc. This file is customizable by end users (for example, you may want to set some parameters or add other services which should be run on a module start-up). But keep in mind that incorrect modifications to boot.py may still lead to boot loops or lock ups, requiring to reflash a module from scratch. (In particular, it’s recommended that you use either webrepl_setup module or manual editing to configure WebREPL, but not both).

As a final step of boot procedure, main.py is executed from filesystem, if exists. This file is a hook to start up a user application each time on boot (instead of going to REPL). For small test applications, you may name them directly as main.py, and upload to module, but instead it’s recommended to keep your application(s) in separate files, and have just the following in main.py:

import my_app
my_app.main()

This will allow to keep the structure of your application clear, as well as allow to install multiple applications on a board, and switch among them.

Known Issues

Real-time clock

RTC in ESP8266 has very bad accuracy, drift may be seconds per minute. As a workaround, to measure short enough intervals you can use utime.time(), etc. functions, and for wall clock time, synchronize from the net using included ntptime.py module.

Due to limitations of the ESP8266 chip the internal real-time clock (RTC) will overflow every 7:45h. If a long-term working RTC time is required then time() or localtime() must be called at least once within 7 hours. MicroPython will then handle the overflow.

Sockets and WiFi buffers overflow

Socket instances remain active until they are explicitly closed. This has two consequences. Firstly they occupy RAM, so an application which opens sockets without closing them may eventually run out of memory. Secondly not properly closed socket can cause the low-level part of the vendor WiFi stack to emit Lmac errors. This occurs if data comes in for a socket and is not processed in a timely manner. This can overflow the WiFi stack input queue and lead to a deadlock. The only recovery is by a hard reset.

The above may also happen after an application terminates and quits to the REPL for any reason including an exception. Subsequent arrival of data provokes the failure with the above error message repeatedly issued. So, sockets should be closed in any case, regardless whether an application terminates successfully or by an exeption, for example using try/finally:

sock = socket(...)
try:
    # Use sock
finally:
    sock.close()

SSL/TLS limitations

ESP8266 uses axTLS library, which is one of the smallest TLS libraries with the compatible licensing. However, it also has some known issues/limitations:

  1. No support for Diffie-Hellman (DH) key exchange and Elliptic-curve cryptography (ECC). This means it can’t work with sites which force the use of these features (it works ok with classic RSA certificates).
  2. Half-duplex communication nature. axTLS uses a single buffer for both sending and receiving, which leads to considerable memory saving and works well with protocols like HTTP. But there may be problems with protocols which don’t follow classic request-response model.

Besides axTLS own limitations, the configuration used for MicroPython is highly optimized for code size, which leads to additional limitations (these may be lifted in the future):

  1. Optimized RSA algorithms are not enabled, which may lead to slow SSL handshakes.
  2. Stored sessions are not supported (may allow faster repeated connections to the same site in some circumstances).

Besides axTLS specific limitations described above, there’s another generic limitation with usage of TLS on the low-memory devices:

  1. The TLS standard specifies the maximum length of the TLS record (unit of TLS communication, the entire record must be buffered before it can be processed) as 16KB. That’s almost half of the available ESP8266 memory, and inside a more or less advanced application would be hard to allocate due to memory fragmentation issues. As a compromise, a smaller buffer is used, with the idea that the most interesting usage for SSL would be accessing various REST APIs, which usually require much smaller messages. The buffers size is on the order of 5KB, and is adjusted from time to time, taking as a reference being able to access https://google.com . The smaller buffer hower means that some sites can’t be accessed using it, and it’s not possible to stream large amounts of data.

There are also some not implemented features specifically in MicroPython’s ussl module based on axTLS:

  1. Certificates are not validated (this may make connections susceptible to man-in-the-middle attacks).
  2. There is no support for client certificates (scheduled to be fixed in 1.9.4 release).