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

RTL00 MP3 player

Neov

Member
да везде и в любое время :) вот пример, вешаем колбек на прием udp, делаем специально задержку:
Код:
static void lwip_udp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{
    printf("udp received: %s\n", p->payload);
    pbuf_free(p);
    vTaskDelay(10000);
}
далее забрасываем udp пакетами, и при переполнении очереди, сама очередь в tcpip thread опустошается, но потом не пополняется. При этом странно, что TCP disconnect пакет как-то пролез. :)
 

pvvx

Активный участник сообщества
да везде и в любое время :) вот пример, вешаем колбек на прием udp, делаем специально задержку:
Код:
static void lwip_udp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{
    printf("udp received: %s\n", p->payload);
    pbuf_free(p);
    vTaskDelay(10000);
}
далее забрасываем udp пакетами, и при переполнении очереди, сама очередь в tcpip thread опустошается, но потом не пополняется. При этом странно, что TCP disconnect пакет как-то пролез. :)
А зачем вы полезли (застопорили) единственный тред LwIP, не запустив ему другой? Ваша ошибка, а не системы. Алгоритмическая.
Дисконнект сработал по софт-таймеру опроса psb - это другой процесс в RTOS.
И где mbox?

"Телепузикам" не стоит лезть в фукции LwIP, не разобрав как он работает в RTOS.
Используйте специальные функции для "телепузиков" - сокеты.
 
Последнее редактирование:

Neov

Member
А зачем вы полезли (застопорили) единственный тред LwIP, не запустив ему другой? Ваша ошибка, а не системы. Алгоритмическая.
Дисконнект сработал по софт-таймеру опроса psb - это другой процесс в RTOS.
И где mbox?
Все верно так и сделал. Все колбеки вешаются на этот тред и потому его блокируют, а вот повалить девайс довольно легко получается. Второй тред по сути и ненужен, достаточно просто затирать очередь новыми пакетами.
в tcpip.c
static sys_mbox_t mbox;
 
Последнее редактирование:

pvvx

Активный участник сообщества
Все верно так и сделал. Все колбеки вешаются на этот тред и потому его блокируют, а вот повалить девайс довольно легко получается.
Проще вставить какую невалидную команду процу, чтобы он улетел на "протектед". Примерно про это вы пишите? :)
С чего не вставите vTaskDelay(10000) в какое аппаратное прерывание? :)
---------
В RTOS нема нормального распределителя “отложенных функций” ( или “стека функций”, или "стека событий"). Нигде не нашел красивой реализации... Пример – идет поток, из него парсим переменные и функции и кидаем их в FIFO для последующего исполнения c указанием приоритета и/или задержки до исполнения. Через создание очереди и запуск отдельных процессов это слишком прожорливо, т.к. каждому процессу для выполнения функции нужен стек и разные уровни приоритета, а их может быть сотни в этом FIFO и в очередях RTOS никакой сортировки не предусмотрено. Для вызова в назначенной очередности нужен ещё типа таймер для каждой функции... Выходит одна бесполезная растрата ресурсов, хотя явно можно это оптимизировать до мелкого и быстрого уровня исполнения... Геройством (писать что-то подобное под RTOS) заниматься не хочу – дайте готовый.
 
Последнее редактирование:

Neov

Member
В RTOS нема нормального распределителя “отложенных функций” ( или “стека функций”, или "стека событий").
Меня удовлетворит потеря части пакетов, т.е. затереть в очереди старые пакеты новыми (ну да, плохо, а куда деваться?), чем вывод из строя tcp/ip стека. Понятно, что все колбеки нужно стараться делать максимально быстрыми и вероятность переполнения очереди близка к нулю, но при желании атаковать устройство довольно легко.
 

pvvx

Активный участник сообщества
Меня удовлетворит потеря части пакетов, т.е. затереть в очереди старые пакеты новыми (ну да, плохо, а куда деваться?), чем вывод из строя tcp/ip стека. Понятно, что все колбеки нужно стараться делать максимально быстрыми и вероятность переполнения очереди близка к нулю, но при желании атаковать устройство довольно легко.
Не думаю, что какая атака поможет. Пишите правильно и всё будет Ok. Проверка показывает, что происходит просто потеря пакетов, а чип в состоянии принять и обработать весь поток в от PHY с HT40. Когда забивается память буферов у LwIP, то он просто скипает пакеты, а при передаче их скипает драйвер WiFi с оповещением - "выкинул столько-то за время n-секунд" если не успевает передать (уложиться в арбитраж внешней AP).
Даже в rtlDuino описываемых проблем нет: Тест скорости приема по UDP и TCP (iperf.exe)
Берете продвинутый роутер с WiFi и гоните полный поток с него на RTL в пределы максимума полосы пропускания канала приема (150Мбит/c) - более в полосу приема чипа не в состоянии физически впихнуть, и никаких ошибок или переполнений не возникает. Все пакетики принимаются, если чип не перегружен другими функциями. Если перегружен другими задачами - тоже ничего не падает, просто принятые пакеты UDP скипнуться.
И где вы видели, чтобы по WiFi в городских условиях хотя-бы каждый тысячный пакет UDP не вылетал на участке передачи из-за помех?
 
Последнее редактирование:

pvvx

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

pvvx

Активный участник сообщества
А вот и нет :) я блокирую TCPIP таск, а прерывание периферии лишь наполняет очередь, его я не блокирую :)
Ну и глупость - блокируете LwIP и говорите что он не работает. Не бред ли?
Вот вам "скетч" для примера, раз уж не умеете пользоваться SDK:
Код:
#include <WiFi.h>
#include <WiFiUdp.h>
#include <stdio.h>

char ssid[] = "mynetwork";  //  your network SSID (name)
char pass[] = "mypassword";       // your network password

unsigned int localPort = 5001;      // local port to listen for UDP packets

WiFiUDP Udp;

void setup() {
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) delay(100);
  Serial.println("Connected to wifi");
  Udp.begin(localPort);
}
int timeout = 1000;
char buf[256];
void loop() {
  while (1) {
    memset(buf, 0, sizeof(buf));
    int n = Udp.read(buf, sizeof(buf));
    if ( n <= 0 ) timeout++;
    else timeout--;
    if (timeout > 3000) timeout = 3000; // assume that the udp timeout is no more than 3s
    else if (timeout < 1) timeout = 1;
    printf("\r%d    ", timeout); //    Serial.println(timeout);
    Udp.setRecvTimeout(timeout);
  }
}
Что и как там блокируется?
Снимок1474.gif
 

rst

Member
А вот и нет :) я блокирую TCPIP таск, а прерывание периферии лишь наполняет очередь, его я не блокирую :)
Никакая пауза в выполнении задачи lwip не должна приводить к его неработоспособности. Хоть 10 сек хоть 20. И не слушайте pvvx. Кадры могут теряться, сокеты могут закрываться по таймауту, но после возобновления работы задачи - работоспособность стека должна восстановиться.
При остановке задачи обработки потока входящих кадров, процесс, пихающий кадры в FIFO входящих кадров (или ISR кто их там пишет?), увидя переполнение FIFO, должен скипать новые кадры и всё - то штатное поведение.
Если у Вас происходит именно нарушение работы после паузы, то проверяйте как пишутся новые кадры в FIFO - вероятно где-то там баг.
 
  • Like
Реакции: Neov

Neov

Member
он не врубается, что если заблокировать тред LwIP вызывающий udp recv_cb(), то он не вызовет других калбаков.
Если заблокировать тред LWIP вызывающий udp recv_cb(), то он вызовет другие калбеки, как только будет разблокирован тред. Для этого есть очередь mbox. RTL00MP3/tcpip.c at master · pvvx/RTL00MP3 · GitHub
Согласен с @rst
 

rst

Member
Не слушайте rst – он не врубается, что если заблокировать тред LwIP вызывающий udp recv_cb(), то он не вызовет других калбаков.
И что??? Сейчас не вызовет - потом после окончания паузы - вызовет.
Если у Вас всё глохнет после такой паузы - выпрямляйте руки.
 

rst

Member
он вызовет другие калбеки, как только будет разблокирован тред.
Вот именно. Или по-крайней мере так должно быть. Если не так - где-то в реализации или портировании баг, который надо искать.
pvvx видимо привык костылить код, вот у него из-за любого чиха какие-то костыли и начинают падать и он считает это нормальным :D
 
  • Like
Реакции: vad7

pvvx

Активный участник сообщества
Если заблокировать тред LWIP вызывающий udp recv_cb(), то он вызовет другие калбеки, как только будет разблокирован тред. Для этого есть очередь mbox. RTL00MP3/tcpip.c at master · pvvx/RTL00MP3 · GitHub
Согласен с @rst
rst описал то, что я говорил. Он наверно не спал и всё перепутал. :)
Очередь там и остановится от вашей вставки, блокирующей исполнение треда.
Система может не восстановиться, если LwIP задано использование 'heap' и забьет всю память, вывалившись на указанном ранее сообщение.

mbox обслуживается другими task, если указаны определенные опции. Но LwIP 1.4.1 имеет уровень "экспериментальный" * (на свой страх и риск :) со вставкой переключателей приоритетов задач и прочих флагов в пользовательском коде...) - используйте более новую версию, дописав все макросы и условия под это.

*В FreeRTOS теперь это пишут явственней - опции "для продвинутых пользователей", а не для вставляющих в критические места системы vTaskDelay(10000). :p Для не продвинутых в LwIP сделаны сокеты. Они работают на ниже уровнем приоритета, чем тред разбора принятых пакетов и калбаки из него.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Вот если по честному - народу нужен не пример, но готовое решение.
Если без жлобства - добавили бы веб мордочку то простецкую, а вывод в spi - по умолчанию (без опций - всегда включен, благо ножки свободные), глядишь и кому еще кроме Вас и пары тройки "продвинутых" и сгодится - идея то хорошая, нужная.
А у нас уровень только до "обучения", а ублажение и прочие акции для увеличения популяции "общества потребления" (ардуинщиков) не рассматриваются. Обратитесь в "сферу услуг" - писателей для Ардуино. Там несложно поправить код - выкидывать куски...
Если доделывать до полной работоспособности, в качестве готового продукта, то потребуется коммерческая лицензия. Для этого тоже существуют люди, занимающиеся этим и отбирать у них хлеб тут не собираются.
Такие вот рамки - полностью готовое незя - ограничено работающими кусками.
 
Последнее редактирование:

Neov

Member
Вот именно. Или по-крайней мере так должно быть. Если не так - где-то в реализации или портировании баг, который надо искать.
pvvx видимо привык костылить код, вот у него из-за любого чиха какие-то костыли и начинают падать и он считает это нормальным :D
Странный г-н pvvx :) Я лишь написал что при переполнении очереди пакетов lwip падает, а он пытается уверовать что при блокировке колбака я блокирую интеррапт, ломаю систему, не пускаю новые пакеты, блокирую очередь.

Повторю: очередь работает исправно, в рамках очереди пакеты не теряются и последовательно обрабатываются, очередь исправно опустошается, только при переполнении очереди, она уже не пополняется.
 
Сверху Снизу