Es müssen 2 CAN-Geräte gekoppelt werden, die sich erstmal nicht verstehen. AT90CAN128/16MHz + MCP2515, also 2 getrennte Bussysteme. Compiler CodeVision. Läuft auf beiden Seiten mit 500kbit und die Daten und IDs müssen hübsch durcheinandergewürfelt werden. Im Prinzip funktionierts, allerdings bekomme ich bei hoher Buslast Zeitprobleme. Hauptverursacher ist folgende Routine: void copy_bit_up (uchar s_botschaft, uchar s_byte, uchar s_bit, uchar d_botschaft, uchar d_byte, uchar d_bit) {if (CAN_Matrix1[s_botschaft].data[s_byte] & (1<<s_bit)) CAN_Matrix2[d_botschaft].data[d_byte]|= (1<<d_bit); //Bit setzen else CAN_Matrix2[d_botschaft].data[d_byte]&= ~(1<<d_bit); //Bit löschen } copy_bit_up (6,1,4,4,1,7); //source Botschaft, source byte_nr, source bit_nr, dest_Botschaft, dest_byte_nr, dest_bit_nr Generatorleuchte Das dauert über 200 Takte... Lösung2: if (CAN_Matrix1[Botschaft6].data[byte1] & (0x10)) CAN_Matrix2[Botschaft4].data[byte1]|= (0x80); //Bit setzen else CAN_Matrix2[Botschaft4].data[byte1]&= ~0x80; Im Gegenzug mit absoluten Werten nur ca. 20 Takte Und da ich ca. 150 Bits je Richtung umsortieren muss, gerät das ganze schnell an Grenzen. Codespeicher hätte ich genug, allerdings möchte ich mir es nicht antun, Lösung2 300 mal zu schreiben, das ist zu fehlerträchtig. Und nun die eigentliche Frage: Gibt es eine Möglichkeit, dieses ähnlich guter alter Assembler-Macro-Programmierung zu lösen?
Hallo! Mal etwas naiv gefragt, Codespeicher hast Du genug, was spricht denn gegen eine look up table ?? mfg, Bjoern
Moin, Den Ausdruck (1<<x) durch Tabellen ersetzen sollte schon einiges bringen, ist auch noch nicht zu groß. Ich würde auch noch eine getrennte Tabelle für die negierten Werte machen. Arbeitet der Compiler bei den logischen Operationen mit 16 oder 8 Bit? Ein Typcasting auf 8 Bit bringt manchmal auch noch etwas.
Vielleicht etwas optimieren: Du berechnest 2 mal 1<<d_bit. Das kannst du in einer Variable speichern. Dann der Datentyp: Welche Werte können (1<<d_bit) bzw. (1<<s_bit) annehmen? Laut deinem Beispiel könnte das nur ein Byte sein, der Compiler wird aber wahrscheinlich ein int daraus machen. Also explizite typumwandlungen vornehmen: ((unsigned char)(1<<d_bit)) Macroprogrammierung kannst du mit Templates machen (wenn der compiler das kann)
Wie wärs, gleich beim Aufruf statt der Bitnummer die Bitmaske zu übergeben ? Dann entfällt die zeitraubende Schieberei. Dem GCC ist leider in Vergleichsausdrücken das 16Bitten selbst mit cast nicht abzugewöhnen. Erst wenn man den Wert in einer 8Bit-Variablen ablegt, muß er notgedrungen nur 8Bit vergleichen, z.B. wenn die Maske schon als 8Bit vorliegt. Peter
So, gerade mal die Funktion mit konstanter Bitadresse compiliert statt der Schieberei void copy_bit_up_test(uchar s_botschaft, uchar s_byte, uchar d_botschaft, uchar d_byte) {if (CAN_Matrix1[s_botschaft].data[s_byte] & (0x80)) CAN_Matrix2[d_botschaft].data[d_byte]|= (0x40); //Bit setzen else CAN_Matrix2[d_botschaft].data[d_byte]&= ~(0x40); //Bit löschen } Da sind es nur noch 130 Takte, dazu käme ja noch der Tabellenzugriff + Parameterübergabe, das wird nicht die Lösung werden. Ich möchte schon zur Compile-Zeit die Bitadresse ausrechnen lassen. Was sind templates? Klingt erstmal interessant.
Wie wird denn copy_bit_up_test() aufgerufen ? Wenn die Argumente Konstanten sind, dann ist es besser gleich beim Aufruf die Adresse zu übergeben, statt erst umständlich ne 2-fache Indirektion ausrechnen zu lassen. Peter
Logisch, direkt die Bitmaske zu übergeben, ist natürlich effektiver. Kam wohl daher, dass im CAN-Funktionsrahmen die Bitvariablen mit Botschaft: ByteNr:BitNr angegeben sind:-) Aber es ist auch nicht die Lösung, braucht 140 Takte
copy_bit_up_test (6,1,0x10,4,1,0x80); //source Botschaft, source byte_nr,source_bit_mask, dest_Botschaft, dest_byte_nr, dest_bit_mask Die Variablen selbst: typedef struct { unsigned int id; unsigned char rtr; unsigned char length; unsigned char data[8]; } CANMessage; CANMessage CAN_Matrix1[24]; CANMessage CAN_Matrix2[24];
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.