Für dieses Forum muß Javascript im Browser aktiviert werden!
Kommentar: Einfügen von HTML im Kommentar: Link einfügen: <a href="LINKURL" target="_blank">LINKTITEL</a> Bild einfügen: <img src="BILDURL"> Text formatieren: <b>fetter Text</b> <i>kursiver Text</i> <u>unterstrichener Text</u> Kombinationen sind auch möglich z.B.: <b><i>fetter & kursiver Text</i></b> C2 Quellcode formatieren: <code>Quellcode</code> ASM Quellcode formatieren: <asm>Quellcode</asm> (Innerhalb eines Quellcodeabschnitts ist kein html möglich.) Wichtig: Bitte mache Zeilenumbrüche, bevor Du am rechten Rand des Eingabefeldes ankommst ! > Hallo Andrè, > > > > > > > Welche Fehlfunktion ??! > > > > > > Na zum Beispiel fehlerhaft arbeitende Eeproms. Oder ein Fehler auf dem i2c-Bus. Oder ein fehlendes i=0; > > > > > Ich hatte die "Fehlfunktiunen" auf Dein Testproggie bezogen. :-) > > Ein fehlerhaft arbeitendes EEProm ist ein defektes EEProm. Da kann man nicht > > viel machen (außer austauschen). > > Wir finden doch noch einen gemeinsamen Standpunkt.... :-) > Wenn ich als Programm z.b. bei einem Fehler des Eeproms eine Meldung wie "Service" aus dem Display > darstellen will/kann, muß ich natürlich auch als Programm erfahren wenn was schief geht. Mir ist klar, das > man in einer Steuerung wie der CC2 dies nicht bis Ultimo durchziehen kann. Aber wo es leicht Möglich ist, > sollte es passieren, und sei es nur um den Ruf der CC2 als sicheres System zu verbessern. > > > Das fällt überhaupt nicht auf, bis Du einen Wert zurückliest. Das EEProm wird funzt weiterhin funzen, > > nur lassen sich die betroffennen Speicherzellen nicht mehr ändern. > > Das sehe ich auch so. Es wäre also ggf. darüber nachzudenken, ob man nicht sogar einen zweiten Satz > Funktionen baut, die genau das beim schreiben schon prüfen oder die vorhandenen Funktionen um eine > "Verify-Option" erweitert. Für Anwendungen bei denen es auf die 100%tige Datensicherheit ankommt. > Man darf ja nicht vergessen, das Eeproms relativ langsam sind und rum um den Schreibvorgang jede Menge > Zeit bleibt, um weitere Operationen durchzuführen. Dazu komme ich aber gleich noch mal. > Ich überlege mir, ob ich das nicht evtl. sogar mit dem Verify machen soll. > > > > Ich halte es jedenfalls für ein Unding, das Treibersoftware (und das ist eeprom.c2 nun mal) gnadenlos > > > über ein offensichtlichen Fehler des eeprom-i2c-Systems hinwegschaut als wenn nichts gewesen wäre. > > > > Wenn das EEProm nicht mehr funzt hat das nichts direkt mit I²C zu tun. > > Das sehe ich immer noch anders... wenn die CC2 steuertechnisch Mist baut weil das i2c-Eprom falsche/veraltete > Daten hat (z.B. auf Grund einer fehlgeschlagenen Schreiboperation), ist es sehr wohl ein Problem des > Gesamtsystems und damit auch der CC2, dem I2C und den Treibern. > Natürlich liegt die Ursache nicht in der CC2 oder den Treibern aber das Problem wurde durch sie auch nicht > verhindert. Die CC2 ist zwar kein Flugzeugboardcomputer aber würdest Du dort auch so agumentieren? > Und wenn nicht, was unterscheidet die CC2 abgesehen vom Preis dann von einem Boardrechner? > Wenn Du mir "Zuverlässigkeit" als Grund nennst, haben wir eine gemeinsame Linie gefunden. > > > Außderdem mußt Du das Ganze auch einmal anders sehen: > > (Fast) jedes Modul ist sozusagen in meiner "Freizeit" entstanden, da ich mit der CC2 selbst, > > also Conrad, nichts zu tun habe, sondern auch nur ein "User" bin. > > Das Entwickeln von Modulen benötigt mit dem Testen eben viel Zeit. > > Besonders, wenn immer mehr ASM mit im Spiel ist. > > Das weis ich zu würdigen und kann es sehr gut nachvollziehen, glaube mir das bitte. > Deswegen ranze ich Dich ja auch nicht an sondern schreibe selbst an dem Modul weiter. > Ich halte Programmfehler nicht für persönliche Fehltritte und es braucht sich auch keiner vor mir > dafür zu rechtfertigen... dazu habe ich selbst schon zu viele gemacht ;-) Nimm es einfach positiv. > > > Dann ist jedoch etwas größeres passiert. Hier müsste dann die Integrität > > des Busses selbst geprüft werden. (Das ist etwas schwerer) > > Jedoch sind Fehlfunktionen an den Bausteinen selbst durch ungewolltes Adressieren > > fast ausgeschlossen, da die Adressierung nach dem START erfolgt. Daten, > > mit i2c.wirte geschrieben, können keinen anderen Baustein ansprechen ! > > Wird am Bus ein START signalisiert, "hören" alle Baustein am Bus zu. > > nach dem Start wird das Adressbyte gesendet. Stimmt dieses nicht mit > > der eigenen Adresse überein, "klinken" sich die Baustein wieder aus, bis > > Das nächste START gesendet wird; dafür muß zuvor jedoch ein STOP gesendet > > werden. > > Als kleine "Lektüre" zum I²C-Bus empfehle ich Dir das Modul i2cext.c2 . > > Hier kannst Du erkennen, wie der Bus funzt. > > Das werde ich mir zu Herzen nemen, aber danke schon mal für die Start/Stop-Geschichte... > das wuste ich z.B. nicht und ist natürlich wichtig für die Funktion. > > > > Ich sag Dir auch was.. ich programmiere schon seit Jahren auf Linux in C und ich weis auch > > > wovon ich rede.. so von wegen Multithreading, Multitasking, Seiteneffekte. > > > > Tja, ein PC ist eben keine CC2. Und man kann das Multithreading auch nicht mit > > dem eines PCs vergleichen. (Besonders, da hier mehr Multitasking vorkommt, was die > > CC2 wiederum nicht kann) > > Mag ja sein... ich sag ja nicht, das ich die CC2 perfekt behersche... aber ich denke, ich kenne > die Unterschiede ganz gut... und nicht nur von PC's... :-) > > > > Ich kenne zwar den i2c-Bus > > > nicht so genau aber wenn Dir einer helfen will, dann hau dem nicht auf die Finger. > > Ich klopfe niemanden auf die Finger. Ich vertrete nur meinen Standpunkt bei dieser > > Diskussion. :-) > > Ok.. akzeptiert. > > > Nebenbei wird diese Funktion um einiges schneller ausgeführt. > > Außerdem geht es bei mir bei Modulen immer um Geschwindigkeit. > > Darum muß man in C2 aufpassen wie man schreibt. > > z.B. if Abfragen auf TRUE sollten so kurz wie möglich sein: > > if Wert==TRUE Anweisung; // das dauert zu lange > > besser ist: > > if Wert Anweisung; > > Sehe ich auch so... war aber auch eigentlich nur sozusagen meine Arbeitsversion... > Ich optimiere eigentlich erst, wenn alles zur zufriedenheit läuft. > > > Auch das zwischenspeichern eines schon bestehenden Status sollte vermieden > > werden.(Rechenzeit) > > Gerade das Schreiben von Eproms - zeitkritisch und auch zeitaufwändig - wäre eigentlich > nicht unter dem Aspekt "Rechenzeit" zu sehen. Durch die Captures in den Funktionen > wartet die CC2 nur schneller :-) :-) :-) > Dazu komme ich aber gleich noch mal. > > > Ich werde mal sehen, ob ich eeprom.c2 irgendwie mir schon früher vornehme. > > Lass mich das doch machen... zumindest was den c2-Teil angeht... wenn der sauber ist, kannst > Du ihn evtl. auch leichter in asm umschreiben. Wenn wir weiter in kontakt bleiben, klapt das doch prima. > > Apropos.... > in den Funktionen read und write wird ja max. 120 ms auf das eeprom gewartet. 100 ms durch Timer, > ca. 20 ms durch die Laufzeit... ich würde das mal als "schnelles warten" bezeichnen. > Was hältst Du von folgender Konstruktion? > > function write(byte eepromaddr,int addr) returns int > { > byte i; > i=0; > eepromaddr= 160 or (eepromaddr shl 1); > loop > { > if i2c.start(eepromaddr) break; > if i>=100 return FALSE; > release; //--------------------------- Änderung, gibt Thread frei > i=i+5; > sleep 5; > capture i2c.flag; //--------------------------- Änderung, Thread ist gesperrt > } > i2c.write(addr shr 8); > i2c.write(addr); > return TRUE; > } > > Die Loopschleife wir ja durch break verlassen wenn der Versuch erfolgreich war. > Ist das Eprom nicht bereit, muß gewartet werden. In der Zeit könnten aber andere Threads laufen. > Das erreiche ich, in dem das Capture vor dem sleep freigegeben und nach dem sleep wieder gesetzt wird. > wärend des sleep hätte die CC2 Zeit, andere Treads zu bedienen da in der Zeit effektiv nichts auf dem i2c passiert. > Durch das setzen von 5 ms lohnt sich der Treadwechsel auch und es dürfte kaum zu verzögerungen kommen. > Das ganze nutzt also vor allem anderen Treads, die wärend des Schreibens des eeproms Rechenzeit benötigen. > > Eine Variante schnellere dazu ist folgende Konstruktion. > > function write(byte eepromaddr,int addr) returns int > { > byte i; > eepromaddr= 160 or (eepromaddr shl 1); > loop > { > if i2c.start(eepromaddr) break; > release; //--------------------------- Änderung, gibt Thread frei > yield > capture i2c.flag; //--------------------------- Änderung, Thread ist gesperrt > } > i2c.write(addr shr 8); > i2c.write(addr); > return TRUE; > } > > Bei dieser Version wird nicht mehr auf die Zeit von 100 ms geprüft sondern nur der Thread sofort abgegeben. > Das ist wohl das schnellste was man sich denken kann, leider würde ein defektes Eprom jedoch zu einer > dauerhaften und vorerst unentdeckten Threadschleife führen da die loop nicht verlassen werden kann. > Das widerum könte durch eine Verify-Funktion nach einer gewissen Zeit (wie oben schon angesprochen) > entdeckt und geprüft werden. (Da ja nun der Thread freigegeben wird(yield)). > > Was sagst Du zu den beiden Funktionen... welche Bedenken hast Du dazu und kannst Du dir vorstellen, > das eine der beiden oder gar beide wie gewünscht laufen? Ich will sie gleich testen, schicke aber erst mal die > "normale Version" mit Fixes. > > Gruß Rolf > > /**************i2c.stop();i2c.stop();****************************************************/ > /* Tri2c.stop();i2c.stop();eiberbibliothek für EEPROM 24C32 bis 24C512 */ > /* */ > /* Author : André Helbig (andre.h@cc2net.de) */ > /* Versi2c.stop();on : 2.3 */ > /* Datum : 7. Juli 2002 */ > /* Geändert : 12. Januar 2003 */ > /* Getestet : ja */ > /* Benötigt : i2c.c2 ab V1.1 */ > /******************************************************************/ > /* Geändert : Rolf Diesing, bezüglich Rückgabewerte V2.3a2 (FIX) */ > /* Überarbeitete Version zur Diskussion im Forum www.cc2net.de */ > /* Funktionsrückgabe TRUE bei Erfolg und FALSE bei Fehler. Die */ > /* Ausname: readbyte,readint,readlong geben den gelesenen Wert */ > /* Ersatz: getbyte,getint,getlong */ > /******************************************************************/ > /******************************************************************/ > /* eepromadr = 0 bis 7 */ > /******************************************************************/ > > const Pagewrite=128;//in Byte; siehe EEProm-Datenblatt > const FALSE = 0; > const TRUE = -1; > > /**Schreibzugriff einleiten****************************************/ > function write(byte eepromaddr,int addr) returns int > { > byte i; > i=0; > eepromaddr= 160 or (eepromaddr shl 1); > loop > { > if i2c.start(eepromaddr) break; > if i>=100 return FALSE; > i=i+1; > sleep 1; > } > i2c.write(addr shr 8); > i2c.write(addr); > return TRUE; > } > > /**einzelnes byte schreiben****************************************/ > function writebyte(byte eepromaddr,int addr, byte data) returns int > { > int i; > capture i2c.flag; > if write(eepromaddr,addr) > { > i2c.write(data); > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > } > > /**einzelnes Integer schreiben*************************************/ > function writeint(byte eepromaddr,int addr, int data) returns int > { > int i; > capture i2c.flag; > if write(eepromaddr,addr) > { > i2c.write((data & 0xFF00) shr 8); > i2c.write(data & 0x00FF); > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > } > > /**einzelnes long schreiben****************************************/ > function writelong(byte eepromaddr, int addr, long data) returns int > { > int i; > capture i2c.flag; > if write(eepromaddr,addr) > { > i2c.write((data & 0xFF000000) shr 24); > i2c.write((data & 0xFF0000) shr 16); > i2c.write((data & 0xFF00) shr 8); > i2c.write(data & 0xFF); > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > } > > /**Byte-Array schreiben*******************************************/ > function writebytearray(byte eepromaddr,int addr, byte data[], int len) returns int > { > int i; > capture i2c.flag; > if write(eepromaddr,addr) > { > for i=0 ... len-1 > { > if ((addr+i) % Pagewrite)==0 and i > {i2c.stop();//sleep 1; > write(eepromaddr,addr+i); > } > i2c.write(data[i]); > } > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > } > > /**Integer-Array schreiben***************************************/ > function writeintarray(byte eepromaddr,int addr, int data[], int len) returns int > // Für "addr" sollten nur geradzahlige Werte übergeben werden !! > // ggf. durch Fehlerfallprüfung return FALSE; ->FIXME<- r.diesing > { > int i; > capture i2c.flag; > if write(eepromaddr,addr) > { > for i=0 ... len-1 > { > if ((addr+i*2) % Pagewrite)==0 and i > {i2c.stop(); > write(eepromaddr,addr+i*2); > } > i2c.write((data[i] & 0xFF00) shr 8); > i2c.write(data[i] & 0x00FF); > } > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > } > > /**String schreiben**********************************************/ > function writestr(byte eepromaddr,int addr, byte s[]) returns int > { > byte a; > int i; > capture i2c.flag; > if write(eepromaddr,addr) > { > for a=0 ... 31 > { > if ((addr+a) % Pagewrite)==0 and a > {i2c.stop(); > write(eepromaddr,addr+a); > } > i2c.write(s[a]); > } > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > } > > /**Lesezugriff einleiten*******************************************/ > function read(byte eepromaddr,int addr) returns int > {byte i; > i=0; > eepromaddr= 160 or (eepromaddr shl 1); > loop > { > if i2c.start(eepromaddr) break; > if i>=100 return FALSE; > i=i+1; > sleep 1; > } > i2c.write(addr shr 8); > i2c.write(addr); > i2c.start(eepromaddr or 1); > return TRUE; > } > > /**einzelnes byte lesen********************************************/ > function readbyte(byte eepromaddr,int addr) returns byte > { > byte data; > capture i2c.flag; > if read(eepromaddr,addr) > { > data=i2c.readlast(); > } > i2c.stop(); > release; > return data; > } > > /**einzelnes Integer lesen*****************************************/ > function readint(byte eepromaddr,int addr) returns int > { > int data; > capture i2c.flag; > if read(eepromaddr,addr) > { > data=i2c.read() shl 8; > data = addr or i2c.readlast(); > } > i2c.stop(); > release; > return data; > } > > /**einzelnes long lesen********************************************/ > function readlong(byte eepromaddr, int addr) returns long > { > long data; > capture i2c.flag; > if read(eepromaddr,addr) > { > data = i2c.read() shl 8; > data = (data or i2c.read()) shl 8; > data = (data or i2c.read()) shl 8; > data = data or i2c.readlast(); > } > i2c.stop(); > release; > return data; > } > > /**Byte-Array lesen***********************************************/ > function readbytearray(byte eepromaddr,int addr, byte data[], int len) returns int > { > int i; > if len < 1 return FALSE; > capture i2c.flag; > if read(eepromaddr,addr) > { > for i=0 ... len-2 > { > data[i] = i2c.read(); > } > data[len-1] = i2c.readlast(); > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > } > > /**Integer-Array lesen*******************************************/ > function readintarray(byte eepromaddr,int addr, int data[], int len) returns int > { > int i; > if len < 1 return FALSE; > capture i2c.flag; > if read(eepromaddr,addr) > { > for i=0 ... len-2 > { > data[i] = (i2c.read() shl 8) or i2c.read(); > } > data[len-1] = (i2c.read() shl 8) or i2c.readlast(); > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > } > > /**String lesen**************************************************/ > function readstr(byte eepromaddr,int addr, byte s[]) returns int > { > byte a; > int i; > capture i2c.flag; > if read(eepromaddr,addr) > { > for a=0 ... 30 > { > s[a] = i2c.read(); > } > s[31] = i2c.readlast(); > i=TRUE; > } > else > i=FALSE; > i2c.stop(); > release; > return i; > }