Forum: Mikrocontroller und Digitale Elektronik stm32 stdperiph-driver: Programmierstil?


von Markus G. (the_grue)


Lesenswert?

Servus!

Gerade habe ein paar Stunden verloren um meinen USART zum Laufen zu 
bekommen. Dank Hilfe aus dem Forum hat's dann geklappt (danke nochmal)

Beitrag "Noch ein STM32F303 USART3 geht nicht"

Jetzt ärgere ich mich gehörig über den Programmierstil im STM32 
StdPeriphDriver: Warum schreiben die dort sowas:
1
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)
2
{
3
  /* Check the parameters */
4
  assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));

anstatt sowas?
1
void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, GPIO_PinSource_t GPIO_PinSource, GPIO_AlternateFunction_t GPIO_AF)
2
{

Dass erstere Methode mit dem Assert keinerlei Sicherheit bringt wenn die 
Werte im gleichen Bereich liegen ist doch klar. und ein
1
 typedef enum {...} GPIO_PinSource_t
 wäre halbwegs typsicher und kostet nix.

Was übersehe ich da? Irgendwelche Kompatibilitätsprobleme? Bin noch 
nicht lange bei ST...

cu
Markus

von kaesschnip (Gast)


Lesenswert?

Markus G. schrieb:
> Was übersehe ich da? Irgendwelche Kompatibilitätsprobleme? Bin noch
> nicht lange bei ST...

Bei ST gilt eins:

Je tiefer du in die hübsche Fassade rein schaust, destö übler wirds.

Die Chips (im speziellen die STM32F4 Serie) sind im Silizium ganz ok.

Bei der Dokumentation, der HAL-Schicht und den darauf aufbauenden 
Treibern (USB, etc.) wird es ganz schnell ganz übel.

Das offz. ST-Forum quilt über was Bugs angeht. Die Dokumentation ist 
auch ziemlich rottig und an einigen Stellen falsch.

http://www.efton.sk/STM32/STM32F4xx_doc_errors.txt

von Jay (Gast)


Lesenswert?

Markus G. schrieb:
> Was übersehe ich da? Irgendwelche Kompatibilitätsprobleme? Bin noch
> nicht lange bei ST...

ST hat, wie praktisch alle Mikrocontroller-Hersteller ein Problem mit 
Software. Software ist nicht Kerngeschäft, da hat man keine Ahnung von, 
will keine Ahnung von haben, man macht schließlich Hardware, und billig 
muss es auch sein.

Weil alle Mikrocontroller-Hersteller so schlechte Treiber-Bibliotheken 
liefern verzichten viele für einfache Operationen auf diese 
Bibliotheken. Die Erfahrung lehrt es ist einfacher die Peripherie nach 
Datenblatt und Errata zu programmieren und notfalls den eigenen Code zu 
debuggen, als das Zeug vom Hersteller verstehen und debuggen zu müssen.

Ausnahmen gibt es auch. Kaum jemand wird sich einen eigenen USB-Treiber 
nach Datenblatt programmieren. Da lebt man lieber mit den Zeug vom 
Hersteller oder einem Drittanbieter.

von aSma>> (Gast)


Lesenswert?

Servus,

> Was übersehe ich da? Irgendwelche Kompatibilitätsprobleme? Bin noch
> nicht lange bei ST...

Wird zum Teil gemacht aber nicht Konsequent.
1
typedef enum
2
{ GPIO_Mode_AIN = 0x0,
3
  GPIO_Mode_IN_FLOATING = 0x04,
4
  GPIO_Mode_IPD = 0x28,
5
  GPIO_Mode_IPU = 0x48,
6
  GPIO_Mode_Out_OD = 0x14,
7
  GPIO_Mode_Out_PP = 0x10,
8
  GPIO_Mode_AF_OD = 0x1C,
9
  GPIO_Mode_AF_PP = 0x18
10
}GPIOMode_TypeDef;
11
12
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) || ((MODE) == GPIO_Mode_IN_FLOATING) || \
13
                            ((MODE) == GPIO_Mode_IPD) || ((MODE) == GPIO_Mode_IPU) || \
14
                            ((MODE) == GPIO_Mode_Out_OD) || ((MODE) == GPIO_Mode_Out_PP) || \
15
                            ((MODE) == GPIO_Mode_AF_OD) || ((MODE) == GPIO_Mode_AF_PP))
16
17
Hier wiederum nicht:
18
19
#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
20
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
21
...

Vielleicht ist OpenSTM32 was für dich. Da ist die lib portabler und wird 
immer weiter entwickelt.

Das ist hier aber nur ein kleiner Tropfen auf den heißen Stein.

mfg

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Warum braucht man für so einfache Peripherals eine komplizierte 
DriverLibrary?

von Herbert (Gast)


Lesenswert?

Random .. schrieb:
> Warum braucht man für so einfache Peripherals eine komplizierte
> DriverLibrary?

Weil du in der Industrie keine Zeit hast so Low Level zu entwickeln. Es 
ist nicht mehr so einfach wie bei den 8bit Controllern und das ist 
einfach zu zeitaufwändig für Entwicklungen hinter denen Geld / Zeitdruck 
steht.

von Random .. (thorstendb) Benutzerseite


Lesenswert?

Herbert schrieb:
> Random .. schrieb:
>> Warum braucht man für so einfache Peripherals eine komplizierte
>> DriverLibrary?
>
> Weil du in der Industrie keine Zeit hast so Low Level zu entwickeln. Es
> ist nicht mehr so einfach wie bei den 8bit Controllern und das ist
> einfach zu zeitaufwändig für Entwicklungen hinter denen Geld / Zeitdruck
> steht.

Wenn ich mir den ganzen Ärger mit den DriverLibs so ansehe, könnte man 
das in der Zeit fast ohne selbige programmieren :-)

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Markus G. schrieb:
> {...} GPIO_PinSource_t[/c] wäre halbwegs typsicher und kostet nix.

Der Compiler wird aus den Aufzählungstypen wahrscheinlich einen int 
machen, dass wären dann ein paar Bytes mehr auf dem stack. Das könnte 
man mit C++11 lösen, aber die meisten HW Herstellen trauen Ihren Kunden 
ja nicht einmal C99 zu.

> Was übersehe ich da? Irgendwelche Kompatibilitätsprobleme? Bin noch
> nicht lange bei ST...

Ansonsten hat Jay es eigentlich ganz gut getroffen.

von W.S. (Gast)


Angehängte Dateien:

Lesenswert?

Markus G. schrieb:
> Gerade habe ein paar Stunden verloren um meinen USART zum Laufen zu
> bekommen.

Ja sag mal, von welcher Vorkenntnis-Position aus bist du denn gestartet? 
Also aus meiner Sicht sind die USART/UART-Cores von ST so übersichtlich 
und einfach in der gewöhnlichen Benutzung als UART's, daß es gerade 
damit doch gar keine Probleme geben dürfte. Statische Interrupts, die 
man bei Bedarf nur wieder zuschalten braucht, ohne dem NVIC nen Softint 
unterjubeln zu müssen - was will man mehr???

Markus G. schrieb:
> Jetzt ärgere ich mich gehörig über den Programmierstil im STM32
> StdPeriphDriver: Warum schreiben die dort sowas:

Gegenfrage: Warum versuchst du, sowas überhaupt zu benutzen? Dieses 
ST-Zeugs war von Anfang an Mist und jeder, der sich das mal angesehen 
hat, weiß, daß man da besser einen großen Bogen drum macht. Knick das 
Zeugs einfach, anstatt dich über deren Stil zu echauffieren.

Ich häng dir mal ne Alternative dran - zum verstehenden Angucken, denn 
das ist für nen STM32F302. Sowas geht ohne all das krude ST-Zeugs.

W.S.

von Lukas K. (carrotindustries)


Lesenswert?

Für komplexe Peripherien, mit gut definierbarer Schnittstelle, wie USB, 
SDIO, oder Ethernet macht Abstraktion durchaus Sinn. Andere (libopencm, 
chibios) bekommen das allerdings ordentlicher hin als ST.
Bei Peripherien wie ADC, Timer, etc. lohnt sich Abstraktion nicht 
wirklich. Ob ich nun die Register direkt beschreibe oder einer Funktion 
sage, wie sie die Register setzen soll, macht keinen arg großen 
Unterschied. Hilfreich dabei wäre noch, wenn ST in den Header-Dateien 
sinnvolle konstanten für Bitfelder definiert, sodass man auch ohne 
Datenblatt ansehen erkennt, was beabsichtigt war. (Aber dann würden 
Leute ja sehen, dass deren HAL praktisch keine Abstraktion bietet)

von W.S. (Gast)


Lesenswert?

Lukas K. schrieb:
> Bei Peripherien wie ADC, Timer, etc. lohnt sich Abstraktion nicht
> wirklich.

Da setzt du einfach zu tief an.

Einen Timer braucht man eigentlich NIE als reinen Selbstzweck.
Stattdessen soll er immer irgend einem "höheren" Zweck dienen.
Und genau dieser Zweck ist normalerweise etwas, das eines sinnvollen 
Treibers bedarf.

Beispiel(aus dem Stegreif): Dreiphasen-Motor mit 3 gekoppelten 
Compare-Registern und/oder drangekoppeltem zweiten Timer für die 
Approximmation der Sinus-Ansteuerung oder sowas in der Art.

Das gibt dann nen Treiber "dreiphasen.c", der sehr wohl seine ganzen 
Innereien ggü. den höheren Programmschichten abstrahiert. An solcher 
Stelle sehe ich die Abstraktion, nicht jedoch bei do_gpio_set(1<<7); 
anstelle GPIO_SET = 1<<7;

W.S.

von Michi (Gast)


Lesenswert?

Random .. schrieb:
> Wenn ich mir den ganzen Ärger mit den DriverLibs so ansehe, könnte man
> das in der Zeit fast ohne selbige programmieren :-)

Ich weiß ja, dass viele über die SPL und die HAL schimpfen, kann das 
aber bisher nicht nachvollziehen. Sie mag ja (teilweise) ineffizient 
geschrieben sein, aber so verbuggt, wie manche einen glauben machen 
wollen, ist sie nicht, finde ich.

Lukas K. schrieb:
> Andere (libopencm,
> chibios) bekommen das allerdings ordentlicher hin als ST.

Ich habe mich mal an der libopencm versucht, habe sie aber nicht 
durchschauen können und auch nicht zum Laufen gebracht. Ein gutes 
Tutorial habe ich nicht gefunden, zumindest nicht für Windows. Sowas ist 
dann natürlich nicht gerade hilfreich...

von Lukas K. (carrotindustries)


Lesenswert?

W.S. schrieb:
> Lukas K. schrieb:
>> Bei Peripherien wie ADC, Timer, etc. lohnt sich Abstraktion nicht
>> wirklich.
>
> Da setzt du einfach zu tief an.
> [...]
> W.S.

Eine Abstraktion wie von dir beschrieben ist keine generische 
Abstraktion, wie sie ST anstrebt. Und ebendiese ist unnütz. Das von dir 
beschriebene fällt für mich schon unter Applikation/Bibliothek.

Michi schrieb:
> Lukas K. schrieb:
>> Andere (libopencm,
>> chibios) bekommen das allerdings ordentlicher hin als ST.
>
> Ich habe mich mal an der libopencm versucht, habe sie aber nicht
> durchschauen können und auch nicht zum Laufen gebracht. Ein gutes
> Tutorial habe ich nicht gefunden, zumindest nicht für Windows. Sowas ist
> dann natürlich nicht gerade hilfreich...
Dann siehst du mal, wie es den Leuten ergeht, die die Beispielprojekte 
von ST auf Linux bauen wollen und mit Dingen wie backspaces in 
Include-Pfaden kämpfen müssen :P

Auf Linux ist's git pull, git submodule init, make

von Markus G. (the_grue)


Lesenswert?

Servus!

Danke für die fleissigen Antworten/die Diskussion! Wie gesagt, ST 
verwende ich noch nicht lange.

Alles selbst zu programmieren und auf die angebotenen Bibliotheken zu 
verzichten ist sicher machbar (hab' ich auf 8051, Atmel und MSP430 auch 
schon gemacht). Je weiter weg man aber vom Einzelkämpfer entwickelt, hin 
zu (nicht mal so großen) Teams, hat man selten die Wahl.

Außerdem bin ich eigentlich ein Freund von Abstrahierung, so lange es 
sinnvoll machbar ist.

Deshalb denke ich, daß eine Bibliothek des Herstellers eigentlich eine 
art Aushängeschild sein sollte, mit der es eine Freude ist zu arbeiten. 
"Seht her, so schön könnt Ihr UNSEREN chip mit UNSERER lib verwenden". 
Ist leider nicht realistisch ;)

cu
Markus

: Bearbeitet durch User
von Tom (Gast)


Lesenswert?

Markus G. schrieb:
> und ein typedef enum {...} GPIO_PinSource_t wäre halbwegs typsicher

In C hilft ein enum der Typsicherheit fast gar nicht. Die Alternative 
wäre das Verpacken des Wertes in ein struct oder Makrozauberei.
1
#include <stdio.h>
2
3
typedef enum  tApple { CoxOrange, Boskop } tApple;
4
typedef enum tColor { Green, Red} tColor;
5
6
void doit(tApple apple)
7
{
8
    if (apple == Red) // gcc -Wall -Wextra warnt, clang -Weverything nicht
9
        return;
10
    return;
11
}
12
13
int main(void)
14
{
15
    doit(Green); //geht mit gcc, clang warnt
16
    tColor x = Boskop; //geht mit gcc, clang warnt
17
    doit(1);  //geht
18
    return 0;
19
}

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Tom schrieb:

> In C hilft ein enum der Typsicherheit fast gar nicht. Die Alternative

Aber im Debugger erhaelt man eine vernuenftige Angabe und nicht nur eine 
Ziffer...

von Markus G. (the_grue)


Lesenswert?

Tom schrieb:
> In C hilft ein enum der Typsicherheit fast gar nicht

Leider hast Du recht. Ich war es über die Jahre so gewohnt auch C-Code 
mit einem C++ compiler zu übersetzen, daß ich die Typenprüfung dem 
C-Compiler untergeschoben habe :(

Trotzdem, "fast gar nicht" ist immer noch besser als "gar nicht".

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
Noch kein Account? Hier anmelden.