Guten Abend zusammen, ich habe einen Raspberry PI 3 B+, welcher einen A/D-Wandler über SPI ausliest. Die SPI-Verbindung taktet mit knapp 16MHz das sind etwa 1MSps die vom ADC pro Sekunde erhalten werden (Das zu Sampelnde Signal ist rel. hochfrequet weshalb tatsächlich 1MSps benötigt werden). Aufgrund der Geschwindigkeit übernimmt der automatische DMA Controller das Auslesen (dieser springt bei der BCM2835 Library, die ich verwende automatisch bei über 96 gesendeten Bytes an). Um eine möglichst lange Messdauer zu erreichen, übergebe ich der SPI Schnittstelle ein möglichst langes Array, damit dieses vom ADC mit den Messwerten gefüllt wird und an mich zuück geliefert wird. Das Problem ist allerdings, dass die Messung dann nur etwa ein paar Sekunden dauert und ich gerne längere Zeiträumen abdecken will. Gibt es eine Möglichkeit das so zu lösen, dass der ADC quasi kontinuierlich (15-20 Sekunden beispielsweise) das Signal sampeln kann? Dabei darf es jedoch auf keinen Fall zur Unterbrechung des Samplings kommen. Der Befehl an den ADC sieht derzeit wie folgt aus Code char tx0[8200000] = {}; char rx[] = {}; bcm2835_spi_transfernb(tx0,rx,samples); Vielen Dank schon einmal vorab für eure Hilfe :)
:
Verschoben durch Moderator
Du muesst deinen Treiber so umprogrammieren das der DMA mit mehren Buffern arbeitet. Dann fuellt der DMA einen Buffer und den anderen leerst du gerade. Ausserdem muss der DMA einen IRQ liefern der jedesmal zuschlaegt wenn der Buffer voll ist und sehr schnell den neuen Transfer aufsetzt. Mit Mikrocontrollern ist sowas moeglich. Ob es auch mit dem Linuxkernel moeglich ist weiss ich nicht, wuerde es aber erwarten weil das ja auch in anderen Bereichen (Audio/Video-Ausgabe) gebraucht wird. Olaf
Also ich denke nicht das es mit dem Linux Kernel da ein Problem gibt, deine Netzwerk Verbindung läuft ja auch schneller. Es hängt einzig und allein an den Fähigkeiten des Entwicklers. Wenn du im User Space bist ist deine Anwendung tendenziell etwas langsamer wie wenn du einen Kernel Treiber schreibst. Jedoch sollte deine Strategie nicht sein ein möglichst langes Array zu verwenden, sondern lieber eine Strategie zum Puffern und weitergeben von Daten. Also eine Art streaming implementieren, zum Beispiel könntest du bei den ganzen SDR Anwendungen schauen wie die das machen. Schliesslich kommen die ja auch mit mehr als 1Msps klar und rechnen dann noch auf den Daten. DMA, Double buffering, circular buffer, streaming, coroutines, asynchronous I/O könntest du mal als weitere Schlüsselwörter zur Suche verwenden. Was ich mich Frageist, was soll es werden. Eine dauerhafte Beobachtung oder reicht es den RAM voll laufen zu lassen und dann die Daten weg zu schreiben? Für den Anfang könntest du ja mal probieren mehrere Arrays anzulegen und dann einfach den spi Befehl mehrfach wiederholen, oder einfach ein Array aus Arrays bauen und mit einer Schleife drüber laufen bis du deine 2O Sekunden hast. Wahrscheinlich nicht schön aber könnte reichen. Interessant wäre zu wissen wie viel Byte pro Sample übertragen werden und ob es Overhead gibt? Relativ Hochfrequent ist ein guter Witz, was ist denn die erwartete höchste Signalfrequenz die du messen möchtest? Mit deinem Array festgelegter Länge solltest du ja auch in der Lage sein auszurechnen wie lange du Daten aufzeichnen kannst, etwa ein paar Sekunden ist eine schlechte Angabe. Ich gehe mal von einem 16bit ADC, wegen der 16MHz zu 1MSPS Beziehung aus, es könnte evtl Sinnvoll sein einen MC dazwischen zu setzen der deinen langsamen aber kontinuierlichen Datenstrom aufzeichnet und dann am besten per DMA in Blöcken schneller weiter gibt z.B. könntest du dann eine gpio Pin setzen wenn wieder ein Datensatz zur Abholung bereit steht. So kannst du trotz Raspi CPU Auslastung einen sauberen Datenstrom sicherstellen. Wäre schön etwas von der Lösung später auch wieder hier zu sehen.
Hat das SPI im Rπ einen RX Buffer? Normalerweise gibt es sowas. Dann gehst du periodisch hin, guckst ob was in diesem Buffer steht und liest es aus. Dann wartest du wieder. Mit Python kann ich so ganz ohne DMA 12 MBit von einem FT2232H UART lesen, dauerhaft.
:
Bearbeitet durch User
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.