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
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?
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!
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
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:
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.
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.
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!
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.
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
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
I2CaI2C(1);// I2C1 benutzen 2 fürI2C2
5
6
...
7
intrc=0;
8
// init I2C, no portremap, use PB6 and PB7
9
rc=aI2C1.Init(I2C_FAST,false);
10
if(rc==0)
11
{
12
uint8_twdata[]={0};
13
uint8_trdata[7];
14
15
// 0x68 is the address for DS1307
16
// write 1 byte (0) to set the addr in DS1307 to 0
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, abertemp 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
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).
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);
?
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.
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.
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.
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);
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:
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
@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 ;)
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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!
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.
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.
> Stefanus F. schrieb:>> Nur, wenn schon der allererste UsecaseNiklas 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.
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?