Turgenev 1 20 июня Опубликовано 20 июня (изменено) · Жалоба Работаю с RAW LwIP на плате NUCLEO-H743ZI2 и случайно обратил внимание, что 99.9% времени, затрачиваемого на запуск контроллера (выход на цикл while(1)) приходится на функцию инициализации MX_LWIP_Init(). На 400 МГц тактовой частоты ядра это время составляет 2 секунды. Измерял вот так: Спойлер cnt_ms_load_mcu = HAL_GetTick(); MX_LWIP_Init(); cnt_ms_load_mcu = HAL_GetTick() - cnt_ms_load_mcu; Архив с проектом прилагаю: Спойлер Nikiten_STM32_Eth.zip Хотел узнать, у вас так же? Кто-нибудь ускорял инициализацию этой библиотеки? Изменено 20 июня пользователем Turgenev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 160 20 июня Опубликовано 20 июня · Жалоба Думается мне, что Вы измеряете скорость автосогласования Ethernet PHY... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 214 21 июня Опубликовано 21 июня · Жалоба 12 часов назад, Arlleex сказал: Думается мне, что Вы измеряете скорость автосогласования Ethernet PHY... Я ТС-у об этом писал в другой теме. Только думаю, что он всё равно ничего не понял. Так как не знает и не желает знать - что делает какая часть его же кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Turgenev 1 21 июня Опубликовано 21 июня · Жалоба Ваши сомнения в такой долгой инициализации натолкнули на поиски. Причина оказалась проста. Код из lan8742.c: Спойлер /* Wait for 2s to perform initialization */ while((pObj->IO.GetTick() - tickstart) <= LAN8742_INIT_TO) { } Комментарий от разработчиков ST в теме (осторожно, очень жесткая критика): Спойлер https://community.st.com/t5/stm32-mcus-embedded-software/stm32h7-phy-driver-for-lan8742-2s-delay/td-p/112767/page/2 Удаление этой 2 сек задержки, предварительно, на работу сети Ethernet не повлияло- пингую, отправляю, принимаю пакеты на 100 МБ/с. Из темы на форуме ST и из кода так и не понял зачем ждать 2 секунды, если PHY и MAC и без нее синхронизируются. 14 часов назад, jcxz сказал: Я ТС-у об этом писал в другой теме. Только думаю, что он всё равно ничего не понял. Так как не знает и не желает знать - что делает какая часть его же кода. Что делает написанный мной код я желаю знать и знаю. Что делает код сторонних библиотек мне достаточно знать в самом общем смысле, если работа библиотеки удовлетворяет моим требованиям, иначе зачем я ее использую. Безусловно полезно знать все на свете, но возможностей для этого не достаёт. Неужели это не так работает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 160 21 июня Опубликовано 21 июня · Жалоба Ды можно и не вдаваться в подробности работы сторонних исходников, но ведь Вам пришлось же вдаваться, как минимум) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Turgenev 1 21 июня Опубликовано 21 июня · Жалоба Ну вы сказали что не должно быть так, я и полез... Мои коллеги несколько лет на это не обращали внимание Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 214 22 июня Опубликовано 22 июня · Жалоба 7 часов назад, Turgenev сказал: Удаление этой 2 сек задержки, предварительно, на работу сети Ethernet не повлияло- пингую, отправляю, принимаю пакеты на 100 МБ/с. Из темы на форуме ST и из кода так и не понял зачем ждать 2 секунды, если PHY и MAC и без нее синхронизируются. Вам уже и написали выше про наиболее вероятную причину - зачем нужна эта задержка: В 20.06.2024 в 18:58, Arlleex сказал: автосогласования Ethernet PHY но вы ведь всё равно не поняли. Предпочитаете пинать колёса, а не вникать. 7 часов назад, Turgenev сказал: Что делает написанный мной код я желаю знать и знаю. Что делает код сторонних библиотек Как только какой-то код, не важно где откопанный, вы влепили в свой проект, он стал вашим кодом. 7 часов назад, Turgenev сказал: Неужели это не так работает? Когда ваше устройство вдруг перестаёт работать, вы тоже заказчику говорите: "Это проблема не у меня, а в той либе, которую я влепил в свой проект. А я не при делах." Так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Turgenev 1 24 июня Опубликовано 24 июня · Жалоба Распишу почему мне не понятно, зачем нужна задержка. Задержка в 2 секунды находится в функции LAN8742_Init(lan8742_Object_t *pObj), в которой не происходит автосогласования, а только конфиг PHY, поправьте если не прав. Процесс автосогласования запускается автоматически после сброса PHY: Спойлер /** * @brief Initialize the lan8742 and configure the needed hardware resources * @param pObj: device object LAN8742_Object_t. * @retval LAN8742_STATUS_OK if OK * LAN8742_STATUS_ADDRESS_ERROR if cannot find device address * LAN8742_STATUS_READ_ERROR if connot read register * LAN8742_STATUS_WRITE_ERROR if connot write to register * LAN8742_STATUS_RESET_TIMEOUT if cannot perform a software reset */ int32_t LAN8742_Init(lan8742_Object_t *pObj) { uint32_t tickstart = 0, regvalue = 0, addr = 0; int32_t status = LAN8742_STATUS_OK; if(pObj->Is_Initialized == 0) { if(pObj->IO.Init != 0) { /* GPIO and Clocks initialization */ pObj->IO.Init(); } /* for later check */ pObj->DevAddr = LAN8742_MAX_DEV_ADDR + 1; /* Get the device address from special mode register */ for(addr = 0; addr <= LAN8742_MAX_DEV_ADDR; addr ++) { if(pObj->IO.ReadReg(addr, LAN8742_SMR, ®value) < 0) { status = LAN8742_STATUS_READ_ERROR; /* Can't read from this device address continue with next address */ continue; } if((regvalue & LAN8742_SMR_PHY_ADDR) == addr) { pObj->DevAddr = addr; status = LAN8742_STATUS_OK; break; } } if(pObj->DevAddr > LAN8742_MAX_DEV_ADDR) { status = LAN8742_STATUS_ADDRESS_ERROR; } /* if device address is matched */ if(status == LAN8742_STATUS_OK) { /* set a software reset */ if(pObj->IO.WriteReg(pObj->DevAddr, LAN8742_BCR, LAN8742_BCR_SOFT_RESET) >= 0) { /* get software reset status */ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, ®value) >= 0) { tickstart = pObj->IO.GetTick(); /* wait until software reset is done or timeout occured */ while(regvalue & LAN8742_BCR_SOFT_RESET) { if((pObj->IO.GetTick() - tickstart) <= LAN8742_SW_RESET_TO) { if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, ®value) < 0) { status = LAN8742_STATUS_READ_ERROR; break; } } else { status = LAN8742_STATUS_RESET_TIMEOUT; break; } } } else { status = LAN8742_STATUS_READ_ERROR; } } else { status = LAN8742_STATUS_WRITE_ERROR; } } } if(status == LAN8742_STATUS_OK) { tickstart = pObj->IO.GetTick(); /* Wait for 2s to perform initialization */ /* while((pObj->IO.GetTick() - tickstart) <= LAN8742_INIT_TO) { }*/ pObj->Is_Initialized = 1; } return status; } Т.е. ожидание 2 с оправдано тем, что происходит процесс автосогласования, который автоматически начался после сброса PHY. Но в RAW LwIP обработка пакетов происходит вызовом функции MX_LWIP_Process() в бесконечном цикле, в которой есть функция работы с PHY - Ethernet_Link_Periodic_Handle(struct netif *netif). Эта функция проверяет состояние канала и возможность/необходимость перехода на другую скорость функцией ethernet_link_check_state(struct netif *netif): Спойлер /** * @brief Check the ETH link state then update ETH driver and netif link accordingly. * @param argument: netif * @retval None */ void ethernet_link_check_state(struct netif *netif) { ETH_MACConfigTypeDef MACConf; int32_t PHYLinkState; uint32_t linkchanged = 0, speed = 0, duplex =0; PHYLinkState = LAN8742_GetLinkState(&LAN8742); if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN)) { HAL_ETH_Stop(&heth); netif_set_down(netif); netif_set_link_down(netif); } else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN)) { switch (PHYLinkState) { case LAN8742_STATUS_100MBITS_FULLDUPLEX: duplex = ETH_FULLDUPLEX_MODE; speed = ETH_SPEED_100M; linkchanged = 1; break; case LAN8742_STATUS_100MBITS_HALFDUPLEX: duplex = ETH_HALFDUPLEX_MODE; speed = ETH_SPEED_100M; linkchanged = 1; break; case LAN8742_STATUS_10MBITS_FULLDUPLEX: duplex = ETH_FULLDUPLEX_MODE; speed = ETH_SPEED_10M; linkchanged = 1; break; case LAN8742_STATUS_10MBITS_HALFDUPLEX: duplex = ETH_HALFDUPLEX_MODE; speed = ETH_SPEED_10M; linkchanged = 1; break; default: break; } if(linkchanged) { /* Get MAC Config MAC */ HAL_ETH_GetMACConfig(&heth, &MACConf); MACConf.DuplexMode = duplex; MACConf.Speed = speed; HAL_ETH_SetMACConfig(&heth, &MACConf); HAL_ETH_Start(&heth); netif_set_up(netif); netif_set_link_up(netif); } } } А состояние/результат работы автосогласования проверяется/устанавливается в функции LAN8742_GetLinkState(lan8742_Object_t *pObj): Спойлер /** * @brief Get the link state of LAN8742 device. * @param pObj: Pointer to device object. * @param pLinkState: Pointer to link state * @retval LAN8742_STATUS_LINK_DOWN if link is down * LAN8742_STATUS_AUTONEGO_NOTDONE if Auto nego not completed * LAN8742_STATUS_100MBITS_FULLDUPLEX if 100Mb/s FD * LAN8742_STATUS_100MBITS_HALFDUPLEX if 100Mb/s HD * LAN8742_STATUS_10MBITS_FULLDUPLEX if 10Mb/s FD * LAN8742_STATUS_10MBITS_HALFDUPLEX if 10Mb/s HD * LAN8742_STATUS_READ_ERROR if connot read register * LAN8742_STATUS_WRITE_ERROR if connot write to register */ int32_t LAN8742_GetLinkState(lan8742_Object_t *pObj) { uint32_t readval = 0; /* Read Status register */ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0) { return LAN8742_STATUS_READ_ERROR; } /* Read Status register again */ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BSR, &readval) < 0) { return LAN8742_STATUS_READ_ERROR; } if((readval & LAN8742_BSR_LINK_STATUS) == 0) { /* Return Link Down status */ return LAN8742_STATUS_LINK_DOWN; } /* Check Auto negotiaition */ if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_BCR, &readval) < 0) { return LAN8742_STATUS_READ_ERROR; } if((readval & LAN8742_BCR_AUTONEGO_EN) != LAN8742_BCR_AUTONEGO_EN) { if(((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT) && ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE)) { return LAN8742_STATUS_100MBITS_FULLDUPLEX; } else if ((readval & LAN8742_BCR_SPEED_SELECT) == LAN8742_BCR_SPEED_SELECT) { return LAN8742_STATUS_100MBITS_HALFDUPLEX; } else if ((readval & LAN8742_BCR_DUPLEX_MODE) == LAN8742_BCR_DUPLEX_MODE) { return LAN8742_STATUS_10MBITS_FULLDUPLEX; } else { return LAN8742_STATUS_10MBITS_HALFDUPLEX; } } else /* Auto Nego enabled */ { if(pObj->IO.ReadReg(pObj->DevAddr, LAN8742_PHYSCSR, &readval) < 0) { return LAN8742_STATUS_READ_ERROR; } /* Check if auto nego not done */ if((readval & LAN8742_PHYSCSR_AUTONEGO_DONE) == 0) { return LAN8742_STATUS_AUTONEGO_NOTDONE; } if((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_100BTX_FD) { return LAN8742_STATUS_100MBITS_FULLDUPLEX; } else if ((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_100BTX_HD) { return LAN8742_STATUS_100MBITS_HALFDUPLEX; } else if ((readval & LAN8742_PHYSCSR_HCDSPEEDMASK) == LAN8742_PHYSCSR_10BT_FD) { return LAN8742_STATUS_10MBITS_FULLDUPLEX; } else { return LAN8742_STATUS_10MBITS_HALFDUPLEX; } } } Тогда зачем ждать железные 2 с при старте, ни к чему не привязанные (может времени нужно больше или меньше), когда в процессе работы согласование PHY с MAC и так постоянно проверяется? Если задержка сделана на случай, если не удалось согласование при старте, оно по-любому запустится в процессе работы. По-моему, это уже не по теме: Спойлер В 22.06.2024 в 06:12, jcxz сказал: но вы ведь всё равно не поняли. Предпочитаете пинать колёса, а не вникать. Так можно отвечать на все вопросы, когда кому-то что-то не понятно. Нашел задержку и тему где она описана- пинал колеса, в этой теме не понял что-то - не хочешь вникать. Не прикрывайтесь советами других, действуйте более открыто, будет меньше текста. В 22.06.2024 в 06:12, jcxz сказал: Когда ваше устройство вдруг перестаёт работать, вы тоже заказчику говорите: "Это проблема не у меня, а в той либе, которую я влепил в свой проект. А я не при делах." Так? Не судите по себе, есть тестировщики, этапы разработки, испытания и тд. Кто заказчику не обкатанное изделие отдает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Turgenev 1 26 июня Опубликовано 26 июня (изменено) · Жалоба Получил проблему из-за удаления 2с задержки в инициализации PHY: соединение по Ethernet устанавливается только после второй перезагрузки устройства, после прошивки МК. Т.е. прошиваю МК, перезагружаю всё устройство и связи по ethernet нет, затем перезагружаю устройство второй раз и связь появляется. Проблема описана вот тут: Спойлер https://community.st.com/t5/stm32-mcus-embedded-software/stm32f207vc-ethernet-with-lwip-works-after-flashing-but-not-any/td-p/276626/page/2 Вкратце: PHY возвращает 0xFFFF при чтении любого его регистра. Малой кровью проблема решается добавлением проверки в LAN8742_Init перед первым чтением регистра PHY в этой функции: Спойлер pObj->IO.ReadReg(0, LAN8742_SMR, ®value); if (regvalue == 0x0000FFFF) { HAL_NVIC_SystemReset(); } Может кому-то будет полезно... Изменено 26 июня пользователем Turgenev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
std 7 7 июля Опубликовано 7 июля (изменено) · Жалоба В 22.06.2024 в 00:41, Turgenev сказал: Удаление этой 2 сек задержки, предварительно, на работу сети Ethernet не повлияло- пингую, отправляю, принимаю пакеты на 100 МБ/с. Из темы на форуме ST и из кода так и не понял зачем ждать 2 секунды, если PHY и MAC и без нее синхронизируются. Проверять надо более комплексно, например выдернуть кабель и снова подключить, сделать power/off - power onn и т.д., наблюдать не светодиод линка, а реальный обмен пакетами. При этом время и результат (успех/неуспех) с разными компьютерами, маршрутизаторами или коммутаторами на разных скоростях и настройках может быть разным. Про задержку. Почему она существует и почему она потребовалась. Существует протокол автосогласования, для того чтобы он отработал требуется время: https://en.wikipedia.org/wiki/Autonegotiation В ST некогда переписали HAL код Ethenet и сделали множество ошибок, одной из них является само построение логики: они сбрасывают PHY, инициализируют, и ждут окончания процесса автосогласования, для чего выдерживают заданную паузу. В этом у них еще и баг, так как в некоторых случаях с гигабитными линками требуемое время существенно больше, до 3сек, то есть превышает заданную ими паузу. Правильный код должен сбросить PHY, проинициализировать, и на этом инициализация должна закончиться, перенеся время ожидания в цикл, в периодическую проверку is link up. Изменено 7 июля пользователем std 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Turgenev 1 Понедельник в 08:40 Опубликовано Понедельник в 08:40 · Жалоба В 07.07.2024 в 03:36, std сказал: В ST некогда переписали HAL код Ethenet и сделали множество ошибок, одной из них является само построение логики: они сбрасывают PHY, инициализируют, и ждут окончания процесса автосогласования, для чего выдерживают заданную паузу. В этом у них еще и баг, так как в некоторых случаях с гигабитными линками требуемое время существенно больше, до 3сек, то есть превышает заданную ими паузу. Получается, что в текущей реализации библиотеки HAL (когда время автосогласования выжидается при инициализации библиотеки LwIP), если включить моё устройство без подключенного кабеля Ethernet к компу (или другому PHY), то контроллер впустую простоит 2 секунды, согласоваться то не с кем. А как мой PHY тогда согласуется с другим PHY, когда я подключаю Ethernet кабель после "пустого" согласования (согласования без подключенного кабеля)? Ведь процедура согласования происходит один раз и только при включении МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 51 Понедельник в 09:05 Опубликовано Понедельник в 09:05 · Жалоба On 7/8/2024 at 11:40 AM, Turgenev said: Получается, что в текущей реализации библиотеки HAL (когда время автосогласования выжидается при инициализации библиотеки LwIP), если включить моё устройство без подключенного кабеля Ethernet к компу (или другому PHY), то контроллер впустую простоит 2 секунды, согласоваться то не с кем. А как мой PHY тогда согласуется с другим PHY, когда я подключаю Ethernet кабель после "пустого" согласования (согласования без подключенного кабеля)? Ведь процедура согласования происходит один раз и только при включении МК. На удачу ))) Выжидание требуется для МАС. PHY согласуется автоматически. По результатам согласование PHY, МАС настраивает свои регистры. Значения Half/Full duplex, 10/100 МБит. По умолчанию МАС настроен на Full Duplex и 100 МБит. PHY скорее всего у вас не гигабитный. Сейчас сеть на 10 Мбит еще умудриться найти надо. Поэтому настройка по умолчанию в подавляющем большинстве случаев подходит. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Turgenev 1 Понедельник в 09:41 Опубликовано Понедельник в 09:41 (изменено) · Жалоба 36 минут назад, dimka76 сказал: На удачу ))) Ужас. Надо с этим что-то делать. Я пробовал разные версии CubeMX и, следовательно, библиотек HAL и LwIP, чтобы запустить Ethernet "из коробки". Да, так не правильно делать, но справедливости ради, ни разу таким способом ничего и не заработало. Но минимальное количество правок кода потребовала версия Cube 6.3.0 и HAL1.9.0 для STM32H7. В этой версии библиотек есть ожидание 2 сек автосогласования. В последующих версиях ST обещали исправить библиотеку HAL Ethernet и исправили, но испортили что-то другое. И так мне не удалось найти версию с нормальной библиотекой Ethernet. Может кто-нибудь использует HAL и LwIP, где эта проблема с ожиданием и многие другие проблемы решены и библиотека стабильна, посоветуете версию? Изменено Понедельник в 09:42 пользователем Turgenev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 51 Понедельник в 10:53 Опубликовано Понедельник в 10:53 · Жалоба On 7/8/2024 at 12:41 PM, Turgenev said: Может кто-нибудь использует HAL и LwIP, где эта проблема с ожиданием и многие другие проблемы решены и библиотека стабильна, посоветуете версию? HAL вам предоставляет только доступ к периферии. Связь HAL и LwIP представлена в виде примера, а не полноценного законченного продукта. Пример вам показывает какие в каком порядке вызывать функции HAL для того, чтобы ознакомится с библиотекой. Полноценное рабочее приложение вы должны сделать самостоятельно. Если вам достаточно функционала примера, то можно остановиться на этом. Если нужно что-то большее, то придется самому развивать этот пример. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 214 Понедельник в 12:12 Опубликовано Понедельник в 12:12 · Жалоба 3 часа назад, dimka76 сказал: Сейчас сеть на 10 Мбит еще умудриться найти надо. Да запросто! Открываем datasheet на один из МК, популярного ныне в РФ (а куда деваться?) китайского производителя WCH (CH32F20x Datasheet For CH32F203/205/207/208xx V2.3). И видим: Цитата Ethernet MAC that reaches gigabit, integrated 10M-PHY module Дешёвое устройство вполне может быть построено на таком МК со встроенным Phy-10M. Да даже если железо в устройстве само по себе поддерживает бОльшие скорости, но скорость может быть зарезана преднамеренно по каким-то причинам (помехоустойчивость, etc.). В наших устройствах мы делали возможность пользователю в конфиге устройства разрешить работу только на нужных режимах из: 10-half, 10-full, 100-half, 100-full. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться