www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Funktionsdeklaration und -aufruf


Autor: Sascha W. (bucky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

um den mitgelieferten Code des Bosch BMP085 Drucksensors ans Laufen zu 
bringen, muss ich die Lese und Schreibfunktion entsprechend dem mir 
verwendeten Bus (TWI/I²C) ergänzen. Diese beginnt bei mir wie folgt und 
funktioniert auch bei manuellem Aufruf:
char bus_read(unsigned char device_addr, unsigned char register_addr, unsigned char *register_data, unsigned char read_length )
(Einmal in der Headerdatei als Prototyp, einmal in der C-Datei mit 
Inhalt)


Der Code von Bosch möchte diese nun aber wie folgt benutzen und mangels 
Erfahrung weiß ich nicht, wie ich die oben genannte Funktion Erstellen 
muss:
p_bmp085->BMP085_BUS_READ_FUNC(p_bmp085->dev_addr, BMP085_CHIP_ID__REG, &data, 1);  /* read Chip Id */

p_bmp085 zeigt auf eine Struct mit diesem Inhaltsauszug:
BMP085_BUS_RD_RETURN_TYPE (*bus_read)( BMP085_BUS_RD_PARAM_TYPES );

mit
#define BMP085_BUS_RD_RETURN_TYPE char
und
#define BMP085_BUS_RD_PARAM_TYPES unsigned char,unsigned char,unsigned char *,unsigned char
sowie
#define BMP085_BUS_READ_FUNC(device_addr, register_addr, register_data, read_length)\
bus_read( device_addr, register_addr, register_data, read_length )

Blickt da wer durch? Abweichend von meiner Lösung sollen ja wohl der 
Return-Typ und die Übergabevariablen durch die in der Headerdatei zu 
findenden Konstanten gesetzt werden. Nur wie?

: Gesperrt durch Moderator
Autor: Ampfing (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

wieso willst Du das was ersetzen? Sollte doch so funktionieren.
BMP085_BUS_RD_RETURN_TYPE (*bus_read)( BMP085_BUS_RD_PARAM_TYPES );
Stellt Dir einen Funktionspointer zur Verfügung, der als Rückgabewert 
BMP085_BUS_RD_RETURN_TYPE hat und als Parameter 
BMP085_BUS_RD_PARAM_TYPES erwartet (also genau Deine bus_read-Funktion).
Müsstest wohl lediglich noch Deinen Header in den Bosch-Code 
integrieren, sonst dürfte der Linker nen Fehler bringen (oder alternativ 
vor die oben zitierte Zeile ein extern setzen).
Ein #define macht nicht anderes als eine reine Textersetzung.

Gruß

Autor: Sascha W. (bucky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sprich ich lasse meine Funktion wie sie ist, mit fest vergebenem 
Rückgabewert und Übergabeparamtern, lasse aber "meinen" Prototypen in 
der Header weg, weil das Erzeugen des von dir genannten Funktionspointer 
die Funktion des Prototypen im Header übernimmt?

Sorry,

ich habe bisher noch nie abseits von Minibeispielen mit Pointern 
gearbeitet und kannte den -> Operator bis eben garnicht, daher die 
Verständnisprobleme.

Autor: Sascha W. (bucky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zur Vollständigkeit, dies ist die ganze Funktion die ich geschrieben 
habe und die erfolgreich vom Chip ließt wenn ich sie direkt in der 
main() aufrufe. Nur wie ich diese jetzt mit dem Bosch Code mit den 
genannten Elementen verheirate weiß ich nicht.
char bus_read(unsigned char device_addr, unsigned char register_addr, unsigned char *register_data, unsigned char read_length )
{
uint8_t i;
 
    //I2C Starten mit device_adresse und WRITE
  TWIM_Start (device_addr, TWIM_WRITE);
  //I2C register_addr schreiben
   TWIM_Write (register_addr);
  //I2C restart mit READ
    TWIM_Start (device_addr, TWIM_READ);
 
  for(i=0;i<read_length;i++)
  {
     if(i<read_length - 1)
    {
      //I2C lesen mit ACK
       *register_data = TWIM_ReadAck();
       register_data++;
    }
    else
    {
      //I2C lesen mit NACK
       *register_data = TWIM_ReadNack();
       //register_data++;
    }
  }
    //I2C STOP
  TWIM_Stop();
  return 0;
}


Der Boschcode möchte diese dann so einsetzen (gekürzt):
int bmp085_init(bmp085_t *bmp085) 
{
  char comres=0;
  unsigned char data;

  p_bmp085 = bmp085;                                      /* assign BMP085 ptr */
  p_bmp085->dev_addr = BMP085_I2C_ADDR;                   /* preset BMP085 I2C_addr */
  comres += p_bmp085->BMP085_BUS_READ_FUNC(p_bmp085->dev_addr, BMP085_CHIP_ID__REG, &data, 1);  /* read Chip Id */
.
.
.
  return comres;

}

Autor: Sascha W. (bucky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die von mir genannten Infos nicht ausreichen kann ich gern auch 
noch weitere Codesegmente nennen. So schwer kann das doch nicht sein... 
In meiner C-Referenz wird diese Art der Zeigernutzung und Deklaration 
auch nicht wirklich behandelt, evtl. hat ja jemand einen Link zu einer 
geeigneten Quelle oder einem Beispiel

Danke,

Bucky

Autor: nicht Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
c von a bis z

Autor: Sascha W. (bucky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@nicht Gast: Darauf wäre ich nun ja kaum gekommen... Nur muss ich 
zugeben auch bei der Suche einer Matheformel selten Algebra und Analysis 
1-3 erneut komplett durchzuarbeiten. Wenn es wirklich so einfach ist, 
dass ich durch erneutes Lesen der theoretischen Grundlagen sofort die 
Anwendung im konkreten Fall erkenne (erkennen sollte), dann bitte ich 
Dich doch es mir hier in 2 Sätzen zu erklären...

Autor: Er (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Darauf wäre ich nun ja kaum gekommen...

Was soll die Ironie?
Du hast doch selbst danach gefragt:
>hat ja jemand einen Link zu einer geeigneten Quelle

Die Antwort hast Du nun.

Klugschwatzen können wir auch alleine.
Und Dein Code is ist nun sowas von einer simplen Anwendung einer 
Funktion.

>Wenn es wirklich so einfach ist, dass ich durch erneutes Lesen der >theoretischen 
Grundlagen sofort die Anwendung im konkreten Fall erkenne >(erkennen sollte), dann 
bitte ich Dich doch es mir hier in 2 Sätzen zu >erklären...

Warum da das Letztere aus dem Ersteren folgt, leuchtet mir nicht ein. 
Umgekehrt wird ein Schuh d'raus: Wenn es so einfach ist, dann lies es 
doch!

Autor: Sascha W. (bucky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ihr (Du) bist also der Meinung, das diese Art der Zeigerverwendung ein 
Standardfall ist? Nun gut, passt mit meiner Definition von Standard 
nicht zusammen wenn man es so selten sieht, sei es drum. Ich verstehe 
diese unguten Gefühle in diesem und manchen anderen Foren nicht, in 1001 
anderen Gebieten zeige ich Dir was fundiertes Wissen ist, in der µC/C 
Programmierung bist Du es der mir voraus ist. Wo ist denn das Problem 
sich zu helfen, insbesondere wenn es so simpel zu sein scheint?

Dieses Gebiet, die µC Programmierung ist für mich ein Mittel zum Zweck 
und wird es wohl auch immer bleiben. Jedes Thema von A-Z fundiert selbst 
erarbeiten, in allen Gebieten der Ingenieurstechnik mit denen man in 
Kontakt kommt? Sorry, habe ich keine Zeit für und Effektivität ist etwas 
anderes...

Entschuldigt dies hier nun hin zu ballern, da ich weiß das ich nur eine 
einzelne Person anspreche und auch hier im Forum nach wie vor 
hilfsbereite Menschen mitlesen und posten...

Es geht doch nur um eine kurze Erklärung damit ich diese Konstellation 
verstehen und benutzen kann:
comres += p_bmp085->BMP085_BUS_READ_FUNC(p_bmp085->dev_addr, BMP085_CHIP_ID__REG, &data, 1);  /* read Chip Id */
mit
BMP085_BUS_RD_RETURN_TYPE (*bus_read)( BMP085_BUS_RD_PARAM_TYPES );

Autor: Er (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ihr (Du) bist also der Meinung, das diese Art der Zeigerverwendung ein
>Standardfall ist?
Wo habe ich_ von _Standard geschrieben? Ich habe geschrieben "simpel".

>Nun gut, passt mit meiner Definition von Standard
>nicht zusammen wenn man es so selten sieht, sei es drum.
Mag sein. Aber was heisst das schon? Erstens ist die Frage ob etwas zum 
Standard wird, wenn es so und so häufig vorkommt reine Definitionssache. 
Wenn Du jeden Tag 8 Stunden Shakespeare liest muss Dir sowas exotisch 
vorkommen. Na und? Zweitens gibt es noch die Bedeutung, das etwas per 
Definition zum Standard wird, wie etwa eine DIN oder ISO. Und da sind 
diese Teilausdrücke unter einer ANSI-Norm erfasst. Also Standard, auch 
wenn ich das noch garnicht behauptet habe.

>Ich verstehe diese unguten Gefühle in diesem und manchen anderen Foren >nicht, in
>1001 anderen Gebieten zeige ich Dir was fundiertes Wissen ist, >in der µC/C
>Programmierung bist Du es der mir voraus ist. Wo ist denn das >Problem sich zu
>helfen, insbesondere wenn es so simpel zu sein scheint?

Darum geht es garnicht. Ich war negativ berührtv von Deiner Reaktion. 
Die entsprechende Antwort habe ich ja schon gegeben.

>Sorry, habe ich keine Zeit für und Effektivität ist etwas anderes...

Das passt voll in das Bild das ich mir von Dir mache. Dir_ ist _Deine 
Zeit zu schade, aber unsere Zeit ist Dir nicht zu schade. Uns (wobei ich 
nicht wirklich berechtigt bin für alle hier zu schreiben) sind Fragen 
lieber die interessant sind. Die tausendste Frage nach Funktionszeigern 
ist nunmal aus unserer Sicht "effektiver" mit dem Hinweis auf den 
"Standard" zu beantworten.

>Entschuldigt dies hier nun hin zu ballern, da ich weiß das ich nur eine
>einzelne Person anspreche und auch hier im Forum nach wie vor
>hilfsbereite Menschen mitlesen und posten...
Ja. Jeden Tag steht ein Dummer auf. Genau.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bucky 2k schrieb:
> Ihr (Du) bist also der Meinung, das diese Art der Zeigerverwendung ein
> Standardfall ist? Nun gut, passt mit meiner Definition von Standard
> nicht zusammen wenn man es so selten sieht, sei es drum.

Du meinst, du hast das bisher selten gesehen.
Mag sein. Tatsächlich kommt das aber so selten gar nicht vor.
Jeder der des öfteren die Funktion qsort aus dem Standardvorrat an 
Funktionen benutzt (ein Array sortieren), benutzt auch Funktionszeiger.

http://www.mikrocontroller.net/articles/FAQ#Funktionszeiger

(Und wenn in deiner Referenz Funktionszeiger nicht vorkommen, dann 
schmess sie weg und benutze ein vernünftiges C-Buch und arbeite es 
durch.)

> Jedes Thema von A-Z fundiert selbst erarbeiten, in allen Gebieten
> der Ingenieurstechnik mit denen man in Kontakt kommt?

Wenn du letztendes für dein Produkt gradestehen musst, dann bleibt dir 
nichts anderes übrig. Das ist das Wesen eines Ingenieurs.

> Sorry, habe ich keine Zeit für und Effektivität ist etwas
> anderes...

Eben. Genau darum gibt es auch Spezialisten auf jedem Gebiet der 
Ingenieurstechnik, die das alles von der Pieke auf gelernt haben und 
beherrschen. Und genau aus dem Grund, weil sie es beherrschen, besitzen 
sie die Unverfrorenheit dafür auch noch Geld zu verlangen.
Warum glaubt eigentlich jeder, dass man Progammieren mit einem 
Schnellsiederkurs in 2 Nachmittagen lernen kann? Ich sage nicht, dass 
Programmieren das am schwersten zu beherrschende Handwerk auf diesem 
Planeten ist. Aber kein Mensch würde auf die Idee kommmen, dass er nach 
einem Schnellsiederkurs in der nächsten Bildungszentrale eigenständig 
ein Auto konstruieren und bauen kann.

Autor: Sascha W. (bucky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun,

wie es aussieht habe ich mich in der Art meiner Fragestellung und im Ton 
vergriffen. Anders kann ich mir diese Reaktion nicht vorstellen. Nach 
der ersten Antwort von Ampfing bin ich davon ausgegangen, dass meine 
Frage in 2-3 Sätzen abgehandelt ist, was eure Aussagen bezüglich 
"simpel" ja zu bestätigen schien. Die Ironie und der Frustbeitrag auf 
die C von a - z Antwort hin meinerseits waren aber ganz sicher fehl am 
Platz. Insbesondere, da ich dies für eine "dumme" Antwort eines anonymen 
Gasts hielt und nicht für einen Hinweis auf das gleichnamige Open-Book! 
Mein Fehler, Entschuldigung dafür...

@Gast:

Keineswegs möchte ich meine Arbeit auf euch abwältzen und euch viele 
Minuten Arbeit bescheren. Wenn aber gestellte Frage in 2 Minuten 
beantwortet werden kann und dem mehrere Tage Arbeit bei Fragesteller 
gegenüber stehen, dann beantworte und helfe ich für meine Person gern.

@Karl heinz Buchegger:

Vielen Dank für den Link, tatsächlich habe ich diese Art der 
Funktionszeigerdarstellung so nicht erkannt in der mir zugesteckten 
Referenz, es handelt sich natürlich tatsächlich um einen simplen Fall. 
Die per Define eingesetzten Textersetzungen haben mich dahingehend 
verunsichert.
Zum zweiten Teil deines Beitrages: Mit ist das Wesen eine Ingenieurs 
durchaus bewusst und diese Art der Diskussion wäre persönlich nie 
Aufgekommen. Ich muss mich im Schreibstil bzw. in der Interpretation des 
Antworten vergriffen haben. Würde ich hier am BMP085 arbeiten, um ihn in 
ein kommerzielles Produkt einzusetzen, wären dies auch andere 
Voraussetzungen. Ich möchte lediglich zwei Effekte bewerten, die 
Messwertänderung durch Ändern der Orientierung des Sensors und das 
Verhältnis von Nutzsignal zu Rauschen an einer bestimmten Messtelle. Für 
diesen Laboraufbau war ich leider nicht bereit, meine weit 
zurückliegenden C-Kenntnisse und Kurse erneut zu bearbeiten, leider. 
Hätte ich die Antwort "C von a bis z" als einen Link identifiziert, 
hätte ich auch nie so reagiert.

Gruß,

Bucky2k

Autor: Sascha W. (bucky2k)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin sogar teils lern- und kritikfähig... Seit 10 min auf meinem 
Tisch:

Autor: Sascha W. (bucky2k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tja, für einen hinzu geholten recht erfahrenen µC-Programmierer und mich 
selbst scheint die Sache zu simpel zu sein ;-)

Selbst nach eingehender Recherche in Büchern, in C von A bis Z, im Netz 
kommen wir nicht dahinter was denn zum Erfolg fehlt. Ich werde es daher 
wohl komplett selbst neu programmieren müssen ohne den 
Funktionszeiger...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
   bmp085_t bmp085Config;

   ...
   bmp085Config.bus_read = bus_read;
   ....

   bmp085_init( &bmp085Config );

ev. sollte man die Funktion anders benennen, damit man keinen Name-Clash 
mit dem Namen des Funktionspointers hat.
char my_bus_read( unsigned char device_addr, unsigned char register_addr, unsigned char *register_data, unsigned char read_length )
{
   ...
}



   bmp085_t bmp085Config;

   ...
   bmp085Config.bus_read = my_bus_read;
   ....

   bmp085_init( &bmp085Config );

   ...

Edit: Sehe gerade, dass du im gcc Forum noch einen Thread dafür 
aufgemacht hast.

Autor: Er (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>recht erfahrenen µC-Programmierer
Worin ist der erfahren? Im Farbe anrühren?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Edit: Sehe gerade, dass du im gcc Forum noch einen Thread dafür
> aufgemacht hast.

Beitrag "Funktionszeiger in struct, ich verstehe es nicht."

Deswegen mache ich hier mal zu.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.