Forum: Mikrocontroller und Digitale Elektronik LWIP möchte kein TCP senden


von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Hallo,
da bin ich grade dabei auf dem MIPS TTL Rechner die Lankarte in Betrieb 
zu nehmen.
Aber noch nicht in echter Hardware, sondern im Emulator und auf dem 
FPGA.

So weit funktioniert das auch schon: es ARPed zurück per LWIP und auch 
Pings über ICMP kommen zurück.

Nur senden von TCP Paketen geht garnicht.
Weil ARP und ICMP (UDP) funktionieren gehe ich jetzt nicht von einem 
Fehler in der Eigenbau LANkarte aus, denn selbst der Treiber bekommt vom 
LWIP keinen call mal zu senden.

Der LWIP läuft grade mit NO_SYS = 1 und daher der callback API.

Ich hab hier einen TCP Listener erstellt:
1
struct tcp_pcb* testpcb;
2
3
void tcp_echo_init(void){
4
  
5
  uprintf(1, "creating tcp echo test\r\n");
6
  testpcb = tcp_new();
7
  uprintf(1, "testpcb: %08X\r\n", (uint32_t)testpcb);
8
  
9
  tcp_err(testpcb, tcpErrorHandler);
10
    tcp_recv(testpcb, tcpRecvCallback);
11
    tcp_sent(testpcb, tcpSentCallback);
12
    
13
    static ip4_addr_t ip;
14
    IP4_ADDR(&ip, 192,168,178,220);
15
    
16
    err_t err;
17
    err = tcp_bind(testpcb, &ip, 666);
18
    uprintf(1, "TCP Bind Err: %i\r\n", err);
19
    
20
    if (ERR_OK != err){
21
      return;
22
    }
23
    
24
    // The tcp_listen() function returns a new connection identifier, 
25
    // and the one passed as an argument to the function will be deallocated.
26
    testpcb = tcp_listen_with_backlog_and_err(testpcb, 1, &err);
27
    uprintf(1, "testpcb: %08X\r\n", (uint32_t)testpcb);
28
    uprintf(1, "TCP Listen Err: %i\r\n", err);
29
    if (NULL == testpcb){
30
      return;
31
    }
32
    
33
    tcp_accept(testpcb, tcpAcceptCallback);
34
    
35
}
36
37
err_t tcpAcceptCallback(void *arg, struct tcp_pcb *newpcb, err_t err){
38
  
39
  (void)arg;
40
    (void)err;
41
    (void)newpcb;
42
    uprintf(1, "newpcb: %08X\r\n", (uint32_t)testpcb);
43
    uprintf(1, "TCP Accept Err: %i\r\n", err);
44
    echopcb = newpcb;
45
}

Die Init läuft ohne Fehler durch und der LWIP erkennt auch ein 
einkommendes SYN Paket auf dem passenden Port.
Nur wird kein SYN+ACK Paket zurückgeschickt.

Logausgabe:
1
init lancard err = 0
2
init lwip
3
done
4
netif status changed 192.168.178.220
5
creating tcp echo test
6
testpcb: 004097A8
7
tcp_bind: bind to port 666
8
TCP Bind Err: 0
9
testpcb: 004093DC
10
TCP Listen Err: 0
11
dhcp_coarse_tmr()
12
dhcp_coarse_tmr()
13
lancard: send a packetwritten err = 0  <- gesendete ARP Antwort
14
15
TCP header:
16
+-------------------------------+
17
|    46904      |      666      | (src port, dest port)
18
+-------------------------------+
19
|           2992306377          | (seq no)
20
+-------------------------------+
21
|           0000000000          | (ack no)
22
+-------------------------------+
23
| 10 |   |000010|     29200     | (hdrlen, flags (SYN 
24
), win)
25
+-------------------------------+
26
|    0xe4cb     |         0     | (chksum, urgp)
27
+-------------------------------+
28
tcp_input: packed for LISTENing connection.
29
TCP connection request 46904 -> 666.
30
tcp_parseopt: MSS
31
tcp_parseopt: other
32
tcp_parseopt: other
33
tcp_parseopt: NOP
34
tcp_parseopt: other
35
tcp_slowtmr: processing active pcb
36
tcp_slowtmr: polling application
37
tcp_slowtmr: processing active pcb
38
<noch mehr timerkrams>
39
tcp_slowtmr: polling application
40
tcp_slowtmr: processing active pcb
41
tcp_slowtmr: removing pcb stuck in SYN-RCVD
42
tcp_pcb_purge
43
tcp_pcb_purge: not all data sent
44
TCP header:
45
+-------------------------------+
46
|    46904      |      666      | (src port, dest port)
47
+-------------------------------+
48
|           2992306377          | (seq no)
49
+-------------------------------+
50
|           0000000000          | (ack no)
51
+-------------------------------+
52
| 10 |   |000010|     29200     | (hdrlen, flags (SYN 
53
), win)
54
+-------------------------------+
55
|    0xe3ca     |         0     | (chksum, urgp)
56
+-------------------------------+
57
tcp_input: packed for LISTENing connection.
58
TCP connection request 46904 -> 666.
59
tcp_parseopt: MSS
60
tcp_parseopt: other
61
tcp_parseopt: other
62
tcp_parseopt: NOP
63
tcp_parseopt: other
64
tcp_slowtmr: processing active pcb
65
tcp_slowtmr: polling application
66
tcp_slowtmr: processing active pcb
67
tcp_slowtmr: polling application
68
<noch mehr timerkrams>
69
tcp_slowtmr: removing pcb stuck in SYN-RCVD
70
tcp_pcb_purge
71
tcp_pcb_purge: not all data sent
72
dhcp_coarse_tmr()
73
TCP header:
74
+-------------------------------+
75
|    46904      |      666      | (src port, dest port)
76
+-------------------------------+
77
|           2992306377          | (seq no)
78
+-------------------------------+
79
|           0000000000          | (ack no)
80
+-------------------------------+
81
| 10 |   |000010|     29200     | (hdrlen, flags (SYN 
82
), win)
83
+-------------------------------+
84
|    0xe1d2     |         0     | (chksum, urgp)
85
+-------------------------------+
86
tcp_input: packed for LISTENing connection.
87
TCP connection request 46904 -> 666.
88
tcp_parseopt: MSS
89
tcp_parseopt: other
90
tcp_parseopt: other
91
tcp_parseopt: NOP
92
tcp_parseopt: other

Am Ende gibts immer ein "tcp_slowtmr: removing pcb stuck in SYN-RCVD"
Aber wieso das da höngen bleibt kann ich jetzt nicht erahnen.
Hat da wer eine Idee?

Einen Hinweis auf ein Problem gibts wenn ich direkt tcp_connect() 
aufrufe um was zu senden:
1
init lancard err = 0
2
init lwip
3
done
4
netif status changed 192.168.178.220
5
testpcb: 004097A8
6
tcp_connect to port 80
7
connect err: -4

Laut err_t gilt:  ERR_RTE = -4 -> Routing problem
Ja aber was denn fürn Routing problem?
Seine eigene IP+Subnetz+Gateway hat er.
Er soll direkt zu einer IP Verbinden.

Keine Route möglich klingt ja erstmal nach "kein netif anwesend"
Ist es aber, sonst würd ja ICMP nicht gehen:
1
ip4_addr_t ipaddr;
2
    ip4_addr_t mask;
3
    ip4_addr_t gw;
4
    
5
    IP4_ADDR(&ipaddr, 192, 168, 178, 220);
6
  IP4_ADDR(&mask, 255, 255, 255, 0);
7
  IP4_ADDR(&gw, 192, 168, 178, 1);
8
    
9
  netif_add(&netif, &ipaddr, &mask, &gw, NULL, netif_myinit, netif_input);
10
  netif.name[0] = 'e';
11
  netif.name[1] = '0';
12
  netif_set_status_callback(&netif, netif_status_callback);
13
  netif_set_default(&netif);
14
  netif_set_up(&netif);
Einen ARP sendet er erst garnicht, also ist es was davor.

von Johannes S. (Gast)


Lesenswert?

habe deinen Codeschnipsel mal in mein Mbed Target mit F407 reingeworfen, 
funktioniert. Beim bind benutze ich allerdings die IPAddrAny, also
1
IP4_ADDR(&ip, 0,0,0,0);

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Danke fürs ausprobiere!

Aber jetzt hab ichs gefunden:
Der Eigenbau MIPS Emulator hat ja einen GDB Server.
Nur kann keine GDB GUI so wirklich mit dem MIPS GDB umgehen, weil dieser 
die Registerausgabe völlig anders Formatiert als zB x86 und ARM GDB.
-> Beitrag "Re: Space Age 2 der 32Bit MIPS Rechner in TTL"

Also auf der Konsole selber rumgetrommelt und mal nachgesehen was in 
tcp_connect() so passiert.
Er will dort zuerst ein netif suchen, aber bekommt NULL.
Wieso bekommt er NULL? Der links ist nicht up.

Also mal in den Init Code gucken.
Da fehlt doch echt ein netif_set_link_up(&netif);
Kopf -> Tisch.

Die TTL Lankarte hat nämlich keine Link Erkennung, also muss ich den 
immer up setzen.
Denn blöderweise habe ich keinen PHY gefunden bei der ich bei 10MBit 
eine der LEDs auf LINK setzen kann.
Die 100mbit LED kann ich ja nicht auswerten.
Per STM32L0 eine config per MDIO reinschieben sehe ich schon als 
geschummelt an. Vor allem weil das dann mal eben die Rechenleistung des 
TTL MIPS ver x-facht.

Aber komisch, dass damit ARP und ICMP/Ping gingen.

von Johannes S. (Gast)


Lesenswert?

gut, das habe ich mir bei dem Test einfach gemacht: das Init des netif 
hat das OS schon gemacht, ich habe deinen Code nur zusätzlich 
reingepackt. Ziemlich dirty, aber selbst das funktioniert :)
ICMP ist ja eine Etage tiefer, da fragt lwip wohl garnicht ob das if up 
ist? Aber korrekterweise sollte es ja nicht antworten.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Bei meinen ARM Projekten ist der link up/down Aufruf im Handler vom PHY 
IRQ.
Per MDIO lässt sich son PHY so einstellen, dass ern IRQ Pin auf low 
zieht und dann kann man per MDIO nachgucken warum.
Das wird mbed dann auch so machen.

Ich überlege echt ob ich Bitbang MDIO mache, das wären nur 4 zusätzliche 
ICs.
Nur die bidirektionaöität über die 3,3V <-> 5V Grenze wird dann etwas 
nervig.

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.