Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

Ethernet LwIP kullanımı

Başlatan robikod, 08 Ocak 2020, 09:05:27

robikod

Stm32 ile birlikte, lwip kütüphanesini kullanıyorum. Bilgisayardan ping attığım zaman, başarılı bir şekilde cevap verebiliyorum. Benim yapmak istediğim ise, STM32 ve lwip kullanarak ping atabilmek bu soruya uzun süredir cevap arıyorum yardımcı olabilecek var mı ?
*FreeRTOS kullanmıyorum
*TCP ile data göndermek istemiyorum.

mufitsozen

Alıntı yapılan: robikod - 08 Ocak 2020, 09:05:27Stm32 ile birlikte, lwip kütüphanesini kullanıyorum. Bilgisayardan ping attığım zaman, başarılı bir şekilde cevap verebiliyorum. Benim yapmak istediğim ise, STM32 ve lwip kullanarak ping atabilmek bu soruya uzun süredir cevap arıyorum yardımcı olabilecek var mı ?
*FreeRTOS kullanmıyorum
*TCP ile data göndermek istemiyorum.

ST AN3966 LwIP TCP/IP stack demonstration for STM32F4x7 microcontrollers.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

robikod

Alıntı yapılan: mufitsozen - 08 Ocak 2020, 10:10:29ST AN3966 LwIP TCP/IP stack demonstration for STM32F4x7 microcontrollers.


O dökümanı okudum, ancak bana faydalı bir konu yok orada. TCP ile echo server uygulamaları mevcut.
Herhangi bir ping göndermeyi denedim https://github.com/goertzenator/lwip/blob/01c6f3f219e8690ad697e48d09dfb5f9b08c055f/contrib-1.4.0/apps/ping/ping.c buradaki kodları kullanarak. Burada ARP request ve ICMP request gidiyor ancak ağdaki her hangi bir cihaza ping attığımda hiçbir cihaz geri dönüş yapmıyor. Request gittiğini görebiliyorum, ancak cevap oluşmuyor

algorist

Alıntı yapılan: robikod - 08 Ocak 2020, 11:33:05O dökümanı okudum, ancak bana faydalı bir konu yok orada. TCP ile echo server uygulamaları mevcut.
Herhangi bir ping göndermeyi denedim https://github.com/goertzenator/lwip/blob/01c6f3f219e8690ad697e48d09dfb5f9b08c055f/contrib-1.4.0/apps/ping/ping.c buradaki kodları kullanarak. Burada ARP request ve ICMP request gidiyor ancak ağdaki her hangi bir cihaza ping attığımda hiçbir cihaz geri dönüş yapmıyor. Request gittiğini görebiliyorum, ancak cevap oluşmuyor
Muhtemel sebep firewallı kapatıp dene arada firewall cihazıda olabilir bilmiyorum nasıl bağlı. Ping attığında tüm paketler gönderilmiyor olabilir belkide sadece broadcast gönderiyorsun. Paket birşekilde düşüyor olabilir bununda sebepleri var.
e-e-e

robikod

#4
Alıntı yapılan: algorist - 08 Ocak 2020, 12:51:58Muhtemel sebep firewallı kapatıp dene arada firewall cihazıda olabilir bilmiyorum nasıl bağlı. Ping attığında tüm paketler gönderilmiyor olabilir belkide sadece broadcast gönderiyorsun. Paket birşekilde düşüyor olabilir bununda sebepleri var.

point to point bağlılar, yani PC ethernet kablosuyla direk cihaza bağlı kendi aralarında network var, PC den cihaza ping atabiliyorum başarılı şekilde. Bu kodlarla ping atmayı denediğimde ping requesti gidiyor ancak reply dönmüyor.

Başka bilgisayardan kendi bilgisayarıma ping attığımda başarılı bir şekilde reply dönüyor.
*Firewall'ı kapattım sorun düzelmedi

brandice5

PC'ye wireshark yukleyip ICMP paketinin gelip gelmedigini kontrol et.

robikod

Alıntı yapılan: brandice5 - 08 Ocak 2020, 16:39:44PC'ye wireshark yukleyip ICMP paketinin gelip gelmedigini kontrol et.


Onu zaten yapıyorum yoksa nasıl anlayacağım request mi reply mı olduğunu. ICMP request stm32den PC ye gidiyor. Ancak cevap dönmüyor..

MrDarK

Stm32 den gönderilen paketi buraya koyabilir misin? Birde pcnin mac adresini yaz bakalım. Bu aşamaya kadar geldiysen iş sonuçlanmış olmalı. Pcnin cvp verdiği ping paketi ile vermeyen ping paketlerini karşılaştıralım.
Picproje Eğitim Gönüllüleri ~ MrDarK

robikod

#8
Tabi ki olur teşekkürler:

*Xtp olan STM32 nin MAC adresi.
*STM32 li cihazın IP adresi: .06 olan. Bilgisayarın ise .100 olan.



Bu da giden request paketinin içeriği:



Request bu şekilde sonsuza kadar cevaplanmadan akıyor.
Cevap döndüğü anda, STM tarafı bunu ya kabul etmiyor ya da kabul edemiyor. Kodlarım buradakiyle birebir aynı : https://github.com/goertzenator/lwip/blob/01c6f3f219e8690ad697e48d09dfb5f9b08c055f/contrib-1.4.0/apps/ping/ping.c

Kodlardaki şu kısımda:

static void
ping_raw_init(void)
{
  ping_pcb = raw_new(IP_PROTO_ICMP);
  LWIP_ASSERT("ping_pcb != NULL", ping_pcb != NULL);

  raw_recv(ping_pcb, ping_recv, NULL);
  raw_bind(ping_pcb, IP_ADDR_ANY);
  sys_timeout(PING_DELAY, ping_timeout, ping_pcb);
}

sys_timeout kısmından biraz şüpheliyim, ama sorunu anlayamadım.

brandice5

Wireshark zaten uyariyi vermis, checksum yanlis diyor.
Senin gonderdigin 0x0000 ama wireshark in hesapladigi olmasi gereken 0xf5e5.
Kodda checksum hesaplayan kismi kontrol et.

robikod

Alıntı yapılan: brandice5 - 09 Ocak 2020, 12:36:55Wireshark zaten uyariyi vermis, checksum yanlis diyor.
Senin gonderdigin 0x0000 ama wireshark in hesapladigi olmasi gereken 0xf5e5.
Kodda checksum hesaplayan kismi kontrol et.

Checksum ile ilgili ilk başlangıçta init fonksiyonlarından birinde aşağıdaki gibi bir tanımlamaya gidiyor.

  heth.Init.RxMode = ETH_RXPOLLING_MODE;
  heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
  heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;


Ping_send fonksiyonu aşağıdaki kod bloğuna gidiyor. Onun dışında başka hiçbir detay bulamadım nedne yanlış hesaplıyor olabilir ?

** Prepare a echo ICMP request */
static void
ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
{
  size_t i;
  size_t data_len = len - sizeof(struct icmp_echo_hdr);

  ICMPH_TYPE_SET(iecho, ICMP_ECHO);
  ICMPH_CODE_SET(iecho, 0);
  iecho->chksum = 0;
//   iecho->id     = 0x8c69;
    iecho->id     = PING_ID;

  iecho->seqno  = htons(++ping_seq_num);

  /* fill the additional data buffer with some data */
  for(i = 0; i < data_len; i++) {
    ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
  }

  iecho->chksum = inet_chksum(iecho, len);
}


/* inet_chksum:
 *
 * Calculates the Internet checksum over a portion of memory. Used primarily for IP
 * and ICMP.
 *
 * @param dataptr start of the buffer to calculate the checksum (no alignment needed)
 * @param len length of the buffer to calculate the checksum
 * @return checksum (as u16_t) to be saved directly in the protocol header
 */

u16_t
inet_chksum(const void *dataptr, u16_t len)
{
  return (u16_t)~(unsigned int)LWIP_CHKSUM(dataptr, len);
}

robikod

#11
Alıntı yapılan: robikod - 09 Ocak 2020, 13:36:23Checksum ile ilgili ilk başlangıçta init fonksiyonlarından birinde aşağıdaki gibi bir tanımlamaya gidiyor.

  heth.Init.RxMode = ETH_RXPOLLING_MODE;
  heth.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
  heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;


Ping_send fonksiyonu aşağıdaki kod bloğuna gidiyor. Onun dışında başka hiçbir detay bulamadım nedne yanlış hesaplıyor olabilir ?

** Prepare a echo ICMP request */
static void
ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
{
  size_t i;
  size_t data_len = len - sizeof(struct icmp_echo_hdr);

  ICMPH_TYPE_SET(iecho, ICMP_ECHO);
  ICMPH_CODE_SET(iecho, 0);
  iecho->chksum = 0;
//   iecho->id     = 0x8c69;
    iecho->id     = PING_ID;

  iecho->seqno  = htons(++ping_seq_num);

  /* fill the additional data buffer with some data */
  for(i = 0; i < data_len; i++) {
    ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
  }

  iecho->chksum = inet_chksum(iecho, len);
}


/* inet_chksum:
 *
 * Calculates the Internet checksum over a portion of memory. Used primarily for IP
 * and ICMP.
 *
 * @param dataptr start of the buffer to calculate the checksum (no alignment needed)
 * @param len length of the buffer to calculate the checksum
 * @return checksum (as u16_t) to be saved directly in the protocol header
 */

u16_t
inet_chksum(const void *dataptr, u16_t len)
{
  return (u16_t)~(unsigned int)LWIP_CHKSUM(dataptr, len);
}

ETH_CHECKSUM_BY_HARDWARE kısmını ETH_CHECKSUM_BY_SOFTWARE ile değiştirdim. Checksum hatası düzeldi ancak yine cevap dönmüyor


algorist

Check sum yanlis olsada calismasi gerekirdi.
e-e-e

robikod

Alıntı yapılan: algorist - 09 Ocak 2020, 14:48:39Check sum yanlis olsada calismasi gerekirdi.

Ethernet init ayarlarım şu şekilde
  heth.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
  heth.Init.RxMode = ETH_RXPOLLING_MODE;
  heth.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
  heth.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
  hal_eth_init_status = HAL_ETH_Init(&heth);
...
Sorun belki buradan kaynaklanıyorda olabilir..


Sizce sorun benim yazılımsal tarafımda mı yoksa, bilgisayar cevap mı vermiyor ? Doğru bir şekilde ping atabiliyor muyum ?


robikod

Şimdi bir nokta dikkatmi çekti, PC tarafı benim cihaza ARP gönderdikten sonra
  if (HAL_ETH_GetReceivedFrame_IT(&heth) != HAL_OK)
    return NULL;

fonksiyonu (ethernetif_input içerisinde) NULL dönmüyor.

Ancak ben  ben ping atmaya başladıktan sonra bu fonksiyon NULL dönüyor yani bilgisyar bir sebepten dolayı benim cihazıma ping gönderemiyor ya da göndermiyor.