Hallo! Um die Bandbreite möglichst hoch zu halten möchte ich folgendes Setup umsetzen: * 2 mal SPI FRAM devices. * 2 mal ATMegaXXX, an denen jeweils nur der UART-SPI frei ist. (SPI hängt auf einem MEGA an einem MCP2515 und auf dem anderen Maga hängt eine SD Karte) Die ATMegas sollen die FRAMS parallel ansprechen können (quasi als FIFO). Der eine schreibt in FRAM1 während der andere gleichzeitig von FRAM2 lesen können soll. Wenn der schreibende ATMega ein FRAM fertig geschrieben hat, so soll er auf das 2te FRAM wechseln und dort weiter schreiben und der Leser soll dann von dem 1ten FRAM lesen. Die Frage ist: wie kann ich die FRAMS SPI-bus mäßig so separieren, daß es immer nur mit einem der beiden ATMega verbunden ist? (Die Annahme ist das das die Syncronisierung der Megas gelöst ist) Eine Lösung könnte sein einen 74HC244 je FRAM (oder ATMega) zu verwenden - da kann ich mit 2 OE jeweils 4 Pins schalten und muß mich nicht um Seiteneffekte die durch VCC ein/aus entstehen könnten kümmern... Ähnliches könne man vielleicht auch unsauber mit zwei 74HC4050 je FRAM machen - eines zu jedem ATmega und dann einen GPIO am jeweiligen Atmega nutzen um VCC des jeweiligen 74HC4050 zu treiben... Gibt es (andere?) empfehlenswerte Lösung für eine "derartige" Bus-trennung wenn ich die beiden Teil-Busse bei jeweils 8MHz betreiben können möchte? Gibt es etwas zu berücksichtigen? Danke, Martin
@ Martin Sperl (msperl) >* 2 mal SPI FRAM devices. >* 2 mal ATMegaXXX, an denen jeweils nur der UART-SPI frei ist. (SPI >hängt auf einem MEGA an einem MCP2515 und auf dem anderen Maga hängt >eine SD Karte) Hmmm. >Die ATMegas sollen die FRAMS parallel ansprechen können (quasi als >FIFO). >Der eine schreibt in FRAM1 während der andere gleichzeitig von FRAM2 >lesen können soll. Machbar, aber irgendwie nicht so sinnvoll. Nimm EINEN AVR mit dem RICHTIGEN Speicher/FIFO und gut. >Die Frage ist: wie kann ich die FRAMS SPI-bus mäßig so separieren, daß >es immer nur mit einem der beiden ATMega verbunden ist? (Die Annahme ist >das das die Syncronisierung der Megas gelöst ist) Über Multiplexer. >Ähnliches könne man vielleicht auch unsauber mit zwei 74HC4050 je FRAM >machen - eines zu jedem ATmega und dann einen GPIO am jeweiligen Atmega >nutzen um VCC des jeweiligen 74HC4050 zu treiben... Nö, VCC und GND sind fest, es werden nur die Signale geschaltet. >Gibt es (andere?) empfehlenswerte Lösung für eine "derartige" >Bus-trennung wenn ich die beiden Teil-Busse bei jeweils 8MHz betreiben >können möchte? Deine Problem liegt viel tiefer, dein Konzept ist nicht sonderlich brauchbar. http://www.mikrocontroller.net/articles/Netiquette#Klare_Beschreibung_des_Problems
Ich sehe das auch so, Dein Konzept scheint sehr unausgegoren. Die AVRs sind nicht dafür gedacht, riesen Datenmengen zwischen mehreren zu transferieren. Entweder man kann die Aufgaben so aufteilen, daß beide MCs vieles getrennt machen können. Oder man nimmt nen größeren MC. Dir geht sonst ein Haufen CPU-Leistung allein zum Transport verloren. Obendrein auch ein Haufen Entwicklungszeit für das Datenprotokoll, damit nichts verloren geht oder verfälscht wird. Peter
OK, ein wenig Hintergrund: Das Problem ist, daß ich das "Konzept" meiner CAN blackbox mit nur einem AVR mit mcp und SD Karte gemeinsam umgesetzt habe, daß es dort aber auf SD Karten seite zu "Verzögerungen" beim schreiben von bis zu 0.15s kommt (was - siehe anderer thread "normal" ist). In diesem Zeitraum sammeln sich dann aber im schlimmsten Fall 400 CAN Nachrichten (bei 500khz CAN Bus geschwindigkeit) an, die dann gepuffert werden müssen. Erfahrungsgemäß treten diese SD-karten-latenzen aber gehäuft auf - sprich bis zu 3 derartiger langer wartezeiten. Daher muß ich für den schlimmsten Fall ca 1200 Messages buffer haben um über so eine "schwelle" zu kommen - das sind dann 19kb. Die müssen dann verspätet geschrieben werden - sprich zwischenzeitlich sammeln sich potentiell noch mehr daten an... Die Blackbox sollte natürlich außerdem im Falle eines Unfalles keine Daten verlieren - und die daten im Ram-Buffer sind natürlich bei strom aus weg. Daher der Ansatz 2 AVR zu verwenden, wovon der eine sich um die Daten Aquirierung kümmert und diese in einen FRam buffer schreibt (aus 2x 32KB Fram chips, auf die nacheinander geschrieben wird FRAM1 - FRAM2 - FRAM1). Und der zeite AVR liest das jeweils nicht gerade beschriebene FRAM aus und schreibt die 32KB mit einem SD_WRITE_MULTIPLE_BLOCKS in einem Rutsch auf die SD Karte - dies sollte hoffentlich weniger "latenzen" auf der SD-Carte verursachen (vorallem wenn ich 64 512-block am stück schreibe). Das ganze ließe sich mit einem "größeren" AVR (mit 1xSPI und 2x USART und mehr SRAM) vielleicht auch machen, die "Programmierung" ist allerdings viel komplizierter, da es viel mehr mögliche Zustände gibt, die man berücksichtigen müsste: * Alles "normal" - sende daten direkt auf die SD Karte * wir haben frische Daten, aber die SD Karte ist "belegt" -> schreibe in FRAM * wir haben frische daten, aber wir holen die Daten vom FRAM um sie auf die SD-Karte zu schreiben * wir haben daten im buffer und daten ältere Daten auf FRAM... Da sind die möglichen Zustände bei einer Parallelisierung viel einfacher: Die CAN seite: * schreibe empfangene Daten auf FRAM1 * schreibe empfangene Daten auf FRAM2 * rollover auf das andere FRAM + Signalisierung des "Partners", daß er mit dem sichern des FRAMs beginnen kann... * möglicher Fehler-Fall: der "Partner" liest noch von der Seite, die wir schreiben wollen Die SD-Karten Seite: * warte auf Signalisierung, daß eines der FRAM daten zum schreiben hat * lies 32K von FRAM1 und schreibe auf SD Karte in einem Rutsch. * lies 32K von FRAM2 und schreibe auf SD Karte in einem Rutsch. Daher: bei hoffentlich minimalem HW-mehraufwand wird die Software-seite einfacher und vorhersagbarer. In 32KB buffer je FRAM kann ich 2048 CAN-nachrichten in einem FRam speichern - das entspricht zirka 0.5s buffer - und die 32K kann ich mit meinem SPI code bei 8MHz in ca 0.032s auslesen und an die SD-karte schicken. Dannach kann die SD-Karte noch einmal 0.46s "trödeln", bis sie die 32KB "wirklich" geschrieben hat bevor es zu einem Buffer-rollover auf dem FRAM kommt - aber die Daten sind ja eigentlich schon an die SD-karte geschickt, sodaß man vermutlich sogar noch mehr Zeit-puffer hat und das FRAM frühzeitig für einen Wechsel freigeben könnte... Durch diesen Ansatz der Trennung ist auch sicher gestellt, daß ich keine Daten bei apruptem "Strom-aus" verliere - die allerletzten Nachrichten liegen im FRAM und ich habe alle Daten für eine Analyse, warum meinem Uboot der Strom ausgegangen ist (Wassereinbruch,...) - ich muß nur bei initialisierung die Daten als erstes aus dem FRAM sichern... Die Frage ist jetzt: was verwende ich am besten als Multiplexer um den Zugriff auf die beiden FRAM zu lösen? Wie schon gesagt fällt mir primär der 74HC244 ein - weiß aber nicht, ob der wirklich als Multiplexer geeignet ist.
Du kannst das Empfangen der Nachrichten und Speichern auf der SD-Karte auch mit einem AVR in zwei getrennten Tasks erledigen. Task 1 empfängt ein Paket vom CAN-Bus und schreibt es in den Puffer. Task 2 holt sich ein Paket aus dem Puffer und schreibt es auf die SD-Karte. Das ist ein typisches Erzeuger-Verbraucher-Szenerio. Beide Tasks rufst Du fortlaufend in der Hauptschleife auf. Sie müssen natürlich so geschrieben sein, dass sie nicht blockieren, wenn es nichts zu empfangen/lesen gibt bzw. während die SD-Karte beschäftigt ist. Sofern die Lese/Schreibdatenrate des FRAMs höher als die doppelte CAN-Datenrate ist, sollte das unkompliziert laufen.
Randnotiz: auf den 74HC244 bin ich gekommen, weil ich eine Website zur AVR-programmierung via Bus-Pirate gestolpert bin (http://hintshop.ludvig.co.nz/show/buspirate-avr-programming/), wo dieser IC zum "decoupling" der Programmer-Leitungen auf verschiedene AVRs verwendet wird...
Martin Sperl schrieb: > daß es dort aber auf > SD Karten seite zu "Verzögerungen" beim schreiben von bis zu 0.15s kommt > (was - siehe anderer thread "normal" ist). Die Zeit mußt Du ja nicht dumm rum warten. Es reicht doch völlig, wenn Du den FRAM an einen MC zum Puffern hängst. Du läßt in der Mainloop 2 Tasks laufen: 1. CAN -> FRAM-FIFO 2. FRAM-FIFO -> SD. Ein zusätzlicher MC ist nicht nötig. Muß die SD mit einem PC ausgewertet werden? Ansonsten könnte auch ein Data-Flash reichen, z.B.: http://de.farnell.com/atmel/at45db321d-su-2-5/speicher-dataflash-32m-8soic-w/dp/1972019 Die haben intern 2 SRAM-Puffer, d.h. einer wird geschrieben, während der andere gerade flasht. Bei Atmel gibt es ne AN, wo der als Audio-Rekorder verwendet wird. Peter
Martin Sperl schrieb: > Durch diesen Ansatz der Trennung ist auch sicher gestellt, daß ich keine > Daten bei apruptem "Strom-aus" verliere Sei Dir da nicht so sicher. Die SD-Karte kann Daten verlieren, wenn sie beim Schreiben gestört wird. Du brauchst in jedem Fall eine frühe Unterspannungserkennung und einen ausreichend dicken Elko, um den gerade laufenden Schreibzugriff sicher zu beenden. Peter
Martin Sperl schrieb: > Die Blackbox sollte natürlich außerdem im Falle eines Unfalles keine > Daten verlieren - und die daten im Ram-Buffer sind natürlich bei strom > aus weg. Das kann man ändern. Wenn Du konsequent alles in 2.5V/3.3V Low-Power-Technik realisiert hast, kannst Du die Versorgungsspannung problemlos mit einem großen Kondensator puffern. Wenn Du dann einen "Strom weg" Interrupt bekommst, hast Du immer noch genügend Zeit, den gesamten Speicher wegzuschreiben und den Prozessor anschließend zu stoppen. Normale MMC- und SD-Karten funktionieren bis 2.7V herunter, wenn Du Low Voltage Karten nimmst, gehen die bis 1.6V > Daher der Ansatz 2 AVR zu verwenden Das ist eigentlich immer eine ziemlich dumme Idee. fchk
@ Martin Sperl (msperl) >AVR mit mcp und SD Karte gemeinsam umgesetzt habe, daß es dort aber auf >SD Karten seite zu "Verzögerungen" beim schreiben von bis zu 0.15s kommt Ist halt so. >(was - siehe anderer thread "normal" ist). Link? >In diesem Zeitraum sammeln sich dann aber im schlimmsten Fall 400 CAN >Nachrichten (bei 500khz CAN Bus geschwindigkeit) an, die dann gepuffert >werden müssen. Ja. > Erfahrungsgemäß treten diese SD-karten-latenzen aber >gehäuft auf - sprich bis zu 3 derartiger langer wartezeiten. Daher muß >ich für den schlimmsten Fall ca 1200 Messages buffer haben um über so >eine "schwelle" zu kommen - das sind dann 19kb. Die müssen dann >verspätet geschrieben werden - sprich zwischenzeitlich sammeln sich >potentiell noch mehr daten an... Dann nimm einen AVR mit ausreichend Speicher, ggf. einen der wenigen AVRs mit externem Speicherinterface für SRAM, dann hast du 64 kB. >Die Blackbox sollte natürlich außerdem im Falle eines Unfalles keine >Daten verlieren - und die daten im Ram-Buffer sind natürlich bei strom >aus weg. Ja und? Die werden soch sowieso nur ein paar hundert Millisekunden gepuffert. Wenn der Strom weg ist, ist auch dein AVR aus, was nützen dir adann die Daten im FRAM? >Das ganze ließe sich mit einem "größeren" AVR (mit 1xSPI und 2x USART >und mehr SRAM) vielleicht auch machen, die "Programmierung" ist >allerdings viel komplizierter, da es viel mehr mögliche Zustände gibt, >die man berücksichtigen müsste: Ja und? Denkst du mit zwei AVRs wird es einfacher? >* Alles "normal" - sende daten direkt auf die SD Karte >* wir haben frische Daten, aber die SD Karte ist "belegt" -> schreibe in >FRAM >* wir haben frische daten, aber wir holen die Daten vom FRAM um sie auf >die SD-Karte zu schreiben >* wir haben daten im buffer und daten ältere Daten auf FRAM... Falscher Ansatz. Man schreibt IMMER in den FIFO und liest IMMER aus dem FIFO, von da an gehts zur SD-Karte. Alles nicht soooo komplex, wenn man sauber denkt und programmiert, siehe Statemachine und Multitasking. >Daher: bei hoffentlich minimalem HW-mehraufwand wird die Software-seite >einfacher und vorhersagbarer. Irrtum. >Durch diesen Ansatz der Trennung ist auch sicher gestellt, daß ich keine >Daten bei apruptem "Strom-aus" verliere Den kann man durch lokale Puffer verhindern. http://www.mikrocontroller.net/articles/Speicher#EEPROM_Schreibzugriffe_minimieren >Die Frage ist jetzt: was verwende ich am besten als Multiplexer um den >Zugriff auf die beiden FRAM zu lösen? Denk nochmal über das Konzept nach! >Wie schon gesagt fällt mir primär der 74HC244 ein - weiß aber nicht, ob >der wirklich als Multiplexer geeignet ist. Nö, das ist ein einfacher Puffer. 74HC157 ist dein Freund, du brauchst davon aber zwei, ggf. drei.
Aber um einen anderen thread über SD-karten zusammenzufassen ( Beitrag "AVR+SD-Card: SD-Card legt manches mal 0.13s "pausen" ein" ): Ich weiß das es via 2 Tasks geht - ich lese vom CAN schon via Interrupt aus und im Haupt-programm schreibe ich auf die SD-Karte. Aber im Schnitt kommen 2 Interrupts (=2 CAN nachrichten) alleine wärend der Zeit, wo ich die Daten einen einzigen 512 byte daten-block übertrage... Und dann muß ich zumidestens 4ms warten bis die Karte den 512 byte block geschrieben hat, was weiteren 16 Nachrichten am CAN Bus entspricht. Aber das ist der Idealfall! Es gibt auch Phasen, wo die SD karte 0.13s braucht bis sie geschrieben hat. (Und das relativ vorhersagbar alle 32 512-byte Blöcke = also 16KB) - vermutlich ein Effekt des wear-leveling Algoritmus. Umgerechnet sammeln sich in 130ms knapp 520 can-nachrichten (und damit bei 16 byte/nachricht 8320byte) an, die verspätet geschrieben werden müssen. Das ginge ja noch mit genügend Speicher ohne FRAM "klimmzüge" - allerdings mit dem Risiko des Daten-verlusts bei "strom aus"... Das 2te Problem ist daß es meist 3 benachbarte Blöcke gibt die ein derartiges Verhalten zeigen (meiner Erfahrung nach Block 29,30 und 31)- sprich da sammeln sich noch mehr Nachrichten an - meiner Schätzung nach knapp 24k. Aber wenn ich dann diese 24K als jeweils einzelne Blöcke schreiben möchte, so ist das "backlog" schon größer 16k und ich komme aus dem Teufelskreis nicht herraus. Allerdings kann man bei SD-Karten auch mehrere Blocks gleichzeitig schreiben - je mehr und je größer desto besser (vorallem wenn an "flash-grenzen" aligned schreibt), daher sollten sich 32kb am Stück viel schneller schreiben lassen, als 64 mal 512 bytes, wo man je block warten muß... Für die SD-Karte wird das ganze auch viel effizienter, denn sie kann intern vielleicht sogar ganze Pages schreiben, was um einiges schneller gehen sollte, als wenn man für 512 bytes eine ganze Flash page (4k, 8K,16k..) schreiben muß. Und das führt zu mehr "Müll", der dann entsorgt werden muß, indem die 32 Pages gelesen werden und als eine neu geschrieben werden. Wenn ich gleich in 16 oder 32K blöcken schreibe, so fällt das nicht ins Gewicht - und nur so erreichen die SD-Karten die angegebenen Geschwindigkeit - nicht beim schreiben einzelner Blocks! Der Vorschlag in dem anderen Thread war auf NAND speicher ohne wear-leveling zurückzugreifen, aber a) sind die nur ein paar MB groß b) sind die Kosten vergleichsweise viel höher als bei SD-Karten c) ist nicht so leicht am PC auszulesen Daher mein Ansatz der "hybrid-lösung" mit FRAM als permanenter Buffer (sollten bis zu 80 Jahre die Daten halten könne) um dann die Daten in gößeren Stücken schreiben zu können... Ich habe daher auch schon an einen AVR mit 1xSPI und 2x USART gedacht, allerdings ergibt sich so das Problem, daß ich im IRQ für den CAN-Nachrichten-Empfang dann grundsätzlich 3 Varianten vorsehen muß: * SPI zum FRAM ist blockiert (weil der haupt-thread gerade davon liest) -> schreibe daten in buffer * SPI zum FRAM ist frei, keine Daten im buffer -> schreibe direkt ins FRAM * SPI zum FRAM ist frei, Daten im Buffer -> schreibe zuerst die gebufferten Daten ins FRAM und dann die neuen Daten. Machbar... Man muß dann aber gegebenenfalls die Datenmenge von ca. 37 CAN-nachrichten, die in 9.2ms aufläuft buffern (9.2ms=16KB*9bit(=8bit daten plus 1 bit verschenkter cycle)/16MHz ist die Zeit die ich brauche um 16K am Stück vom FRAM auszulesen und an die SD-Karte zu schicken). Diese 37 (=9.2ms/(0.25ms/CANNachricht)) Nachrichten gehen dann im "Strom aus" Fall allerdings verloren - nicht was ich mir erhoffe... OK, der schreibende Haupt-prozess könnte alle 64 byte oder so nachsehen, ob es neue daten gibt die der IRQ handler eingelesen hat und dann das Lesen unterbrechen und ins FRAM schreiben - da gehen dann allerding einige Cycles verloren nur um diesen Teil der State-machine abzuarbeiten (SPI lesen abbrechen (CS High), CS low, Daten Buffer addresse errechnen und daten beginnen einzulesen (ist es wirklich nur eine Nachricht), SPI WRITECMD+Adresse+16 byte schreiben,CS high, CS low,SPI READCMD+Adresse zum weiter lesen, weitere 64 byte lesen) Damit wird der gesamte transfer ineffizienter (ich schätze, daß ich in der Zeit in der ich das obige umsetze fast 32 byte vom FRam lesen könnte - sagen wir zumindestens 24 bytes) Und daher macht IMO eine Separierung der "Aufgaben" auf meherere Prozessoren die Programmierung wie schon gesagt einfacher und effizienter, da es keine so komplexe state-machine erfordert wie wenn ich alle Möglichkeiten in einer State-machine abhandeln müßte (unter Berücksichtigung der zeitlichen Limitierungen - wie zum Teil oben beschrieben)... (Ganz zu Schweigen von der Wahrscheinlichkeit von Programmfehlern, vergessenen Nebenläufigkeiten, übersehenen seltenen States in der state-machine,... und dem damit geparten Zeitaufwand verglichen mit dem "einfacheren" code durch Separierung auf zwei AVRs...) Zusätzlich ließe sich dann das ganze "Werkel" dann bei nur mehr 8-12MHz mit 3.3V betreiben und ich brauche keine 5V mehr um die AVRs bei 16-20MHz zu betreiben (und einen Pegel-Wandler auf 3.3V für die SD-Karte) um das ganze zu "stemmen"... (OK, der CAN-bus-treiber braucht noch 5V) Und es ist kostengünstiger 2 Mega168 zu verwenden als einen von den größeren SMD-only AVRs mit 16+KB Speicher, die dann obendrein nicht mehr so einfach am Breadboard zu montieren sind um das ganze zu entwickeln... (Und strom-sparender ist es vermutlich obendrein noch, denn da lässt sich sehr einfach "extended-standby sleep" einbauen wenn man eine externe clock verwendet) Es steckt daher schon einiges zeitkonsumierende Erfahrung und Gedanken hinter dem jetzigen parallelen-Design mit Fram als Buffer - vorallem wenn man alle Randbedingungen berücksichtigt... Ich werde mir jetzt einmal den 74HC157 ansehen - vielleicht löst der das Problem... Mich wundert allerdings, wie der "decouple"-Vorschlag von dem Bus-pirate link (http://hintshop.ludvig.co.nz/show/buspirate-avr-programming/) dann mit dem dort verwendeten 74HC244 dann funktioniert, aber vielleicht verstehe ich da etwas falsch...
Dein Problem ist also kurz gesagt, dass der Task zum Schreiben auf die SD-Karte blockweise arbeiten soll und das lange dauert. Dabei blockiert er das FRAM und es können in der Zeit keine neuen CAN-Nachrichten gespeichert werden. Deshalb willst Du die neuen CAN-Nachrichten nochmal im SRAM puffern, bis der FRAM wieder freigegeben wird. Warum machst Du es nicht umgekehrt: Der Task zum Schreiben auf die SD-Karte holt sich pro Aufruf nur einen Datensatz aus dem FRAM und speichert ihn in einem lokalen SRAM-Puffer. Wenn er genug Datensätze in seinem Puffer hat, dass er sie blockweise auf die SD-Karte schreiben kann, macht er das. Der Task, der Daten vom CAN-Bus abholt, schreibt sie dagegen sofort ins FRAM. Das kann er, weil der andere Task das FRAM nie länger als zum Lesen von einem Datensatz blockiert.
Du denkst viel zu kompliziert. Es ist vollkommen wurscht, wie lange die SD-Karte Gedenkpausen braucht. Solange der FRAM alle derweil auflaufenden Nachrichten puffern kann, ist alles in Butter. Und die werden dann im nächsten Rutsch geschrieben. Und wenn dann nur eine Nachricht aufgelaufen ist, wird eben nur eine geschrieben. Die SD-Routine sollte auch nur kleine Häppchen (z.B. 16Byte) aus dem FRAM lesen, damit der CAN-Interrupt wieder was reinschreiben kann. Wenn CAN->FRAM ein Interrupt ist, muß ja im Main der FRAM atomar gelesen werden. Dem CAN+FRAM würde ich die UART als SPI geben, dann hat die SD den anderen SPI für sich allein. Ansonsten wirds kompliziert, wenn sich Main und Interrupt um die selbe SPI prügeln. Peter
Und ganz allgemein: Vergiss irgendwelche komplizierten Statemachines. Die Daten wandern über genau einen Pfad vom CAN-Interface über die Pufferspeicher bis hin zur SD-Karte, ohne irgendwelche Abkürzungen und Sonderfälle. Dazu braucht man keine zwei Mikrocontroller. Der Programmcode wird mit zwei Mikrocontrollern niemals einfacher als mit einem, und schon gar nicht weniger fehleranfällig.
Jein - der "receiver" teil ist im interrupt, der dann die "Erfahrung" machen kann, daß CS zum FRam schon low ist - dann kann er den transfer nicht sinvoll beenden... Zum transferieren vom FRAM auf die SD karte brauche ich nur Register - das ganze geht interleaved sehr gut ohne nur einen SPI-cycle zu verschwenden (sprich 50% SCK duty-cycle) - wenn ich zuerst lese und dann schreibe, so verschwende ich mehr Zeit. Ich könnte alle 32 oder 64 bytes im transfer einen CLI/SEI block einführen - der Interrupt kann nur dann triggern. Wengleich ich mir nicht sicher bin, ob dann eine "edge" während der zeit mit Interrupt disabled dann in diesem CLI/SEI überhaupt triggern würde... Dann müßte ich - wie schon vorher angedeutet - den Interrupt-pin abfragen und außerhalb des IRQs handlen, nachdem ich den Bus freigegeben habe. Mit dem "Hold" pin und alternativer Nutzung der 2 FRams läßt sich das vielleicht bewerkstellingen, daß ich mir zumindestens den address setup ersparen kann, was es etwas effizienter gestalten würde. Wie schon gesagt: es geht viel - irgendwo wird es etwas komplizierter (entweder auf HW oder auf SW seite)... Die Frage ist, ob es nicht aufwändiger ist einen anderen als zwei meiner "Haus und Hof" AVRMega168 zu verwenden und dann den code in funktionalität zu trennen (ist ja im Grunde genommen ja schon da)... Auf der einen Seite erfordert es nur den IRQ Handler anzupassen, daß er statt in den Buffer gleich ins FRAM zu schreibt - brauche ich so oder so. und dann sieht die "hauptschleife" wie folgt aus:
1 | while (1) { sleep(); } |
Und auf der anderen Seite brauche ich nur einen IRQ handler der mich nach einen pin state change (z.b: pins FRAM1 und FRAM2 CS from "can-receiver" - vieleicht noch ein Pin: "daten zu schreiben" ) aufweckt und dann lese ich je nach Pin levels von FRAM1 oder von FRAM2 und ich schreibe auf die SD-Card ohne auf irgendetwas Rücksicht nehmen zu müssen. Sieht dann so aus:
1 | while (1) { |
2 | /* check if there is data to be written SIGNAL */
|
3 | if (ISSET(WRITE_BUFFER_PIN)) { |
4 | /* check which CS line from the Peer is low - select the other FRAM to write */
|
5 | if (ISSET(FRAM1_CS)) { |
6 | writeFRAM1ToSD(); |
7 | notifyMasterOnWritten(); |
8 | } else if (ISSET(FRAM2_CS)) { |
9 | writeFRAM2ToSD(); |
10 | notifyMasterOnWritten(); |
11 | }
|
12 | } else { |
13 | /* nothing happened */
|
14 | /* reset watchdog - there must be a timer interrupt as well to trigger a reset of the watchdog */
|
15 | wdr_reset(); |
16 | /* sleep until we get woken again by an interrupt*/
|
17 | sleep(); |
18 | }
|
19 | }
|
(OK, da gehört noch etwas CLI/SEI an die richtigen Stellen) Dann ist das ganze "einfache lineare" Programmierung, die fast nur "sleep" macht wenn nichts los ist... Alles auf einem AVR erfordert mehrere Sonderfälle, wo dann ein unroll und optimieren auf Durchsatz nicht mehr so einfach möglich ist (wie oben beschrieben muß ich dann Pausen machen um zu sehen, ob es neue Daten gibt und um den bus freizugeben - da bräuchte ich dann eine AVR mit 4 SPI bussen - einer für CAN, einer für SD, einer für jedes FRAM... Dann könnte man das "einfach" machen - es soll einfach und verlässlich sein Und die beiden Codes oben sehen für mich "verlässlich" aus - wenn das HW setup auch verlässlich ist... (und ich hoffe halt, daß das Multiplexen "funktioniert"...)
Martin Sperl schrieb: > Der Vorschlag in dem anderen Thread war auf NAND speicher ohne > wear-leveling zurückzugreifen, aber > a) sind die nur ein paar MB groß Falsch. http://de.farnell.com/hynix-semiconductor/h27uag8t2btr-bc/speicher-flash-nand-16gb-48tsop/dp/2147273 > b) sind die Kosten vergleichsweise viel höher als bei SD-Karten > c) ist nicht so leicht am PC auszulesen Mach doch ein USB-Interface dran. Achso ... dafür brauchst Du wieder einen extra Chip. Dann nim doch gleich einen der Aufgabe angemessenen Controller. Der hat dann auch CAN gleich eingebaut. > Und daher macht IMO eine Separierung der "Aufgaben" auf meherere > Prozessoren die Programmierung wie schon gesagt einfacher und > effizienter, da es keine so komplexe state-machine erfordert wie wenn > ich alle Möglichkeiten in einer State-machine abhandeln müßte (unter > Berücksichtigung der zeitlichen Limitierungen - wie zum Teil oben > beschrieben)... Du hast einen Knoten im Kopf und einen offenbar ungeeigneten Controller in den Fingern. Normalerweise löst man so etwas mit einem Ringpuffer. Ein solcher hat einen Schreibpointer, für den CAN-IRQ und einen Lesepointer für den SD-Task. Google mal nach diesem Konzept. Und wie gesagt: Ein paar Sekunden kannst Du immer mir einem dicken Elko überbrücken. > Zusätzlich ließe sich dann das ganze "Werkel" dann bei nur mehr 8-12MHz > mit 3.3V betreiben und ich brauche keine 5V mehr um die AVRs bei > 16-20MHz zu betreiben (und einen Pegel-Wandler auf 3.3V für die > SD-Karte) um das ganze zu "stemmen"... (OK, der CAN-bus-treiber braucht > noch 5V) Ja, selber schuld, sage ich da nur. Es gibt auch Controller, die mit 40 MHz laufen und auch nur 3.3V brauchen. Und 32k RAM eingebaut haben. Sogar welche im DIL28. Und obendrein noch weniger Strom ziehen, da neuere Halbleitertechnologie. Und 3.50€ bei Reíchelt kosten. Du musst nur mal Deinen Schädel für was anderes als AVR öffnen. Schau hier: http://www.reichelt.de/PIC-32-Controller/32MX150F128B-ISP/3//index.html?ACTION=3&GROUPID=4509&ARTICLE=121326&SHOW=1&START=0&OFFSET=500& > Und es ist kostengünstiger 2 Mega168 zu verwenden als einen von den > größeren SMD-only AVRs mit 16+KB Speicher, die dann obendrein nicht mehr > so einfach am Breadboard zu montieren sind um das ganze zu entwickeln... > (Und strom-sparender ist es vermutlich obendrein noch, denn da lässt > sich sehr einfach "extended-standby sleep" einbauen wenn man eine > externe clock verwendet) Kostengünstiger als 3.50€ sicher nicht... > Es steckt daher schon einiges zeitkonsumierende Erfahrung und Gedanken > hinter dem jetzigen parallelen-Design mit Fram als Buffer - vorallem > wenn man alle Randbedingungen berücksichtigt... Ja, um Erfahrungen zu sammeln, braucht man Zeit. fchk PS: Der genannte PIC hat kein CAN, wie ich gesehen habe. Dann nimm halt einen dsPIC33EP256GP502, der läuft mit 70 MHz und hat LIN und CAN und 256k Flash und 32k RAM und sollte für Dich geeignet sein. Gibts leider nicht bei Reíchelt.
@ Martin Sperl (msperl) >Jein - der "receiver" teil ist im interrupt, der dann die "Erfahrung" >machen kann, daß CS zum FRam schon low ist - dann kann er den transfer >nicht sinvoll beenden... Hier liegt einer deiner Fehler. >Zum transferieren vom FRAM auf die SD karte brauche ich nur Register - ?? Programmierst du in ASM? OMG! >das ganze geht interleaved sehr gut ohne nur einen SPI-cycle zu >verschwenden (sprich 50% SCK duty-cycle) - wenn ich zuerst lese und dann >schreibe, so verschwende ich mehr Zeit. Geh mal davon aus, dass es hier viele Leute wissen, was sie erzählen. Du eher weniger. >Ich könnte alle 32 oder 64 bytes im transfer einen CLI/SEI block >einführen - der Interrupt kann nur dann triggern. Wengleich ich mir >nicht sicher bin, ob dann eine "edge" während der zeit mit Interrupt >disabled dann in diesem CLI/SEI überhaupt triggern würde... Du bist viel zu sehr in Details vertieft und hast überhaupt keinen gescheiten Überblick. Weder über das Problem, noch über die üblihen Lösungsansätze. >Wie schon gesagt: es geht viel - irgendwo wird es etwas komplizierter >(entweder auf HW oder auf SW seite)... Bla Bla. >Alles auf einem AVR erfordert mehrere Sonderfälle, wo dann ein unroll >und optimieren auf Durchsatz nicht mehr so einfach möglich ist (wie oben Du hast einen Tunnelblick.
OK - nach einer runde Radfahren muß ich sagen, daß es vermutlich mit einem Mega164P gehen könnte. Allerdings würde es ein paar "Verrenkungen" im Code erfordern und ein paar weitere Leitungen um hold auf dem FRAM zu halten. Ich werde es doch einmal mit nur einem Mega probieren, für den Fall, das es nicht passt, so werde ich es mit 4 74HC157 und 2 Mega168 versuchen... @fcks: Farnell - geht als Privatmann leider unerfindlichen Gründen nicht! Pic: Ich habe jetzt erst vor kurzem mit AVR begonnen und möchte momentan einmal dabei bleiben...
Martin Sperl schrieb: > Pic: Ich habe jetzt erst vor kurzem mit AVR begonnen Das merkt man. > und möchte momentan > einmal dabei bleiben... Auch wenn Du gegen die Wand fährst? Denk nochmal darüber nach. fchk
Martin Sperl schrieb: > @fcks: Farnell - geht als Privatmann leider unerfindlichen Gründen > nicht! Geht zu hbe-shop.de - das ist die Privatkundenversion mit identischem Sortiment. fchk
>> und möchte momentan >> einmal dabei bleiben... > >Auch wenn Du gegen die Wand fährst? Denk nochmal darüber nach. Billiges STM32F4 Discovery und dann auf USB Stick speichern. 192kB RAM Onboard. DMA für alles mögliche;) Für CAN braucht man nur noch einen Transceiver. 20 Euro Lösung.
Die AVR's mögen ja für eine Sachen gut geeignet sein. Naja ich mag die Dinger nicht, aber das ist meine persönliche Meinung Nur für das was du machen willst sind die AVR's ungeeignet. Falsche Schnittstellen, zu klein, zu langsam. Einzig sinnvolle für das was du da vorhast. Such dir einen Cortex Mx der direkt einen CanController, eine SPI mit DMA und dazu großen Ram hat. Dann kannst du dir den ganzen Hickhack mit 2 µC zu synchronisieren ersparen. zb die vorgeschlagenen STM oder die Lm3sxxx von Ti Bei beiden bekommst du die µC mit IDE für einiges billiger als das ganze für den AVR kostet. Und ja man kann einen Wohnungsumzug mit einem Kombi machen, aber jeder der kann wird sich da mindestens einen Lieferwagen besorgen. und warum ? weil es Sinn macht. ==> Ja sowas geht mit AVR, aber es macht kein Sinn !! Falls du bei deiner Konstruktion bleiben willst, dann such mal nach dem Stichwort "DualPort Ram" damit kommst du näher an dein Ziel.
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.