Forum: Mikrocontroller und Digitale Elektronik ENC28J60 myEthernet mit NeMo Stack Probleme


von Oliver R. (koreif)


Lesenswert?

Hallo, ich bedanke mich schonmal im Voraus für eure Hilfe.
Zu meinem Problem. Ich möchte über ein myEthernet Daten an einen PC 
senden. Dafür hatte ich vor die NeMo-Stack Bibliothek zu verwenden. Mit 
dieser habe ich in Avr Studio ein neues Projekt erstellt. Dort ist das 
Problem, das der Code anscheinend irgendwie eine Mischung aus C und C++ 
ist.
In der net.h steht in der Zeile 183.
1
 extern uint8_t EEMEM  eeIpAddr[4];
Was folgende Fehlermeldung erzeugt:
expected '=', ',', ';', 'asm' or '__attribute__' before 'eeIpAddr'
Ich finde leider nicht die C Syntax um die Variable im EEPROM zu 
speichern.

Nun zum nächsten Problem. Ich habe in meiner main folgenden Interrupt:
1
 ISR ( USART0_RX_vect )
2
{
3
  usart_new_char();
4
}
Was folgende Fehlermeldung erzeugt:
undefined reference to `usart_new_char'
Ich binde in meiner main die usart.h ein in welcher die Funktion 
deklariert ist:
1
 #define USART_NEW_CHAR()      (recv_buf.writ != recv_buf.read)

Usart.c:
1
 void usart_new_char(void)
2
{
3
  recv_buf.buf[recv_buf.writ] = USART_RECV_CHAR();
4
  if(++recv_buf.writ >= BUFLEN) recv_buf.writ = 0;
5
}

Ich danke euch für eure Zeit.

von Stefan F. (Gast)


Lesenswert?

Oliver R. schrieb:
> usart_new_char()
> USART_NEW_CHAR()

Groß/Klein Schrift ist dem C Compiler nicht egal.

> EEMEM
> Ich finde leider nicht die C Syntax um die Variable im EEPROM zu
> speichern.

Bedenke, dass man bei AVR das EEprom nicht einfach wie RAM adressieren 
kann. Da muss man den Umweg über Hilfsfunktionen nehmen. Ist alles dort 
erklärt:

Siehe 
https://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html

von Oliver R. (koreif)


Angehängte Dateien:

Lesenswert?

Danke Steffan, das hat die Fehler behoben.
Das mit der groß/klein Schrift war schon peinlich^^

Ich habe immer noch paar Fehler wo ich echt nicht verstehe wo das 
Problem ist.
1
tmp = tcpOpen( remoteIp , 1397 , 1234 , NULL ); // Verbidung oeffnen
erzeugt die Fehlermeldung: undefined reference to `tcpOpen'
Obwohl tcpOpen() mir von der DIE vorgeschlagen wird.
In der main wird net_tcp.h eingebunden
1
 #include "net_tcp.h"
Diese enthält:
1
 uint8_t tcpOpen(uint8_t * ipAddr, uint16_t remotePort, uint16_t localPort, connHandler handler);
Die implementierung in net_tcp.c sieht folgendermaßen aus:
1
 uint8_t tcpOpen(uint8_t * ipAddr, uint16_t remotePort, uint16_t localPort, connHandler handler)
2
{
3
  uint8_t * mac;
4
  uint8_t ind;
5
6
  // Prüfe, ob Verbindung bereits existiert
7
  ind = tcpGetConnHandle(myIpAddr, ipAddr, localPort, remotePort);
8
9
  if(ind != 255)
10
  {
11
    if(debugLevel & DEBUGLVL_STACK_TCP_ERROR)
12
    {
13
      usart_send_line_P(PSTR("tcpOpen: conn already exists"));
14
    }
15
    return ind;
16
  }
17
18
  // Suche nach freiem Eintrag in TCP-Verbindungsliste
19
  ind = tcpGetFreeConnEntry();
20
21
  // Kein freier Eintrag mehr vorhanden
22
  if(ind == 255)
23
  {
24
    if(debugLevel & DEBUGLVL_STACK_TCP_ERROR)
25
    {
26
      usart_send_line_P(PSTR("tcpOpen: connList full"));
27
    }
28
    return 255;
29
  }
30
  else
31
  {
32
    // MAC-Adresse zu IP-Adresse ermitteln
33
    mac = arpGetMac(ipAddr);
34
35
    tcpConnList[ind].handler = handler;
36
    tcpConnList[ind].localPort = localPort;
37
    tcpConnList[ind].remoteIp[0] = ipAddr[0];
38
    tcpConnList[ind].remoteIp[1] = ipAddr[1];
39
    tcpConnList[ind].remoteIp[2] = ipAddr[2];
40
    tcpConnList[ind].remoteIp[3] = ipAddr[3];
41
    tcpConnList[ind].remotePort = remotePort;
42
    tcpConnList[ind].closeAfterSend = 0;
43
44
    // MAC-Adresse ist noch nicht bekannt: ARP Request absetzen
45
    if(mac == NULL)
46
    {
47
      tcpConnList[ind].timer = TCP_ARP_REQUEST_TIMEOUT;
48
      tcpConnList[ind].retryCnt = 0;
49
      tcpSetConnStatus(ind, TCP_STAT_ARP_REQUEST);
50
      arpRequest(ipAddr);
51
    }
52
    // MAC-Adresse bereits bekannt: Verbindungsanfrage senden
53
    else
54
    {
55
      tcpConnList[ind].iss = tcpInitialSeqCnt;
56
      tcpConnList[ind].sndUNA = tcpConnList[ind].iss;
57
      tcpConnList[ind].sndNXT = tcpConnList[ind].iss + 1;
58
      tcpSetConnStatus(ind, TCP_STAT_SYN_SENT);
59
60
      tcpConnList[ind].timer = TCP_ACK_TIMEOUT;
61
      tcpConnList[ind].retryCnt = 0;
62
63
      // Verbindungsanfrage erstellen und senden
64
      tcpCreatePacket(&pack, mac, ipAddr, remotePort, localPort, tcpConnList[ind].iss, 0, 0, TCP_FLAGS_SYN, TCP_WINDOW_LENGTH);
65
      enc28SendPacket(pack.buf, HTONS(pack.pkt.ipArp.ip.ipLength) + 14);
66
    }
67
  }
68
69
  return ind;
70
}

Andere Funktionen tcpSend(), tcpClose(), sowie die Variable 
tcpInitialSeqCnt, aus net_tcp.h werden ebenfalls nicht gefunden obwohl 
sie von der IDE vorgeschlagen werden.

Ich bedanke mich nochmals für eure Hilfe.

von Stefan F. (Gast)


Lesenswert?

Es gibt da dreierlei Suchpfade:

- für die IDE
- für den Compiler
- für den Linker

Möglicherweise stimmen diese nicht überein.

Und dann musst du noch bedenken, dass der Compiler schon zufrieden ist, 
wenn er die Deklaration einer Funktion in einer Header Datei findet. Der 
Linker, der das ganze zu einem ausführbaren programm zusammen baut, 
braucht aber die compilierte Version der Funktion. Die findet er 
üblicherweise in einer *.o Datei die der Compiler aus einer *.c Datei 
heraus erstellt hat.

Vermutlich fehlt dir also die *.c Datei, in der die fehlende Funktion 
definiert ist. Oder sie wurde nicht compiliert, warum auch immer.

von Oliver R. (koreif)


Lesenswert?

Ok habe das Compiler Problem nun gelöst.
Lösung:
Im Projekt im "Solution Explorer" auf "Show All Files" gehen und dann 
alle Datein mit Rechtsklick über "Include To Project" zum Projekt 
hinzufügen.

Nun scheint alles zu funktionieren außer das Data Memory Usage mit 
116,2% überschritten wird.
"Data Memory Usage : 4759 bytes   116,2 % Full
Warning: Memory Usage estimation may not be accurate if there are 
sections other than .text sections in ELF file  (Memory Overflow)"

von jo mei (Gast)


Lesenswert?

Oliver R. schrieb:
> Nun scheint alles zu funktionieren außer das Data Memory Usage mit
> 116,2% überschritten wird.

Na hättste halt mal von Anfang an aufs richtige Pferd gesetzt.
Will heissen W5100 oder W5500. Dafür gibt es auch "Libs". Ist
schneller und verbraucht deutlich weniger Speicherplatz für
die Bedienung des Netzwerks da Vieles bereits im Chip abgehandelt
wird.

So gesehen ist der ENC28J60 wirklich ein Teil von vorgestern.

von Stefan F. (Gast)


Lesenswert?

1
// Die folgenden zwei defines beeinflussen maßgeblich den RAM-Verbrauch der Firmware.
2
// Diese sollten für die jeweilige Anwendung entsprechend angepasst werden, um Speicher zu sparen.
3
4
#define TCP_RXTX_BUFLEN             512         //!< Anzahl Bytes für jeweils Sende- und Empfangspuffer
5
#define TCP_MAX_CONNECTIONS         3           //!< Max. Anzahl gleichzeitig geöffneter Verbindungen

Für dein Hallo-Welt brauchst du schätzungsweise nur 50 bytes Puffer eine 
Verbindung.

von Oliver R. (koreif)


Angehängte Dateien:

Lesenswert?

Danke für eure Hilfe.

Ich habe das Problem gelöst indem ich TCP_MAX_CONNECTIONS von 3 auf 1 
reduziert habe.

Das Projekt compiliert aber leider ist mir nun aufgefallen das der 
ENC28J60 auf dem myEthernet Board nicht an dem SPI Bus angeschlossen ist 
sondern an I/O Ports (D2=SO, D3=SI, D4=SCK, D5=CS)(Schaltplan befindet 
sich im Anhang)
Der Code bleibt in der enc28j60.c in der Zeile 462 „spiWrite(ENC_SPI_RCR 
| regAddr);“ hängen. Die Funktion wird in den Zeilen 736-743 
implementiert.
Besteht die Möglichkeit auf diesen Ports ein SPI Bus zu simulieren? Hat 
dort wer Erfahrung?

Zu meiner Aufgabe:
Ich muss über ein Mikrofon Daten sammeln, mit einer ADC Auflösung von 
mindestens 12 Bit. Ich muss 40.000 Messungen die Sekunde auswerten und 
diese an einen PC übertragen. Daraus ergeben sich ca. 0,08MB/s an Daten.

Zu dem W5500:
Ich könnte noch umsteigen, aber dafür müsste ich mir sicher sein, dass 
ich das dann ohne Probleme umgesetzt bekomme. Ist es trivial die 
Bibliothek in ein Mikrokontroller-Board einzubinden.

von Stefan F. (Gast)


Lesenswert?

Ich glaube nicht, dass du diese Geschwindigkeit mit den Chips überhaupt 
erreichen kannst. Meine ähnliche Anwendung mit einem parallel 
angebundenen CP2201 kam auf 50k Byte pro Sekunde.

Mit einem Wiznet Controller stehen die Chancen viel besser.

von jo mei (Gast)


Lesenswert?

Oliver R. schrieb:
> Daraus ergeben sich ca. 0,08MB/s an Daten.

Schon anspruchsvoll.

Oliver R. schrieb:
> Zu dem W5500:
> Ich könnte noch umsteigen, aber dafür müsste ich mir sicher sein, dass
> ich das dann ohne Probleme umgesetzt bekomme.

Das geht auch nur vielleicht. Kommt sehr auf die Datenpaket-
Grösse an. Kleine Pakete über TCP ergeben eine recht niedrige
Datenrate. Die Wiznet Chips haben auch ihre Latenzzeiten und die
Übertragung per SPI will auch getan sein. Über UDP wäre es
schneller aber da müsstest du schon genau wissen was du brauchst
und was das für Risiken birgt.

Ich würde für diesen Zweck auf jeden Fall eines von den STM32
Nucleo Boards mit Ethernet Anschluss verwenden. Wenn es mehr
Boards sein sollen dann reduziert nachbauen. Oder eine
Kombination aus STM32 f407 Blackboard und Ethernet PHY zusammen-
schustern. Ist die einfachste Möglichkeit ins LAN zu kommen.

von jo mei (Gast)


Lesenswert?

Oliver R. schrieb:
> techb_schaltplan-myethernet.png

Der ATMega644 hat übrigens 3 Vcc Pins die alle weit voneinander
entfernt liegen. Deshalb braucht er auch 3 (in Worten: drei)
Abblock-Kondensatoren und nicht nur einen ärmlichen.

Wer das nicht glaubt wird bestraft und merkt es nicht mal.
Naja, vielleicht später mal ....

von Oliver R. (koreif)


Lesenswert?

Ich weiß das das myEthernet Board das nicht Schaft. Mir geht es erstmal 
darum überhaupt Daten von meinem Microcontroller an den PC zu schicken.

Kennt irgendwer eine Möglichkeit wie ich den ENC auf dem myEthernet 
Board ansprechen kann obwohl dieser nur an den I/O Ports(D2=SO, D3=SI, 
D4=SCK, D5=CS) angeschlossen ist und nicht an dem SPI Bus?

von Stefan F. (Gast)


Lesenswert?

Da musst du wohl eine soft-spi Schnittstelle implementieren. Stichwort: 
Bit banging

Ich bezweifle dass sich die Mühe für das Olle zu langsame Teil lohnt.

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.