• Система автоматизации с открытым исходным кодом на базе 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 падает, а он пытается уверовать что при блокировке колбака я блокирую интеррапт, ломаю систему, не пускаю новые пакеты, блокирую очередь.

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