• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Зачем и boot.py, и main.py?

RotaryF

New member
Вот и я взглянул в сторону микроПитона, благо под рукой и ESP8266, и ESP32.
Успел и поиграться малость с лампочками+, даже некое подобие Cron(a) под свои нужды наваял.
Для более полного понимания "процесса" хочу выяснить нафиг такая 2х-ступенчатая процедура загрузки, зачем этой змейке 2 файла? Какая разница произведу ли я полную инициализацию своей системы только в boot.py или же задействую и boot.py, и main.py?
Ну да, гибче, а как эту улучшенную (по ср., скажем, с Lua-init) гибкость грамотно использовать?
Все равно хоть после программной перезагрузки, хоть после глубокого сна процедура одинакова - перезапускаются и boot.py, и main.py :confused:
 

nikolz

Well-known member
Вот и я взглянул в сторону микроПитона, благо под рукой и ESP8266, и ESP32.
Успел и поиграться малость с лампочками+, даже некое подобие Cron(a) под свои нужды наваял.
Для более полного понимания "процесса" хочу выяснить нафиг такая 2х-ступенчатая процедура загрузки, зачем этой змейке 2 файла? Какая разница произведу ли я полную инициализацию своей системы только в boot.py или же задействую и boot.py, и main.py?
Ну да, гибче, а как эту улучшенную (по ср., скажем, с Lua-init) гибкость грамотно использовать?
Все равно хоть после программной перезагрузки, хоть после глубокого сна процедура одинакова - перезапускаются и boot.py, и main.py :confused:
читайте документацию там все есть про "нафига"
 

__ab__

New member
читайте документацию там все есть про "нафига"
чтобы ответ был полезен, а не был просто троллингом, обычно дают ссылки или цитаты,, если упоминают документацию.
мне известно вот это место в документации 3. The internal filesystem — MicroPython 1.9.3 documentation
пункт 3.3
И документация в этом месте врет - main.py не и импортируется самим python - его надо явно импортировать из boot.py
Если знаете другое упоминание в документации, приведите ссылку пожалуйста.

Зачем все же это разделение? Чтобы стимулировать программиста не пытаться отъедать ресурсы прикладной логикой в случае, если необходимые системные функции не загрузились.

Я обычно меняю boot.py на вот такой:
Код:
import gc, webrepl, esp, network, json, os, time
MAIN=None

#В файле config.json держим логин и пароль сети
#{"wlan_pwd": "XXXX", "wlan": "XXXX"}

def init():
    global MAIN
    lst = os.listdir()
    if 'config.json' in lst:
        try:
            with open('config.json', 'r') as x:
                cfg = json.load(x)
        except:
            return

    if 'wlan' in cfg:
        wlan = network.WLAN(network.AP_IF)
        wlan.active(False)

        wlan = network.WLAN(network.STA_IF)
        wlan.active(True)
        wlan.connect(cfg['wlan'], cfg['wlan_pwd'])

        x = 0 # 10 секунд ждем соединения WiFi
        while x < 10:
            if wlan.isconnected():
                webrepl.start()
                break
            x += 1
            time.sleep(1)

    # если есть main пытаемся запустить
    if 'main.py' in lst:
        MAIN = __import__('main')
        lst = dir(MAIN)
        if 'init' in lst:
            MAIN.init()

esp.osdebug(None)
init()
gc.collect()
ну а в main и прочих модулях - логика, которая просто не сможет работать, ели не отработало то, что есть в boot
 

RotaryF

New member
чтобы ответ был полезен, а не был просто троллингом, обычно дают ссылки или цитаты,, если упоминают документацию
Вот, это уже больше похоже на ответ и желание помочь.
А предыдущее "по документации" смахивает на х.з., но с умным видом :cool:
 

RotaryF

New member
Думаю, что тему можно закрывать, но напоследок я скажу (на основании своего опыта). ;)
"Исторически так сложилось". Возможно, разработчики чего там замышляли для усиления безопасности системы, но толку от этого хрен да ни хрена.
boot.py "первоначально автоматически создается системой" и рекомендуют туда лишний раз не лезть (если вам ни приспичит поиграться с WEBrepl). При этом файл никак не защищен от изменений o_O, так что при желании(?) переносите туда весть свой функционал main.py, но традиции есть традиции - зачем их без надобности нарушать? Делайте основное управление своей системой в main.py и будет вам счастье.
Связка boot.py-main.py вполне себе работает (если не дергаться) и пусть себе работает :D
 

__ab__

New member
Более того, он вообще не будет работать, если не залить его в файл boot.py ;)
Не вижу большой проблемы в том, чтобы перед началом работы залить файлы boot и config...

а еще можно так:
Код:
if 'config.json' in lst:
        try:
            with open('config.json', 'r') as x:
                cfg = json.load(x)
        except:
            return
else:
        cfg = {}
 

apatrushev

New member
Так лучше, да. Просто "дурако-устойчивый код" это хорошо. Кто-то может залить его через webrepl, например, и ресетнуть девайс. После чего будет весьма удивлён. Я вот как-то так поправил ваш код. Теперь "экстренная связь" с устройством будет даже в случае проблем.
Я сам этот код лично ещё не проверил - проверю, удалю этот дисклеймер.
Код:
import gc, webrepl, esp, network, json, os, time

# config.json example
# {
#     "wlan": {"ssid": "XXX", "password": "XXX"},
#     "webrepl": {"port": "III", "password": "XXX"}
# }

def init():
    try:
        with open('config.json', 'r') as fd:
            cfg = json.load(fd)
    except (OSError, ValueError):
        return webrepl.start()

    webrepl_config = cfg.get('webrepl', {})
    webrepl.start(**webrepl_config)
    if 'wlan' in cfg:
        sta = network.WLAN(network.STA_IF)
        sta.active(True)
        sta.connect(cfg['wlan']['ssid'], cfg['wlan']['password'])
        while not sta.isconnected():
            time.sleep(0.1)
        webrepl.stop()
        ap = network.WLAN(network.AP_IF)
        ap.active(False)
        webrepl.start(**webrepl_config)

    if 'main.py' in os.listdir():
        main = __import__('main')
        lst = dir(main)
        if 'init' in lst:
            main.init()

esp.osdebug(None)
init()
gc.collect()
 

nikolz

Well-known member
Так лучше, да. Просто "дурако-устойчивый код" это хорошо. Кто-то может залить его через webrepl, например, и ресетнуть девайс. После чего будет весьма удивлён. Я вот как-то так поправил ваш код. Теперь "экстренная связь" с устройством будет даже в случае проблем.
Я сам этот код лично ещё не проверил - проверю, удалю этот дисклеймер.
Код:
import gc, webrepl, esp, network, json, os, time

# config.json example
# {
#     "wlan": {"ssid": "XXX", "password": "XXX"},
#     "webrepl": {"port": "III", "password": "XXX"}
# }

def init():
    try:
        with open('config.json', 'r') as fd:
            cfg = json.load(fd)
    except (OSError, ValueError):
        return webrepl.start()

    webrepl_config = cfg.get('webrepl', {})
    webrepl.start(**webrepl_config)
    if 'wlan' in cfg:
        sta = network.WLAN(network.STA_IF)
        sta.active(True)
        sta.connect(cfg['wlan']['ssid'], cfg['wlan']['password'])
        while not sta.isconnected():
            time.sleep(0.1)
        webrepl.stop()
        ap = network.WLAN(network.AP_IF)
        ap.active(False)
        webrepl.start(**webrepl_config)

    if 'main.py' in os.listdir():
        main = __import__('main')
        lst = dir(main)
        if 'init' in lst:
            main.init()

esp.osdebug(None)
init()
gc.collect()
размечтался.
попробуй,
удали.
 

__ab__

New member
Теперь "экстренная связь" с устройством будет даже в случае проблем.
Совершенно не обязательно - ведь:
1) в любом параметре можно ошибиться.
2) на ESP32 это работать не будет, т.к. в отличие от 8266 она не запоминает имени и пароля точки доступа, соответственно инициализация webrepl не сработает до кода:
Код:
if 'wlan' in cfg:
        sta = network.WLAN(network.STA_IF)
.....
И я бы не стал очень сильно увлекаться дурако-устойчивостью : любые вычисления требуют ресурсов, в том числе и обеспечивающие устойчивость. На устройстве, в ресурсах ограниченном, лучше лишнего не писать...

Да и вот это вот не очень код:
Код:
    webrepl.start(**webrepl_config)
    if 'wlan' in cfg:
        sta = network.WLAN(network.STA_IF)
       .....
        webrepl.start(**webrepl_config) # зачем ?
Кстати, webrepl и так неплохо инциализируется из своего конфига, так что я, в плане webrepl, не стал бы что-то менять в и так неплохо работающем коде ;)
 

nikolz

Well-known member
Совершенно не обязательно - ведь:
1) в любом параметре можно ошибиться.
2) на ESP32 это работать не будет, т.к. в отличие от 8266 она не запоминает имени и пароля точки доступа, соответственно инициализация webrepl не сработает до кода:
Код:
if 'wlan' in cfg:
        sta = network.WLAN(network.STA_IF)
.....
И я бы не стал очень сильно увлекаться дурако-устойчивостью : любые вычисления требуют ресурсов, в том числе и обеспечивающие устойчивость. На устройстве, в ресурсах ограниченном, лучше лишнего не писать...

Да и вот это вот не очень код:
Код:
    webrepl.start(**webrepl_config)
    if 'wlan' in cfg:
        sta = network.WLAN(network.STA_IF)
       .....
        webrepl.start(**webrepl_config) # зачем ?
Кстати, webrepl и так неплохо инциализируется из своего конфига, так что я, в плане webrepl, не стал бы что-то менять в и так неплохо работающем коде ;)
что мешает на ESP32 запомнить имя и пароль точки доступа?
 

nikolz

Well-known member
Прошивки micropython несколько разные на 32 и 8266 - одна сохраняет, а другая - нет.
При этом смысла лезть в прошивку и править её нет - всё легко решается кодом на python.
вы что-то путаетесь в терминологии.
код на питоне превращается компилятором и линкером в кусок прошивки.
 

__ab__

New member
вы что-то путаетесь в терминологии.
Как то неожиданно, что IT "гуру" может не знать, что такое интерпретатор...
Python как раз яркий представитель интерпретаторов - транслирует программу в p-код, который и интерпретирует..

Прошивка в данном случае это и есть интерпретатор. Текстовый файл .py транслируется в байткод и выполняется
Собственно вот C-код micropython, где видно как оно работает (выполняется байт-код)..
При желании, там же, рядом, не сложно найти как оно транслируется...

Больше читайте ;)
 

nikolz

Well-known member
Как то неожиданно, что IT "гуру" может не знать, что такое интерпретатор...
Python как раз яркий представитель интерпретаторов - транслирует программу в p-код, который и интерпретирует..

Прошивка в данном случае это и есть интерпретатор. Текстовый файл .py транслируется в байткод и выполняется
Собственно вот C-код micropython, где видно как оно работает (выполняется байт-код)..
При желании, там же, рядом, не сложно найти как оно транслируется...

Больше читайте ;)
ну да хамство вас не украшает.
не хотел читать ликбез.
но придется
питон как и луа и джава имеют VM
VM это не интерпретатор
интерпретатор работает со строкой вашей программы на конкретном языке и разбирает строку в реальном времени
VM машина работает с кодами ее собственных команд, как и любой железный процессор.
--------------
Но в ESP и OC и библиотеки и программа юзера помещаются во флеш в виде прошивки.
Поэтому даже если вы напишите что-то для интерпретатора, то и интерпретатор и ваш текст станут частью прошивки.
 

__ab__

New member
ну да хамство вас не украшает.
Оно никого не украшет, и Вас тоже ;)
Вы уж простите, если что, но видно что вы не очень знаете питон, то как он устроен и работает, но при этом пытаетесь что-то советовать.
Зачем? Сбивать с толку новичков, которых тут полно и самоутверждаться на них?
Судя по количеству симпатий в профиле, Вы многое знаете, но знать всё - невозможно. В этом нет ничего страшного :)

Про луа не скажу - не близок он мне и не ковырялся я в нем. Ни как профи, ни для хобби.
А что до Java и Python, есть разные реализации, которые немного по разному работают (особенно для Python)
В классическом варианте оба эти инструмента транслируют строки кода в байт-код, который потом интерпретируется (ссылку на интерпретирующий код код я давал). В случае Java - транслятор это javac и машина это java. В случае питона все происходит внутри одной программы, причем эта программа умеет еще и на лету транслировать строки в байт код и передавать интерпретатору байт-кода (repl).
Для того чтобы работать быстрее, питон умеет создавать претранслированные файлы байт-кода (но это не код процессора, в отличие от объектнгого кода, который генерит компилятор!)
Кроме того, python (с первых версий) изначально отличался тем, что его интерпретатор легко встроит в код для C компилятора (изначально), а так же в сам питон легко встраивать библиотеки, написанные на С, при этом такие библиотеки выглядят, как написанные на питоне (пример: psycopg2)
Пишу "изначально", потому подойдет любой код, который сможет слинковать Python (ASM, pascal...)
Но не надо путать C библиотеки с библиотеками которые написаны на питоне.
Первые встроены в firmware (раз не нравится "прошивка"), вторые генерируются динамически.
 
  • Like
Реакции: fps

BigStupidBeast

New member
Для тех кто будет читать это в 2020м.
main.py стартует самостоятельно.
версия прошивки esp32-idf3-20191220-v1.12
если вставить кусок кода из примера выше

Python:
import os
lst = os.listdir()

if 'main.py' in os.listdir():
    main = __import__('main')
    lst = dir(main)
    if 'init' in lst:
        main.init()
то программа запустится дважды.

Python:
import main
эффект тот же

(для запуска рекомендую использовать Thonny. ESPlorer криво залил мне на ESP32 файлы, а Mu не видит что лежит на ESP32. )
 
Сверху Снизу