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

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

porex

New member
Кстати мне пришла желтая отладочная плата с 4 Мбайтами на борту, хотя об этом нигде не было написано
Интересно... мой ESP-01 при вызове
[inline]spi_flash_real_size()[/inline] выдает 524288 байт, а на желтой отладочной выдает 4194304 байт. Получается у меня тоже флешка на 4 МБайта. Хотя при старте и там и там пишет Flash size: 512K.
Victor, как у вас на отладочной плате Web сервер работает, нормально? Страницы загружаются?
 

porex

New member
Попробуйте пожалуйста если не сложно. Хочу проверить у меня одного проблемы с ним или нет.
 

porex

New member
@Victor, можете не пробовать, у вас тоже не заработает)))
Проблема кроется в функции
Код:
/****************************************************************************
* WEBFS_size()
***************************************************************************/
uint32 ICACHE_FLASH_ATTR WEBFS_base_addr(void)
{
    uint32 addr = WEBFS_DISK_ADDR_MINFLASH;
    if(spi_flash_real_size() > SIZE_MIN_FLASH)    addr = WEBFS_DISK_ADDR_BIGFLASH;
    return addr;
}
Если флешка больше 512К, то устанавливается адрес WEBFS равный 0x80000, но при этом в Makefile адрес WEBFS равен 0x0A000. Далее в WEBFS.c есть проверка на корректность файловой системы, но все напрасно т.к. в файле web_srv.c не обрабатывается false результат при вызове функции parse_header. Строка 1524(2).
Код:
// разбираем докачан или нет заголовок HTTP, что там принято GET или POST и открываем файл и прием content, если это POST и не прием файла.
        if(parse_header(&CurHTTP, ts_conn)) { // заголовок полный? нет
            if(ts_conn->sizei < MAX_HTTP_HEAD_BUF) {
И кстати пока искал ошибку в этом же файле нашел вызов [inline]webserver_open_file(CurHTTP, ts_conn);[/inline] без обработки false результата. Строка 1028
 

porex

New member
Похоже поспешил я с выводами, не совсем в обработке результата parse_header
 

lvm1976

New member
да в чем же прикол, вроде бы как все просто но ошибки
Код:
/******************************************************************************
* FunctionName : Send_cmd_server
* посылка GET команды на сервер,  тупо без обратки
* пример http://192.168.4.1/?gpio1_out=3
* или http://lvm1976.dyndns.org:1326/?gpio1_out=3
******************************************************************************/
void ICACHE_FLASH_ATTR Send_cmd_server(uint8 *cmd_server) {

    if(os_strncmp(&cmd_server, "http://", 7) == 0) cmd_server += 7;
    if (cmpcpystr(clntTcp->clnttcp_server_dns, cmd_server, '\0', ':', 16) == 0) {
        if (cmpcpystr(clntTcp->clnttcp_server_dns, cmd_server, '\0', '/', 32) == 0) {
            LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("Failed to addresses for clntTcp client!\n"));
        }
    }
    if (cmd_server[0] >= '0' && cmd_server[0] <= '9')
        if (cmpcpystr(NULL, cmd_server, '\0', '.', 4) != 0) {
            clntTcp->clnttcp_server_addresses = strtoip(clntTcp->clnttcp_server_dns);
        }
    uint8 buf[5] = "80";
    cmpcpystr(buf, cmd_server, ':', '/', 32);
    clntTcp->clnttcp_server_port = atoi(buf);
    cmd_server = (uint8 *)cmpcpystr(NULL, cmd_server, '\0', '/', 32);
    os_memset(clntTcp->clnttcp_url, 0, sizeof(clntTcp->clnttcp_url));
    os_sprintf(clntTcp->clnttcp_url, cmd_server);
    if (clntTcp == NULL) {
        clntTcp = (struct sclntTcp *)os_zalloc(sizeof(struct sclntTcp));
        if (clntTcp == NULL) {
            LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("Failed to allocate mem for clntTcp client!\n"));
        }
    }
    if(clntTcp->clnttcp_pcb == NULL) {
        clntTcp->clnttcp_pcb = tcp_new();
        if (clntTcp->clnttcp_pcb != NULL) {
            tcp_sent(clntTcp->clnttcp_pcb, json_client_sent);
            tcp_connect(clntTcp->clnttcp_pcb, &clntTcp->clnttcp_server_addresses, clntTcp->clnttcp_server_port, json_connected);
        }
        else
            LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("Failed to allocate tcp pcb for clntTcp client!\n"));
        os_free(clntTcp);
        clntTcp = NULL;
    }
}

static err_t ICACHE_FLASH_ATTR json_connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
    char *string = "{\"hop\": 0}";
    os_sprintf(string,"GET /%s HTTP/1.0\r\n\r\n", clntTcp->clnttcp_url);
    LWIP_UNUSED_ARG(arg);
    if(err == ERR_OK)
    {
        tcp_write(clntTcp->clnttcp_pcb, string, strlen(string), 0);
        tcp_output(clntTcp->clnttcp_pcb);
        json_client_close(clntTcp->clnttcp_pcb);
    }
    return err;
}

static err_t ICACHE_FLASH_ATTR json_client_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
{
    LWIP_UNUSED_ARG(arg);
    return ERR_OK;
}
 

lvm1976

New member
Чет-то не нашел в топике какие у вас ошибки. Куда смотреть?
ошибку исправил:
Код:
            tcp_connect(clntTcp->clnttcp_pcb, (ip_addr_t *)&clntTcp->clnttcp_server_addresses, clntTcp->clnttcp_server_port, json_connected);
добавил кусок
Код:
static void ICACHE_FLASH_ATTR json_client_close(struct tcp_pcb *pcb)
{
    tcp_arg(clntTcp->clnttcp_pcb, NULL);
    tcp_sent(clntTcp->clnttcp_pcb, NULL);
    tcp_close(clntTcp->clnttcp_pcb);
}
Все собирается , работать не хочет
 

pvvx

Активный участник сообщества
1. Что такое MEMW() ?
Сброс "кэша" которого нет у данного CPU + синхронизация шин (ожидание отработки их fifo. fifo у шин тоже только на запись. Но .. фиг знает - четкого описания проца нет от китайцев, а тут место такое - зависимое от этого, по тому и вставлена).
Данная команда вставлена, т.к. в трансляторе, опцией генерации кода, отключено вставка "memw" при каждом обращении к volatile.
UART1_STATUS - это опечатка, речь же идет об UART0, или так надо?
Опечатка, функция не проверялась, т.к. не используется.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Я на прошивке @pvvx подключал два USB-TTL. Нулевой, как обычно, а первый, отладочный только GPIO2 = TX1 (еще и GND конечно). Мне показалось это очень удобным. Не приходится отключать отладочный терминал на время прошивки. Сейчас удивляюсь, почему все так не делают :)
Там только одна беда. Не выходит быстро включить UART1 (второй который) и лезут всякие кракозябы. Ставить задержку (в старте-то(!) ) тоже жалко и она не спасает от кракозяб. После переключения Pll CPU с 52(установка ROM-BIOS на модуле с кварцем 26MHz) на 80 Mhz частота долго выходит на новую... Вопрос как переключать/включать при инициализации UARTx TXx уже ставился, но ни ответу ни привету.... :)
 
Последнее редактирование:

pvvx

Активный участник сообщества
@Victor, можете не пробовать, у вас тоже не заработает)))
Если флешка больше 512К, то устанавливается адрес WEBFS равный 0x80000, но при этом в Makefile адрес WEBFS равен 0x0A000. Далее в WEBFS.c есть проверка на корректность файловой системы, но все напрасно т.к. в файле web_srv.c не обрабатывается false результат при вызове функции parse_header. Строка 1524(2).
Так всё и рассчитано. На большую flash диск загружают по HTTP или программой PVFS2.exe. Иначе, через Makefile будите "грузить диск" в 16M flash весь день по COM порту :)
 

pvvx

Активный участник сообщества
И кстати пока искал ошибку в этом же файле нашел вызов [inline]webserver_open_file(CurHTTP, ts_conn);[/inline] без обработки false результата. Строка 1028
Возврат анализируется в флагe SCB_FOPEN, в следующей строке :)
И предупреждаю вас - json не поддерживается современными браузерами и "политикой безопасности сетей" :)
Пример простейшей передачи параметров из Internet Explorer-а (стандартная передача параметров у современных браузеров):
Код:
POST /timeout.htm HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Referer: http://sesp8266/protect/wifi.htm
Accept-Language: ru
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=---------------------------7df37e05082e
Accept-Encoding: gzip, deflate
Host: sesp8266
Content-Length: 3532
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: start=0x40000000; set_ramaddr=0x3FFF0000; set_ramdata=0x12345678; stop=0x40000100

-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_rdcfg"

0xffffffff
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_mode"

1
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_ssid"

HOME_AP_TST
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_ssid"

ESP8266
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_psw"

0123456789
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_hssid"

0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_bssid"

bc:ae:c5:eb:09:90
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_psw"

0123456789
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_sbss"

0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_chl"

1
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_csta"

5
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_phy"

2
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_ip"

192.168.1.50
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_aum"

0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_msk"

255.255.255.0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_ip"

192.168.4.1
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_gw"

192.168.1.1
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_msk"

255.255.255.0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_aucn"

0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_aucn"

1
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_gw"

192.168.4.1
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_mac"

18:fe:34:9f:c0:bf
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_mac"

1a:fe:34:9f:c0:bf
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_dncp"

0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_st_dncp"

1
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_dncp"

0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_dncp"

1
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_sip"

192.168.4.2
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_eip"

192.168.4.10
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_sleep"

0
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_mcns"

4
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_ap_bint"

100
-----------------------------7df37e05082e
Content-Disposition: form-data; name="wifi_newcfg"

0x13fff
-----------------------------7df37e05082e--
Итого запрос в 4-ре пакета TCP, общим размером в 4058 байт.
На что от Web сервера на ESP8266 через 0.003091 секунды пришел ответ:
Код:
HTTP/1.1 302 Found
Server: PVs/0.1
Connection: close
Location: timeout.htm
Web вывел отладку в UART и установил настройки Wifi...
Если не нравиться формат multipart/form-data то можно и по старинке с GET:
Код:
GET /timeout.htm?wifi_rdcfg=0xffffffff&wifi_mode=2&wifi_st_ssid=HOME_AP_TST&wifi_ap_ssid=ESP8266&wifi_st_psw=%2C354%25%24%27%3B1%7E%D0%81%D1%919%D1%8B%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82&wifi_ap_hssid=0&wifi_st_bssid=bc%3Aae%3Ac5%3Aeb%3A09%3A90&wifi_ap_psw=0123456789&wifi_st_sbss=0&wifi_ap_chl=1&wifi_csta=5&wifi_phy=2&wifi_st_ip=192.168.1.50&wifi_ap_aum=0&wifi_st_msk=255.255.255.0&wifi_ap_ip=192.168.4.1&wifi_st_gw=192.168.1.1&wifi_ap_msk=255.255.255.0&wifi_st_aucn=0&wifi_st_aucn=1&wifi_ap_gw=192.168.4.1&wifi_st_mac=18%3Afe%3A34%3A9f%3Ac0%3Abf&wifi_ap_mac=1a%3Afe%3A34%3A9f%3Ac0%3Abf&wifi_st_dncp=0&wifi_st_dncp=1&wifi_ap_dncp=0&wifi_ap_dncp=1&wifi_ap_sip=192.168.4.2&wifi_ap_eip=192.168.4.102&wifi_sleep=0&wifi_ap_mcns=4&wifi_ap_bint=100&wifi_newcfg=0x13fff HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
Referer: http://sesp8266/protect/wifi.htm
Accept-Language: ru
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: sesp8266
DNT: 1
Connection: Keep-Alive
Cookie: start=0x40000000; set_ramaddr=0x3FFF0000; set_ramdata=0x12345678; stop=0x40000100
Authorization: Basic RVNQODI2NjowMTIzNDU2Nzg5
TCP Segment Len: 1187 (такое тоже не лезет в NodeMCU, но это коммент не вам) ...
Но (!) метод GET вставляет запрос в Referer на все вызываемые из HTML файлы:
srv[80] 192.168.1.2:2488 [1] read: 1187 of1[timeout.htm] GET f[/timeout.htm] head[201]:200 send: of2[footer.inc] cf2 cf1 749 dis
srv[80] 192.168.1.2:2489 [2] read: 1156 of1[style.css] GET f[/style.css] head[187]:200 send: 1231 cf1 dis
srv[80] 192.168.1.2:2490 [3] read: 1177 of1[scripts.js] GET f[/scripts.js] head[193]:200 send: 495 cf1 dis
srv[80] 192.168.1.2:2491 [4] read: 1192 of1[logo.gif] GET f[/logo.gif] head[163]:200 send: 393 cf1 dis
вставка происходит так:
Код:
GET /logo.gif HTTP/1.1
Accept: image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5
Referer: http://sesp8266/timeout.htm?wifi_rdcfg=0xffffffff&wifi_mode=2&wifi_st_ssid=HOME_AP_TST&wifi_ap_ssid=ESP8266&wifi_st_psw=%2C354%25%24%27%3B1%7E%D0%81%D1%919%D1%8B%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82&wifi_ap_hssid=0&wifi_st_bssid=bc%3Aae%3Ac5%3Aeb%3A09%3A90&wifi_ap_psw=0123456789&wifi_st_sbss=0&wifi_ap_chl=1&wifi_csta=5&wifi_phy=2&wifi_st_ip=192.168.1.50&wifi_ap_aum=0&wifi_st_msk=255.255.255.0&wifi_ap_ip=192.168.4.1&wifi_st_gw=192.168.1.1&wifi_ap_msk=255.255.255.0&wifi_st_aucn=0&wifi_st_aucn=1&wifi_ap_gw=192.168.4.1&wifi_st_mac=18%3Afe%3A34%3A9f%3Ac0%3Abf&wifi_ap_mac=1a%3Afe%3A34%3A9f%3Ac0%3Abf&wifi_st_dncp=0&wifi_st_dncp=1&wifi_ap_dncp=0&wifi_ap_dncp=1&wifi_ap_sip=192.168.4.2&wifi_ap_eip=192.168.4.102&wifi_sleep=0&wifi_ap_mcns=4&wifi_ap_bint=100&wifi_newcfg=0x13fff
Accept-Language: ru
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
Accept-Encoding: gzip, deflate
Host: sesp8266
DNT: 1
Connection: Keep-Alive
Cookie: start=0x40000000; set_ramaddr=0x3FFF0000; set_ramdata=0x12345678; stop=0x40000100
Authorization: Basic RVNQODI2NjowMTIzNDU2Nzg5
В Content-Type: multipart/form-data нет ограничений в длине переменных в HTTP ничем, в отличии от старых методов (ограничение только в atoi, принимающей длину в ASCII :p )
Аналогично и в ответе - XML ныне кушают все. Json - помирает, его замещают другие протоколы...
 
Последнее редактирование:

pvvx

Активный участник сообщества
да в чем же прикол, вроде бы как все просто но ошибки
Прикол в подходе - я пытаюсь впихнуть непихиваемое в ESP8266 и до предела поддержать стандарты. А вы пытаетесь написать разбираемый красивый код на СИ. В этом и прикол :) И основная цель не коды, а "пробить тропу" - показать, что возможно на ESP8266. Остальное - вторично.
 

jcmvbkbc

New member
Что такое MEMW() ?
Сброс "кэша"
Это ложь. memw не сбрасывает кеш.

On processor/system implementations that always reference memory in program order,
MEMW may be a no-op. Implementations that reorder load, store, or cache instructions, or
which perform merging of stores (for example, in a write buffer) must order such memo-
ry references so that all memory references executed before MEMW are performed before
any memory references that are executed after MEMW.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Это ложь. memw не сбрасывает кеш.
"кэш" то в кавычках, чтобы не писать - CPU ждет все застрявшие обращения к памяти, окончания обработки шинных буферов и т.д. по этой команде, что по простому называется <<Сброса "кеш">> Сброса не в смысле объявления невалидности дескрипторов кэш, а в смысле сброса = выливания, записи, слива и т.д. :p
У данного CPU (ESP8266) эквивалентно EXTW. Различий в кол-ве тактов их действия и итогов работы при обращении к периферии СPU и загруженных fifo шин не обнаружено.
А так-же проверено, что и без них всё работает. Вставлена в узловые места на всякий пожарный случай :) Некоторые на ней делают задержки, путем ожидания CPU синхронизации c клоком шины - пример в драйвере ws2812 :)
В итоге эти команды дают потерю до 13 тактов CPU на ожидании слива "кэш" и увеличивают объем кодов драйверов (к каждому обращению к порту компилятор автоматом вставляет код команды memw).
 
Последнее редактирование:

pvvx

Активный участник сообщества
@lvm1976 - забыл, что сам TCP client уже наполовину написан в tcp_srv_conn.c и работает в той версии Web_base. Не дописан интерфейс с Web/HTML, т.к. и не выбрана концепция управления им. Его необходимо привязывать к событиям EVENT_STAMODE_GOT_IP и другим... Но, на момент вставки/отладки TCP "клиентов" выяснилось, что эти события в SDK Espressif очень глючат и силы/время было переброшено на исправление этого. В результате Espressif дал новые либы с исправлениями, но официально они не вышли и, пока, входят только в мою прошивку :)
 
Последнее редактирование:

Andy Korg

Moderator
Команда форума
Хотел переехать на ка ver 0.3.2 (15.05.15), а чет-то ошибки при компиляции полезли:
Код:
tcp_terminal.c: In function 'tcp_term_close':
tcp_terminal.c:32:29: error: 'struct SystemCfg' has no member named 'term_port'
#define tcp_term_port syscfg.term_port
                             ^
tcp_terminal.c:255:21: note: in expansion of macro 'tcp_term_port'
  if (err == ERR_OK) tcp_term_port = 0;
                     ^
tcp_terminal.c: In function 'tcp_term_init':
tcp_terminal.c:272:28: error: 'struct SystemCfg' has no member named 'term_twrec'
   p->time_wait_rec = syscfg.term_twrec; // =0 -> вечное ожидание
                            ^
tcp_terminal.c:273:28: error: 'struct SystemCfg' has no member named 'term_twcls'
   p->time_wait_cls = syscfg.term_twcls; // =0 -> вечное ожидание
                            ^
tcp_terminal.c:32:29: error: 'struct SystemCfg' has no member named 'term_port'
#define tcp_term_port syscfg.term_port
                             ^
tcp_terminal.c:285:4: note: in expansion of macro 'tcp_term_port'
    tcp_term_port = portn;
    ^
mingw32-make[2]: *** [.output/eagle/obj/tcp_terminal.o] Error 1
Подскажите плиз чего подправить?
 

pvvx

Активный участник сообщества
А чего же он тогда не отрабатывает полное отсутствие WEBFS?:)
Как это не отрабатывает? Файл то не откроется.
А web.cgi и fsupload разгребаются в другом месте.
Хотел переехать на ка ver 0.3.2 (15.05.15), а чет-то ошибки при компиляции полезли:
Подскажите плиз чего подправить?
Он переименован на tcp2uart_xxx и подобное, т.к. сменился алгоритм его работы.
 
Последнее редактирование:
Сверху Снизу