amiller 2 May 24, 2022 Posted May 24, 2022 · Report post Приветствую! Прошу помочь с гарантированно рабочим примером, который хоть что-то делает. Пробовал разные примеры из сети, с сайта STM,а также сгенерированные кубом. Мне надо сделать UDP-клиент, но сдвигов нет. Всё остальное на процессоре уже работает, только с ETH заминка вышла. Активности нет, на пинги не реагирует. Только светодиоды мигают, но это я так понимаю функция PHY. Или подскажите последовательность шагов, что и в каком порядке запускать, чтобы оживить функционал. Quote Share this post Link to post Share on other sites More sharing options...
GenaSPB 7 May 24, 2022 Posted May 24, 2022 · Report post Ознакомьтесь сhttps://community.st.com/s/question/0D50X0000BOtfhnSQB/how-to-make-ethernet-and-lwip-working-on-stm32 Мне помогло. Quote Share this post Link to post Share on other sites More sharing options...
amiller 2 September 16, 2022 Posted September 16, 2022 · Report post Приветствую! Получилось вернуться к этому проекту. Мне нужно через Ethernet посылать данные по UDP. Вроде удалось завести это дело. Насколько я понял, минимальная последовательность для отправки одного UDP пакета такая: p_udp = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_POOL); err = pbuf_take(p_udp, &buff, size); err = udp_sendto(pcb, p_udp, &client, udp_d_port); Исходя из этого два вопроса: 1. Пересылаются без ошибок UDP пакеты, длина которых не превышает 1136 байт с учётом заголовка. Пакеты большей длины обрезаются, а UDP CRC становится равной нулю. Мне для совместимости с предыдущей версией нужен пакет длиной 1480. Можно в lwip увеличить максимальную длину пакета? И какой параметр за это отвечает? 2. Мне нужен поток данных 25-30 Мбит в секунду. Достижимо ли это с lwip? Как оптимизировать процесс передачи данных? Насколько я понял, функция pbuf_take просто копирует (программно) данные из моего буфера в промежуточный буфер, снабженный заголовками UDP, IP и Ethernet. Если сформировать эти заголовки самостоятельно, то может при простой отправке UDP можно и без LWIP обойтись? Оставить ему ARP и DHCP? Заранее спасибо за любую инфу по этой теме. Похоже на второй вопрос частично сам могу ответить. По крайней мере это легко проверить. Очень вероятно, что можно выделить статический буфер с учётом длины заголовков. А udp_sendto сформирует заголовки и отправит пакет прямо из моего буфера. Только надо разобраться, как определить, что текущая операция передачи пакета завершена. Quote Share this post Link to post Share on other sites More sharing options...
dimka76 15 September 16, 2022 Posted September 16, 2022 · Report post On 9/16/2022 at 1:22 PM, amiller said: p_udp = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_POOL); err = pbuf_take(p_udp, &buff, size); err = udp_sendto(pcb, p_udp, &client, udp_d_port); ...... 2. Мне нужен поток данных 25-30 Мбит в секунду. Достижимо ли это с lwip? Как оптимизировать процесс передачи данных? Насколько я понял, функция pbuf_take просто копирует (программно) данные из моего буфера в промежуточный буфер, снабженный заголовками UDP, IP и Ethernet. Если сформировать эти заголовки самостоятельно, то может при простой отправке UDP можно и без LWIP обойтись? Оставить ему ARP и DHCP? Заранее спасибо за любую инфу по этой теме. Похоже на второй вопрос частично сам могу ответить. По крайней мере это легко проверить. Очень вероятно, что можно выделить статический буфер с учётом длины заголовков. А udp_sendto сформирует заголовки и отправит пакет прямо из моего буфера. Лично я никогда не использовал функцию pbuf_take, т.е. аллокация, отправка, освобождение. Если вы не используете RTOS и функция отправки пакетов у вас блокирующая и если вы всегда отправляете пакеты одного размера, то можно немного сэкономить времени на аллокации и освобождении. Сразу выделить память p_udp = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_POOL); и все время ее использовать. И p_udp будет вашим статическим буфером. И писать ваши данный сразу в p_upd->payload. On 9/16/2022 at 1:22 PM, amiller said: Только надо разобраться, как определить, что текущая операция передачи пакета завершена. А как у вас отправляются пакеты - смотрите реализацию функции low_level_output в файле ethernetif.c И скорее всего, даже наверняка, функция сама ждет завершения отправки. И пока не отправит, то не выйдет из нее. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 84 September 16, 2022 Posted September 16, 2022 · Report post В 16.09.2022 в 13:22, amiller сказал: 2. Мне нужен поток данных 25-30 Мбит в секунду. Достижимо ли это с lwip? Как оптимизировать процесс передачи данных? Насколько я понял, функция pbuf_take просто копирует (программно) данные из моего буфера в промежуточный буфер, снабженный заголовками UDP, IP и Ethernet. Если сформировать эти заголовки самостоятельно, то может при простой отправке UDP можно и без LWIP обойтись? Оставить ему ARP и DHCP? Не знаю как в lwip и как дело обстоит конкретно в вашем МК, но обычно Ethernet-блок имеет DMA-транспорт для приёма/передачи Ethernet-кадров в/из ОЗУ. Частенько этот транспорт работает только с определённым регионом ОЗУ МК (не любое место ОЗУ допустимо). Если расположить буферы формируемых на передачу Ethernet-кадров в этом регионе, то можно формировать их прямо "по месту", внутри буфера. Тогда не нужны будут дополнительные копирования память-память. И готовый кадр будет забирать уже DMA (при старте его передачи Ethernet-блоком). В своём TCP-стеке я именно так и поступаю: исходящие кадры формирую прямо в Ethernet-ОЗУ, без промежуточных копирований. Естественно - никаких куч, дин.памяти и прочей ненужной требухи. В Ethernet-ОЗУ декларирован массив кадров, заполняемых по мере надобности. По заполнении очередного свободного кадра из массива, его дескриптор ставится на цепочку передающего FIFO. В ISR завершения передачи кадра, этот кадр метится как свободный и доступный для заполнения новым кадром. Процесс заполнения и передачи идёт параллельно: пока предыдущие кадры стоят в передающей очереди и передаются Ethernet-блоком, в это время следующие кадры заполняются/формируются процессором. Так можно достигнуть макс.производительности. Но для этого вам скорее всего придётся самостоятельно детально изучить Ethernet-периферию. Не полагаясь на lwip. PS: Почему на lwip свет клином сошёлся? Можно ведь свой стек написать. Или можно использовать более лёгкие готовые стеки (например uIP). Quote Share this post Link to post Share on other sites More sharing options...
amiller 2 September 20, 2022 Posted September 20, 2022 · Report post On 9/16/2022 at 6:25 PM, jcxz said: Не знаю как в lwip и как дело обстоит конкретно в вашем МК, но обычно Ethernet-блок имеет DMA-транспорт для приёма/передачи Ethernet-кадров в/из ОЗУ. Частенько этот транспорт работает только с определённым регионом ОЗУ МК (не любое место ОЗУ допустимо). Если расположить буферы формируемых на передачу Ethernet-кадров в этом регионе, то можно формировать их прямо "по месту", внутри буфера. Тогда не нужны будут дополнительные копирования память-память. И готовый кадр будет забирать уже DMA (при старте его передачи Ethernet-блоком). В своём TCP-стеке я именно так и поступаю: исходящие кадры формирую прямо в Ethernet-ОЗУ, без промежуточных копирований. Естественно - никаких куч, дин.памяти и прочей ненужной требухи. В Ethernet-ОЗУ декларирован массив кадров, заполняемых по мере надобности. По заполнении очередного свободного кадра из массива, его дескриптор ставится на цепочку передающего FIFO. В ISR завершения передачи кадра, этот кадр метится как свободный и доступный для заполнения новым кадром. Процесс заполнения и передачи идёт параллельно: пока предыдущие кадры стоят в передающей очереди и передаются Ethernet-блоком, в это время следующие кадры заполняются/формируются процессором. Так можно достигнуть макс.производительности. Но для этого вам скорее всего придётся самостоятельно детально изучить Ethernet-периферию. Не полагаясь на lwip. PS: Почему на lwip свет клином сошёлся? Можно ведь свой стек написать. Или можно использовать более лёгкие готовые стеки (например uIP). Спасибо, именно в эту сторону я двигаюсь. Предыдущая версия устройства у меня была с внешним контроллером W5100. Там необходимые элементы стека были реализованы ручками. По крайней мере UDP передача и DHCP клиент. Лишние копирования информации уже исключил. Сейчас планирую изучить взаимодействие lwip с ethernet периферией и вернуться к самостоятельной реализации стека. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 84 September 20, 2022 Posted September 20, 2022 · Report post 6 часов назад, amiller сказал: Сейчас планирую изучить взаимодействие lwip с ethernet периферией и вернуться к самостоятельной реализации стека. А lwip в этом процессе - зачем? Неужто у вашего МК отсутствует мануал, описывающий Ethernet-периферию? Quote Share this post Link to post Share on other sites More sharing options...
amiller 2 September 21, 2022 Posted September 21, 2022 · Report post 13 hours ago, jcxz said: А lwip в этом процессе - зачем? Неужто у вашего МК отсутствует мануал, описывающий Ethernet-периферию? Да всё достаточно просто. Посчитал, что освоение Etрernet периферии с нуля достаточно сложный процесс. Предполагал, что сгенерирую пример Кубом, разберусь и адаптирую под себя. Но ни одна из нескольких попыток использования Куба для формирования модуля связи не увенчалась успехом. Потом пробовал несколько "рабочих" примеров из интернета, настраивал ноги физики под себя и пытался запустить. Один простой пример заработал криво-косо. Далее долго вычищал из него кубовский мусор, поженил со своим софтом. Сейчас всё работает. Понятно, что lwip избыточен для моих задач, да и вносит свою долю неопределенности в надежность. Поэтому следующий шаг - постепенно перейти на свою понятную реализацию стека. Мне нужно то от стека очень немного. Quote Share this post Link to post Share on other sites More sharing options...
amiller 2 September 27, 2022 Posted September 27, 2022 · Report post В процессе оптимизации софта обнаружил в регистре ETH->MACCR интересный бит ARPEN (STM32H743ZIT6). Описание достаточно краткое, но судя по всему этот бит включает автоматический ответ на ARP запросы на уровне MAC ETH модуля. Если я правильно понял описание, если IP адрес из ARP запроса совпадает с регистром ETH->MACARPAR, то контроллер автоматически отвечает, подставляя в ответ MAC адрес из регистра ETH->MACA3R. Проблема возникла в записи любого числа в регистр ETH->MACARPAR. Не могу это сделать и программно и в отладчике. Гугл находит только один вопрос на эту тему, но без ответа. https://community.st.com/s/question/0D50X0000BAEwqMSQT/enable-arp-offload-on-stm32h753 Кто нибудь пробовал запустить этот сервис? Получилось? 1 Quote Share this post Link to post Share on other sites More sharing options...
dimka76 15 September 27, 2022 Posted September 27, 2022 · Report post On 9/27/2022 at 7:39 AM, amiller said: В процессе оптимизации софта обнаружил в регистре ETH->MACCR интересный бит ARPEN (STM32H743ZIT6). А вы Errata почитайте. Quote Share this post Link to post Share on other sites More sharing options...
amiller 2 September 27, 2022 Posted September 27, 2022 · Report post 10 minutes ago, dimka76 said: А вы Errata почитайте. Спасибо, всегда забываю про эту часть документации... Действительно в Errata есть такой пункт: "ARP offload function not effective" Только в качестве причины указана другая проблема, до которой я ещё не дошёл. А проблема с записью в регистр ETH->MACARPAR никак не поясняется. Тем не менее вопрос потерял смысл, надо ARP запросы парсить программно. Quote Share this post Link to post Share on other sites More sharing options...