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

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

  1. Домосед

    Домосед Нерд

    :) Ну я то уже исхожу из опыта, полученного в процессе работы системы на ардуино. Потому примерно понимаю какие значения нужно иногда менять. Конечно, особой надобности нет. Но пусть будет.
     
  2. RotaryF

    RotaryF Нерд

    Добрый день сообществу.
    На какое-то время я отвлекся от Lua, но необходимость в нем возникла вновь, на этот раз применительно к ESP32.
    Вопрос - какие сейчас существуют реально работающие Lua-прошивки для этой аппаратной платформы?
    Хорошо бы еще к этому добавить более-менее удобоваримую IDE :rolleyes:
     
  3. ИгорьК

    ИгорьК Гуру

    Ух, барство то. :) notepad++ наше все.

    esp32.net - там собрано.
     
  4. RotaryF

    RotaryF Нерд

    Действительно собрано, благодарю.
    На первый взгляд живее всех Lua RTOS от Whitecat :confused:
     
  5. vklimk

    vklimk Нерд

    Игорь, читаю Ваши уроки, хочу разобраться во всем не спеша. Сто лет тому назад я программировал на C/C++, поэтому у меня могут быть стереотипы, которые мешают понять некоторые вещи в lua...
    Есть вопрос по поводу процитированного кода, а именно строки "t = nil" в анонимной функции. Действительно ли нужно явно обнулять t в этом случае? Это, ведь, локальная переменная получается, которая после выхода из анонимной функции автоматически должна "почиститься" (и счетчик ссылок на таймер декрементируется или как это устроено в lua для дальнейшего сбора мусора).
    Не могли бы Вы пояснить этот момент?
     
  6. ИгорьК

    ИгорьК Гуру

    Честный ответ будет - я не знаю.

    Следуя правилам языка уничтожать переменную нет необходимости.
    Следуя опыту работы с модулем на Lua - уничтожать надо все что в данный момент стало ненужным.

    Я немного описал ситуацию с памятью здесь.
    Доберусь до компа - покажу косяк/противоречие разработчиков в модуле таймера.
    Сейчас со смартфона лучше не отвечу.
     
    vklimk нравится это.
  7. ИгорьК

    ИгорьК Гуру

    Вот смотрите. Как следует из описания модуля таймера, в случае, если назначен его однократный запуск, прекращение регистрации таймера не требуется:

    upload_2019-5-28_17-4-30.png

    А теперь смотрим пример от туда же, но чуть выше:

    upload_2019-5-28_17-6-20.png

    Замечаем небольшое противоречие.

    Я не хочу спускать собак на разработчиков, они делают величайшее дело.
    Однако возможны и ошибки и баги и разные версии. Поэтому, ИМХО, самым надежным будет уничтожать все локальные переменные при первой же возможности.
    Язык не требует этого, но и не запрещает.

    Ну и куда деться вот от этого: https://nodemcu.readthedocs.io/en/l...-implemented-when-programming-for-the-esp8266

    upload_2019-5-28_17-13-13.png

    Если тут начнутся указания на то, что в тексте речь о глобальных переменных, то... и локальным и, тем более - замыканиям, от этого хуже точно не будет.
     
    Последнее редактирование: 28 май 2019
    vklimk нравится это.
  8. vklimk

    vklimk Нерд

    Ну, в примере с документацией нет противоречия. Написано, что нет необходимости прекращения регистрации, но там и не запрещено это делать. Так же, как и любой таймер можно несколько раз "отрегистрировать" - первый раз отрегистрирует (если он был зарегистрирован), а остальные просто ничего не будет происходить. Тут просто пример устаревший, очевидно (скорее всего, это или копи-паст, или когда-то давно нужно было отрегистрировать такой таймер).
    А, вот, про референсы и upvalues - с этим мне нужно еще нужно будет разобраться. Пока что у меня смутные представления про то, как устроена сборка мусора и как работают счетчики ссылок.
    Спасибо большое, Игорь.
     
  9. ИгорьК

    ИгорьК Гуру

    Удивительно работают
     
  10. vklimk

    vklimk Нерд

    Мне кажется, использовать ipairs для debug.getregistry() не совсем правильно. Этот итератор не всегда возвращает все индексные записи в таблице, а некоторые индексные записи содержат числа - для нас они не представляют интерес. Лучше, скорее всего, будет так:
    Список индексных записей в регистре:
    Код (Lua):
    do
      local r = {}
      for k,v in pairs(debug.getregistry()) do
        if type(k) == "number" and type(v) ~= "number" then table.insert(r, v) end
      end
      table.sort(r, function(a, b) return tostring(a)<tostring(b) end)
      for _,v in pairs(r) do print(v) end
    end
    Количество индексных записей в регистре:
    Код (Lua):
    do
      local count = 0
      for k,v in pairs(debug.getregistry()) do
        if type(k) == "number" and type(v) ~= "number" then count = count + 1 end
      end
      print(count)
    end
     
    Последнее редактирование: 29 май 2019
  11. ИгорьК

    ИгорьК Гуру

    Нет.
    Нам нужно только количество индексных записей.
    Причина - интерпретатор все а) замыкания и б) калбэки вносит в таблицу (регистр) парой индекс - число. Именно они могут не удаляться из регистра при "неправильно" составленном коде.
    Это написано в документации, но пока ссылку не дам - на смартфоне.
     
  12. vklimk

    vklimk Нерд

    Очень хочется узнать про этот регистр и как им эффективно пользоваться для устранения утечек памяти. Потому как очень сложно утечки искать просто сто раз перечитывая код и просматривая _G...
     
  13. vklimk

    vklimk Нерд

    39. LFS на компьютере.
    В дополнение к посту Пример создания LFS варианта исполняемых файлов
    Чтобы не зависеть от веб-сервиса, который собирает LFS-образы, и иметь возможность поиграть с ключами кросс-компилятора lua, да, и, ускорить процесс сборки, я собрал luac.cross для своей Win7 x64 для текущей ветки master.
    Пользоваться просто:
    1. Распаковываем архив luac.cross.zip на своем компьютере.
    2. В папку myimage помещаем файлы, которые хотим записать в LFS-образ (lua-скрипты, например).
    3. Запускаем build_LFS_image.bat
    4. Забираем LFS-образ в папке output (собираются сразу два образа - один для float-прошивки, второй - для integer-прошивки)

    Я уже попробовал LFS и это реально работает. Написал свои скрипты - при их запуске без LFS node.heap() показывает 5-6КБ и при малейшем возрастании нагрузки - перезагрузка из-за нехватки памяти. С LFS - node.heap() показывает 28КБ и скрипты работают без сбоев (пока что :) ).
     

    Вложения:

    • luac.cross.zip
      Размер файла:
      1,5 МБ
      Просмотров:
      631
    Последнее редактирование модератором: 2 июн 2019
    swc и ИгорьК нравится это.
  14. ИгорьК

    ИгорьК Гуру

    Класс. У меня все руки не доходят. Работаю с реле sonoff а там 1мб модуль ESP-8285
     
  15. swc

    swc Гик

    Последнее редактирование: 2 июн 2019
  16. swc

    swc Гик

    ИгорьК нравится это.
  17. ИгорьК

    ИгорьК Гуру

    Последнее редактирование: 2 июн 2019
  18. vklimk

    vklimk Нерд

    По поводу Вашей проблемы "файл *.img размером более 48 кб в область LFS не загружается".
    Файл образа содержит закомпрессированный файл, пишется в LFS уже разкомперссированный, как я понимаю. Посмотрите с помощью winrar содержимое образа - увидите реальный размер. И скорее всего, он будет больше 128КБ, которые можно указать для LFS в сервисе сборки прошивок nodemcu-build.com. Отсюда и ошибка. Это только предположение.
    И, если это так, то Вы можете собрать прошивку nodemcu самостоятельно - там можно установить размер LFS до 256КБ (файл app\include\user_config.h).
    Код (C++):
    // The Lua Flash Store (LFS) allows you to store Lua code in Flash memory and
    // the Lua VMS will execute this code directly from flash without needing any
    // RAM overhead.  If you want to enable LFS then set the following define to
    // the size of the store that you need.  This can be any multiple of 4kB up to
    // a maximum 256Kb.

    //#define LUA_FLASH_STORE 0x10000
     
    PS. В luac.cross.zip, который я размещал, установлена проверка размера LFS до 128КБ (ключ -m в build_LFS_image.bat). И она работает. Я попробовал поставить размер между размером образа и размером файла в образе - получил ошибку "The image is too large for specfied LFS size". Это, кстати, подтверждает предположение о том, что образ разархивируется перед записью в LFS.
     
    Последнее редактирование: 2 июн 2019
    swc и ИгорьК нравится это.
  19. swc

    swc Гик

    Вы абсолютно правы. Так и есть. Пока пользуюсь оверлеями LFS. Перед использованием нужного куска кода загружаю его в область LFS. Немного тормозит при замене, но терпимо. Надо заняться размером 256 кб.
     
  20. vklimk

    vklimk Нерд

    Могу собрать прошивку, я уже настроил себе среду сборки. Только отредактируйте файлы конфигурации (user_modules.h и ucg_config.h) на Ваш вкус.
     

    Вложения:

    • user_modules.h
      Размер файла:
      2,8 КБ
      Просмотров:
      708
    • ucg_config.h
      Размер файла:
      2,6 КБ
      Просмотров:
      660
    swc нравится это.