Forum: Mikrocontroller und Digitale Elektronik STM32F4 TCP Socket mit Keil middleware


von Anderle K. (anderl)


Angehängte Dateien:

Lesenswert?

Hallo miteinander,
Ich verwende das STM32F4 discovery, middleware 7.0.0 und CMSIS 4.5.0. 
Über einen externen ADC will ich Daten mit 192kHz (24bit) samplen und 
über I2S an den uC senden. Dann will ich die Daten über einen TCP Socket 
an der PC schicken und mit Matlab weiterverarbeiten.
Um das zu 'simulieren' verwende ich gerade den DAC+Timer7+DMA+lookup 
table um einen 2kHz Sinus zu erzeugen und verbinde das Signal direkt mit 
dem ADC des uC (A0). Dort sample ich die Daten mit ca. 20kHz und schicke 
sie über DMA in ADCbuffer (32bit). Die Daten in ADCbuffer sehen dann so 
aus: 0x00000xxx.
ADCbuffer hat 500 32bit Werte. Ich benutze dann die callbacks

void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
 osSignalSet(tid_Thread_TCP, 2U);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
 osSignalSet(tid_Thread_TCP, 3U);
}

Um erst die ersten 1000 bytes zu versenden und dann die zweiten 1000 
bytes. Dafür läuft der thread TCP_thread.

  #define TCP_LENGTH 1000
  uint8_t *sendbuf1;
  uint8_t *sendbuf2;

  int Init_Thread_TCP (void) {

  tid_Thread_TCP = osThreadCreate(osThread(Thread_TCP), NULL);
  if (!tid_Thread_TCP) return(-1);

  return(0);
}

void Thread_TCP (void const *argument) {

  while (1) {

 osSignalWait(2U, osWaitForever);    // Wait for signal
 while (!netTCP_SendReady (tcp_sock)) {}

 sendbuf1 = netTCP_GetBuffer (TCP_LENGTH);
 memcpy (sendbuf1, &ADCBuffer[0], TCP_LENGTH);
 netTCP_Send(tcp_sock,sendbuf1,TCP_LENGTH*sizeof(uint8_t));

osSignalWait(3U, osWaitForever);    // Wait for signal

 while (!netTCP_SendReady (tcp_sock)) {}
 sendbuf2 = netTCP_GetBuffer (TCP_LENGTH);
 memcpy (sendbuf2, &ADCBuffer[TCP_LENGTH/4], TCP_LENGTH);
 netTCP_Send (tcp_sock, sendbuf2, TCP_LENGTH*sizeof(uint8_t));
  }

In Matlab überspringe ich dann die Nullen und setze die bytes wieder 
zusammen. Ich erhalte einen Sinus, allerdings weist dieser an 
verschiedenen Stellen Phasensprünge auf (Anhang). Ich denke dass das 
daran liegt, das der TCP socken zu lange braucht um wieder bereit zu 
sein und der buffer ADCbuffer dann überläuft.
Meinen Fragen daher:
Kann es sein dass die TCP Verbindung zu langsam ist? Ich sample ja nur 
mit 20kHz. Später will ich mit mindestens 200kHz samplen. Ist dies 
theoretisch möglich? Brauche ich einen Zwischenbuffer? Wenn ich einen 
Zwischenbuffer hätte, würde dieser dann bei höheren Samplefrequenzen 
nicht überlaufen?
Könnten Sie mir bitte weiterhelfen. Vllt sogar ein Beispiel schicken. 
Leider finde ich nämlich nichts vergleichbares online.

Vielen, vielen Dank schon mal

von Little B. (lil-b)


Lesenswert?

Anderle K. schrieb:
> void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
> {
>  osSignalSet(tid_Thread_TCP, 2U);
> }
> void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
> {
>  osSignalSet(tid_Thread_TCP, 3U);
> }

Bitte denk dran, dass du hier nicht die Bitnummer übergibst, sondern 
eine Bitmaske! Also hier besser 0x1, 0x2, 0x4, 0x8, etc. verwenden.

Das Discovery Board hat ja zunächst mal kein Ethernet. Welchen Adapter 
verwendest du, und wie hast du ihn angeschlossen?

von Anderle K. (anderl)


Lesenswert?

Achte ich drauf. Danke.
ich verwende das STMF4BB. Die Phy die da drauf ist heißt LAN8720.

Danke

von Little B. (lil-b)


Lesenswert?

Anderle K. schrieb:
> Kann es sein dass die TCP Verbindung zu langsam ist? Ich sample ja nur
> mit 20kHz. Später will ich mit mindestens 200kHz samplen. Ist dies
> theoretisch möglich? Brauche ich einen Zwischenbuffer? Wenn ich einen
> Zwischenbuffer hätte, würde dieser dann bei höheren Samplefrequenzen
> nicht überlaufen?

Ein Standard TCP nimmt die Daten aus deinem ADC-Buffer und speichert 
diese in einen eigenen Output Buffer. Einen Zwischenpuffer solltest du 
also nicht benötigen, wenn das TCP vernünftig große Buffer hat.

192kHz * 32bit etwas über 3Mbit (3072kBit).
dazu noch grob geschätzte 20% TCP Overhead macht das dann rund 3,7Mbit.
Das sollte sogar mit einem ENC28J60 funktionieren.
Nimmt man den Onboard Ethernet, schafft man mit einem perfekt 
eingestellten lwIP etwa 50Mbit. Ich schaffe mit meinem 
selsbtgeschriebenen TcpIpStack bis zu 90Mbit.

von Anderle K. (anderl)


Lesenswert?

Danke für die Antwort. Ok also theoretisch ist es schon mal möglich. Das 
ist gut. Ich weis leider sehr wenig über die Funktionen die ich 
verwende. Ich kann sie mir nicht anschaun und in der Dokumentation steht 
für meinen Geschmack zu wenig. Einstellen kann ich nicht mehr als die 
thread stack sizes und und die Größe des Memory Pools (<64000bytes). Was 
mit den Daten passiert nachdem ich sie an TCP_send übergeben habe weis 
ich leider nicht.

Naja. Mit der Keil middleware hat keiner Erfahrungen gemacht?

von Anderle Kopernana (Gast)


Lesenswert?

Keiner irgendeine Idee??

von Dummy (Gast)


Lesenswert?

Bau doch einen Counter in das Telegramm ein.

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.