Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F107+uIP ICMP request
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
ksv198
Доброго времени суток!

Суть проблемы: пытаюсь пропинговать с контроллера обычный комп в сети, использую uIP v 1.0
Сам стэк работает, все примеры нормально бегают, и вебсервер и телнет и.д.
Железяка пингуется со стороны компа. На компе ICMP разрешён, другие компы его пингуют.
При попытке отправить ICMP request с железяки Wireshark видит пакет, но комп не отвечает.
Вот скрин с Wireshark: Нажмите для просмотра прикрепленного файла

Как отправляю - заполняю все поля в буфере (uip_buf) и пинаю:

uip_arp_out();
vSendMACData( uip_len ); //это функция отправки данных драйвера Ethernet для STM32F107

В Wireshark вижу, что сначала уходит ARP запрос и на него приходит нормальный ответ от компа, с МАС-ами и IP соответствующими железкам. А вот затем вижу ушедший ICMP request и.... никакого ответа.

В чём может быть засада?
bzx
Цитата(ksv198 @ Dec 19 2013, 18:31) *
...В чём может быть засада?

Контрольную сумму (CRC) проверьте.
ksv198
Цитата(bzx @ Dec 19 2013, 20:39) *
Контрольную сумму (CRC) проверьте.


Да!!! Спасибо большое, 4 часа протупил, сумма в заголовке ICMP была не правильной.
Ответ пошёл.
Misha_Traktorist
Не могли бы поделиться кодом? Тоже надо сделать пинг с девайса)))
romas2010
Цитата(ksv198 @ Dec 19 2013, 20:02) *
Да!!! Спасибо большое, 4 часа протупил, сумма в заголовке ICMP была не правильной.
Ответ пошёл.


Да,в IP пакетах надо CRC всегда считать...кстати STM аппаратно считает CRC этих пакетов установкой битов в дескрипторе передачи TDES0.CIC = 3
Misha_Traktorist
Кому надо, делается это вот так:
Код
        // Составляем IP заголовок
        ICMPBUF->vhl = 0x45;
        ICMPBUF->tos = 0;
        uint16_t    len = sizeof(struct uip_icmpip_hdr);    // длина будет равна заголовку ip + icmp
        ICMPBUF->len[0] = len >> 8;
        ICMPBUF->len[1] = len & 0xff;
        uint16_t    ipid = 0;
        ICMPBUF->ipid[0] = ipid >> 8;
        ICMPBUF->ipid[1] = ipid & 0xff;
        ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
        ICMPBUF->ttl = UIP_TTL;
        ICMPBUF->proto = UIP_PROTO_ICMP;
        // указываем свой ip и ip удаленного устройства.
        uip_gethostaddr(ICMPBUF->srcipaddr);
        uip_ipaddr(&ICMPBUF->destipaddr, 192,168,1,101);

        ICMPBUF->ipchksum = 0;
        ICMPBUF->ipchksum = ~(uip_ipchksum());

        ICMPBUF->type = ICMP_ECHO;
        ICMPBUF->icode = 0;
        ICMPBUF->icmpchksum = 0;
        ICMPBUF->icmpchksum = uip_chksum((uint16_t*)&ICMPBUF->type, 8);
        ICMPBUF->icmpchksum = ~((ICMPBUF->icmpchksum == 0) ? 0xffff : ICMPBUF->icmpchksum);

        printf("type %d, code %d, icmpchksum %d\r\n", ICMPBUF->type, ICMPBUF->icode, ICMPBUF->icmpchksum);

        uip_len = UIP_IPH_LEN + 8;    // длина равна заголовку ip + заголовку icmp

        uip_arp_out();
        enc28j60_send_packet((uint8_t *) uip_buf, uip_len);

Данный код подходит как для пинга внутренней сети, так и внешней.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.