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
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 | }
|
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
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, ...).
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 .
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
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.
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 | }
|
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 ?
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.
♪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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.