Stm32 ve Eternet Sorunu

Başlatan robikod, 18 Aralık 2018, 15:49:00

robikod

Merhaba, stm32 ile eternet üzerinden iletişim kurmaya çalışıyorum.Bu kodları referans aldım (https://github.com/xukai871105/uip_freemodbus_tcp/tree/master/User)
Bunun için eternet modülü olarak enc28j60 modülünü seçtim.  (SPI'ın doğru çalışıp çalışmadığını ARP paketi yollayarak test ettim doğru çalışıyordu)
Bilgisayarı ethernet girişinden modüle bağladım ve bilgisayarımın ipsini referans aldım.

Init ayarlarını yaptıktan sonra while içerisindeki kodlar şu şekilde:


while (1)
    {

        // serialprint("hi");
        // Delay(5);
        eMBPoll();
        led_poll();

        /* 从网络设备读取一个IP包,返回数据长度 */
        uip_len = tapdev_read();
        serialprint("tap_dev= %d\n", uip_len);

        /* 收到数据	*/
        if (uip_len > 0)
        {
            /* 处理IP数据包 */
            if (BUF->type == htons(UIP_ETHTYPE_IP))
            {
                uip_arp_ipin();
                uip_input();

                if (uip_len > 0)
                {
                    uip_arp_out();
                    tapdev_send();
                }
            }
            /* 处理ARP报文 */
            else if (BUF->type == htons(UIP_ETHTYPE_ARP))
            {
                uip_arp_arpin();
                if (uip_len > 0)
                {
                    tapdev_send();
                }
            }
        }

        /* 0.5秒定时器超时 */
        if (timer_expired(&periodic_timer))
        {
            timer_reset(&periodic_timer);

            // GPIOD->ODR ^= GPIO_Pin_3;

            /* 处理TCP连接, UIP_CONNS缺省是10个 */
            for (uint8_t i = 0; i < UIP_CONNS; i++)
            {
                /* 处理TCP通信事件 */
                uip_periodic(i);
                if (uip_len > 0)
                {
                    uip_arp_out();
                    tapdev_send();
                }
            }

Sorun burada şu ki, uip_len = tapdev_read(); her zaman 0 dönüyor. Bunun sebebi de enc28j60.c kodlarımdaki şu fonksiyonda if ((rxstat & 0x80)==0) kısmının her zaman 1 dönüp len=0 olması. Bu sorunu nasıl çözebilirim ? Yardımcı olursanız çok sevinirim.

unsigned int enc28j60_packet_receive(unsigned char *packet, unsigned int maxlen)
    {
    
        unsigned int rxstat;
        unsigned int len;
    
        if (enc28_read(EPKTCNT) == 0)
        {
            return (0);
            // GPIO_SetBits(GPIOE, GPIO_Pin_9);
        }
    
        enc28_write(ERDPTL, (next_pack_ptr));
        enc28_write(ERDPTH, (next_pack_ptr) >> 8);
    
        next_pack_ptr = enc28_readOp(ENC28J60_READ_BUF_MEM, 0);
        next_pack_ptr |= enc28_readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
    
        len = enc28_readOp(ENC28J60_READ_BUF_MEM, 0);
        len |= enc28_readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
    
        len -= 4;
    
        rxstat = enc28_readOp(ENC28J60_READ_BUF_MEM, 0);
        rxstat |= enc28_readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
    
        enc28_writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
    
        if (len > maxlen - 1)
        {
            len = maxlen - 1;
        }
    
        if ((rxstat & 0x80) == 0)
        {
    
            GPIO_SetBits(GPIOE, GPIO_Pin_9);
    
            len = 0;
        }
        else
        {
    
            enc28_readBuffer(packet, len);
        }
    
        enc28_write(ERXRDPTL, (next_pack_ptr));
        enc28_write(ERXRDPTH, (next_pack_ptr) >> 8);
    
        enc28_writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
    
        return (len);

crazy


hwdesigner


z

Bana e^st de diyebilirsiniz.   www.cncdesigner.com

robikod


robikod

Teşekkür ederim kaynaklar için, ancak ben bu kaynakların hepsini inceledim ve baktım benim sorunumu çözmesi için bu kaynaklardan referans alarak birkaç değişiklik yaptım ancak sorunumu çözemedi.

robikod

#6
Alıntı yapılan: z - 19 Aralık 2018, 00:42:53Fazla yetenekli degil ama bir bak istersen.

http://www.cncdesigner.com/wordpress/?p=6149

https://www.picproje.org/index.php/topic,65851.msg513599.html#msg513599

https://github.com/Bunalmis/ENC28J60-STM32F103C8



Bu proje size ait sanırım, emeğinize sağlık çok güzel bir anlatım olmuş. Benim sorunum aslında, ethernet üzerinden ARP ve IP paketlerini analiz etmemi sağlayan packet receive fonksiyonumdaki bazı değerler sonucu hiçbir ARP,Ethernet paketi bulamaması. Buınun sebebi ethernet kablosunu direk bilgisyara bağlamam mı yoksa bu fonksiyon içerisindeki hatalarım mı ? SPI diyebiirsiniz ancak  ARP paketi yollayıp wireshark üzerinden görebiliyorum bunu dolayısıyla SPI doğru çalışıyor. Bunun dışında ne gibi bir sorun olabilir ?

bsenguler

Doğrudan ethernet kablosunu bilgisayara takarsan çalışmaz,birebir ethernet kablosunu ethernet kart/modul ile ethernet anahtarlayıcı arasında kullanabilirsiniz, ethernet modulden bilgisayar çapraz olarak bağlanmış bir ethernet kablosu kullanmanız gerekmektedir.

robikod

Alıntı yapılan: bsenguler - 20 Aralık 2018, 11:28:03Doğrudan ethernet kablosunu bilgisayara takarsan çalışmaz,birebir ethernet kablosunu ethernet kart/modul ile ethernet anahtarlayıcı arasında kullanabilirsiniz, ethernet modulden bilgisayar çapraz olarak bağlanmış bir ethernet kablosu kullanmanız gerekmektedir.
Şimdi o şekilde denedim, modülü modeme bağladım eternet kablosu ile (bundan önce moden ip,netmask ve broadcast bilgilerini değiştirdim) yine de (rxstat & 0x80) == 0 kısmı 0 dönüyor. (receive packet kısmında)

bsenguler

Ip adresini elle giriyorsanız, modemle aynı networkte oldugunuzdan emin olun, ornegin modem 192.168.1.0/24 te ise sizde 192.168.1.0/24 te olun yoksa diğer cihazlar ile görüşemezsiniz.

robikod

#10
Alıntı yapılan: bsenguler - 20 Aralık 2018, 11:47:07Ip adresini elle giriyorsanız, modemle aynı networkte oldugunuzdan emin olun, ornegin modem 192.168.1.0/24 te ise sizde 192.168.1.0/24 te olun yoksa diğer cihazlar ile görüşemezsiniz.


Kod içerisindeki ayarlara göre şu şekilde ayarlıyorum bu ayarları da ethernet kablosunu ilk önce bilgisyara taktım ve ifconfig komutu ile terminalden enp2s (ethernet) üzerinden aldım. Daha sonra kodda aşağıdaki şekilde yaptım, ethernet kablosunu pc'den çıkarıp module taktım kodları yükledim. Bu şekilde aynı networkte olmuş olmuyor muyum ?
    uip_ipaddr(ipaddr, 192, 168, 1, 104);
    uip_sethostaddr(ipaddr);
    /* Yonlendirici ip*/
    uip_ipaddr(ipaddr, 192, 168, 255, 255);
    uip_setdraddr(ipaddr);
    /* Netmask */
    uip_ipaddr(ipaddr, 255, 255, 0, 0);
    uip_setnetmask(ipaddr);

bsenguler

Bilgisayarınız modeme bağlı iken çalışıyorsa, modülünüzde çalışması lazım.

navy

Alıntı yapılan: robikod - 18 Aralık 2018, 15:49:00Merhaba, stm32 ile eternet üzerinden iletişim kurmaya çalışıyorum.Bu kodları referans aldım (https://github.com/xukai871105/uip_freemodbus_tcp/tree/master/User)
Bunun için eternet modülü olarak enc28j60 modülünü seçtim.  (SPI'ın doğru çalışıp çalışmadığını ARP paketi yollayarak test ettim doğru çalışıyordu)
Bilgisayarı ethernet girişinden modüle bağladım ve bilgisayarımın ipsini referans aldım.

Init ayarlarını yaptıktan sonra while içerisindeki kodlar şu şekilde:


while (1)
    {

        // serialprint("hi");
        // Delay(5);
        eMBPoll();
        led_poll();

        /* 从网络设备读取一个IP包,返回数据长度 */
        uip_len = tapdev_read();
        serialprint("tap_dev= %d\n", uip_len);

        /* 收到数据	*/
        if (uip_len > 0)
        {
            /* 处理IP数据包 */
            if (BUF->type == htons(UIP_ETHTYPE_IP))
            {
                uip_arp_ipin();
                uip_input();

                if (uip_len > 0)
                {
                    uip_arp_out();
                    tapdev_send();
                }
            }
            /* 处理ARP报文 */
            else if (BUF->type == htons(UIP_ETHTYPE_ARP))
            {
                uip_arp_arpin();
                if (uip_len > 0)
                {
                    tapdev_send();
                }
            }
        }

        /* 0.5秒定时器超时 */
        if (timer_expired(&periodic_timer))
        {
            timer_reset(&periodic_timer);

            // GPIOD->ODR ^= GPIO_Pin_3;

            /* 处理TCP连接, UIP_CONNS缺省是10个 */
            for (uint8_t i = 0; i < UIP_CONNS; i++)
            {
                /* 处理TCP通信事件 */
                uip_periodic(i);
                if (uip_len > 0)
                {
                    uip_arp_out();
                    tapdev_send();
                }
            }

Sorun burada şu ki, uip_len = tapdev_read(); her zaman 0 dönüyor. Bunun sebebi de enc28j60.c kodlarımdaki şu fonksiyonda if ((rxstat & 0x80)==0) kısmının her zaman 1 dönüp len=0 olması. Bu sorunu nasıl çözebilirim ? Yardımcı olursanız çok sevinirim.

unsigned int enc28j60_packet_receive(unsigned char *packet, unsigned int maxlen)
    {
    
        unsigned int rxstat;
        unsigned int len;
    
        if (enc28_read(EPKTCNT) == 0)
        {
            return (0);
            // GPIO_SetBits(GPIOE, GPIO_Pin_9);
        }
    
        enc28_write(ERDPTL, (next_pack_ptr));
        enc28_write(ERDPTH, (next_pack_ptr) >> 8);
    
        next_pack_ptr = enc28_readOp(ENC28J60_READ_BUF_MEM, 0);
        next_pack_ptr |= enc28_readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
    
        len = enc28_readOp(ENC28J60_READ_BUF_MEM, 0);
        len |= enc28_readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
    
        len -= 4;
    
        rxstat = enc28_readOp(ENC28J60_READ_BUF_MEM, 0);
        rxstat |= enc28_readOp(ENC28J60_READ_BUF_MEM, 0) << 8;
    
        enc28_writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
    
        if (len > maxlen - 1)
        {
            len = maxlen - 1;
        }
    
        if ((rxstat & 0x80) == 0)
        {
    
            GPIO_SetBits(GPIOE, GPIO_Pin_9);
    
            len = 0;
        }
        else
        {
    
            enc28_readBuffer(packet, len);
        }
    
        enc28_write(ERXRDPTL, (next_pack_ptr));
        enc28_write(ERXRDPTH, (next_pack_ptr) >> 8);
    
        enc28_writeOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
    
        return (len);


merhaba aynı problem bendede var bu sorunu çözdünüz mü

robikod

Alıntı yapılan: navy - 29 Ocak 2020, 10:27:06merhaba aynı problem bendede var bu sorunu çözdünüz mü
kod kütüphanesini değiştirdim. Başka bir yerden uip kütüphanesi aldım komple değiştirdim düzeldi