Hallo zusammen,
und wieder einmal haben sich Lücken in meinem C-Wissen aufgetan, wo ich
sie nicht vermutet habe. Obwohl mittlerweile auch der K&R in meinem
Besitz und benutzt ist.
Ich will ein switch-case-Konstrukt mit einer Zeigervariable machen (ich
nutze den ARM-GCC):
was wegen obiger Fehlermeldung nicht geht.
Aber wie geht man hier sauber vor? In ein uint32_t casten? In eine
if/elseif-Kette umwandeln? Oder etwas ganz anderes?
Viele Grüße
W.T.
Rolf Magnus schrieb:> Warum übergibst du denn überhaupt einen Pointer, wenn du ihn nur zur> Fall-Unterscheidung nutzen willst?
Kennst Du eine bessere Möglichkeit, GPIOs zu unterscheiden?
Rene H. schrieb:> switch(*gpio) ....>> sollte das Problem lösen.
Hmmmm...GPIO_TypeDef ist wie folgt definiert:
1
typedefstruct
2
{
3
__IOuint32_tCRL;
4
__IOuint32_tCRH;
5
__IOuint32_tIDR;
6
__IOuint32_tODR;
7
__IOuint32_tBSRR;
8
__IOuint32_tBRR;
9
__IOuint32_tLCKR;
10
}GPIO_TypeDef;
Was bewirkt der Dereferenzierungsoperator bei einem struct?
Wenn ich darüber nachdenke, wundere ich mich gerade, warum der
"=="-Operator hier funktioniert...naja, viel Padding wird bei uint32_t
ja nicht gemacht.
Rene H. schrieb:> sollte das Problem lösen.
Das löst garnichts. Bei dem Controllertyp, den Walter gerade benutzt
und dem Headerfile, was er dafür gerade in Händen hält, sind die
Ports als struct's deklariert. Einen kompletten Struct kann man aber
nicht als case-Value benutzen, das ist auch logischer Unsinn.
Abgesehen davon halte ich Walters Herangehensweise inzwischen auch für
GRUNDFALSCH. Er versucht nämlich, die Ports per Namen zu
vereinheitlichen, um Namensgleichheit zwischen ARM und AVR herzustellen.
Wahrscheinlich will er gleiche Initialisierungs-Quelltexte für so
unterschiedliche Architekturen schreiben. Sowas kann nicht funktionieren
und es ist auch logischer Mumpitz. Ungleiche Hardwaren (Hardwares ?)
kann man auf der alleruntersten Ebene NICHT über einen Kamm scheren,
dazu schreibt man sich lowest-level-Routinen, die höhere Funktionalität
(also Lampe_ein, Motor_aus und so) auf die darunterliegende Hardware
umsetzen.
W.S.
Walter Tarpan schrieb:> Was bewirkt der Dereferenzierungsoperator bei einem struct?
Ah, ok, das wusste ich nicht, dass das ein typedef struct ist, ich
dachte an einen enum. Dann geht das natürlich nicht.
In dem Fall würde ich eher auf if else gehen (nicht schön, braucht aber
meines Wissens nicht mehr Taktzyklen).
Walter Tarpan schrieb:> naja, viel Padding wird bei uint32_t> ja nicht gemacht.
Da sollten bei einem ARM eigentlich kaum Padding Bytes eingesetzt
werden.
Grüsse,
R.
W.S. schrieb:> Abgesehen davon halte ich Walters Herangehensweise inzwischen auch für> GRUNDFALSCH.> [...]> Wahrscheinlich will er gleiche Initialisierungs-Quelltexte für so> unterschiedliche Architekturen schreiben.
Auf einem gewissen Level hast Du sogar Recht: Ja, in der main() soll
tatsächlich einfach
1
Pwmdat_t=pwm_init(GLCD_PWM_CH);
stehen. Für beide Architekturen.
W.S. schrieb:> [...]> Er versucht nämlich, die Ports per Namen zu> vereinheitlichen, um Namensgleichheit zwischen ARM und AVR herzustellen.> [...]
Nein, das will ich nicht. Nicht überall. Du mischst hier mehrere
Forenanfragen zu Funktionen auf völlig unterschiedlicher Ebene. Es gibt
eine Handvoll Bitbangig-Sachen, wo ich das tatsächlich gemacht habe. Und
es gibt deutlich mehr Parallelimplementierungen, wo sich AVR und Cortex
lediglich die Headerdateien teilen.
Und generell hat das bislang sehr gut geklappt. Ich habe mein Projekt
jetzt zu 90% von AVR auf ARM migriert und die Source-Code-Qualität auf
beiden Seiten hat deutlich zugenommen.
>Ich habe mein Projekt>jetzt zu 90% von AVR auf ARM migriert und die Source-Code-Qualität auf>beiden Seiten hat deutlich zugenommen.
Und die Geschwindigkeit vermutlich deutlich abgenommen.
Protip: Die CMSIS/Standard Peripheral Library hat extrem schlechtes
Design. Alles was man an Informationen benötigt um einen Port zu
identifizieren und nutzen ist eine 3 (oder so) bit-Zahl die die
Port-Nummer (0-4 = A-E o.ä.) angibt. Die Adresse der zugehörigen
Port-Register und die RCC-Register-Bitnummer ("RCC_APB2Periph_GPIOx")
lässt sich direkt daraus berechnen (einfach mal in die Definition von
RCC_APB2Periph_GPIOx, und ins Manual über die RCC-Register schauen).
D.h. es reicht dann
holger schrieb:> Und die Geschwindigkeit vermutlich deutlich abgenommen.
Nicht genug, als daß die Funktion des Geräts dadurch beeinträchtigt
worden wäre.
Vermutlich dauert die Initialisierung jetzt 100mal länger als zuvor -
dummerweise ist sie aber immer noch so schnell, daß sie fertig ist,
bevor ich den Finger vom Netzschalter zu den Bedienelementen bewegt
habe.
Dr. Sommer schrieb:> Protip: Die CMSIS/Standard Peripheral Library hat extrem schlechtes> Design. Alles was man an Informationen benötigt um einen Port zu> identifizieren und nutzen ist eine 3 (oder so) bit-Zahl die die> Port-Nummer (0-4 = A-E o.ä.) angibt. Die Adresse der zugehörigen> Port-Register und die RCC-Register-Bitnummer ("RCC_APB2Periph_GPIOx")> lässt sich direkt daraus berechnen (einfach mal in die Definition von> RCC_APB2Periph_GPIOx, und ins Manual über die RCC-Register schauen).> D.h. es reicht dannenum Port { GPIOA=0, GPIOB, GPIOC, GPIOD };> void init (Port p) {> RCC_APB2PeriphClockCmd(4 << p,ENABLE);> RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);> }> int main () {> init (GPIOB);> }Und schon hast du den ganzen Aufwand gespart...
Danke für den Tipp! Die GPIOx als enum neu zu definieren wiederstrebt
mir zwar- aber das Ganze funktioniert ja auch mit den
Original-Definitionen.
Walter Tarpan schrieb:> Danke für den Tipp! Die GPIOx als enum neu zu definieren wiederstrebt> mir zwar-
Immer noch viel besser als der "#define" Haufen aus der Std Peripheral
Library... Von mir aus auch "static const uint8_t GPIOA = 0;".
Johann L. schrieb:> Das ist kein Fehler, es ist eine Warnung.
Stimmt. Den Tippfehler kann ich allerdings wegen des Hinweises auf den
Tippfehler nicht mehr beheben :-)
Walter Tarpan schrieb:> Und generell hat das bislang sehr gut geklappt.
..und hat dir bisher ca. 70000 Quellzeilen beschert, wie du in einem
anderen Thread geschrieben hattest. Ich stell jetzt mal keine
Vermutungen an, ob das bislang alles nur Quellzeilen waren, die aus dem
Gleichmach-Wunsch zwischen AVR und ARM deinerseits herrühren. Ich sag
nur eins: du stellst das Ganze verkehrt an, stolperst dabei über
grundsätzliche Unmöglichkeiten, die dir nicht nur in C blühen, sondern
dich auch in allen anderen Programmiersprachen angrinsen würden - und du
bist erstaunlich beratungsresistent. Na dann mach mal.
W.S.
W.S. schrieb:> [...]> und du> bist erstaunlich beratungsresistent.
Du meinst weil ich
a) in einem Menü einen Funktionszeiger caste, anstelle das Menü einfach
komplett objektorientiert neu zu schreiben und
b) einfache Bitbanging-Funktionen partout nicht für jede Plattform
einzeln in eine Datei schreibe
bin ich beratungsresitent?
Du hast Recht!