ESP-8266/ESP32 NodeMCU Lua: азы программирования.

Тема в разделе "ESP8266, ESP32", создана пользователем ИгорьК, 25 июл 2017.

  1. swc

    swc Гик

    О птичках. (О компиляторе LFS). Компилятор с github, аналогично и с интерактивного сайта все отлично компилирует, но код работать не хочет.
    Постоянная перезагрузка. Мой вариант работает без проблем. Об этом я писал разработчикам еще полгода назад. Не работает.
    Вопрос: это только у меня?
     
    ИгорьК и serg3295 нравится это.
  2. serg3295

    serg3295 Гик

    У меня проекты небольшие. Всё работает. Кросс взят с github. Версия его и прошивки синхронизированы. Могу завтра попробовать собрать вариант кросса текущей версии, а то собирал только предыдущий.
    Я вот подумал, а не может быть дело в _init.lua? Ну так, вдруг...

    UPD. Собрал для проверки в MSVS luac.cross.exe Получился размер 1 858 кБ, а не 1 841 кБ как на git'e. Но всё работает нормально. Компилирует и запускается.
     
    Последнее редактирование: 23 окт 2020
    ИгорьК и swc нравится это.
  3. swc

    swc Гик

    Заменил. Все пошло. Появился полезный инструмент - node.getpartitiontable(). Теперь, зная начальный адрес LFS можно образ заливать прямо во FLASH, минуя SPIFFS. Исключается лишний шаг node.LFS.reload(). Компилировать с опцией -а.
     
    Последнее редактирование: 23 окт 2020
    serg3295 и ИгорьК нравится это.
  4. serg3295

    serg3295 Гик

    Да, с ключом -a все замечательно работает (правда почему-то кросс-компилятору пришлось скармливать lfs_mapped address, иначе он ругался, а для выгрузки esptool'ом lfs_base.).
    Тут у меня появились вопросы:
    • esptool грузит по COM'у, то есть большой файл идёт долго. Как ещё можно выгрузить в абсолютный адрес flash? ftp и http уже не получится.
    • Как долго по времени выполняется flashreload на больших файлах lfs.img. У меня таких больших файлов нет, и не могу оценить.
    • Что дольше - залить, например, 60 кб по ftp(http) и flashreload, или по COM'у в абсолютный адрес и node.restart()?
    • Какая от этой картины от этого ключа польза. Пока я могу только предположить, что проект настолько большой, что и lfs.img в spiffs уже не влазит, тогда только с ключом -a. Может есть ещё какое-то практическое применение. Не зря же они этот ключ вводили :)
    некритичная мелочь - жёсткая привязка к конкретному проекту по абсолютному адресу. Хотя, возможно, при одинаковых железках можно один раз вбить адреса в скрипт и забыть.
     
    ИгорьК и swc нравится это.
  5. swc

    swc Гик

    Если можно, пожалуйста выложите командную строку компилятора. Я морочился (недолго) с опцией -а - не получилось.
    • У меня файл *img более 128 кб размещается в области LFS 256 кб.
    • Длительность загрузки зависит от программы. NodeMCU_Tool грузит дольше раза в два, чем ESPLorer.
    • flashreload выполняется секунд за 10. Сяду за проект - измерю точно.
    Преимущество заливки по адресу (на мой взгляд) - меньше телодвижений. Заливать Esptool.py или другими прошивальщиками.
    Поскольку выделение максимального объема LFS и постоянного начала области SPIFFS во всех проектах никому не вредит, то жесткая привязка к адресу прошивки уместна.
     
    ИгорьК и serg3295 нравится это.
  6. serg3295

    serg3295 Гик

    смотрим, где lfs
    Код (C++):
    do
      local s,p={},node.LFS.config
      for _,k in ipairs{'lfs_base','lfs_mapped','lfs_size','lfs_used'} do
      s[#s+1] ='%s = 0x%06x' % {k, p[k]}
      end
      print ('{ %s }' % table.concat(s,', '))
    end
     
    Видим
    > { lfs_base = 0x07c000, lfs_mapped = 0x4027c000, lfs_size = 0x020000, lfs_used = 0x0019cc }

    Build LFS. (Эта строчка из моего скрипта lfs.ps1. Подкорректируете в cmd.)
    luac.cross.exe -o $args[1] -f -m 0x020000 -a 0x4027c000 -l $args[2] | Out-file $args[3]

    Шил в LoLin не нажимая никаких кнопок.

    esptool.py --port COM4 write_flash 0x07c000 "./.output/lfs.bin"

    reset

    Подумал о применении этого ключа -a. Возможно, если разрабатывать не приложения для nodeMCU, а саму целевую систему, то удобно сразу всё объединять при сборке и заливать всё вместе. Как и написано в документации: "The LFS can then be flashed to the ESP along with the firmware image."
    Или на стадии production может нужно.
    UPD. В процессе экспериментов выяснилось - "Хорошая вещь, надо брать"(c)
    При настроенном скрипте телодвижение всего одно - нажать кнопку "пуск", и проконтролировать лампочку "готов" :) И тогда одним из факторов становится суммарная скорость операции.
     
    Последнее редактирование: 25 окт 2020
    ИгорьК и swc нравится это.
  7. swc

    swc Гик

    Измерения. Файл *img = 132 кб (распакованный).
    Загрузка:
    • NodeMCU_Tool - 1 мин. 13 сек.
    • ESPLorer - 23 сек.
    • node.LFS.reload() - 10 сек.
     
    serg3295 нравится это.
  8. serg3295

    serg3295 Гик

    Время огорчает. Пришлось почитать документацию по nodemcu-tool. А там автор пишет
    Включил в прошивку модуль encoder, и приятно удивился скорости закачки. 30 кб file.bin залетело за 9 сек. Время сравнялось с ESP!
    Короче, RTFM! :)
    UPD. А вот даже так: загрузка файла bin 96 750 байт
    esplorer 42 сек
    nodemcu 25 31 сек (с убранным --minify)
     
    Последнее редактирование: 24 окт 2020
    ИгорьК и swc нравится это.
  9. swc

    swc Гик

    esptool.py грузит LFS за 3 сек. Не успеваю секундомер включить-выключить. Но не идет. Вероятно путаю адреса.
    Прошивка 500 кб - 30 сек. Работает. Однако LFS напрямую - не хочет.
    Мне кажется, что *img файл не предназначен для прямой заливки.
     
    Последнее редактирование: 24 окт 2020
    ИгорьК и serg3295 нравится это.
  10. serg3295

    serg3295 Гик

    Добавил в auto.ps1 и tasks.json команду "COM: absolute LFS Build & upload", которая собирает lfs по абсолютному адресу и выгружает в ESP, используя esptool вместо nodemcu-tool. Проставляем свои адреса lfs_base и lfs_mapped внутри файла auto.ps1.
    у меня работает. Заливается img. Тестировал на проекте FTPandTelnet, который выкладывал раньше.
    UPD.
    Начал сомневаться, не влияет ли размер файла на процесс. Тестировал только на маленьких проектах. Собрал к рабочей части кода кучу lua_examples для веса. В процессе наткнулся на такую вещь - компилятор отказался работать :), мотивируя тем, что
    luac.cross.exe: '-f': Number of modules > 50
    Но, большой файл lfs с количеством модулей 50 штук собрался и выгрузился. И даже заработал.
    Код (C++):
    -- это esptool выдал
    Compressed 204476 bytes to 77298...
    Wrote 204476 bytes (77298 compressed) at 0x0007c000 in 6.8 seconds (effective 240.1 kbit/s)...
    Hash of data verified.

    -- а это размер в железке.
    { lfs_base = 0x07c000, lfs_mapped = 0x4027c000, lfs_size = 0x040000, lfs_used = 0x031ebc }
    UPD2. Немного облагородил auto.ps1.
     

    Вложения:

    • vscode.zip
      Размер файла:
      3,1 КБ
      Просмотров:
      188
    • autoPS1.zip
      Размер файла:
      749 байт
      Просмотров:
      197
    Последнее редактирование: 25 окт 2020
    ИгорьК и swc нравится это.
  11. swc

    swc Гик

    Ваша работа во многом облегчила мою работу. Огромное спасибо за помощь!
    C Lua я работаю в Notеpad++ по нескольким причинам:
    1. Не нужна инсталляция, переносится на любые компьютеры вместе с настройками.
    2. Открывается мгновенно по F4.
    3. Легко настроить окно редактора со свойствами, близкими к ESPlorer - там привычная гамма цветов и шрифта.
    Для компиляции и заливки LFS использую bat-файл (с моими адресами, портами и именами - измените на свои):
    Код (C++):
    echo Y|del out_img\LFS_UI_mapped.img
    luac.cross.exe -o out_img/LFS_UI_mapped.img -f -m 0x040000 -a 0x40278000 -l in_files/*.* > out_img/log.log
    esptool.py --port COM7 write_flash 0x078000 out_img\LFS_UI_mapped.img
    pause
    bat-файл запускается по клавише F9. Для этого надо создать ярлык для bat-файла, перенести его на рабочий стол и в свойствах указать нужную клавишу/комбинацию клавиш.
    Чем хорош такой подход: - компилятор и загрузчик независимы от редактора и существуют сами по себе.
    Код можно писать в любом редакторе, а компилировать и заливать прошивку нажатием назначенной клавиши.
    Все легко и просто.
     
    Последнее редактирование: 25 окт 2020
    dmitrij2023, serg3295 и ИгорьК нравится это.
  12. serg3295

    serg3295 Гик

    Ну, потратил 15 мин только для того, чтобы этот аргумент не был определяющим ;). Настраивать можно как угодно
    vsesp.jpg
     
    swc и ИгорьК нравится это.
  13. swc

    swc Гик

    Вложения:

    • Все.jpg
      Все.jpg
      Размер файла:
      544,3 КБ
      Просмотров:
      191
    serg3295 нравится это.
  14. serg3295

    serg3295 Гик

    В новом выпущенном релизе для ESP8266 кроме ряда улучшений и bugfix'ов появилась приятная опция -
    отображение в списке беспроводных устройств роутера ESP'шки с тем hostname, который вы задали, а не ESP_6_цифр_mac.

    Для этого необходимо в файле user_config.h раскомментировать строку, написав туда hostname, который нужен.
    Требования к имени hostname описаны в комментариях выше этих строчек.

    #define WIFI_STA_HOSTNAME "YourHostname"
    //#define WIFI_STA_HOSTNAME_APPEND_MAC

    Затем собрать прошивку.
     
    ИгорьК и swc нравится это.
  15. Lihouzov

    Lihouzov Нуб

    Всем привет. Не могу понять почему происходит утечка памяти.

    создаю файл lpa.lua
    Код (C++):
    print('lpa.lua')
    for we=1,1 do

    end
    выполняю dofile('lpa.lua')- утечки нет. Добавлю в цикл print
    Код (C++):
    print('lpa.lua')
    for we=1,1 do
    print('xxx')
    end
     
    dofile('lpa.lua')- 64 байта не возвращается, почему???
     
  16. ИгорьК

    ИгорьК Гуру

    Потому что так работает NodeMCU. Из сказанного не следует, что память течет. Система что-то положила в регистр в ожидании, может что-то на будущее потребуется.

    Память течет не так.
     
  17. Lihouzov

    Lihouzov Нуб

    Вызвал dofile- не вернулось часть памяти, загрузил освободил модуль- еще часть.
    Неясно логика. Сборщик мусора оставил ресурсы системе...
    Как систему заставить вернуть ресурсы?

    Еще один фрагмент кода:
    Код (C++):

    do
    istr = ""
    for lp=1,200 do
       istr=istr.."1"
    end
    print(node.heap(), #istr)
    istr = nil
    collectgarbage()
    end
     
    Выполняем и смотрим память до и после выполнения:
    Код (Text):
    > =node.heap()
    38480
    > do
    istr = ""
    for lp=1,200 do
    istr=istr.."1"
    end
    print(node.heap(), #istr)
    istr = nil
    collectgarbage()
    end
    37352    200
    > =node.heap()
    37808
     
    Система зарезервировала себе 672 байта оперативной памяти.

    Если цикл установить на 2000, то интерпритатор lua вылетает на случайной итерации примерно большей чем 800.
    Как обойти эту ошибку?
    Как сформировать строку в 2000 символов?
     
    Последнее редактирование: 29 ноя 2020
  18. ИгорьК

    ИгорьК Гуру

    Вам жалко? :)

    Там в оглавлении большими красными буквами предлагается что-то прочитать. Прочитайте внимательно.

    Ну и начинайте делать что-то полезное, тогда уйдут многие вопросы. Если вам для понятных целей потребуется строка в 2000 символов, её можно сформировать. Но сначала цели, а потом "как это сделать".

    Вот вам цикл на туеву хучу итераций. Разбирайтесь. Логарифм от миллиона. Изучите - и поймете как делать циклы любого размера, не ломая при этом wifi и другие параллельные процессы.

    Повторюсь, у вас есть задача? Начните её решать и разговор будет интересней. Если вы истово верите в malloc и free - вам в среду ардуино. Если вам надо быстро писать код - пишите на Lua и вам что-то подскажут здесь.

    ESP-8266 - это устройство iot, а не серверная платформа, кстати. Хотя и сервер на ней делают. Если вы теперь решите на ней писать динамические сайты, то тоже не стоит. Для этого есть более подходящее железо.
     
    Последнее редактирование: 29 ноя 2020
    swc нравится это.
  19. Lihouzov

    Lihouzov Нуб

    Задача есть и циклы мне не нужны.
    Вот функция, как ее заставить работать со входной строкой 1000 символов?
    Код (C++):
    local StrToHEX = function(Str)
    local res = ""
    for lp=1, #Str do
      res=res..Str.format("%X", Str:byte(lp))
    end
    return res
    end
     
  20. ИгорьК

    ИгорьК Гуру

    И тут же ниже "for". Это как?

    Так не годится, эта тема про основы языка на ESP-8266, а не решение ваших задач.

    Я дал вам направление ранее, там вполне достаточно материала.

    Я не уверен что модуль сможет удержать в памяти 3х1000 символов одновременно, молотить их в цикле и при этом делать ещё что-то. Возможно придется писать и читать через file().