Forum: Mikrocontroller und Digitale Elektronik stm32f4xx lan8720 uip


von dicovery (Gast)


Lesenswert?

guten Tag,
gibt es denn irgendwo ein example für den stm32f4 und Lan8720 mit 
uip,was ich bisher gesehen hab ist alles mit Lwip.

vielleicht kann mir jemand weiterhelfen
mfg

von dicovery (Gast)


Lesenswert?

Ist denn das soweit richtig
anstatt: uip_len = enc28j60PacketReceive(UIP_CONF_BUFFER_SIZE, 
&uip_buf[0]);

STM32eth: ETH_HandleRxPkt(uip_buf);
1
  //uip_len = enc28j60PacketReceive(UIP_CONF_BUFFER_SIZE, &uip_buf[0]); // Paket aus dem ENC28J60 auslesen und in den Buffer zwischenspeichern
2
 
3
//uip_len = ETH_HandleRxPkt(uip_buf);
4
     
5
    if(uip_len > 0) // Falls ein Paket empfangen wurde
6
      { 
7
      
8
9
        
10
       if(BUF->type == htons(UIP_ETHTYPE_IP)) // Falls IP-Paket empfangen wurde
11
        {
12
13
        uip_arp_ipin(); // IP-Paket empfangen und ARP-Tabelle aktualisieren
14
        uip_input(); // Prozesse für die Abarbeitung des Paketes starten
15
  
16
          if(uip_len > 0) // Falls Paketlänge größer 0 ist
17
              {
18
              uip_arp_out(); // ARP-Paket schicken und ausfragen, welchen Client diese IP-Pakete gehören
19
              TransmitPacket(); // IP-Pakete dem Client schicken  
20
           //enc28j60PacketSend(uip_len,uip_buf); // IP-Pakete dem Client schicken
21
            }
22
              } 
23
          
24
        else if(BUF->type == htons(UIP_ETHTYPE_ARP)) // Falls ARP-Paket empfangen wurde
25
            {
26
        uip_arp_arpin(); // ARP-Paket in den uIP-Stack lesen 
27
  
28
         if(uip_len > 0) // Falls der Inhalt des ARP-Pakets nicht 0 ist
29
          {
30
            TransmitPacket(); // Auf ARP-Paket vom Client antworten
31
          //enc28j60PacketSend(uip_len,uip_buf); // IP-Pakete dem Client schicken
32
          }
33
              }
34
      } 
35
      
36
      else if(timer_expired(&periodic_timer)) // Falls Periodentimer abgelaufen ist, Paket-Weiterleitung
37
      {
38
39
      timer_reset(&periodic_timer); // Periodentimer reseten
40
              
41
        for(n = 0; n < UIP_CONNS; n++)  // Für alle aktiven TCP-Verbindungen 
42
         {
43
         uip_periodic(n); // Jeweilige TCP-Verbindung abfragen ob noch Pakete für diese Verbindng vorhanden sind
44
  
45
           if(uip_len > 0) // Falls welche vorhanden sind
46
            {
47
              uip_arp_out(); // ARP-Paket schicken und ausfragen, welchen Client diese Pakete gehören
48
              TransmitPacket(); // Pakete dem Client schicken
49
            //enc28j60PacketSend(uip_len,uip_buf); // IP-Pakete dem Client schicken
50
            }
51
               }
52
53
     if(timer_expired(&arp_timer)) // Falls ARP-Timer abgelaufen ist, Eintrag in der ARP-Tabelle nicht mehr aktuell
54
      {
55
56
    
57
      timer_reset(&arp_timer); // ARP-Timer reseten
58
      uip_arp_timer(); // Alte Einträge in der ARP-Tabelle löschen
59
          }
60
       }
61
62
63
64
65
void TransmitPacket(void)
66
{
67
      int i;
68
     u8 data[1500];
69
70
      // Copy the header portion part
71
      for(i=0; i < (UIP_LLH_LEN + 40); ++i) {
72
         data[i] =  uip_buf[i];
73
      }
74
75
      // Copy the data portion part
76
      for(; i < uip_len; ++i) {
77
          data[i] =  uip_appdata[i - UIP_LLH_LEN - 40 ];
78
      }
79
80
      ETH_HandleTxPkt(data,uip_len);
81
}

von dicovery (Gast)


Lesenswert?

ich bekomme das nicht zum laufen mit dem Lan8720
ETH_HandleRxPkt ETH_HandleTxPkt gibst in dem Treiber nicht vom f4eth.

Könnte mir denn wer weiterhelfen
mfg

von dicovery (Gast)


Lesenswert?

kann mir hier niemand weiterhelfen

von nosilent (Gast)


Lesenswert?

Der Lan8720 ist ja ein (R)MII PHY, im Gegensatz zum ENC und die haben 
komplett verschiedene Schnittstellen.
Klappt den die Initialisierung vom Lan8720 ? Schau mal ob du die 
Register vom PHY auslesen kannst...

Warum willst du eigt. den uip verwenden?
Ich habe auf dem STM32F4xx (genauer uC fällt mir jetzt nicht ein) die 
Performance gemessen und ich würde her zum LwIP tendieren. Ist zwar 
größer, kann dafür mehr und man kann den wirklich gut optimieren (in 
Bezug auf Datendurchsatz, Anzahl der TCP/UDP Verbindungen, Latenz, ...).

von dicovery (Gast)


Lesenswert?

Die Initialisierung vom Lan8720 klappt einwandfrei.

ich wollte gerne den uip weiter verwenden da hab ich nun meine 
verschiedenen Webpage .

Beim Lwip muss ich ja nun wieder komplett von vorne anfangen.

Der ETH vom stm32_f4x7 läuft ja im DMA.

Es muss doch eine Schnittstelle geben um: uip_len = 
enc28j60PacketReceive(UIP_CONF_BUFFER_SIZE, &uip_buf[0]);

daran scheiterte ich .

von dicovery (Gast)


Lesenswert?

Hallo,
gibt es denn garkein beispiel mit lan8720 und uip???

von Little B. (lil-b)


Lesenswert?

Du kannst vieleicht etwa sowas schreiben:
1
uint16_t stm32eth_Receive (uint8_t* pbuf) {
2
  uint8_t i;
3
  stm32eth_ReceiveDescriptor_t *pdesc;
4
5
  // get the least recent buffer
6
  pdesc = (stm32eth_ReceiveDescriptor_t*)(ETH->DMACHRDR);
7
  // and check all buffers to the most recent buffer
8
  for (i=0; i<STM32ETH_NR_OF_INPUT_FRAMES; i++) {
9
    if (pdesc->RDES0.bits.Own == 0) {
10
      // cpu owns this descriptor, process it!
11
      memcpy(pbuf, pdesc->Buffer1, pdesc->RDES1.bits.TransmitBuffer1Size);
12
      // return buffer to hardware
13
      pdesc->RDES0.bits.Own = 1;
14
      // activate dma, if it was suspended
15
      ETH->DMARPDR = 0xFFFFFFFF;
16
      return pdesc->RDES1.bits.TransmitBuffer1Size;
17
    }
18
    pdesc = (stm32eth_ReceiveDescriptor_t*)(pdesc->NextDescriptor);
19
  }
20
  return 0;
21
}

Dies impliziert allerdings, dass du deine Buffer entsprechend 
initialisiert hast. Zum Beispiel so:
1
  ETH->DMARDLAR = (uint32_t)stm32eth_ReceiveDescriptor;    // first receive descriptor
2
  // initialization of receive buffers
3
  stm32eth_ReceiveDescriptor[0].RDES0.u32 = 0;
4
  stm32eth_ReceiveDescriptor[0].RDES0.bits.Own = 1;
5
  stm32eth_ReceiveDescriptor[0].RDES1.u32 = 0;
6
  stm32eth_ReceiveDescriptor[0].RDES1.bits.SecondAddressChained = 1;
7
  stm32eth_ReceiveDescriptor[0].RDES1.bits.TransmitBuffer1Size = 1518;
8
  for (i=1; i<STM32ETH_NR_OF_INPUT_FRAMES; i++)
9
    stm32eth_ReceiveDescriptor[i] = stm32eth_ReceiveDescriptor[0];
10
11
  for (i=0; i<STM32ETH_NR_OF_INPUT_FRAMES; i++) {
12
    // for easier access of transmit buffers, receive buffers are located behind transmit buffers
13
    stm32eth_ReceiveDescriptor[i].Buffer1 = stm32eth_EthernetFrames[i];
14
    stm32eth_ReceiveDescriptor[i].NextDescriptor = (uint8_t*)(stm32eth_ReceiveDescriptor + i + 1);
15
  }
16
  // last descriptor must point back to first descriptor!
17
  stm32eth_ReceiveDescriptor[i-1].NextDescriptor = (uint8_t*)(stm32eth_ReceiveDescriptor);

mit
1
/**
2
 * @brief  DMA information for receiving frames
3
 * @ingroup  Drivers
4
 * @details
5
 * The dedicated DMA for transferring frames from external phy to memory needs
6
 * this struct as information source of the frame location in RAM. After
7
 * receiving the frame, status and length information are stored in it. Refer to
8
 * STM32F4 Family Data Sheet page 961 and following for more information.
9
 */
10
typedef struct __attribute__ ((__packed__)) {
11
  union {
12
    struct {
13
      uint8_t PayloadChecksumError:1;
14
      uint8_t CrcError:1;
15
      uint8_t DribbleBitError:1;
16
      uint8_t ReceiveError:1;
17
      uint8_t ReceiveWatchdogTimeout:1;
18
      uint8_t FrameType:1;
19
      uint8_t LateCollision:1;
20
      uint8_t IpHeaderChecksumError:1;
21
      uint8_t LastDescriptor:1;
22
      uint8_t FirstDescriptor:1;
23
      uint8_t VlanTag:1;
24
      uint8_t OverflowError:1;
25
      uint8_t LengthError:1;
26
      uint8_t SourceAddressFilterFail:1;
27
      uint8_t DescriptorError:1;
28
      uint8_t ErrorSummary:1;
29
      uint16_t FrameLength:14;
30
      uint8_t DestinationAddressFIlterFail:1;
31
      uint8_t Own:1;
32
    } bits;
33
    uint32_t u32;
34
  } RDES0;
35
  union {
36
    struct {
37
      uint16_t TransmitBuffer1Size:13;
38
      uint8_t reserved1:1;
39
      uint8_t SecondAddressChained:1;
40
      uint8_t ReceiveEndOfRing:1;
41
      uint16_t TransmitBuffer2Size:13;
42
      uint8_t reserved2:2;
43
      uint8_t DisableInterruptOnCompletion:1;
44
    } bits;
45
    uint32_t u32;
46
  } RDES1;
47
  uint8_t *Buffer1;
48
  uint8_t *NextDescriptor;
49
  union {
50
    struct {
51
      uint8_t IpPayloadType:3;
52
      uint8_t IpHeaderError:1;
53
      uint8_t IpPayloadError:1;
54
      uint8_t IpChecksumBypassed:1;
55
      uint8_t Ipv4PacketReceived:1;
56
      uint8_t Ipv6PacketReceived:1;
57
      uint8_t PtpMessageType:4;
58
      uint8_t PtpFrametype:1;
59
      uint8_t PtpVersion:1;
60
      uint32_t reserved:18;
61
    } bits;
62
    uint32_t u32;
63
  } RDES4;
64
  uint32_t reserved;
65
  uint32_t ReceiveFrameTimestampLow;
66
  uint32_t ReceiveFrameTimestampHigh;
67
}stm32eth_ReceiveDescriptor_t;
68
69
/**
70
 * @brief  DMA receive descriptors
71
 * @ingroup  Drivers
72
 * @details
73
 * Each input frame buffer has its DMA receive descriptor. These descriptors are
74
 * chained as a ring buffer.
75
 */
76
stm32eth_ReceiveDescriptor_t stm32eth_ReceiveDescriptor[STM32ETH_NR_OF_INPUT_FRAMES];
77
78
/**
79
 * @brief  Ethernet frame buffers
80
 * @ingroup  Drivers
81
 * @details
82
 * This is the static allocation of all receive buffers. Each buffer
83
 * can store one standard Ethernet frame, which has 1500 bytes Data and 18 bytes
84
 * mac information.
85
 */
86
uint8_t stm32eth_EthernetFrames[STM32ETH_NR_OF_INPUT_FRAMES][1518];

und
1
#define STM32ETH_NR_OF_INPUT_FRAMES      10

Dies ist nur ein Beispiel, eine Variation dessen, was ich mit meinem 
selbst geschriebenen TCP/IP Stack verwende. Alle RTOS Sachen sind 
hoffentlich drausen. Ich übernehme keinerlei Haftung für diesen Code und 
behaupte auch nicht, dass er funktioniert. Bei Fehlern darf gerne selber 
nachgedacht werden. Supportanfragen werden in Rechnung gestellt.

: Bearbeitet durch User
von dicovery (Gast)


Angehängte Dateien:

Lesenswert?

anbei die Treiber

von dicovery (Gast)


Lesenswert?

scheint wohl niemand mit zuarbeiten uip stm32f4

von itzztitz (Gast)


Lesenswert?

nimm aus einem beispiel mit LwIP den ethernet treiber heraus und nutze 
die transmit/Receive funktionen bei dir

der empfang/ senden der daten ist dann das selbe


ich würde dir auch empfehlen  den LwIP zu nutzen...
mit einem freeRTOS zusammen hast da ordetlich luft
zb auch für TLS verbindungen


schnapp dir ein RTOS LwIP demoprojekt und portiere deine kleine seite 
und fetrig.

von dicovery (Gast)


Angehängte Dateien:

Lesenswert?

wäre das so richtig wie von ihnen vorgeschlagen.
1
 
2
uip_len = ethernetif_input(uip_buf);
3
     
4
    if(uip_len > 0) // Falls ein Paket empfangen wurde
5
      { 
6
      
7
8
        
9
       if(BUF->type == htons(UIP_ETHTYPE_IP)) // Falls IP-Paket empfangen wurde
10
        {
11
12
        uip_arp_ipin(); // IP-Paket empfangen und ARP-Tabelle aktualisieren
13
        uip_input(); // Prozesse für die Abarbeitung des Paketes starten
14
  
15
          if(uip_len > 0) // Falls Paketlänge größer 0 ist
16
              {
17
              uip_arp_out(); // ARP-Paket schicken und ausfragen, welchen Client diese IP-Pakete gehören
18
              low_level_output(); // IP-Pakete dem Client schicken  
19
           //enc28j60PacketSend(uip_len,uip_buf); // IP-Pakete dem Client schicken
20
            }
21
              } 
22
          
23
        else if(BUF->type == htons(UIP_ETHTYPE_ARP)) // Falls ARP-Paket empfangen wurde
24
            {
25
        uip_arp_arpin(); // ARP-Paket in den uIP-Stack lesen 
26
  
27
         if(uip_len > 0) // Falls der Inhalt des ARP-Pakets nicht 0 ist
28
          {
29
            low_level_output(); // Auf ARP-Paket vom Client antworten
30
          //enc28j60PacketSend(uip_len,uip_buf); // IP-Pakete dem Client schicken
31
          }
32
              }
33
      } 
34
      
35
      else if(timer_expired(&periodic_timer)) // Falls Periodentimer abgelaufen ist, Paket-Weiterleitung
36
      {
37
38
      timer_reset(&periodic_timer); // Periodentimer reseten
39
              
40
        for(n = 0; n < UIP_CONNS; n++)  // Für alle aktiven TCP-Verbindungen 
41
         {
42
         uip_periodic(n); // Jeweilige TCP-Verbindung abfragen ob noch Pakete für diese Verbindng vorhanden sind
43
  
44
           if(uip_len > 0) // Falls welche vorhanden sind
45
            {
46
              uip_arp_out(); // ARP-Paket schicken und ausfragen, welchen Client diese Pakete gehören
47
              low_level_output(); // Pakete dem Client schicken
48
            //enc28j60PacketSend(uip_len,uip_buf); // IP-Pakete dem Client schicken
49
            }
50
               }
51
52
     if(timer_expired(&arp_timer)) // Falls ARP-Timer abgelaufen ist, Eintrag in der ARP-Tabelle nicht mehr aktuell
53
      {
54
55
    
56
      timer_reset(&arp_timer); // ARP-Timer reseten
57
      uip_arp_timer(); // Alte Einträge in der ARP-Tabelle löschen
58
          }
59
       }

von dicovery (Gast)


Lesenswert?

itzztitz schrieb:
> nimm aus einem beispiel mit LwIP den ethernet treiber heraus und
> nutze
> die transmit/Receive funktionen bei dir
>
> der empfang/ senden der daten ist dann das selbe
>
> ich würde dir auch empfehlen  den LwIP zu nutzen...
> mit einem freeRTOS zusammen hast da ordetlich luft
> zb auch für TLS verbindungen
>
> schnapp dir ein RTOS LwIP demoprojekt und portiere deine kleine seite
> und fetrig.

welche sind das

kann mir denn niemand hier weiterhelfen ?

von dicovery (Gast)


Lesenswert?

es gibt anscheinend Niemand der den uip mit stm32f4  nutzt. sehr schade

von ♪Geist (Gast)


Lesenswert?

dicovery schrieb:
> es gibt anscheinend Niemand der den uip mit stm32f4  nutzt. sehr schade

Ja, wozu auch, wenn LwIP läuft? Ich meine uIP ist zwar schmaller, aber 
LwIP bitet mehr Performance und ist ST aus gleich portiert.

von dicovery (Gast)


Lesenswert?

♪Geist schrieb:
> dicovery schrieb:
> es gibt anscheinend Niemand der den uip mit stm32f4  nutzt. sehr schade
>
> Ja, wozu auch, wenn LwIP läuft? Ich meine uIP ist zwar schmaller, aber
> LwIP bitet mehr Performance und ist ST aus gleich portiert.

ja das ja alles gut und schön aber nirgends gibs ein Beispiel wenn ich 
zum Beispiel auf der Webseite ein button drücke led ein das mir ein Bild 
angezeigt wird led ein.

wo gibst solch ein Beispiel

von Helmut (Gast)


Lesenswert?

itzztitz schrieb:
> nimm aus einem beispiel mit LwIP den ethernet treiber heraus und
> nutze die transmit/Receive funktionen bei dir
> der empfang/ senden der daten ist dann das selbe
>


Ich bin nicht vom Fach,dennoch habe ich im Lwip1.4 mal geschaut nach der 
Sende/Empfangs Funktion aber nicht gefunden.

Der TO hat offenbar Probleme das umzusetzen wie vorgeschlagen, dennoch 
wäre es vielleicht Hilfreich ihm zu zeigen wo diese Funktion sind.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.