Форум РадиоКот https://radiokot.ru/forum/ |
|
W5500 дробит DHCP пакеты https://radiokot.ru/forum/viewtopic.php?f=24&t=186956 |
Страница 1 из 1 |
Автор: | bezzabotna [ Ср фев 15, 2023 13:30:55 ] | ||
Заголовок сообщения: | W5500 дробит DHCP пакеты | ||
Добрый день! Пытаюсь получить динамический IP для своего девайса (STM32 + W5500). Со статическим IP передача данных (UDP сервер и клиент) работают. А вот реализация DHCP протокола не получается. DHCP_DISCOVER передается в роутер, но по какой то причине полезные данные фрагментированы строго по 2 байта и у каждого пакета свой заголовок вместо одного заголовка и одного пакета данных (около 500Б). Прикладываю картинку как это выглядит в сниффере. Тайминги там тоже какие то странные. И от мк это вряд ли зависит. Было испробовано: -отключение прерываний сокета -изменение размера буфера сокета в W5500 (1 и 2 КБ) В режиме DHCP W5500 настраивается только на сокет 0, а остальные сокеты используются потом при реинициализации (if(dhcpInitFlag == false)) -замена микросхемы W5500 и роутера -без изменений. А так же была попытка использовать пк в качестве DHCP сервера. Что интересно, пк как то умудрялся переварить эти пакеты, но в ответ присылал что-то странное, похожее на оффер, но не совсем по протоколу. Кончились идеи( Может быть что-то посоветуете? Заранее спасибо Настройка DHCP сокета: Код: Spi2Init(); // Cброс чипа // W5500Disable(); // HAL_Delay(RESET_DELAY); W5500Enable(); HAL_Delay(RESET_DELAY); // Обязательный программный сброс W5500WriteByte(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_MR, COMMON_MR_RST); W5500ReadByte(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_MR); // Установка Force ARP W5500WriteByte(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_MR, COMMON_MR_FARP); // Установка MAC-адреса //memcpy(&NetInfo.mac[0], NetInfo.GetMac(), sizeof(NetInfo.mac)); FlashReadMacAddress(&NetInfo.devMac[0]); W5500WriteBuff(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_SHAR, &NetInfo.devMac[0], sizeof(NetInfo.devMac)); // Установка маски подсети uint8_t subr[4] = {255,255,255,0}; ///W5500WriteBuff(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_SUBR, &NetInfo.sn[0], sizeof(NetInfo.sn)); W5500WriteBuff(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_SUBR, &subr[0], sizeof(subr)); if(dhcpInitFlag == false) { ... } else if(dhcpInitFlag == true) { uint8_t zeroip[4] = {255,255,255,255}; W5500WriteBuff(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_SIPR, &zeroip[0], sizeof(zeroip)); W5500WriteBuff(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_GAR, &zeroip[0], sizeof(zeroip)); uint8_t intLevel[2] = {0xFF, 0xFE};// 267мкс, t = 4 * (INTLEVEL + 1) / 150MHz W5500WriteBuff(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_INTLEVEL, &intLevel[0], sizeof(intLevel)); W5500WriteByte(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_SIMR, COMMON_SIMR_SN_MASK(DhcpClientSocket)); W5500WriteByte(W5500_SOCKET_REG_BLOCK(DhcpClientSocket),W5500_SOCKET_REG_IMR, \ (SOCKET_IMR_SENDOK | /*SOCKET_IMR_TIMEOUT |*/ SOCKET_IMR_RECV /*| SOCKET_IMR_DISCON | SOCKET_IMR_CON*/)); W5500WriteByte(W5500_SOCKET_REG_BLOCK(DhcpClientSocket), W5500_SOCKET_REG_RXBUF_SIZE, DHCP_CLIENT_SOCKET_SIZE/1024); W5500WriteByte(W5500_SOCKET_REG_BLOCK(DhcpClientSocket), W5500_SOCKET_REG_TXBUF_SIZE, DHCP_CLIENT_SOCKET_SIZE/1024); } // Включение общих прерываний : IP уже есть в сети, IP недопустим W5500WriteByte(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_IMR, \ (COMMON_IMR_IP_CONFLICT_MASK | COMMON_IMR_IP_UNREACH_MASK)); // Установка таймаута 200мc uint8_t rtr[2] = {0x0F, 0xA0}; // RTR = (tms(400ms) / 1ms) X 10 = 4000(0x0FA0) W5500WriteBuff(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_RTR, &rtr[0], sizeof(rtr)); // Установка кол-ва повторений после таймаута - 7 W5500WriteByte(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_RCR, 0x07); // Сброс - включение PHY W5500WriteByte(W5500_COMMON_REG_BLOCK, W5500_COMMON_REG_PHYCFGR, COMMON_PHYCFGR_RST); NVIC_EnableIRQ(EXTI15_10_IRQn); Реализация передачи Код: bool W5500WriteTxSocket(uint8_t socket, uint8_t* d, uint16_t l)
{ uint16_t sendLen = l; uint16_t socketSize; if (socket == TcpClientSocket) socketSize = TCP_CLIENT_SOCKET_SIZE; else if (socket == DhcpClientSocket) socketSize = DHCP_CLIENT_SOCKET_SIZE; else socketSize = OTHER_SOCKET_SIZE; if(sendLen > socketSize) return false; // ожидание отправки предыдущего пакета uint16_t freeSize = 0; while(freeSize != socketSize) { uint8_t fsr[2]; W5500ReadBuff(W5500_SOCKET_REG_BLOCK(socket), W5500_SOCKET_REG_TX_FSR, &fsr[0], sizeof(fsr)); W5500ReadBuff(W5500_SOCKET_REG_BLOCK(socket), W5500_SOCKET_REG_TX_FSR, &fsr[0], sizeof(fsr)); freeSize = (fsr[0] << 8) | fsr[1]; // freeSize = |RD-WR| для UDP или |ACK-WR| для TCP } // Прочитать указатель в буфере сокета, куда начинать сохранять данные uint8_t wr[2]; W5500ReadBuff(W5500_SOCKET_REG_BLOCK(socket), W5500_SOCKET_REG_TX_WR, &wr[0], sizeof(wr)); W5500ReadBuff(W5500_SOCKET_REG_BLOCK(socket), W5500_SOCKET_REG_TX_WR, &wr[0], sizeof(wr)); uint16_t startWriteAdr = (wr[0] << 8) | wr[1]; // Сохранение данных в буфере сокета uint8_t txBuff[3 + sendLen]; txBuff[0] = wr[0]; txBuff[1] = wr[1]; txBuff[2] = (uint8_t) (((W5500_TXBUF_BLOCK(socket) << 3) & 0xF8) | (WRITE_VDM_MODE & 0x07)); memcpy(&txBuff[3], d, sendLen); uint8_t r[sendLen + 3]; if (false == Spi2Exchg(txBuff, r, sendLen + 3)) return false; // Обновление стартового адреса startWriteAdr += sendLen; wr[0] = (uint8_t) (startWriteAdr >> 8); wr[1] = (uint8_t) startWriteAdr; W5500WriteBuff(W5500_SOCKET_REG_BLOCK(socket), W5500_SOCKET_REG_TX_WR, &wr[0], sizeof(wr)); // Команда на отправку данных из буфера сокета в сеть W5500WriteByte(W5500_SOCKET_REG_BLOCK(socket), W5500_SOCKET_REG_CR, SOCKET_COM_SEND); //Ожидание выполнения команды while(0 != W5500ReadByte(W5500_SOCKET_REG_BLOCK(socket), W5500_SOCKET_REG_CR)); return true; }
|
Автор: | Метеоролог [ Ср фев 15, 2023 14:14:35 ] |
Заголовок сообщения: | Re: W5500 дробит DHCP пакеты |
Видно что маску подсети задали. Но не видно что задаете конкретный IP. И IP днс сервера надо тоже указывать, у вас это роутер. Или я плохо посмотрел... |
Автор: | bezzabotna [ Ср фев 15, 2023 14:20:24 ] |
Заголовок сообщения: | Re: W5500 дробит DHCP пакеты |
Так все эти мероприятия и направлены на то, чтобы получить динамический IP от роутера) |
Автор: | musor [ Ср фев 15, 2023 14:31:52 ] |
Заголовок сообщения: | Re: W5500 дробит DHCP пакеты |
разве ширпортребные роутеры умеют отдавать джин айпий за натом? их вашето ка раз ставят чтоб девайсвсы к внешке с этой динамикой умели подключатца а сами сидя на статике и да раздача адресоф DHCP это вовсе не динамика по сути после присвоения менятся пара мак-айпи уже не будет пока не пергрузиш роут(некоторые роуты также в энергонезависске сохраняют это тогда и отключени сети не поможет надо стирать в сетапе ) |
Автор: | Метеоролог [ Ср фев 15, 2023 14:36:47 ] |
Заголовок сообщения: | Re: W5500 дробит DHCP пакеты |
Так все эти мероприятия и направлены на то, чтобы получить динамический IP от роутера) А епта) Не правильно понял ваш посыл. На роутере должен быть включен DHCP Добавлено after 3 minutes 25 seconds: разве ширпортребные роутеры умеют отдавать джин айпий за натом? Почему за натом? Автор подключает сетевую напрямую к роутеру. И роутер должен выдать IP, но для этого на роутере должен быть включен DHCP |
Автор: | bezzabotna [ Ср фев 15, 2023 15:58:51 ] |
Заголовок сообщения: | Re: W5500 дробит DHCP пакеты |
DHCP включен(дал IP адрес на ПК), а WAN я на этом роутере не использую. Добавлено after 44 minutes 2 seconds: Я нашла решение, хотя это скорее костыль. Поменяла номер сокета с нуля на другой и пакеты перестали дробиться, DHCP заработал |
Автор: | Метеоролог [ Ср фев 15, 2023 16:03:15 ] |
Заголовок сообщения: | Re: W5500 дробит DHCP пакеты |
А если уже готовые библиотеки использовать? ![]() https://github.com/afiskon/stm32-w5500 |
Автор: | bezzabotna [ Ср фев 15, 2023 17:27:22 ] |
Заголовок сообщения: | Re: W5500 дробит DHCP пакеты |
Мне не понравилась реализация. Да и для понимания процессов лично мне оказалось полезным разобраться в документации и написать самостоятельно. Но DHCP клиент реализован на основе этой библиотеки, только некоторые методы заменены. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |