Перейти к содержанию
    

Помогите с примером LWIP + LAN8720A + STM32Н743ZIT6 без RTOS

Приветствую!
Прошу помочь с гарантированно рабочим примером, который хоть что-то делает.
Пробовал разные примеры из сети, с сайта STM,а также сгенерированные кубом.
Мне надо сделать UDP-клиент, но сдвигов нет.
Всё остальное на процессоре уже работает, только с ETH заминка вышла.
Активности нет, на пинги не реагирует. Только светодиоды мигают, но это я так понимаю функция PHY.
Или подскажите последовательность шагов, что и в каком порядке запускать, чтобы оживить функционал.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!
Получилось вернуться к этому проекту.
Мне нужно через 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 сформирует заголовки и отправит пакет прямо из моего буфера. Только надо разобраться, как определить, что текущая операция передачи пакета завершена.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

И скорее всего, даже наверняка, функция сама ждет завершения отправки. И пока не отправит, то не выйдет из нее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 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).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 периферией и вернуться к самостоятельной реализации стека.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, amiller сказал:

Сейчас планирую изучить взаимодействие lwip с ethernet периферией и вернуться к самостоятельной реализации стека.

А lwip в этом процессе - зачем? Неужто у вашего МК отсутствует мануал, описывающий Ethernet-периферию?   :umnik2:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 hours ago, jcxz said:

А lwip в этом процессе - зачем? Неужто у вашего МК отсутствует мануал, описывающий Ethernet-периферию?   :umnik2:

Да всё достаточно просто. Посчитал, что освоение Etрernet периферии с нуля достаточно сложный процесс.
Предполагал, что сгенерирую пример Кубом, разберусь и адаптирую под себя.
Но ни одна из нескольких попыток использования Куба для формирования модуля связи не увенчалась успехом.
Потом пробовал несколько "рабочих" примеров из интернета, настраивал ноги физики под себя и пытался запустить.
Один простой пример заработал криво-косо.
Далее долго вычищал из него кубовский мусор, поженил со своим софтом.
Сейчас всё работает. Понятно, что lwip избыточен для моих задач, да и вносит свою долю неопределенности в надежность.
Поэтому следующий шаг - постепенно перейти на свою понятную реализацию стека.
Мне нужно то от стека очень немного.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В процессе оптимизации софта обнаружил в регистре 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
Кто нибудь пробовал запустить этот сервис? Получилось?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 9/27/2022 at 7:39 AM, amiller said:

В процессе оптимизации софта обнаружил в регистре ETH->MACCR интересный бит ARPEN (STM32H743ZIT6).

А вы Errata почитайте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 minutes ago, dimka76 said:

А вы Errata почитайте.

Спасибо, всегда забываю про эту часть документации...
Действительно в Errata есть такой пункт: "ARP offload function not effective"
Только в качестве причины указана другая проблема, до которой я ещё не дошёл.
А проблема с записью в регистр ETH->MACARPAR никак не поясняется.
Тем не менее вопрос потерял смысл, надо ARP запросы парсить программно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...