Hallo zusammen,
ich nutze bei meinem aktuellen Projekt für die Konfiguration das TunerStudio. Das ist ein Tool, mit dem die Steuergeräte konfiguriert und appliziert werden. Das ist richtig cool gemacht. Für die Konfiguration wird eine INI-Datei angelegt, in der unter anderen die eigentliche Konfiguration des Steuergerätes beschrieben wird, bei mir sieht sie zum Beispiel so aus:
CodeBox C
Wie man sieht, besteht die Konfig aus drei U08 Bytes (entspricht uint8_t) und zwei U16 (was uint16_t entspricht) Bytes, also insgesamt 9 Byte lang.
Das ist zum Beispiel das Menü um den Byte 0 und 2 zu konfigurieren:

Und hier werden Byte 1 und der Rest konfiguriert:

Insgesamt umfasst die Konfig 9 Byte im EEPROM der MCU. So weit, so gut. Wenn man jedoch Byte 0 und 1 anschaut, sieht man eigentlich eine Mischung als Bitfelder ( mit der Größe) und ENUM (mit den möglichen Werten, INVALID bedeutet, dass dieser Wert nicht angezeigt wird).
In der MCU ist es wie folgt angelegt:
1. Initialie Konfig:
CodeBox C
2. Wird beim Start gelesen und in den RAM gepackt:
CodeBox C
Das funktioniert alles sehr gut.
Nun wird das ganze in einen Struct gepackt:
CodeBox C
Nun kann ich über die Struct-Member auf die Daten zugreifen:
CodeBox C
Auch das geht.
Wenn man sich jetzt zum Beispiel die Zeile
CodeBox C
Finde ich jetzt ehrlich gesagt nicht so prickelnd....
Gibt es eine elegantere Möglichkeit sowas zu lösen?
Vielen Dank Euch!
ich nutze bei meinem aktuellen Projekt für die Konfiguration das TunerStudio. Das ist ein Tool, mit dem die Steuergeräte konfiguriert und appliziert werden. Das ist richtig cool gemacht. Für die Konfiguration wird eine INI-Datei angelegt, in der unter anderen die eigentliche Konfiguration des Steuergerätes beschrieben wird, bei mir sieht sie zum Beispiel so aus:
CodeBox C
isCANEnabled = bits, U08, 0, [0:0], "false", "true" canSpeed = bits, U08, 0, [1:2], "125kbit", "250kbit", "500kbit", "1mbit" interfaceActivation = bits, U08, 0, [3:3], "Input", "CAN" isCANDebugEnabled = bits, U08, 0, [4:4], "false", "true" unused1 = bits, U08, 0, [5:7], "1", "2", "3", "4", "5", "6", "7", "8" isChannel1Enabled = bits, U08, 1, [0:0], "false", "true" isChannel2Enabled = bits, U08, 1, [1:1], "false", "true" channel1OutputMode = bits, U08, 1, [2:3], "Analog", "CAN", "Analog & CAN", INVALID channel2OutputMode = bits, U08, 1, [4:5], "Analog", "CAN", "Analog & CAN", INVALID channel1AnalogOutputMode = bits, U08, 1, [6:6], "Wideband", "Narrowband emulation" channel2AnalogOutputMode = bits, U08, 1, [7:7], "Wideband", "Narrowband emulation" stoich_ratio = scalar, U08, 2, ":1", 0.1, 0.0, 0.0, 25.5, 1 channel1CANid = bits, U16, 3, [0:10], $CAN_ADDRESS_HEX channel2CANid = bits, U16, 5, [0:10], $CAN_ADDRESS_HEX debugMessageID = bits, U16, 7, [0:10], $CAN_ADDRESS_HEX
Wie man sieht, besteht die Konfig aus drei U08 Bytes (entspricht uint8_t) und zwei U16 (was uint16_t entspricht) Bytes, also insgesamt 9 Byte lang.
Das ist zum Beispiel das Menü um den Byte 0 und 2 zu konfigurieren:

Und hier werden Byte 1 und der Rest konfiguriert:

Insgesamt umfasst die Konfig 9 Byte im EEPROM der MCU. So weit, so gut. Wenn man jedoch Byte 0 und 1 anschaut, sieht man eigentlich eine Mischung als Bitfelder ( mit der Größe) und ENUM (mit den möglichen Werten, INVALID bedeutet, dass dieser Wert nicht angezeigt wird).
In der MCU ist es wie folgt angelegt:
1. Initialie Konfig:
CodeBox C
uint8_t eeprom_config[] EEMEM = {0x03, 0x03, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2. Wird beim Start gelesen und in den RAM gepackt:
CodeBox C
uint8_t controllerSettings[sizeof(eeprom_config)]; eeprom_read_block((void*)controllerSettings, (const void*) eeprom_config, sizeof(eeprom_config));
Das funktioniert alles sehr gut.
Nun wird das ganze in einen Struct gepackt:
CodeBox C
typedef struct { // first byte in the config: uint8_t isCanEnabled : 1; uint8_t canSpeed : 2; uint8_t interfaceActivation : 1; uint8_t isCANDebugEnabled : 1; uint8_t unused1 : 3; // second byte in the config: uint8_t isChannel1Enabled : 1; uint8_t isChannel2Enabled : 1; uint8_t channel1OutputMode : 2; uint8_t channel2OutputMode : 2; uint8_t channel1AnalogOutputMode : 1; uint8_t channel2AnalogOutputMode : 1; // third by in the config: uint8_t stoich_ratio; uint16_t channel1CANid; uint16_t channel2CANid; uint16_t debugMessageID; } tConfig; tConfig* configuration = (tConfig*)controllerSettings;
Nun kann ich über die Struct-Member auf die Daten zugreifen:
CodeBox C
if (configuration->isCanEnabled == 1) { uart2_sendS((uint8_t*) "CAN ist enabled\n\r", 17); }
Auch das geht.
Wenn man sich jetzt zum Beispiel die Zeile
anschaut, sieht man, dass es eigentlich ein enum mit vier Member ist und im Bitfeld steht dann entsprechend 0x00, 0x01, 0x10 und 0x11 diese vier Werte eben. Wenn ich es jetzt in was "Brauchbares" übersetzen müsste, müsste ich einen enum mit den vier Werten anlegen und das Bitfeld drauf casten:canSpeed = bits, U08, 0, [1:2], "125kbit", "250kbit", "500kbit", "1mbit"
CodeBox C
typedef enum { can_125 , can_250 , can_500 , can_1000 } tCANSpeed; ..... switch ((tCANSpeed) configuration->canSpeed) { case can_125: // mach was break; case can_250: // mach was break; case can_500: // mach was break; case can_1000: // mach was break; }
Finde ich jetzt ehrlich gesagt nicht so prickelnd....
Gibt es eine elegantere Möglichkeit sowas zu lösen?
Vielen Dank Euch!