Espruino:Примеры/Расширение возможностей Espruino 1 – Создание собственного расширения прошивки
Расширение возможностей Espruino 1 – Создание собственного расширения прошивки[1]
Это руководство служит кратким введением в написание ваших собственных расширений для Espruino, а также создание собственного двоичного кода.
Более подробно об этом можно почитать в этом руководстве по созданию собственного класса.
Использование свободной flash-памяти для текста
Идея в том, чтобы взять неиспользуемую flash-память и сохранить в эту область текстовые данные. HTTP-сервер использует много HTML-команд, и их хранение в исходном JavaScript-коде требует много памяти. На маленьких чипах вроде ESP8266 это быстро становится проблемой.
Несколько команд для работы с flash-памятью уже есть, так что идея в том, чтобы добавить дополнительную команду вроде...
readString(StartAddress of Flashpage, sequenceNumber inside this page)
В этом руководстве мы пройдём следующие шаги:
- Создание файла обёртки
- Шаблон для .h и .c
- Добавление исходного кода функции на C
- Внесение изменений в файл сборки
- Запуск
Создание файла обёртки
Основа для всего нашего мероприятия – это Espruino. Соответственно, нам нужно будет использовать уже устоявшиеся правила и соглашения для этого языка. К ним относится, например, то, как называть файлы исходного кода. В нашем случае это будет «jswrap_FlashExtension». Наш код тестировался только для ESP8266, и он не является частью стандартного ESP8266-порта для Espruino, и поэтому путём для хранения файлов исходного кода будет «/Esrpuino/targets/esp8266/myLibs». Нам понадобится один заголовочный файл и один файл с исходным кодом: «jswrap_FlashExtension.h» и «jswrap_FlashExtension.c».
Шаблон для .h и .c
Давайте начнём с заголовочного файла. Часть с авторскими правами в этот раз можно пропустить. Лично я рекомендую подсмотреть, как устроены другие файлы, и делать что-то похожее. Помните, что Espruino – это язык с открытым кодом.
#include "jsvar.h"
#include "jswrap_flash.h"
JsVar *jswrap_flash_readString(int addr, int pointer);
Подключать jsvar.h никогда не лишне, это одна из важнейших частей Espruino. Если ваше устройство работает только на JavaScript, то с помощью jsvar.h в нём будет обрабатываться хранение всего – и переменных, и исходного кода. Заголовочный файл jswrap_flash.h отвечает за все функции, связанные с flash-памятью, и некоторые из них, скорее всего, будут для вас полезны. Наконец, третья строчка – это описание функции, более подробно об этом смотрите в следующем разделе.
Добавление исходного кода функции на C
#include "jswrap_FlashExtension.h"
#include "jshardware.h"
Первая строчка добавляется для всего, что пишется на C. Со второй строчкой интереснее – это заголовочный файл для всех функций, связанных с «железом». К ним относится и считывание данных с flash-памяти.
/*JSON{
"type" : "staticmethod",
"class" : "Flash",
"name" : "readString",
"generate" : "jswrap_flash_readString",
"params" : [
["addr","int","An address in the page to store strings"],
["pointer","int","seqNr of string"]
],
"return" : ["JsVar","A Uint8Array"]
}
*/
На первый взгляд, эта часть закомментирована и никакого толка от неё нет. Но на самом деле эти комментарии сканируются фоновым скриптом. Как видите, некоторые данные здесь представлены в JSON-формате. И они конвертируются в ещё один C-файл. В конце концов, этот сгенерированный файл будет связующим звеном между JavaScript-файлом и скомпилированной C-функцией. Простите, если сумбурно, уверен, есть немало людей, которые объяснят это лучше меня.
Начнём давайте с краткого описания пути – текст хранится в flash-памяти, и наше расширение, напоминаю, предназначено для его считывания. Начало каждой страницы flash-памяти – это набор указателей на сами данные. Начало и размер каждого текстового элемента хранятся в виде 16-битных значений. Сам текст начинается после части с указателями. Вариантов того, как сохранять данные, на самом деле много, но в нашем случае вполне хватит и этого.
JsVar *jswrap_flash_readString(int addr, int pointer){
int startAddr, length, pnt,tmp;
pnt = addr + pointer * 4;
jshFlashRead(&tmp, (uint32_t)(pnt), 4);
length = tmp >> 16;
startAddr = tmp & 0xffff;
return jswrap_flash_read(length,addr + startAddr);
}
Считывание данных из flash-памяти – это функция, связанная с «железом» (jshFlashRead), которая выполняется в границах 4 байт. Значение Int32 поделено на начало и размер. Наконец, нам остаётся лишь воспользоваться уже готовой функцией чтения из объекта Flash, чтобы прочесть текст. Формат возвращаемых данных – это Uint8Array, который можно без труда преобразовать в строку при помощи E.toString().
Внесение изменений в файл сборки
Теперь, когда исходный код готов, настало время для компиляции и компоновки. Файлу сборки необходимо знать о дополнительных файлах. И это ответ на вопрос о том, зачем нам нужна поддиректория myLibs – чтобы не вносить изменения для каждого нового расширения, мы будем искать файлы только в этой директории.
ifdef USE_ESP8266
DEFINES += -DUSE_ESP8266
WRAPPERSOURCES += libs/network/esp8266/jswrap_esp8266_network.c \
targets/esp8266/jswrap_esp8266.c
INCLUDE += -I$(ROOT)/libs/network/esp8266
SOURCES += \
libs/network/esp8266/network_esp8266.c\
libs/network/esp8266/pktbuf.c\
libs/network/esp8266/ota.c
ifdef USE_MYLIB
WRAPPERSOURCES += $(wildcard targets/esp8266/myLibs/jswrap*.c)
SOURCES += $(wildcard targets/esp8266/myLibs/lib*.c)
endif
endif
В файле сборки уже есть фрагмент, который добавляет во внутренний список файлы, специфичные для платы. Если в USE_MYLIB будет задано «1», шаблонная функция будет искать и добавлять дополнительные файлы. Строчки рядом с шаблонными функциями не являются частью стандартного файла сборки. Их нужно обязательно добавить перед следующим этапом.
Запуск
Итак, все изменения внесены, теперь пора запустить файл сборки. В моём случае запись прошивки выполнялась при помощи программатора NodeMCU под Windows. В целях упрощения этого процесса у моей виртуальной машины и Windows есть общая папка. Сам файл сборки создаёт TAR-файл со всеми двоичными файлами. Для обработки TAR-файлов есть специальные приложения, но гораздо проще сделать это в самой виртуальной машине.
ESP8266_BOARD=1 USE_MYLIB=1 make
tar -xzf espruino*.tgz -C /mnt/hgfs/C_tmp_VMWare
cd /mnt/hgfs/C_tmp_VMWare
rm -rvf espruino
mv espruino* espruino
cd
Разумеется, всё никогда не работает идеально и со всем этим могут возникнуть проблемы. Вы всегда можете оставить обратную связь об этом руководстве и возникших проблемах на форуме Espruino или на Gitter.
См.также
Внешние ссылки