Hallo zusammen, momentan sende ich Daten vom Master zum Slave. Der Slave kopiert im Interrupt (Stop-Bit) den Buffer mit der empfangenen I2C-Nachricht in einen RAM-Buffer. Diesen möchte ich in der Main-Loop verarbeiten. Wie stelle ich sicher, dass mir bei einen neuen Interrupt der RAM-Buffer nicht wieder überschrieben wird, obwohl ich den RAM-Buffer in der Main-Loop noch nicht verarbeitet habe. Ich wollte jetzt nicht den RAM-Buffer größer machen (momentan 25 Byte), da ich nur 1 kByte RAM habe. Zudem will ich die Nachricht nicht direkt im Interrupt verarbeiten. ??? Danke im voraus! Gruß
Du sperrst den Buffer bis der Inhalt verarbeitet wurde. Vorher darf nichts neues rein. Das führt aber evt. zum Verlust von Nachrichten. Das kannst du einfach über ein lockbit/byte Flag realisieren. Die I2C Empfangsroutine wertet das Flag aus und verwirft ankommende Bytes wenn das Flag gesetzt ist. Es gibt nur 2 Möglichkeiten: Entweder die Nachrichten kommen zeitlich langsam genug an, dann ist alles ok, oder sie kommen schneller als du sie verarbeiten willst/kannst. Dann musst du entscheiden: Speichern in einem Buffer welcher groß genug ist, oder Buffer sperren und Nachrichten verlieren.
Ehren schrieb: > Wie > stelle ich sicher, dass mir bei einen neuen Interrupt der RAM-Buffer > nicht wieder überschrieben wird, obwohl ich den RAM-Buffer in der > Main-Loop noch nicht verarbeitet habe. Wenn das I²C Interface ordentliches Clock-Stretching macht, dann einfach den I2C-Interrupt deaktivieren und in main() nach der Verarbeitung wieder anschalten.
Wenn du keine einlaufenden Daten willst, dann kannst du den µC dagegen sperren, indem du I2C deaktivierst, bis der Puffer verarbeitet ist. Der Master kriegt dann NACK. Alternativ liesse sich ggf. Clock Stretching nutzen, um einen Master-Zugriff so lange anzuhalten, bis der Slave wieder aufnahmefähig ist. Dazu müsste man dann aber mehr über den Slave wissen. Nicht jeder Master kann Clock Stretching sauber verarbeiten. Zwei die es nicht können sind Bus Pirate und Raspberry Pi.
Genau wie cyblord schreibt; wobei ich nicht den Buffer sperre, sondern i2c erst gar nicht wieder aktiviere. Sendet der Master weiter, kriegt er ein NAK (bzw. keine Antwort). Das kann natürlich den Master verwirren. Wenn du den Master selbst unter Kontrolle hast, kannst du dort ein sauberes Retry machen. Ist die Nachricht verarbeitet, aktivierst du den Slave wieder. Ich mach das so bei meinen i2c-LCD-Slaves. edit: andere waren schneller...
Nen Double Buffer könnte sich schon lohnen. Wenn die main halt die Daten verarbeitet kann in einem zweiten Bufferempfangen werden. Sollte dieser auch voll sein wird hoffenlich der erste bald wieder frei sein. Solange muß das Protokoll halt dafür sorgen das dem Sender mitgeteilt wird warte mal bzw. bitte wiederhole noch mal die Nachricht. Machst du ja auch so wenn du dir ne Handy nummer aufschreibst: Äh was kam nach der 5 Ziffer?? Kannst du noch mal wiederholen?!
Hallo zusammen, Danke für die Antworten. Werde versuchen den I2C zu deaktivieren, bis er die Nachricht verarbeitet hat. Ansonsten muss ich mal schauen wie groß ich meinen Ringspeicher machen kann... Danke und Gruß
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.