Hallo!
Anhand des unter
https://github.com/BoschSensortec/BME680_driver
geliefeten Codes von Bosch versuche ich den o.g. Sensor zum Leben zu
erwecken.
Die Datei README.md liefert eine Schritt-für-Schritt-Anleitung, dessen
Schritte mir leider zu groß sind.
Beispiel:
int8_trslt=0;/* Return 0 for Success, non-zero for failure */
42
43
/*
44
* The parameter dev_id can be used as a variable to store the I2C address of the device
45
*/
46
47
/*
48
* Data on the bus should be like
49
* |------------+---------------------|
50
* | I2C action | Data |
51
* |------------+---------------------|
52
* | Start | - |
53
* | Write | (reg_addr) |
54
* | Write | (reg_data[0]) |
55
* | Write | (....) |
56
* | Write | (reg_data[len - 1]) |
57
* | Stop | - |
58
* |------------+---------------------|
59
*/
60
61
returnrslt;
62
}
Die mit "!" gekennzeichneten Zeilen verstehe ich nicht. Ich vermute, der
Anwender soll seinem Code entsprechend I2C-Anweisungen durchführen. Aber
wie nur?
Die von Dir angesprochen Zeilen musst du selber Implementieren. Da dies,
von dem von dir verwendeten Micocontroller abhängig ist, macht es keinen
Sinn Source Code anzugeben.
Viele Grüße
Sven G. schrieb:> Die von Dir angesprochen Zeilen musst du selber Implementieren.
Das hab´ich mir schon gedacht.. Nur, im ersten Abschnitt INIT, wird die
Struktur gas_sensor.read mittels Funktion user_i2c_read; befüllt.
Warum ist denn dort nicht die Parameterliste angegeben?
dev_id, reg_addr, *reg_data, len angegeben?
Stephan schrieb:> Sven G. schrieb:>> Die von Dir angesprochen Zeilen musst du selber Implementieren.>> Das hab´ich mir schon gedacht.. Nur, im ersten Abschnitt INIT, wird die> Struktur gas_sensor.read mittels Funktion user_i2c_read; befüllt.>
NEIN!
Da wird ein Ptr auf eine Funktion zugewiesen!
> Warum ist denn dort nicht die Parameterliste angegeben?> dev_id, reg_addr, *reg_data, len angegeben?
Weil es KEIN Funktionsaufruf ist!
Stephan schrieb:> Die mit "!" gekennzeichneten Zeilen verstehe ich nicht. Ich vermute, der> Anwender soll seinem Code entsprechend I2C-Anweisungen durchführen.
Bei den gekennzeichneten Stellen mußt du Zeiger auf deine Funktionen
zum Zugriff auf I2C (oder SPI) und für eine Delay-Funktion einfügen.
Falls du das Konzept function pointer noch nicht kennst, ist jetzt
genau der richtige Zeitpunkt, das nachzulesen.
Weiter unten sind leere Funktionsrümpfe für diese Funktionen gezeigt,
aus denen du ersehen kannst, welche Parameter der Code von Bosch
übergibt, wenn er deine Funktionen aufruft und welches Ergebnis er
jeweils erwartet.
In bme680_defs.h findest du auch die typedefs für die function pointer
und Makros für die erwarteten Rückgabewerte (z.B. BME680_OK, wenn alles
glatt gelaufen ist).
Vielen Dank Axel. Über Funktionspointer bin ich tatsächlich noch nicht
gestolpert. Und, ich muss gestehen, dass mich die Lektüre des Artikels
unter https://www.mikrocontroller.net/articles/Funktionszeiger_in_C nur
mehr verwirrt hat. Zitat: "Um Menüs oder ähnliche Dinge aufzubauen, ist
es oft praktisch, ein Array von Funktionszeigern zu definieren." Wo ist
da der zusammenhang?!
Ich vermute stark, ich muss das u.g. Template mit Leben füllen. Vermute
ferner, dass ich eine Funktion implementieren soll, dessen Rückgabewert
der BME-Antwort gemäß Parameterliste entspricht. Nur warum ist der
Rückgabewert ein int8_t?
[c]
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t
*reg_data, uint16_t len)
{
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
/*
* The parameter dev_id can be used as a variable to store the I2C
address of the device
*/
/*
* Data on the bus should be like
* |------------+---------------------|
* | I2C action | Data |
* |------------+---------------------|
* | Start | - |
* | Write | (reg_addr) |
* | Stop | - |
* | Start | - |
* | Read | (reg_data[0]) |
* | Read | (....) |
* | Read | (reg_data[len - 1]) |
* | Stop | - |
* |------------+---------------------|
*/
return rslt;
}
[/]
:(
Stephan schrieb:> Vielen Dank Axel. Über Funktionspointer bin ich tatsächlich noch nicht> gestolpert. Und, ich muss gestehen, dass mich die Lektüre des Artikels> unter https://www.mikrocontroller.net/articles/Funktionszeiger_in_C nur> mehr verwirrt hat. Zitat: "Um Menüs oder ähnliche Dinge aufzubauen, ist> es oft praktisch, ein Array von Funktionszeigern zu definieren." Wo ist> da der zusammenhang?!
Dieser Zusammenhang ist in der Tat nicht zwingend. Die hauptsächliche
Verwendung von Funktionspointern sind Callback-Funktionen
(https://de.wikipedia.org/wiki/Rückruffunktion)
Ganz konkret füllst du für die Treiber-Software von Bosch eine Struktur
mit Funktionszeigern und der Treiber ruft deine Funktionen immer dann
auf (Callback) wenn er es für nötig befindet. Der Vorteil besteht an
dieser Stelle darin, daß der exakt gleiche Code von Bosch verwendet
werden kann, um den Sensor abzufragen, vollkommen egal ob der Sensor per
I²C oder SPI angebunden ist, wie das Interface konkret aufgebaut ist und
sogar, ob es vielleicht mehrere solche Sensoren am gleichen Bus gibt.
Und das einfach nur, indem du ein paar passende Funktionen für die
low-Level Kommunikation mit dem Sensor schreibst und Zeiger auf (im
Quelltext praktisch: die Namen für) diese Funktionen in eine Struktur
füllst.
> Ich vermute stark, ich muss das u.g. Template mit Leben füllen. Vermute> ferner, dass ich eine Funktion implementieren soll, dessen Rückgabewert> der BME-Antwort gemäß Parameterliste entspricht. Nur warum ist der> Rückgabewert ein int8_t?
Das ist der kleinste Wert, den eine Funktion in C zurückgeben kann. Und
tatsächlich erwartet die Bosch Software ja auch nur entweder 0 oder
einen von 0 verschiedenen Wert.