Hallo Leute, ich habe eine I2C Kommunikationsschnittstelle, die schnell reagieren muss. So dachte ich mir, es wäre effizienter CMD-Byte aus dem Datenstream zu extrahieren und gezielt eine entsprechende Funktion ausführen, ohne dabei viel Zeit mit IF oder SWITCH- Abfragen zu verlieren. Mach es Sinn sich was in diese Richtung zu überlegen? Also ich habe mir vorgestellt, zu jedem CMD eine entsprechende Funktion zu erstellen und diese dann aufzurufen, z.B. CMD "0x0A" wird in der Funktion translate_cmd() erkannt und ruft folglich die Funktion f_A() auf. Geht sowas überhaupt?
Du könntest dir ein Array mit Function-Pointern anlegen! Das 0x0A wäre dann der Index für das Array, wo der Pointer auf die entsprechende Funktion hinterlegt ist!
@ Gast (Gast) >Hallo Leute, ich habe eine I2C Kommunikationsschnittstelle, die schnell >reagieren muss. Naja, hast du schonmal über die Relationen nachgedacht? I2C arbeitet mit 100..400 kbit/s, macht ~11..44 kBytes/s, sprich 23..90us/Byte. Eine CPU mit beispielsweise 8 MHz macht in der Zeit ~184..736 Takte. Das sollte reichen, um einen normalen switch() auszuwerten. MFG Falk
Gast wrote: > Hallo Leute, ich habe eine I2C Kommunikationsschnittstelle, die schnell > reagieren muss. So dachte ich mir, es wäre effizienter CMD-Byte aus dem > Datenstream zu extrahieren und gezielt eine entsprechende Funktion > ausführen, ohne dabei viel Zeit mit IF oder SWITCH- Abfragen zu > verlieren. > > Mach es Sinn sich was in diese Richtung zu überlegen? Ja. Macht nicht nur wegen der gesparten Auswertezeit sinn, sondern, du wirst es gleich sehen, man dadurch eine sehr wartungsfreundliche Struktur bekommt. Voraussetzungen: Deine CMD-Bytes sollten aufsteigend vergeben werden. > Also ich habe mir > vorgestellt, zu jedem CMD eine entsprechende Funktion zu erstellen und > diese dann aufzurufen, z.B. CMD "0x0A" wird in der Funktion > translate_cmd() erkannt und ruft folglich die Funktion f_A() auf. Geht > sowas überhaupt?
1 | typedef void (*Function)( void ); |
2 | |
3 | void process_00() // Bearbeitet das Commando mit Cmd Code 0x00 |
4 | {
|
5 | }
|
6 | |
7 | void help() // Bearbeitet das Commando mit Cmd Code 0x01 |
8 | {
|
9 | }
|
10 | |
11 | void shutdown() // Bearbeitet das Commando mit Cmd Code 0x02 |
12 | {
|
13 | }
|
14 | |
15 | void stop() // Bearbeitet das Commando mit Cmd Code 0x04 |
16 | {
|
17 | }
|
18 | |
19 | Function CmdFunctions[] = |
20 | {
|
21 | process_00, // Commando = 0x00 |
22 | help, // 0x01 |
23 | shutdown, // 0x02 |
24 | NULL, // für 0x03 gibt es keine Behandlung |
25 | stop // 0x04 |
26 | };
|
27 | |
28 | #define ARRAY_SIZE(X) ( sizeof(X) / sizeof(*(X)) )
|
29 | |
30 | void translate_cmd( uint8_t Code ) |
31 | {
|
32 | if( Code > ARRAY_SIZE( CmdFunctions ) ) |
33 | return; |
34 | |
35 | Function Fnc = CmdFunctions[ Code ]; // Funktion bestimmen |
36 | if( Fnc != NULL ) |
37 | (*Fnc)(); // Funktion aufrufen |
38 | }
|
Siehe auch: http://www.mikrocontroller.net/articles/FAQ#Funktionszeiger
@ iaby: ich schaue, ob es dadurch schneller wird @ falk: das ist mir klar, doch bin ich in der Situation, wo ich es nöttig habe und ab 115 Abfragen nichts mehr geht. @ Karl: vielen Dank für die Anregung
Falk Brunner wrote: > Naja, hast du schonmal über die Relationen nachgedacht? > > I2C arbeitet mit 100..400 kbit/s, macht ~11..44 kBytes/s, sprich > 23..90us/Byte. Eine CPU mit beispielsweise 8 MHz macht in der Zeit > ~184..736 Takte. Das sollte reichen, um einen normalen switch() > auszuwerten. Wie schon gesagt, wenn du richtig viele Befehle hast? Außerdem heißt I2C nicht automatisch immer 100 oder 400kbit/s. Das originale I2C vielleicht. Aber man kann ja den I2C Bus auch mit höheren Frequenzen betreiben.
I2C - gepollt oder per IRQ? Polling frisst natürlich gewaltig viel Rechenzeit wenn die CPU auf die daten warten muss.
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.