MicroPython:Платы/ESP8266/Общая информация о порте ESP8266

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Общая информация о порте ESP8266[1]

ESP8266 – это популярное WiFi-устройство типа SoC (от англ. «system on chip», т.е. «система на чипе»), разработанное Espressif Systems.

Большое разнообразие плат

Платы и модули, оснащенные ESP8266, выпускаются разными компаниями, и их существует огромное множество. Разработчики порта MicroPython постарались сделать его максимально универсальным, чтобы его можно запустить на максимально возможном количестве плат/модулей, но пользователь все равно может столкнуться с некоторыми ограничениями. В качестве базовой платы для порта была взята Adafruit Feather HUZZAH (к примеру, тесты выполнялись именно на ней). Если у вас какая-то другая плата, убедитесь, что у вас есть даташит, схема и прочие справочные материалы на нее, чтобы вы всегда могли подглядеть разные аспекты ее функционирования.

Чтобы сделать максимально универсальный ESP8266-порт, поддерживающий как можно больше плат, были приняты следующие конструкторские решения:

  • Нумерация GPIO-контактов основана на нумерации контактов чипа ESP8266, а не на некой «логической» нумерации. Советуем держать под рукой руководство, схему или распиновку своей платы, чтобы сверяться между ее контактами и контактами ESP8266. Также просим пользователей различных плат составлять схемы того, как контакты их плат и ESP8266 соответствуют или не соответствуют друг другу, и делиться ими на форуме MicroPython – идея в том, чтобы со временем создать на форуме большую коллекцию этих схем для всеобщего просмотра и использования.
  • В MicroPython поддерживаются почти все контакты ESP8266, за исключением тех, что не имеет смысла поддерживать (к примеру, контакты, используемые для подключения к чипу SPI flash, не доступны, т.к. они редко используются для других целей, а их использование может привести к блокировке платы). Впрочем, какой бы модели не была плата, у нее никогда не будут доступны все контакты. Подробнее читайте в документации к своей плате.
  • У некоторых плат может не быть внешних контактов и внутреннего функционала для поддержки режима глубокого сна ESP8266.

Технические характеристики и даташиты SoC

Даташиты и прочие справочные материалы для чипа ESP8266 доступны на сайте производителя. Это главная документация по техническим характеристикам чипа, его функциям, режимам работы, внутреннему функционалу и т.д.

Для вашего удобства некоторые из этих технических характеристик приведены ниже:

  • Архитектура: Xtensa lx106
  • Частота CPU: 80 МГц (с возможностью разгона до 160 МГц)
  • Общее количество RAM-памяти: 96 Кб (часть зарезервирована для системы)
  • BootROM: 64 Кб
  • Внутренняя FlashROM: Нет
  • Внешняя FlashROM: код и данные через SPI Flash. Как правильно, размер между 512 Кб и 4 Мб
  • GPIO: 16 + 1 (на GPIO-контактах также реализованы другие функции, включая использование внешней FlashROM и UART-портов, пробуждение из режима глубокого сна и т.д.)
  • UART: один UART-порт с RX- и TX-линиями (без аппаратного квитирования), один UART-порт, оснащенный только TX-линией
  • SPI: два интерфейса SPI (один используется для FlashROM)
  • I2C: штатный внешний I2C отсутствует («bit-banging» можно использовать на всех контактах)
  • I2S: один
  • Программирование: через UART с помощью загрузчика BootROM. ESP8266 нельзя «окирпичить», поскольку у него внешняя FlashROM, а загрузчик BootROM доступен всегда.

Ограниченные ресурсы памяти

Функционал ESP8266 серьезно ограничен (особенно это касается RAM-памяти). Поэтому старайтесь не хранить в ней большие контейнерные объекты (списки, словари) и буферы. У него также нет полнофункциональной ОС, которая могла бы отслеживать используемые ресурсы и автоматически подчищать их, поэтому эти задачи ложатся на пользователя или пользовательское приложение: не забывайте закрывать открытые файлы, сокеты и т.д. как можно быстрее после использования.

Процесс загрузки

При загрузке порт MicroPython для ESP8266 запускает скрипт «_boot.py», хранящийся во внутренних замороженных модулях. Он монтирует файловую систему в FlashROM или, если она недоступна, выполняет первоначальную настройку модуля и создает файловую систему. Эта часть процесса загрузки считается фиксированной, и конечный пользователь ее модифицировать не может (даже если вы выполняете сборку из исходного кода, всё равно постарайтесь воздержаться от модификаций; кастомизацию начальной части процесса загрузки лучше делать, только если вы разработчик или продвинутый пользователь, который сможет диагностировать любые проблемы, возникающие при модификации стандартного процесса загрузки).

Когда монтирование файловой системы будет выполнено, из нее будет запущен скрипт «boot.py». Стандартная версия этого файла создается во время первоначальной настройки модуля и оснащена командами для запуска демона WebREPL (по умолчанию отключен, настраивается с помощью модуля webrepl_setup) и т.д. Конечный пользователь может отредактировать этот файл (к примеру, вы можете захотеть изменить некоторые параметры или модифицировать список сервисов, запускаемых при старте модуля). Но учтите, что некорректная модификация «boot.py» может привести к зацикливанию загрузки или блокировке платы, что потребует перепрошивки модуля с нуля. (В частности, для настройки WebREPL советуем использовать либо модуль webrepl_setup, либо делать это вручную, но ни то и другое вместе).

На завершающем этапе процесса загрузки из файловой системы выполняется файл «main.py» (если он существует). Этот файл словно крючок цепляет приложение пользователя, запуская его при каждой загрузке (и вам не приходится делать это в REPL). Работая с маленькими тестовыми приложениями, их можно прямо так и называть – «main.py» – а затем загружать в модуль, но мы рекомендуем держать свои приложения в отдельных файлах, а затем просто написать в «main.py» следующее (разумеется, здесь вместо «my_app» должно быть название вашего приложения):

import my_app
my_app.main()

Благодаря этому структура вашего приложения останется ясной и понятной. Кроме того, это позволит установить на плату несколько приложений и переключаться между ними.

Известные проблемы

Часы реального времени (RTC)

В ESP8266 у RTC-часов очень плохая точность, время может «съезжать» на несколько секунд в минуту. Поэтому для измерения коротких интервалов лучше использовать utime.time() и прочие похожие функции, а при использовании фактического времени синхронизируйте его через интернет при помощи встроенного модуля ntptime.py.

Из-за ограничений чипа ESP8266 счетчик его RTC-часов достигает предела каждые 7 часов 45 минут. Поэтому при долгом использовании RTC-времени нужно хотя бы раз в каждые 7 часов вызывать time() или localtime(). MicroPython доделает все остальное.

Сокеты и переполнение WiFi-буфера

Сокеты экземпляров остаются активными, пока их не закрывают явно. У этого два последствия. Во-первых, они занимают RAM-память, поэтому если приложение открывает сокеты, но не закрывает их, то в конце концов израсходует всю память.

Во-вторых, из-за некорректно закрытого сокета низкоуровневая часть WiFi-стека поставщика начнет выдавать ошибки «Lmac». Такое происходит, когда данные поступают в сокет, но не обрабатываются вовремя. Это может переполнить входную очередь WiFi-стека и привести к зависанию. В итоге восстановиться можно будет только с помощью полной перезагрузки.

Ситуация выше также может произойти, когда приложение прекращает работу и по какой-то причине (включая исключение) выходит в REPL. Последующий приток данных приводит к сбою плюс попутно с этим постоянно выскакивает ошибка выше.

Поэтому сокеты нужно закрывать в любом случае – независимо от того, закрывается ли приложение как надо или вместе с исключением – например, с помощью try/finally:

sock = socket(...)
try:
    # используем «sock»:
finally:
    sock.close()

Ограничения SSL/TLS

ESP8266 использует библиотеку axTLS. Это одна из самых маленьких TLS-библиотек плюс у нее подходящая лицензия. Но у нее есть и проблемы/ограничения:

  • Она не поддерживает алгоритм Диффи-Хеллмана и эллиптическую криптографию. Это значит, что она не может работать с сайтами, для которых обязательно использование этих технологий (но хорошо работает с классическими RSA-сертификатами).
  • В ней используется полудуплексный способ связи. Библиотека axTLS использует один буфер и для отправки, и для получения данных, что позволяет сэкономить немало памяти и хорошо работает с протоколами вроде HTTP. Но зато могут возникнуть проблемы с протоколами, которые не работают по классической модели запроса-ответа.

Помимо собственных ограничений axTLS, конфигурация, используемая в MicroPython, серьезно урезана, чтобы отвечать требованиям к размеру кода, что ведет к дополнительным ограничениям (в будущем эта проблема, возможно, будет решена):

  • Отсутствуют оптимизированные RSA-алгоритмы, что может замедлить квитирование SSL.
  • Не поддерживается сохранение сессий (в некоторых обстоятельствах эта функция позволяет быстрее выполнять повторные подключения к одному и тому же сайту).

Кроме того, есть еще одно общее ограничение использования TLS на устройствах, обладающих маленьким ресурсом памяти:

  • Согласно стандарту TLS, максимальный размер TLS-записи (это единица TLS-коммуникации; перед обработкой вся запись должна быть помещена в буфер) составляет 16 Кб. Это почти половина памяти, доступной на ESP8266, поэтому из-за проблем с фрагментацией памяти в нее будет трудно сохранить любое более-менее продвинутое приложение. В качестве компромисса используется буфер меньшего размера – идея в том, чтобы все самые важные данные SSL были доступны через различные REST API, которым требуются, как правило, сообщения гораздо меньшего размера. Размер буферов – около 5 Кб, но время от времени меняется, а за ориентир берется возможность доступа к https://google.com. Впрочем, из-за маленького буфера вы не сможете подключиться к некоторым сайтам, а также передавать большое количество данных.

Кроме того, несколько функций TLS не реализовано в MicroPython’овском модуле uss1, основанном на axTLS:

  • Сертификаты не проверяются (из-за этого соединения могут быть уязвимы к «атаке посредника»).
  • Нет поддержки клиентских сертификатов (планируется исправить в релизе 1.9.4).

См.также

Внешние ссылки