Hallo miteinander, ich benutzeeinen STM32f429 mit 2Mbyte Flash und 256kbyte RAM und den Keil Compiler. Ich sample 32bit Werte mit einer Frequenz von 96kHz. Das würde ich nun gerne möglichst lang machen. Das Program macht folgendes: Nach einem Trigger fängt der externe ADC an zu samplen und sendet die Daten via I2S an den uC. Dieser schreibt sie dann mittels DMA in eine variable BUFFER. Sobald BUFFER voll ist werden die Daten mittels Ethernet versendet. Es ist nun wichtig dass BUFFER möglichst groß ist. Die einfache Rechnung (aber natürlich falsche Rechnung) ist 2MB/4/96000=5s sampling Zeit. Eine oder zwei Sekunden wären aber auch schon super. #define ADCBUFFER_LENGTH 55000 uint16_t I2SBuffer[ADCBUFFER_LENGTH]; Das geht im Moment gut allerdings nur bis genau 75207. Dann fangen die Fehler an. .\Objects\UC1_Test.axf: Error: L6220E: Execution region RW_IRAM1 size (196616 bytes) exceeds limit (196608 bytes). Region contains 15 bytes of padding and 0 bytes of veneers (total 15 bytes of linker generated content). Ist es mit meiner HW möglich ein array mit beispielsweiße #define ADCBUFFER_LENGTH 800000 anzulegen? Wo wird die Variable im Moment gespeichert? Benutze ich den Flash über haupt? Brauch ich einen externen Flash? Sorry aber ich habe im Moment gar keine Ahnung. Wäre auch dankbar über Tipps/Links wo man solche Dinge nachlesen kann. Vielen Dank schon mal
@ Anderle (Gast) >#define ADCBUFFER_LENGTH 55000 >uint16_t I2SBuffer[ADCBUFFER_LENGTH]; >Das geht im Moment gut allerdings nur bis genau 75207. Dann fangen die >Fehler an. >.\Objects\UC1_Test.axf: Error: L6220E: Execution region RW_IRAM1 size >(196616 bytes) exceeds limit (196608 bytes). Region contains 15 bytes of >padding and 0 bytes of veneers (total 15 bytes of linker generated >content). Da fehlt das richtige Linkerscript, das die die vollen 2MB zur Verfügung stellt. Jetzt kennt der Compiler nur einen 196kB SRAM. Der STM32 hat aber mehrer RAM-Bereiche.
Anderle schrieb: > Die einfache Rechnung ist 2MB/4/96000=5s Du kannst deine Daten nicht (kurzfristig) im Flash speichern. Du hast als RAM aber nur 1/10 des angenommenen Speichers. Und dein Programm braucht selber natürlich auch noch was...
Anderle schrieb: > #define ADCBUFFER_LENGTH 800000 anzulegen? > Wo wird die Variable im Moment gespeichert? Benutze ich den Flash über > haupt? Brauch ich einen externen Flash? Du brauchst externes RAM. Dann können wir weiter reden ;-)
Anderle schrieb: > Ist es mit meiner HW möglich ein array mit beispielsweiße > #define ADCBUFFER_LENGTH 800000 anzulegen? Nein, der Puffer kommt ja als sich ständig ändernder Wert ins Ram und nicht ins Flash in dem nur das Programm und die statisch konstanten Werte stehen, dein Flash wäre erstens nach kurzer Zeit wegen zu vielen programmiervorgängen kaputt und zweitens schreibt es sich langsam ins Flash. Von 256k noch 196k frei zu haben, und trotzdem Internet-Stack, ist doch in Ordnung. Wenn das Programm noch malloc macht, ist nicht mal sicher, daß es mit ADCBUFFER_LENGTH=50000 überhaupt noch läuft, vielleicht ist der Stack dann bei komplexten Operationen schon voll (ich denke aber eher, daß der Stack in ausreichender Grösse reserviert ist).
Die 2MB sind doch Flash. Du willst bestimmt nicht (wenn das überhaupt geht) deine adc Werte in den Flash speichern. Wenn dein RAM voll ist ist er voll. Dafür gibt es externen SDRAM und der muss dann als neuer Bereich im linker Skript angelegt werden. Wenn du keinen externen RAM hast wird es quasi nicht möglich sein so lange Daten zu Puffern.
Anderle schrieb: > Ich sample 32bit Werte mit einer Frequenz von 96kHz. Das > würde ich nun gerne möglichst lang machen. Und du brauchst die vollen 32bit bei 96KHz ? Ein Wert von 0 bis 4,294,967,296 ale 10.4us ? Glaube ich kaum... Was ist uberhaupt so schnell ?
Selbst bei "nur" einer Sekunde und 16-Bit Daten wird das schon arg eng. Hast ja bestimmt auch noch andere Sachen im RAM und nicht nur deine ADC Werte. Was du machen kannst (und aufgrund fehlender Hardware wahrscheinlich machen musst) ist, dass du dir eine DMA einrichtet, die dir bei Array voll einen Interrupt auslöst. Dann biegst du den Speicherbereich um auf ein neues leeres Array und speicherst da rein. In der Zeit hast du hoffentlich genug Zeit die Daten raus zu senden über was auch immer. Du sendest dann zwar öfter, hast aber den Vorteil, keinen so riesen großen Speicher nur für rumliegende Daten zu verbraten. Das ganze heißt Doppelpufferung oder Ping-Pong Buffering. Du findest da sicher auch einiges bereits für deinen Mikrocontroller. Marc V. schrieb: > Anderle schrieb: >> Ich sample 32bit Werte mit einer Frequenz von 96kHz. Das >> würde ich nun gerne möglichst lang machen. > Und du brauchst die vollen 32bit bei 96KHz ? > Ein Wert von 0 bis 4,294,967,296 ale 10.4us ? > Glaube ich kaum... > Was ist uberhaupt so schnell ? Linker und rechter Kanal eines Audio-Codecs zusammen auslesen. Ist ziemlich oft der Fall ;-) Also obere beiden Bytes Links und die unteren beiden Rechts... Grüße Dennis
>Sobald BUFFER voll ist werden die Daten mittels Ethernet versendet. >Es ist nun wichtig dass BUFFER möglichst groß ist. Lege 2 Buffer an, wo einer groß genug ist um ein Ethernet Paket zu füllen. a)Fülle den ersten Buffer von I2S, wenn er voll ist, wechsle auf den 2. buffer und sende den ersten über Ethernet weg. b)Wenn der 2. buffer voll ist wechsle wieder auf den ersten und sende den 2. über Ethernet. c) fange wieder bei a) an. Du brauchst auf einmal viel weniger RAM und kannst so viel über Ethernet versenden wie du willst. Gruß, dasrotemopped.
Ach soooo, das sind 2MB Flash ;-) Naja, ein FIFO braucht man hier schon, aber sicher nicht für 1s. Selbst 100ms sollten schon SEHR luxeriös sein, wahrscheinlich reichen 1-10ms Speichertiefe. Denn soo langsam und unberechenbar ist Ethernet nicht.
Dennis X. schrieb: > Linker und rechter Kanal eines Audio-Codecs zusammen auslesen. Ist > ziemlich oft der Fall ;-) Also obere beiden Bytes Links und die unteren > beiden Rechts... Ja, 2 x 16bit klingt besser. Das ergibt 96KHz * 4 Byt = 384KB/s. Schafft man doch locker mit SD-Card, wo liegt das Problem ?
Ich habe etwas ähnliches am laufen. Stm32f407 sampled über den adc in den internen RAM (doublebuffer). Der schickt die daten alle 100ms-1000ms (je nach samplingrate) an einen stm32 f429. Dort liegen sie dann im externen 8mbsdram (doublebuffer). Von dort aus über ethernet (udp) an den PC.
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.