STM32F4 TCP Socket mit Keil middleware

OP #4373306
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
Angehängte Dateien:
#4373339
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?
#4373352
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.
OP #4373386
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren