• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Разработка ‘библиотеки’ малого webсервера на esp8266.

pvvx

Активный участник сообщества
Только теперь вывод в отладку увеличился, загрузка идет два раза
Зачем вы использовали память в загрузчике? Он вам и нагенерил второй сегмент...
Используйте IRAM или опишите не включать RAM в выход и сами инициализируйте переменные там, если они нужны...
 

pvvx

Активный участник сообщества
для отладки написал: ets_printf("\nRapid loader!!!\r\n");
Основная цель - это наименьший загружаемый код до включения кеширования. Далее у вас в доступе 1 Мегабайт кода. :)
Я вон борюсь cо вставкой транслятора СИ на код резервирования стека при входе в процедуру. Никак его не выкинуть.:mad: Он там не нужен.
Код:
40100000 <_stext>:
40100000:    000700           excw
40100003:    020060           excw
40100006:    006000           rsil    a0, 0
40100009:    ffffe0           excw
4010000c:    001000           excw
4010000f:    00c000           excw
40100012:    784020           excw
40100015:    400046           j    4011001a <_lit4_end+0xff6a>
40100018:    200080           or    a0, a0, a8
4010001b:    f94140           excw

4010001c <call_user_start>:
4010001c:    fff941           l32r    a4, 40100000 <_stext>
4010001f:    f0c112           addi    a1, a1, -16 <---- ВОТ ОНО!
40100022:    3109         s32i.n    a0, a1, 12 <---- ЕЩЁ не нужный!
40100024:    020c         movi.n    a2, 0
40100026:    4429         s32i.n    a2, a4, 16
40100028:    80a032           movi    a3, 128
4010002b:    4d6432           s32i    a3, a4, 0x134
4010002e:    fff531           l32r    a3, 40100004 <_stext+0x4>
40100031:    052c         movi.n    a5, 32
40100033:    7368         l32i.n    a6, a3, 28
40100035:    205650           or    a5, a6, a5
40100038:    7359         s32i.n    a5, a3, 28
4010003a:    402462           l32i    a6, a4, 0x100
4010003d:    00a152           movi    a5, 0x100
40100040:    205650           or    a5, a6, a5
40100043:    406452           s32i    a5, a4, 0x100
40100046:    2358         l32i.n    a5, a3, 8
40100048:    fff041           l32r    a4, 40100008 <_stext+0x8>
4010004b:    105540           and    a5, a5, a4
4010004e:    ffef41           l32r    a4, 4010000c <_stext+0xc>
40100051:    204540           or    a4, a5, a4
40100054:    2349         s32i.n    a4, a3, 8
40100056:    024d         mov.n    a4, a2
40100058:    023d         mov.n    a3, a2
4010005a:    ffee01           l32r    a0, 40100014 <_stext+0x14>
4010005d:    0000c0           callx0    a0
40100060:    ffec21           l32r    a2, 40100010 <_stext+0x10>
40100063:    ffed01           l32r    a0, 40100018 <_stext+0x18>
40100066:    0000c0           callx0    a0
40100069:    000000           ill
 

vad7

Active member
pvvx, Не подскажите как победить такой глюк - меняю что-нибудь в app_main.c,
жму Make Target -> all, меняются файлы - libsdk.a, libaddmain.a, app_main.o и все!
В прошивке изменений нет, приходится очищать папку app\.output\eagle\image\ чтобы изменения попали в прошивку.
 

pvvx

Активный участник сообщества
pvvx, Не подскажите как победить такой глюк - меняю что-нибудь в app_main.c,
жму Make Target -> all, меняются файлы - libsdk.a, libaddmain.a, app_main.o и все!
В прошивке изменений нет, приходится очищать папку app\.output\eagle\image\ чтобы изменения попали в прошивку.
Есть такое - так впихнут проект meSDK. Простым копированием в папку :) Если меняете что в нем, то надо clear или очистку всего, т.к. в основном make отслеживается только наличие libsdk.a
Попробуйте дописать основной makefile. Я с ходу не придумал как это сделать и оставил как "срослось"... Тем более лазать в meSDK для WEB не требуется...
да уж, атрибут naked не поддерживается...
Ну хоть это __attribute__ ((noreturn)) работает.
А так выходит тот-же код в 92 байта :), но нифига не понятно:
Код:
    .text
    .align    4
    .literal_position
    .global    call_user_start
    .type    call_user_start, @function
call_user_start:
    movi    a4, rtc_    // IO_RTC_4 = 0
    movi.n    a2, 0
    s32i.n    a2, a4, 16
    movi    a3, 0x80  // GPIO_MUX = VAL_MUX_GPIO0_SDK_DEF
    s32i    a3, a4, 308
    movi    a3, spi0_
    movi.n    a5, 0x20    // SPI0_USER |= SPI_CS_SETUP
    l32i.n    a6, a3, 28
    or        a5, a6, a5
    s32i.n    a5, a3, 28
    l32i    a6, a4, 256 // GPIO_MUX_CFG |= BIT(MUX_SPI0_CLK_BIT) // QSPI = 80 MHz
    movi    a5, 0x100
    or        a6, a6, a5
    s32i    a6, a4, 256
    l32i.n    a4, a3, 8    // SPI0_CTRL = (SPI0_CTRL & SPI_CTRL_F_MASK) | SPI_CTRL_F80MHZ;
    srli    a5, a4, 12
    movi    a4, 1
    or        a5, a4, a5
    slli    a4, a5, 12
    s32i.n    a4, a3, 8
    mov.n    a4, a2         // Cache_Read_Enable(0, 0, 0);
    mov.n    a3, a2
    call0    Cache_Read_Enable
    movi    a2, 0x40200070+0x40 // +0x40 size: addld.bin
    call0    0x40200070
    .size    call_user_start, .-call_user_start
92 байта - это уже на один символ выводимый ROM-BIOS в UART меньше в размере загружаемого кода. А это 134 us + не надо догружать ещё кусок в десток байт по по тормозному SPI методу - дает наверно в итоге ещё пару миллисекунд.
Можно ещё ужать загружаемую часть до 80 байт :) и далее уже QSPI и "кеширование" у Flash включена и грузим что угодно... Но общая длина у лоадера остается примерно однаковая...
ROM-BIOS грузит по SPI этот код кусочками по 32 байта - в SPIRead циклы по 32 байта с выставлением на каждый блок адреса и команды для Flash... Вот если "ужать" до 64 байт - то хорошо. :) А далее уже в flash можно врубить CPU на 160 MHz и всё грузить через аппаратный кеш - там трафик потока к 40 Мегабайтам в секунду с Flash
Это всё дает возможность использовать deep_sleep на более короткие промежутки с экономией питания. Надо рассчитать минимально энергетически выгодный промежуток перехода к полному deep_sleep, относительно временного, без полного отключения всех частей CPU (там вроде потребление к 2 mA, но могу попутать - смотреть надо).
У ESP есть ещё более хитрый вариант перезагрузки - сразу с запуском кода из IRAM и без вывода всяких сообщений в UART. Он приоритетнее для выхода из deep_sleep - питание при deep_sleep не снимается и память всё помнит. Можно восстановить и "продолжить" прошлую "сесию" без грмоздкой инициализации китай-SDK, восстановив только необходимые регистры WiFi и т.д... Но такое попахивает закрытым проектом, т.к. требует внимательного написания и тестов, на что требуется много времени.
 
Последнее редактирование:

AlexMelven

New member
pvvx, если можно, позадаю еще вопросы про китайские либы, от которых вы избавляетесь? :) пример ESP8266_MESH_DEMO у меня заработал, три платы друг с дружкой связываются, одна из них становится root - через нее шлются сообщения TCP серверу (скрипт на питоне), который отправляет их обратно пославшему. Теперь хочется попробовать прикрутить это к Web_Base. По аналогии с моими экзерсизами со smartconfig, я подключил первую библиотеку libmesh.a, исправил все ошибки компилятора и в конце получил ошибки линкера, например:
Код:
../lib\libsdk.a(espconn_mesh.o): In function `espconn_mesh_layer':
(.irom0.text+0x3580): undefined reference to `ets_snprintf'
вроде понял что ets_snprintf есть в libmain.a, но это вроде как та самая либа, от которой вы избавляетесь и добавление ее ни к чему хорошему не приведет. Вопрос - как заставить libmesh.a искать ets_snpintf в коде Web_Base?
 

pvvx

Активный участник сообщества
pvvx, если можно, позадаю еще вопросы про китайские либы, от которых вы избавляетесь? :) пример ESP8266_MESH_DEMO у меня заработал, три платы друг с дружкой связываются, одна из них становится root - через нее шлются сообщения TCP серверу (скрипт на питоне), который отправляет их обратно пославшему. Теперь хочется попробовать прикрутить это к Web_Base.
Цель то какая? Побаловаться? :)
Вопрос - как заставить libmesh.a искать ets_snpintf в коде Web_Base?
А в Web-свалке такого нет.
Зачем мучаетесь? Используйте китайский SDK. Примеров web серверов к нему навалом.
И в libmesh.a нет запросов к ets_snpintf. Вообще такой нет во всех китай-либах
------
Нашел в eagle_lib.o там свалка всякого...
 
Последнее редактирование:

AlexMelven

New member
И в libmesh.a нет запросов к ets_snpintf.
сорри, пропустил букву - ets_snprintf - ищется в libmesh.a и в libmain.a
В вебсвалке нету, но я нашел исходник некой os_snprintf и предположил что это должно быть что-то похожее. Вставил код в вебсвалку, но ошибка не исчезает. Видимо нужна директива линкеру, чтобы брал процедуру не из библиотеки а у меня. Что-то нашел в интернете про -fno-builtin, -fno-builtin-function - но пока не соображу куда это приткнуть :)
Не побаловаться, у меня задача сделать подобие MESH сети из устройств, чтобы можно было ими управлять и с телефона и через веб, обновлять прошивки. По сути китайский вариант, но китайское что-то не особо компилируется, чтобы хотя-бы просто посмотреть. Вон ESP8266_LIGHT_WITH_MESH пример - тысяча ошибок, почему-то все неявные вызовы функций, отсутствие описания функций в заголовках (как они их вообще вызывали в своем "работающем" примере?) - добился чтобы все ошибки исчезли, загрузил прошивку в флешку - сыплются исключения еще на стадии загрузки. Хотя возможно вы правы, взять пример с китайским вебом и начать прикручивания всего что работает от него.. В том числе смотреть что улучшено у вас.
 

pvvx

Активный участник сообщества
Вон ESP8266_LIGHT_WITH_MESH пример - тысяча ошибок, почему-то все неявные вызовы функций, отсутствие описания функций в заголовках (как они их вообще вызывали в своем "работающем" примере?)
У китайцев в SDK стоят опции компилятору игнорировать всё, что только возможно отключены любые варнинги - смотрите их makefiles. Без этого у них ничего не собирается.
По поводу линковки ваших функций ничего делать не требуется, кроме линковки уже на стадии сборки всего проекта из либ. Вам надо всего описать линковщику что входит в проект - какие либы и если есть раздельные объектники от и их... Вас куда-то не туда понесло с опциями и почим - ничего не надо, функция должна быть без атрибута static всё.
 
Последнее редактирование:

pvvx

Активный участник сообщества
AlexMelven - OTA не лезет даже с meSDK1.5.2 в 512 килобайт. Нет места под диск. Общая сумма прошивки, с одним WEB без остального (вывод отладки отключен и в meSDK (!)), ужимается до 253 килобайта, суммируя туда все сохранения настроек (16 килобайт от SDK + эмуляция EEPROM 3 сектора 12 килобайт). Т.е. под диск остается 2 килобайта, если flash в 256 килобайт :) Но можно изголиться и использовать одни настройки на обе прошивки или чисто при ОТА как обновление. Тогда малый диск в 512 лезет.
В китайском варианте вы не влезаете и в 512 килобайт. Т.е. OTA там только при 1 мегабайте flash и то стремная... а размер "кешируемой" области всего 1 Мег. Т.е. вам придется ставить 2 flash и переключать их CS.
 
Последнее редактирование:

AlexMelven

New member
у меня флешка 32 мегабита. Под диск есть место :) Тем более что две копии диска хранить не требуется. А с линковкой пока не получается - с этого и начинал, что просто добавил еще одну библиотеку libmesh.a
 

pvvx

Активный участник сообщества
у меня флешка 32 мегабита. Под диск есть место :) Тем более что две копии диска хранить не требуется. А с линковкой пока не получается - с этого и начинал, что просто добавил еще одну библиотеку libmesh.a
Для двух прошивок, используемых по очереди в китайском варианте ваши 32 мегабайта бесполезны. Кеш всего 1 Мег.
Для OTA вам придется писать загрузку в сегменты flash выше 1 Мег, а по старту, проверив контрольку , переписывать первую область до 1 Мег.
У китайцев по тому для их SDK две flash с разными CS.
Уже слепил "AT" прошивку на SDK 1.5.2 под 512 кило - Вариант прошивки AT esp8266ru на новых SDK для модулей с 512k flash. И то пришлось поизголяться над китай-либами - переносить хаком область сохранений настроек "AT" и сертификатов. Никаких OTA там невозможно.
Замещены эти процедуры в eagle.rom.addr.v6.ld:
PROVIDE ( xSPIEraseSector = 0x40004a00 );
PROVIDE ( xSPIRead = 0x40004b1c );
PROVIDE ( xSPIWrite = 0x40004a4c );
Код:
#include "bios/spiflash.h"

extern SpiFlashOpResult xSPIRead(uint32_t faddr, uint32_t *dst, size_t size);
extern SpiFlashOpResult xSPIWrite(uint32_t faddr, const uint32_t *src, size_t size);
extern SpiFlashOpResult xSPIEraseSector(uint32_t sectornum);

SpiFlashOpResult SPIRead(uint32_t faddr, uint32_t *dst, size_t size)
{
    if(faddr >= 0x30000 && faddr < 0x40000) faddr &= ~0x20000;
    return xSPIRead(faddr,dst,size);
}

SpiFlashOpResult SPIWrite(uint32_t faddr, const uint32_t *src, size_t size)
{
    if(faddr >= 0x30000 && faddr < 0x40000) faddr &= ~0x20000;
    return xSPIWrite(faddr, src, size);
}

SpiFlashOpResult SPIEraseSector(uint32_t sectornum)
{
    if(sectornum >= 0x30 && sectornum < 0x40) sectornum &= ~0x20;
    return xSPIEraseSector(sectornum);
}
Т.е. овстроена обманка - всё что идет от SDK в 0x30..0x40 сектор, всё перенаправлено в 0x10..0x20 сектор.
Ну и в eagle.app.v6.ld:
MEMORY
{
dport0_0_seg : org = 0x3FF00000, len = 0x10
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
iram1_0_seg : org = 0x40100000, len = 0x8000
irom0_0_seg : org = 0x40220000, len = 0x5C000
}
Коду для Flash там 388189 байт + 16 кило под настройки WiFi и 16 кило под сертификаты ssl и прочее. Это без OTA коду и OTA загрузчиков.
Короче китайцы опять в своем репертуаре - могли, но не стали делать OTA на 512 кило flash в AT прошивке. Причина - дыра в середине для сохранения настроек и раздутый захламленный SDK с неправильным подходом к OTA.
Не ясна причина, почему не могут дать исходники libmain.a. Их ворованный libnet80211.a, libpp.a, libwpa.a никого не интересует. И 90% багов у них именно в их писанине libmain.a (остальное то всё ворованное с опен сорцов, ну кроме ещё libphy.a и ошибок мало).
Так их лавочку скоро перекроют Убийцы ESP8266: Часть 2 - Nufront NL6621. У них этот уровень открыт, а закрыто только специализированная часть работы с WiFi.
 
Последнее редактирование:

vad7

Active member
В какой программе удобно веб страницы для вебсервера редактировать, а то вручную уже надоело?
 

vad7

Active member
В eclipse, это в ручную и получается. Хотелось бы визуального, который и стили и javascript и т.д. поддерживал. Я понимаю, что такого софта должно быть куча, но есть же не очень навороченные и проверенные?
 

vad7

Active member
@pvvx, Обнаружил одну проблемку - если upload_boundary() = 200 и установлен флаг SCB_REDIR, то перехода не происходит, а рвется соединение.
 

pvvx

Активный участник сообщества
@pvvx, Обнаружил одну проблемку - если upload_boundary() = 200 и установлен флаг SCB_REDIR, то перехода не происходит, а рвется соединение.
И к чему это?
Что должно тогда быть?
upload_boundary() = 200 - найден завершающий разделитель: "\r\n--boundary--", т.е. конец соединения.
Описывайте целиком протокол, что и после чего.
 
Последнее редактирование:

vad7

Active member
Eсли мы пытаемся закачать неверный bin файл, то в upload_boundary() идут строчки:
SetSCB(SCB_REDIR);
rom_xstrcpy(pupload->filename, disk_err1_filename);
return 200;

Я так понял, что это сообщение об ошибке на экран.
Так вот оно не отображается, а получаем "Internet Explorer не может отобразить страницу".

bufi[521]0, cont:244760 tst,fn='file.bin' prh#f108,200,1 [HASHTAG]#f10a[/HASHTAG] (83) 302 dis
srv[80] 192.168.4.2:1531 [1] error -8 (Connection aborted)
srv[80] 192.168.4.2:1531 [1] disconnect
 
Последнее редактирование:

pvvx

Активный участник сообщества
Ну а я что могу сделать? Ответ, что редирект передается:
redir.gif
Сказано сто раз - претензий по HML не принимается, если не представлена альтернатива.

srv[80] 192.168.4.2:1531 [1] error -8 (Connection aborted)
srv[80] 192.168.4.2:1531 [1] disconnect
Причина - error -8 - эксплорер бросил соединение.
 
Последнее редактирование:
Сверху Снизу