Forum: Mikrocontroller und Digitale Elektronik CubeMX und HAL - I2C hängt sich auf


von Peter (Gast)


Lesenswert?

Hallo,

ich arbeite mich gerade in die HAL Bibliothek ein und habe Probleme mit 
dem I2C.

Der CubeMX generiert ja die ganze Hardware-Initialisierungen und man 
muss dann nur noch die Transmit-Funktion aufrufen:

HAL_I2C_Master_Transmit(h_i2c, (slave_address << 1), p_data, length, 
100);

Dummerweise funktioniert das nicht - das BUSY Bit wird gesetzt und nicht 
mehr gelöscht. Dies ist offenbar auch ein bekannter Bug für den es sogar 
einen/mehrere Workarounds gibt. Diese funktionieren aber bei mir nicht, 
und da ich schon den halben Tag damit rummache, habe ich jetzt auch die 
Schnautze voll.

Die Hardware ist soweit in Ordnung, da ein Treiber mit der Standard 
Perpheral Library und diesem Setup läuft.

Meine Frage ist nun, ob jemand vielleicht etwas lauffähigen Code mit dem 
CubeMX und dem HAL für einen STM32F103C8 hat?

Gruß und Danke Peter

von pegel (Gast)


Lesenswert?

Für den SSD1306 mit oder ohne DMA hat das prima funktioniert.

Welcher I2C Baustein macht denn Probleme?
Hast du eine Möglichkeit die Signale anzusehen?

von Harry L. (mysth)


Lesenswert?

pegel schrieb:
> Für den SSD1306 mit oder ohne DMA hat das prima funktioniert.

as kann ich bestätigen.
Häng doch mal die vom CubeMX generierte PDF und deine main.c an!

von Stefan F. (Gast)


Lesenswert?

Peter schrieb:
> Meine Frage ist nun, ob jemand vielleicht etwas lauffähigen Code
> mit dem CubeMX und dem HAL für einen STM32F103C8 hat?

Ich habe lauffähigen Code ohne Cube HAL, aber auf Basis der CMSIS Core 
Library, die in allen HAL Projekten als Unterbau enthalten ist. Das ist 
nicht ganz das, wonach du suchst, aber zur Not hilft es vielleicht 
trotzdem.

http://stefanfrings.de/stm32/index.html#i2c

von S------- R. (simonr)


Lesenswert?

https://www.st.com/content/ccc/resource/technical/document/errata_sheet/7d/02/75/64/17/fc/4d/fd/CD00190234.pdf/files/CD00190234.pdf/jcr:content/translations/en.CD00190234.pdf

Seite 26

Alternativ gibt es das Problem, dass eventuell noch was anderes am 
selben Pin hängt und danach initialisiert wird. Schau dir ganz genau an 
wo die Pins initialisiert werden, wo das peripheral und wo die clocks

von pegel (Gast)


Lesenswert?

Ich kann mich dunkel an ein Problem mit Datentypen dabei erinnern.
Danach habe ich mir angewöhnt die Typen anzugeben, seit dem gab es keine 
Probleme mehr.

Z.B. in der Art:
1
HAL_I2C_Master_Transmit(&hi2c1,(uint16_t)OLED_I2C_ADDR,(uint8_t*)init_sequence,sizeof(init_sequence),100);

von Gerd E. (robberknight)


Lesenswert?

Peter schrieb:
> ich arbeite mich gerade in die HAL Bibliothek ein und habe Probleme mit
> dem I2C.
>
> Der CubeMX generiert ja die ganze Hardware-Initialisierungen und man
> muss dann nur noch die Transmit-Funktion aufrufen:
[...]
> Dummerweise funktioniert das nicht - das BUSY Bit wird gesetzt und nicht
> mehr gelöscht. Dies ist offenbar auch ein bekannter Bug für den es sogar
> einen/mehrere Workarounds gibt. Diese funktionieren aber bei mir nicht,
> und da ich schon den halben Tag damit rummache, habe ich jetzt auch die
> Schnautze voll.

Jetzt ist der Zeitpunkt gekommen einen Schritt zurückzutreten, die 
Zusammenhänge zu betrachten, seine Schlüsse zu ziehen und den bisherigen 
Weg in Frage zu stellen:

Warum nimmst Du CubeMX?

Was bringt es Dir? Was würde Dir ohne es fehlen?

Bringt es im Endeffekt mehr Nutzen oder kostet das Zusammensuchen der 
Bezeichner und Funktionen, das Verstehen der Funktionen, der Workaround 
um Bugs evtl. mehr als es nutzt?

Versuch auch mal alternative Wege:
- libopencm3
- die Register alle selbst ansprechen
- ChibiOS HAL

Such hier mal im Forum ein bischen nach für und wider zum Cube, da 
findest Du noch mehr Berichte und Argumente.

Mein Fazit für mich ist, daß ich um das Cube einen weiten Bogen mache.

von Stefan F. (Gast)


Lesenswert?

Falls Dir mein I²C Code Beispiel ziemlich komplex vorkommt: Auf AVR wäre 
der Quelltext sehr viel kürzer. Aber ich habe mir das nicht so 
ausgedacht, ich habe lediglich die Hinweise aus der entsprechenden 
Application Note und dem Errata umgesetzt.

> Mein Fazit für mich ist, dass ich um das Cube einen weiten Bogen mache.

Meins auch, aus den selben Gründen, die du genannt hast. Leider ist die 
I²C Schnittstelle gerade kein gutes Beispiel, um die Einfachheit der 
Programmierung "zu Fuß" zu demonstrieren.

von pegel (Gast)


Lesenswert?

Wieso endet die Diskussion wenn jemand CubeMX einsetzt eigentlich immer 
gleich?
Lasst doch jeden machen wie er will.

Nur weil ein kleines Problem auftritt muss man nicht gleich alles 
verteufeln.

Und nun: Feuer!

von pegel (Gast)


Lesenswert?

Ach ja, in den Beispielen von ST wird es auch mit Datentyp Angabe 
gemacht.
Aus der I2C/I2C_TwoBoards_ComPolling/Src/main.c :
1
while(HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)I2C_ADDRESS, (uint8_t*)aTxBuffer, TXBUFFERSIZE, 10000)!= HAL_OK)

von Gerd E. (robberknight)


Lesenswert?

pegel schrieb:
> Wieso endet die Diskussion wenn jemand CubeMX einsetzt eigentlich immer
> gleich?
> Lasst doch jeden machen wie er will.
>
> Nur weil ein kleines Problem auftritt muss man nicht gleich alles
> verteufeln.

Wo habe ich verteufelt? Wo habe ich ihn nicht machen lassen wie er will?

ST empfiehlt das Cube halt an jeder Ecke, das ist ja der Hersteller und 
die werden es schon wissen etc. Viele Neueinsteiger wissen daher gar 
nicht daß es Alternativen gibt und denken das wäre halt so wie es ist.

Jeder muss seine Entscheidung für sich treffen. Doch dafür muss er erst 
mal wissen daß er überhaupt eine Wahl hat und was die Alternativen sind.

Darauf wollte ich hinwesen, mehr nicht.

von Peter (Gast)


Lesenswert?

Hallo,

danke für die vielen Antworten.

Dummerweise hatte ich hier gerade ein ganz anderes Problem.
Beitrag "OpenOCD startet plötzlich nicht mehr, Boards defekt"

Es ist inzwischen (teilweise) gelöst, aber ich bin immer noch etwas 
skeptich, was denCubeMX betrifft. Trotzdem werde ich es weiterhin 
versuchen den I2C zum laufen zu bringen.

Bei meinem Test-Projekt, welches die im anderen Thread genannten 
Probleme hervor brachte, hatte ich übrigens keinerlei weitere Hardware 
an dem Testboard hängen - also auch keine weiteren Signal-Pegel (mit 
ausnahme des JTAG).

Gruß Peter

von temp (Gast)


Angehängte Dateien:

Lesenswert?

Da ich weder die HAL noch die alte SPL-Libs verwende, habe ich mir die 
I2C-Routinen selbst lowlevel auf Registerbasis geschrieben. Ich hänge 
die hier mal mit an, eventuell kann das ja mal wer gebrauchen.

Benutzt werden kann es so um die ersten 7 Byte aus einer DS1307
rtc zu lesen:
1
#include <i2c.h> 
2
3
4
I2C aI2C(1); // I2C1 benutzen 2 fürI2C2
5
6
...
7
  int rc=0;
8
  // init I2C, no portremap, use PB6 and PB7 
9
  rc=aI2C1.Init(I2C_FAST, false);
10
  if (rc==0)
11
    {   
12
    uint8_t wdata[]={0};
13
    uint8_t rdata[7];
14
15
    // 0x68 is the address for DS1307
16
    // write 1 byte (0) to set the addr in DS1307 to 0
17
    // read 7 byte from addr 0 in DS1307  
18
    int rc=aI2C.WriteAndRead(0x68,wdata,1,rdata,7);
19
    if (rc!=7)
20
      return false; 
21
    }
22
...

(Das kurze Beispiel ist jetzt nicht getestet)

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

pegel schrieb:
> Welcher I2C Baustein macht denn Probleme?
> Hast du eine Möglichkeit die Signale anzusehen?

Das ist so ein LCD Modul:
https://funduino.de/nr-19-i%C2%B2c-display

SCL und SDA sind beide auf high, und es ist kein einziger Wackler zu 
sehen.

Harry L. schrieb:
> Häng doch mal die vom CubeMX generierte PDF und deine main.c an!

Das PDF hängt an, die main.c auch.

Stefanus F. schrieb:
> Ich habe lauffähigen Code ohne Cube HAL, aber

temp schrieb:
> Da ich weder die HAL noch die alte SPL-Libs verwende, habe ich mir die
> I2C-Routinen selbst lowlevel auf Registerbasis geschrieben.

Es geht mir nur um den CubeMX, aber danke.

Der Witz ist, dass das Senden über I2C (nach der Initialisierung durch 
den Cube) nur aus einer einzigen Funktion HAL_I2C_Master_Transmit() 
besteht - aber es geht trotzdem nicht.

Gerd E. schrieb:
> Warum nimmst Du CubeMX?

Die StdPeriphLib wird nicht mehr weiter entwickelt. Wenn ich also 
up-to-date bleiben will, dann muss ich wechseln.

pegel schrieb:
> Ach ja, in den Beispielen von ST wird es auch mit Datentyp Angabe

Das halte ich für überzogen, aber nun gut.


Gruß Peter

von temp (Gast)


Lesenswert?

Beim kurzen Überfliegen habe ich nichts gefunden wo du die Gpio-Pins für 
I2C und Opendrain konfigurierst.

von Peter (Gast)


Angehängte Dateien:

Lesenswert?

temp schrieb:
> Beim kurzen Überfliegen habe ich nichts gefunden wo du die Gpio-Pins für
> I2C und Opendrain konfigurierst.

Das wird alles in den als 'weak' definierten Funktionen der 
stm32f1xx_hal_msp.c Datei erledigt (hier HAL_I2C_MspInit()).
Diese Funktionen wiederum werden durch die HAL-Treiber eingebunden. In 
Falle des I2C durch HAL_I2C_Init() (siehe Anhang).
Vorab wird die komplette Datei durch den CubeMX projekt-spezifisch 
erstellt (ich sag ja: Der Cube ist was für Faule).

von pegel (Gast)


Lesenswert?

Peter schrieb:
> Das halte ich für überzogen, aber nun gut.

Wie jetzt?

Warum machst du nicht einfach mal aus deinem:

HAL_I2C_Master_Transmit(&hi2c1, (0x27 << 1), &value, 1, 100);

ein:

HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)(0x27 << 1), (uint8_t*)value, 
1, 100);

?

von Peter (Gast)


Lesenswert?

pegel schrieb:
> Warum machst du nicht einfach mal aus deinem:
>
> HAL_I2C_Master_Transmit(&hi2c1, (0x27 << 1), &value, 1, 100);
>
> ein:
>
> HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)(0x27 << 1), (uint8_t*)value,
> 1, 100);
>
> ?

Weil das meiner Meinung nach keinen Unterschied macht wenn 'value' als 
uint8_t definiert ist.
Und (0x27 << 1) passt auch immer noch in einen 8 Bit Wert rein - in 
einen 16 Bit Wert also allemal.

von W.S. (Gast)


Lesenswert?

pegel schrieb:
> Nur weil ein kleines Problem auftritt muss man nicht gleich alles
> verteufeln.
>
> Und nun: Feuer!

Nein. Eher den Löschwagen.

So wie ich das sehe, machen all diese Hersteller-Helferlein zwei Dinge:

Erstens halten sie den Benutzer soweit von der eigentlichen Hardware ab, 
daß er meint, sie nicht verstehen zu müssen, womit er auf eben diese 
Hersteller-Programme und folglich auf den Hersteller angewiesen 
wird/bereits ist. Ist eben die Hersteller-Bindung. Man sieh das hier in 
diesem forum häufig, daß Leute zwar Arm-Cortex meinen, aber dazu "Stm32" 
sagen. Ist wie Hoover für Staubsauger zu sagen.

Zweitens bauschen sie all die Hardware-Dinge gewaltig auf, mit Unmengen 
zusätzlicher Bezeichner, die man sich nie und nimmer wirklich merken 
kann.

Peter schrieb:
> ich arbeite mich gerade in die HAL Bibliothek ein und habe Probleme..

Und deshalb würde ich dir eher dazu raten, derartige 
herstellerspezifische Helferlein besser nicht verwenden zu wollen und 
stattdessen deinen eigenen Weg zu gehen und dir deine eigenen 
Lowlevel-Treiber zu schreiben.

Allerdings sind mMn die I2C-Cores der meisten heutigen µC eher krötig 
gemacht. Frühere Cores waren primitiv und haben den Benutzer mit 
Unmengen von Interrupts zu jedem blöden Zustandswechsel am I2C 
belästigt. Heutige I2C-hardware ist hingegen teilweise völlig 
überzüchtet, so daß sie irgendwelche Transfers ganz allein erledigen 
will, was jedoch andere Probleme macht, insbesondere dann, wenn man beim 
Öffnen einer Verbindung noch nicht weiß, wieviel Bytes beim Transfer 
tatsächlich zu erwarten sind - was ja eigentlich die Regel ist. Nicht 
umsonst gibt es ACK/NAK.

In Problemfällen neige ich dazu, den I2C schlichtweg mal per Software zu 
benutzen, um Zickigkeiten des I2C-Cores auszuschließen. Dies zusammen 
mit dem Oszilloskop hilft sehr. Mir sind bei solchen Gelegenheiten auch 
Chips aufgefallen, die extrem zickig sind bei den Low-Pegeln, weswegen 
man dort schon beim Adressieren kein ACK kriegt.

W.S.

von Peter (Gast)


Lesenswert?

W.S. schrieb:
> Und deshalb würde ich dir eher dazu raten, derartige
> herstellerspezifische Helferlein besser nicht verwenden zu wollen und
> stattdessen deinen eigenen Weg zu gehen und dir deine eigenen
> Lowlevel-Treiber zu schreiben.

Ich habe ja schon gesagt, dass die StdPeriphLib eingestellt wird. 
Deshalb will ich wechseln.

von pegel (Gast)


Lesenswert?

Peter schrieb:
> Weil das meiner Meinung nach ...

Ich geb es auf.
Dann mach mal.

von Peter (Gast)


Lesenswert?

pegel schrieb:
> Ich geb es auf.
> Dann mach mal.

Dann erklär mir mal bitte was der entscheidende Unterschied ist?

Übrigens, wenn ich das so mache wie Du vorschlägst, dann bekomme ich 
eine Warnung:
warning: cast to pointer from integer of different size

Sollte es vielleicht nicht vielmehr so lauten?
HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)(0x27 << 1), (uint8_t*)&value, 
1, 100);

von pegel (Gast)


Lesenswert?

Die Funktion HAL_I2C_Master_Transmit erwartet eine 16bit Adresse.
Du gibst ihr 8bit und weißt nicht was in den anderen 8bit steht.

Das & hängt natürlich davon ab, wie value definiert ist.

Meine Funktion sieht so aus:
1
void oled_on(){
2
  const uint8_t disp_on [] = {
3
      0x00,
4
      0xAF,
5
  };
6
  HAL_I2C_Master_Transmit(&hi2c1,(uint16_t)OLED_I2C_ADDR,uint8_t*)disp_on,sizeof(disp_on),100);
7
}

von m.n. (Gast)


Lesenswert?

W.S. schrieb:
> In Problemfällen neige ich dazu, den I2C schlichtweg mal per Software zu
> benutzen, um Zickigkeiten des I2C-Cores auszuschließen.

... oder wenn es einfach nur funktionieren soll ;-)

Peter schrieb:
> Ich habe ja schon gesagt, dass die StdPeriphLib eingestellt wird.

Das ist doch kein sonderliches Problem. Für GPIO oder ... kannst Du doch 
ruhig die SPL weiter verwenden, wenn Du magst. Die sind doch zum größten 
Teil bei allen STM32 gleich. Lediglich bei RCC und einigen anderen 
Einheiten können mehr Bits dazugekommen sein. Das steht dann im 
Referenz-Handbuch.

Haupsache ist, daß die "stm32fxxx.h" verfügbar ist. Dort sind alle 
vorhandenen Register und Definitionen aufgeführt.

von pegel (Gast)


Lesenswert?

Ich sehe gerade vor uint8_t ist eine Klammer verloren gegangen.

von Peter (Gast)


Lesenswert?

pegel schrieb:
> Die Funktion HAL_I2C_Master_Transmit erwartet eine 16bit Adresse.
> Du gibst ihr 8bit und weißt nicht was in den anderen 8bit steht.

Danke für den Hinweis. Ich hätte gedacht, das wird automatisch mit 
Nullen vorbelegt.

von Peter (Gast)


Lesenswert?

Ich habe den Fehler gefunden.

temp schrieb:
> Beim kurzen Überfliegen habe ich nichts gefunden wo du die Gpio-Pins für
> I2C und Opendrain konfigurierst.

Das hat mich auf die richtige Fährte gebracht.

Denn diese Konfigurationen werden zwar alle durch den CubeMX automatisch 
erstellt und aufgerufen. Aber im Fall des I2C hat der CubeMX eben nicht 
gemacht, was er für GPIO, DMA und UART tat. Auch wenn die MX_I2C1_Init() 
Funktion zwar automatisch generiert wurde, wurde sie nicht in die 
Start-Sequenz eingefügt:
1
  ...
2
3
  /* USER CODE END SysInit */
4
5
  /* Initialize all configured peripherals */
6
  MX_GPIO_Init();
7
  MX_DMA_Init();
8
  MX_USART1_UART_Init(); 
9
10
  /* USER CODE BEGIN 2 */
11
  x_user_init(&hi2c1, &huart1);
12
13
  ...

Wie man oben sieht hat der CubeMX die Initialisierungen für DMA, GPIO 
und USART automatisch eingefügt, aber die für I2C nicht.

Nach händischem Einfügen von MX_I2C1_Init() läuft jetzt alles.

Gruß Peter

von Peter (Gast)


Lesenswert?

Nachtrag:

Das witzige ist, wenn ich den Code im CubeMX erneut generiere, dann ist 
der Eintrag für I2C wieder verschwunden. Die für GPIO, UART und DMA sind 
noch da.

Das kann nur ein Bug sein - nicht der Einzige.

von pegel (Gast)


Lesenswert?

Inzwischen gibt es CubeMX 5.0.0.

von pegel (Gast)


Lesenswert?

Häng doch mal deine .ioc Projektdatei an.

von Harry L. (mysth)


Lesenswert?

Sowas:
1
for (uint32_t i = 0; i < 100000; i++)
2
    asm("NOP");
wird dir um die Ohren fliegen, da der Compiler das gerne weg-optimiert.
Dafür gibt es HAL_Delay(),
Und wenn dir diese Wartezeit genommen wird, führt das genau zu dem von 
dir beschriebenen Verhalten.

von Stefan F. (Gast)


Lesenswert?

Für mich gibt's nur einen Grund, die HAL zu verwenden: USB.

Aber diesen Wind haben mir Niklas Gürtler und W.S. aus den Segeln 
genommen.

von Harry L. (mysth)


Lesenswert?

Stefanus F. schrieb:
> Für mich gibt's nur einen Grund, die HAL zu verwenden: USB.
>
> Aber diesen Wind haben mir Niklas Gürtler und W.S. aus den Segeln
> genommen.

Und wen interessiert das?
Der TO hat explizit nach HAL und nicht nach Alternativen dazu gefragt.

von Stefan F. (Gast)


Lesenswert?

Harry L. schrieb:
> Und wen interessiert das?

Mich. Ich darf auch mal nachtreten.

von Harry L. (mysth)


Lesenswert?

Stefanus F. schrieb:
> Harry L. schrieb:
>> Und wen interessiert das?
>
> Mich. Ich darf auch mal nachtreten.

Dann mach doch deinen eigenen "ich hasse HAL"-Thread auf.

Solche "Meinungen" sind hier nicht zielführend, bringen den TO kein 
Stück weiter und stören nur.

: Bearbeitet durch User
von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

mit
asm volatile("NOP");
ist dann wieder alles in Ordnung und der Gammel HAL muss nicht genutzt 
werden.

Stefanus F. schrieb:
> Für mich gibt's nur einen Grund, die HAL zu verwenden: USB.
>
> Aber diesen Wind haben mir Niklas Gürtler und W.S. aus den Segeln
> genommen.

Der USB Host Code ist der einzige HAL Code den ich in meinen Projekten 
nutze und der hat BUGS BUGS BUGS.
In Verbindung mit nem RTOS jedenfalls.
So Scherze wie: der IRQ handler spielt an der Statemachine des Threads 
rum ud sendet DANN ein Event. Der Thread kennt aber noch den alten 
Zustand.
Das führt dann dazu, dass ein eingesteckter USB Stick nicht immer 
erkannt wird und der USB Host dann in einem undefinierten Zustand 
verweilt.
Nach 2-3mal stecken gehts dann...

Die haben es zudem doch glatt vergessen in der "USBH_LL_Init".
Den LOCK State des Initstructs auf 0 zu setzen.
Wodurch der HAL mit "locked" gestartet wurde und er somit nix machte.
Das funktioniert nur beim ersten Mal, da ist das struct noch durch bss 
genullt.

von Johannes S. (Gast)


Lesenswert?

Mw E. schrieb:
> und der hat BUGS BUGS BUGS.

Und die SW die du schreibst ist auf Anhieb fehlerfrei? Respekt!

von W.S. (Gast)


Lesenswert?

Peter schrieb:
> Das kann nur ein Bug sein - nicht der Einzige.

So etwas sollte dir doch eigentlich zu denken geben, oder?

Ich meine, wenn einem schon die Bugs so dicht um die Ohren fliegen, dann 
sollte das doch ausreichend Anlaß sein, ein gewisses Maß an Skepsis 
aufkommen zu lassen. Und eben auch den Gedanken, sich besser von so 
etwas zu verabschieden und den eigenen Kram zu pflegen.

W.S.

von W.S. (Gast)


Lesenswert?

Harry L. schrieb:
> Dann mach doch deinen eigenen "ich hasse HAL"-Thread auf.

Es sind wohl deine Beiträge, die hier alles andere als zielführend 
sind.

Ich sag's mal so (zum wiederholten Male):

Wenn unsereiner jemanden sieht, wie der verzweifelt mit dem Kopf gegen 
die Wand rennt, weil er durch selbige durchkommen will, sich aber dabei 
nur eine Beule nach der anderen holt,...

DANN: ist es meiner Meinung nach wirklich der beste Ratschlag, ihm zu 
sagen:
"Hör auf, gegen die Wand zu springen. Besinne dich lieber, tritt dann 
einen Schritt zur Seite und gehe durch die dort vorhandene Tür".

Genau das hat Stefanus getan und genau DAS ist auch ein guter und zum 
Thema passender Ratschlag.

W.S.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

@jojos,
Hab ich nicht gesagt.
Nur drücke ich niemanden meine SW so auf wie ST es mit dem CubeMX+HAL 
tut.
Das wird ja überall von ST wie warme Semmeln angeboten und als das 
nonplusultra.
Sobald mans mal nutzt stehen einem die Haare zu berge.
Vor allem wenns so offensichtliche Dinge sind die bei Tests auffallen 
müssten. (Haben die keine QC Abteilung für den HAL?)

Bei meinem Registergeclimper hatte ich mich mal vertippt und der HSE 
wurde nicht für die PLL genommen, sondern der HSI.
Fällt erst auf wenn man mal 8MHz statt 16MHz verbaut und man sich über 
den zickenden UART wundert ;)

von Johannes S. (Gast)


Lesenswert?

Mitmachen, mitgewinnen :) Fehler bei STM melden und hoffen das die auch 
beseitigt werden.
Immerhin wird das alles kostenlos angeboten und die Community hat da 
sicher schon einiges mitverbessert.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Najaa :/
Wenn man nach so diesen HAL Bugs sucht findet man imemr wieder, dass die 
schon reported wurden und nicht viel passiert ist.
Das USB Host Problem wird sich nur durch viel umschreiben der 
Statemachine.
Bis jtzt muss ich mir mit nem Workaround helfen: USb Host komplett 
beenden wenn der Stick gezogen wird und neuinit des Host.

von Harry L. (mysth)


Lesenswert?

W.S. schrieb:
> Ich sag's mal so (zum wiederholten Male):
>
> Wenn unsereiner jemanden sieht, wie der verzweifelt mit dem Kopf gegen
> die Wand rennt, weil er durch selbige durchkommen will, sich aber dabei
> nur eine Beule nach der anderen holt,...

Komm mal langsam wieder runter von deinem hohen Ross!

Ich bin zumindest auf die ursprüngliche Frage des TO eingegangen - du 
betreibst -wie üblich- nur dein "HAL-Bashing"

Ich hab keine Probleme mit HAL, und alles, was ich hier von den 
"HAL-Kritikern" lese ist fast ausnahmslos Blabla, weil die sich gar 
nicht erst die Mühe gemacht haben, das überhaupt "verstehen zu wollen", 
und sowieso alles viel besser können, als die Leute von ST.

Dein Code, den du nicht müde wirst, an allen erdenklichen Stellen 
anzupreisen ist ganz sicher auch nicht fehlerfrei und auch nicht der 
Weisheit letzter Schluß.

Das mag ja für dich das Optimale sein - für Andere muß das noch lange 
nicht zutreffen.

von Stefan F. (Gast)


Lesenswert?

Harry L. schrieb:
> Alles, was ich hier von den
> "HAL-Kritikern" lese ist fast ausnahmslos Blabla, weil die sich gar
> nicht erst die Mühe gemacht haben, das überhaupt "verstehen zu wollen"

Das schätzt du aber ganz falsch ein. Ich kann Dir mit Sicherheit sagen, 
dass ich die HAL ernsthaft verwenden wollte. Mit ganz viel Doku lesen, 
denn da es nur mein Hobby ist (der Weg ist das Ziel) hatte ich auch die 
Zeit dazu.

Und ich bin sicher, dass dies auch W.S. gilt. Der Mann ist nicht blöd.

Nur, wenn schon der allererste Usecase (Clock Initialisierung mit 
Default Settings!) den µC zum aufhängen bringt, weil die == mit != 
verwechselt haben, damm bei zweiten Usecase Bits im falschen Register 
gesetzt werden und beim dritten Usecase auffällt, dass sie nicht einmal 
ihre eigenen Empfehlungen aus dem Errata umgesetzt haben, dann verliert 
man die Lust an der HAL.

Ich habe keinen Bock, mich nach dieser Erfahrung auf so viel fremden 
Code zu verlassen. Wirklich leicht zu lesen ist er ja auch nicht gerade. 
Bevor ich diesen Rotz umfangreich analysiert und kontrolliere, schreibe 
ich es lieber selbst. Dann weiß ich auch, was ich da mache.

Beruflich entwickle ich Java Enterprise Anwendungen. Glaube mir, ich bin 
es absolut gewohnt, massenweise fremde Libraries und Sourcen 
einzubinden. Auch dort muss ich zwischen Rotz und guten Libraries 
unterscheiden - und zwar ernsthaft, denn da können Fehler das Aus der 
Firma bedeuten.

Verglichen mit den Java Libraries, ist die HAL ein großer Haufen 
schlecht dokumentierter und schlecht gepflegter Rotz. Noch wesentlich 
schlechter als die kurzlebige SPL. Da ist mir sogar Arduino noch lieber, 
und das soll schon was bedeuten.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Ich habe keinen Bock, mich nach dieser Erfahrung auf so viel fremden
> Code zu verlassen. Wirklich leicht zu lesen ist er ja auch nicht gerade.
> Bevor ich diesen Rotz umfangreich analysiert und kontrolliere, schreibe
> ich es lieber selbst. Dann weiß ich auch, was ich da mache.

Ging mir genauso ... Erstes STM32-Projekt mit HAL versucht und 
festgestellt, dass es nicht nur buggy ist sondern auch erstaunlich viel 
Performance frisst, da sehr viel Overhead.

Mühsam damals das Projekt dann von HAL wieder weg-migriert und seitdem 
läuft alles wunderbar und ich fasse HAL nicht mehr an.

CubeMX finde ich allerdings super, um die Pins zu konfigurieren ... Code 
lasse ich mir da aber nicht generieren.

von temp (Gast)


Lesenswert?

Stefanus F. schrieb:
> ist die HAL ein großer Haufen
> schlecht dokumentierter und schlecht gepflegter Rotz. Noch wesentlich
> schlechter als die kurzlebige SPL. Da ist mir sogar Arduino noch lieber,
> und das soll schon was bedeuten.

Volle Zustimmung auch von mir. Auch zu der Aussage bezüglich Arduino. 
Der Code den die Arduino-Leute schreiben ist jedenfalls deutlich besser 
als der von dem STM-Praktikanten.
Wer weiß schon ob die HAL nicht auch nur so ein kurzes Leben hat. Die 
Register bleiben. Und die gesamte Doku ist in einem einzigen pdf. Was 
will man mehr.

von Stefan F. (Gast)


Lesenswert?

temp schrieb:
> Und die gesamte Doku ist in einem einzigen pdf. Was  will man mehr.

Nicht untertreiben, es sind drei:

- Reference Manual
- Datasheet
- Errata

Für die Assembler Programmierer kommt noch das dazu:

- STM32 Cortex Mx Programming Manual

von Chris J. (Gast)


Lesenswert?

Hallo,

ohne alles gelesen zu haben, kann ich Dir sagen, dass die I2C prime Cell 
Bugs hat! Da habe ich mich auch schon dran tot gesucht, dass die 
Statemachine sich aufhängt. Habe aber lauffähigen StdPeriph Code für den 
M3. Mit kompletter Fehlerabfrage aller Events.

von temp (Gast)


Lesenswert?

Stefanus F. schrieb:
> Nicht untertreiben, es sind drei:

Ok, geb mich geschlagen.

von fsdf (Gast)


Lesenswert?

Ich verwende HAL

ja ich finde auch hier bugs.
Aber es ist ja auch meine Entscheidung...

Gerade der USB Host mit RTOS funktioniert wirklich nicht sauber.
Da sollte man nochmal drüberwischen


Aber ansonst habe ich bisher bei sehr wenigen stellen Probleme gehabt.
Gerade die seriellen Verbindungen funktionieren recht gut.

Und sehr oft saß das Problem VOR dem Rechner!!

Und so viel Overhead frisst das auch nicht ,
es sei denn man nutzt nur O0 Optimierung.

von Chris J. (Gast)


Lesenswert?

fsdf schrieb:
> ja ich finde auch hier bugs.
> Aber es ist ja auch meine Entscheidung...

Ich meine damit Bugs in der Hardware! Bei mir lief die Anwendung ein 
paar Stunden, bis dann ein Event Flag nicht mehr kam, was aber kommen 
musste.
Und O0 benutze ich bei allen Hardware Zugriffen, damit das was da steht 
auch genauso ausgeführt wird. Ist bei uns in der Firma übrigens auch 
Codierungs Richtlinie geworden für den GCC.

von Stefan F. (Gast)


Lesenswert?

Chris J. schrieb:
> -O0 ist bei uns in der Firma übrigens auch
> Codierungs Richtlinie geworden für den GCC.

Habt Ihr mit dem Optimizer schlechte Erfahrung gemacht? Wenn ja, würde 
mich interessieren, was vorgefallen ist. Oder geht es darum, 
nachträglich einen Debugger anstöpseln zu können.

von temp (Gast)


Lesenswert?

Chris J. schrieb:
> Und O0 benutze ich bei allen Hardware Zugriffen, damit das was da steht
> auch genauso ausgeführt wird. Ist bei uns in der Firma übrigens auch
> Codierungs Richtlinie geworden für den GCC.

Besser du machst für deine Firma keine Werbung.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Aber diesen Wind haben mir Niklas Gürtler und W.S. aus den Segeln
> genommen.

Na da danke ich... ;-)

Chris J. schrieb:
> Und O0 benutze ich bei allen Hardware Zugriffen, damit das was da steht
> auch genauso ausgeführt wird. Ist bei uns in der Firma übrigens auch
> Codierungs Richtlinie geworden für den GCC.
Hast du dir den vom GCC generierten Code bei -O0 mal angeschaut? Der ist 
nicht nur einfach ineffizient, da ist jede Menge komplett unnötiges Zeug 
drin. So Dinge wie:
1
80004284:  e50b100c   str  r1, [r11, #-12]
2
80004288:  e51b000c   ldr  r0, [r11, #-12]

kommen da in Mengen vor. Ich finde den optimierten Code (-O2) sogar 
deutlich besser lesbar. Funktionen welche zur Laufzeit nichts machen und 
nur Referenzen casten (insb. std::forward) werden zu längeren Prozeduren 
- für jeden Typ einzeln!
1
80004250 <Foo& std::forward<Foo&>(std::remove_reference<Foo&>::type&)>:
2
80004250:  e52db004   push  {r11}    ; (str r11, [sp, #-4]!)
3
80004254:  e28db000   add  r11, sp, #0
4
80004258:  e24dd00c   sub  sp, sp, #12
5
8000425c:  e50b0008   str  r0, [r11, #-8]
6
80004260:  e51b3008   ldr  r3, [r11, #-8]
7
80004264:  e1a00003   mov  r0, r3
8
80004268:  e28bd000   add  sp, r11, #0
9
8000426c:  e49db004   pop  {r11}    ; (ldr r11, [sp], #4)
10
80004270:  e12fff1e   bx  lr

Diese Funktion macht absolut nichts. Die könnte man zu einem schlichten 
"bx lr" vereinfachen. Bei eingeschaltetem Optimizer passiert das auch, 
wird inlined. Den unoptimierten Code möchte man gar nicht auf den armen 
Controller spielen... Ohne Optimizer ist wie mit angezogener Handbremse 
zu fahren. Ich hatte es bisher nur sehr selten, dass wirklich etwas 
kaputt optimiert wurde, und das passiert auch nur bei fehlerhaftem Code. 
Ich konnte die Optimierung immer recht problemlos bei Hardware-Zugriffen 
nutzen. Nur Styp-by-Step-Debugging ist lästiger.

Stefanus F. schrieb:
> Nicht untertreiben, es sind drei:

Das ARMv7-M Architecture Reference Manual ist auch enorm hilfreich...

Stefanus F. schrieb:
> Nur, wenn schon der allererste Usecase
Wie neu war denn der Controller? Wenn das etwas reift, sollte es doch 
stabiler werden... Ich arbeite auch selten mit CubeMX, aber habe z.B. 
mal eine einfache DC-Motorregelung gebastelt: Im CubeMX den 
PWM-Input-Capture, PWM-Output und GPIO zusammen geklickt, ein paar 
Zeilen Füllcode und den eigentlichen Regler in C geschrieben, und hat 
sofort funktioniert. So war das schon ganz nett.

: Bearbeitet durch User
von Chris J. (Gast)


Lesenswert?

Stefanus F. schrieb:
> Habt Ihr mit dem Optimizer schlechte Erfahrung gemacht? Wenn ja, würde
> mich interessieren, was vorgefallen ist.

Inzwischen hat auch der Keil Compiler Einzug gehalten. Es geht einfach 
darum, dass wenn Du SIL 3 Produkte herstellst der Notified Body, in dem 
Fall der TÜV oder die PTB nachvollziehen können will ob der Code die 
Richtlinien einhält. Die gehen durch den Asm durch. Und das geht nicht, 
wenn der Compiler etwas erzeugt, was keiner mehr nachvollziehen kann. 
Auf O0 erzeugt jede Zeile einen Abschnitt, stur durch. Keine Var wird 
weg optiomiert. Man denke nur an globale Variablen, die weg optimiert 
werden könnten. Ebensfalls verboten sind alle Arten von Zeiger 
Funktionen und Rekursionen. Als ich noch Gutachter der KTA 3503 war 
gingen wir auch jeden einzelnen Asm Befehl durch in Steuerungen an denen 
lebenswichtige Funktionen eines Kraftwerkes hängen.

Versuche einen Compiler als "bewährte Technik" durch zu kriegen laufen 
seit 2014 mit IAR, die ihren zertifizieren lassen wollen.

Bei 180 Mhz und 1MB Flash juckt es keinen ob da mehr oder weniger Code 
drin ist.

von Stefan F. (Gast)


Lesenswert?

> Stefanus F. schrieb:
>> Nur, wenn schon der allererste Usecase

Niklas G. schrieb:
> Wie neu war denn der Controller?

STM32F103RBT6, also eher ein Opa, aber noch nicht tot.

> Wenn das etwas reift, sollte es doch stabiler werden...

Aber dass man die PLL erst nutzen kann NACHDEM sie Ready ist, sollte 
jedem Entwickler bei ST klar sein - auch den Praktikanten. Die haben es 
aber anders herum programmiert: Erst auf die PLL umschalten, dann 
warten, dass sie Ready wird.

Solch grobe Fehler erwartet man nicht in diesem Framework.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Erst auf die PLL umschalten, dann
> warten, dass sie Ready wird.

Vielleicht ist die Hardware ja clever genug, erst dann umzuschalten, 
wenn die PLL ready ist. So erschlägt man dann 2 Klappen mit einer 
Warteschleife. Ich meine, solchen Code hier irgendwo auch schon ohne HAL 
gesehen zu haben... War er sogar von W.S.?

Chris J. schrieb:
> Bei 180 Mhz und 1MB Flash juckt es keinen ob da mehr oder weniger Code
> drin ist.
Wie ist das mit Leistungsaufnahme, Akku-Lebensdauer und Stückpreis des 
Controllers?

: Bearbeitet durch User
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.