Hallo lieber Forumgemeinde, nachdem ich bei meinem letzten Projekt (PC Kommunikation zum STM32 M3 mittels USB) viele tolle Antworten erhalten habe, versuche ich es nochmals auf diesem Weg in der Hoffnung, dass jemand die Zeit findet mir zu helfen. Ich habe die hier verbreitete Routine von "W.S." genommen, um eine USB Virtual Com Port Kommunikation zu meinem PC ("Visual Studio") herzustellen. Ich konnte ich die HAL Library von STM Cube nicht verwenden, da mein, für meine Verhältnisse doch recht komplexes Programm schon annähernd fertig und ohne HAL-Libraries geschrieben war. Hier bot die USB.c und USB.h von W.S. (hier im Forum viel diskutiert) eine wirklich tolle Alternative. Jetzt stehe ich vor dem Problem, dass für eben dieses fertige Programm DFU funktionieren soll. Ich könnte über das Touch Panel gezielt in den Firmware Modus wechseln, also in die entsprechenden Routinen springen und dann im DFU Modus die HEX File über den PC übertragen (entsprechende PC Software ist vorhanden) Hat irgend jemand diesbezüglich einen Hinweis oder Software für mich die diese Option ohne HAL ermöglicht? Für jeden Tip bin ich dankbar...
https://github.com/rogerclarkmelbourne/STM32duino-bootloader wenn es denn unbedingt ein stm32 ohne DFU-im-ROM seien soll..
Hallo 23mts, danke, aber was mache ich jetzt mit den 100 Dateien? Die überschneiden sich ja auch z.T mit meinen clock Einstellungen tec. Am liebsten wäre mir lediglich eine DFU.c und EINE dfu.h mit einer Funktion namens "EnterDFUMode"...
Ich würde ein neues Projekt mit der HAL erstellen und dann deine ganzen Files dazu kopieren. Schau mal wie einfach ein hello-World mit der HAL aussieht: http://stefanfrings.de/stm32/index.html#vcphal
no Chance, ich habe canbus, USB, SPI1,SPI2 am laufen incl. diverser schneller Zähler, PWM und Timer. Das alles jetzt nochmal zur HAL zu übertragen halte ich für schlichtweg unmöglich, da ALLE SETTINGS neu gemacht werden müssen. Eine Katastrophe. Das hatte ich bei der Implementierung von USB schonmal mit mäßigem Erfolg probiert...
Die DFU-Funktionalität packt man am besten in einen eigenen Bootloader, d.h. ein eigenes Programm und damit oft ein eigenes Binary, was vor deiner eigentlichen Applikation im Flash liegt und als erstes ausgeführt wird. Dieser Bootloader kann dann entweder per DFU eine neue Applikation ins Flash laden oder wenn das nicht gewünscht ist (meist nach einem Timeout) einfach die normale Applikation laden, die hinter deinem Bootloader liegt. DFU-Bootloader für den F1 gibt es relativ viele. Neben dem bereits erwähnten STM32duino/Maple Bootloader z.B. https://github.com/PX4/Bootloader oder https://github.com/paparazzi/luftboot . Der Bootloader muss natürlich zu deiner Hardware passen, d.h. du musst HSE-Frequenz und USB-Reenumerationsmethode anpassen. Ggf. dann noch Status-LED oder was auch immer. Dann deine eigentliche Applikation an die neue Adresse linken und den Offset der Vektortabelle setzen (VTOR).
Halli Hallo Christopher, viiielen Dank für die ausführliche Beschriebung. Aber leider habe ich nur ca 10% deiner Ausführungen verstanden. Ich arbeite seit ca 2 Jahren mit dem STM und bin froh die "normalen Funktionen" wie SPI, CAN, UART etc ans laufen gebracht zu haben. (Arbeite mit EmBitz als Programmierumgebung und Programmiere über SWD. Wie das flashen eines eigenen Bootloaders funktioniert weiß ich leider nicht. Auch nicht das Einfügen der bin Datei. Könntest du das, auch wenn es sehr ätzend für dich sein mag, ein bisschen für blonde erklären?
Hanna schrieb: > Ich konnte ich die HAL Library von STM Cube nicht verwenden, da mein, > für meine Verhältnisse doch recht komplexes Programm schon annähernd > fertig und ohne HAL-Libraries geschrieben war. Wenn du das alles ohne HAL hinbekommen hast, sollte es doch auch kein Problem sein, das DFU auch noch ohne HAL umzusetzen? Du könntest dir einen eigenen Request für den Control Endpoint bauen, bei dessen Empfang sich das Gerät trennt und wieder als DFU-Gerät anmeldet. Alternativ schaltest du zwischen verschiedenen Configurations um. Wenn USB an sich schon läuft, ist doch der Empfang von Daten und das Schreiben in den Flash machbar. Siehe z.B. auch hier USB-Tutorial mit STM32 zur Programmierung des USB ohne HAL.
Ich glaube, jetzt hast du ihn erschreckt. Niklas, deine Library mag eine gute Lösung sein. Doch wenn der TO sein eigenes Projekt nicht in ein HAL Rahmengerüst hinein bekommen kann, dann kommt er mit deiner Implementierung vermutlich auch nicht zurecht.
Hanna, hast du schon einmal daran gedacht, einfach einen ST-Link Adapter zusammen mit deinem Gerät auszuliefern (evtl. fest eingebaut)? Wenn du einen mit Firmware Version 2.1 nimmst, kann man Firmware Upgrades ganz ohne Zusatz-Software hochladen - einfach per Drag&Drop mit dem Dateimanager.
Stefan U. schrieb: > Doch wenn der TO sein > eigenes Projekt nicht in ein HAL Rahmengerüst hinein bekommen kann, dann > kommt er mit deiner Implementierung vermutlich auch nicht zurecht. Die Idee war mehr, dass man W.S.' Implementierung mithilfe der im Tutorial übersichtlicher dargestellten Informationen umbaut, weniger einfach meinen Code zu übernehmen. Es wird wohl kaum einen fertigen Code geben, der direkt perfekt zu W.S.' VCP-Implementation passt. Wenn man es schafft alles ohne HAL zu machen hat man offenbar schon einiges an Verständnis. Die USB-Peripherie ist einfacher als z.B. die vom USART...
> Die USB-Peripherie ist einfacher als z.B. die > vom USART... Das sehe ich anders. Meine erste Hello-World Meldung hatte ich schon nach wenigen Minuten gesendet. Man muss ja nicht gleich mit DMA anfangen.
Hallo, mit ST Adapter ausliefern ist zwar möglich, die SWD Anschlüsse sind jetzt im Gehäusedesign nicht nach außen geführt :-( Ich dachte das alles wäre einfacher. Ich verstehe hier wirklich zu 80% nur Bahnhof :-(
Stefan U. schrieb: > Das sehe ich anders. Meine erste Hello-World Meldung hatte ich schon > nach wenigen Minuten gesendet. Man muss ja nicht gleich mit DMA > anfangen. Ja so schnell geht es per USB nicht. Aber zähl mal die Seiten im Reference Manual für USART und die für USB, und wie viele Einstellungs-Register die jeweils haben... Es sollte eigentlich ohne größere Probleme möglich sein, HAL-Code für einzelne Komponenten ins Projekt einzubinden. Das Einbinden der HAL zwingt einen nicht dazu, alles damit zu machen. Das Hauptproblem besteht in eventuellen Namenskonflikten mit der Unzahl an Makros in der HAL - aber die lassen sich durch Suchen&Ersetzen lösen. Ich habe schon HAL mit direkten Registerzugriffen gemischt, teilweise auch beim selben Peripherie-Modul.
Der Bootloader und die Application sind verschiedene Baustellen. Man kann auch das HAL Beispiel für DFU_Standalone oder DFU einfach für den Lader verwenden und das eigene Prog auf die Adresse nach dem Lader linken.
Hanna schrieb: > Wie das flashen eines eigenen Bootloaders funktioniert weiß ich leider > nicht. Auch nicht das Einfügen der bin Datei. > Könntest du das, auch wenn es sehr ätzend für dich sein mag, ein > bisschen für blonde erklären? Ich kann es mal versuchen. Erstmal ist es wichtig zu wissen, wo überhaupt so ein Cortex-M anfängt zu arbeiten. Am Anfang des Flash-Speichers liegt die Interrupt-Vektortabelle, d.h. eine Tabelle von Funktionszeigern, welche auf die Funktionen zeigen, die ausgeführt werden sollen, wenn ein entsprechender Interrupt ausgelöst wurde. Der allererste Eintrag in dieser Tabelle ist jedoch genau genommen kein Funktionszeiger, sondern der initiale Stackpointer. Der zweite Eintrag ist dann jedoch schon gleich der Reset-Handler und dieser wird dann auch direkt angesprungen. Im Reset-Handler wird unter anderem die SystemInit-Funktion aufgerufen, welche typischerweise die Clock-Konfiguration vornimmt, bevor am Ende des Reset-Handlers die eigentliche main-Funktion angesprungen wird. Wie schon gesagt ist die DFU-Funktionalität (in Software) in Form eines Bootloaders (kurz BL) ein eigenes Programm. Beim von dir eingesetzten Controller beginnt der Flash an der Adresse 0x8000000. Mal angenommen der Bootloader hat (auf volle kB aufgerundet) 8192 Byte, dann ist der Bereich von 0x8000000 bis 0x8001FFF mit deinem BL belegt. Wenn dein Controller startet, dann startet er also erstmal (über den Reset-Handler) in die main des BL. Typischerweise lauscht der BL dann für eine bestimmte Zeit ob eine Verbindung mit DFU zu Stande gekommen ist. Ist das der Fall, dann kann der BL deine eigentliche Applikation (App) per USB laden und sie in den Flash schreiben und zwar hinter den BL, d.h. in diesem Beispiel beginnend bei 0x8002000. Ist keine DFU-Verbindung zu einem PC zu Stande gekommen, sorgt der Bootloader dafür, dass die Applikation, welche hinter dem Bootloader liegt ausgeführt wird, d.h. er lädt den Stackpointer wieder auf das Ende des RAM und springt den Reset-Vektor an (den deiner App bei 0x8002000). Nun folgt wieder das Prozedere vom Anfang, d.h. der (App-)Reset-Handler ruft die (App-)SystemInit und (App-)main auf. Damit deine App bei 0x8002000 überhaupt funktionieren kann muss diese erstmal an diese Adresse gelinkt werden (statt 0x8000000). Dazu musst du das Linkerscript anpassen (xyz.ld). Normalerweise steht da so etwas wie
1 | MEMORY |
2 | { |
3 | flash (rx) : ORIGIN = 0x08000000, LENGTH = 64K |
4 | sram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K |
5 | } |
in dem Beispiel mit dem 8kB großen BL wird daraus dann
1 | MEMORY |
2 | { |
3 | flash (rx) : ORIGIN = 0x08002000, LENGTH = 56K |
4 | sram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K |
5 | } |
d.h. statt 0x8000000 ist der "origin" nun bei 0x8002000 und die größe des Flashs ist von diesem Punkt betrachtet nur noch 56kB (weil ja die ersten 8kB vom BL belegt sind). Jetzt hast du also den BL bei 0x8000000 und deine App bei 0x8002000 jedoch hast du jetzt auch zwei Interrupt-Vektortabellen. Ohne weiteres Zutun würde jetzt ein Interrupt in deiner App den Interrupt-Handler des BL aufrufen, weil dessen Tabelle nunmal am Beginn des Flash liegt. Um das zu ändern gibt es bei den Cortex-M3 ein "Vector Table Offset Register". In dieses Register schreibt man dann den Wert, an welchem die "neue" Vektortabelle liegt, d.h. in diesem Fall 0x8002000, d.h.
1 | SCB->VTOR = 0x8002000; |
Das packst du in die SystemInit deiner App oder zumindest an den Anfang deiner (App-)main aber jedenfalls bevor irgendein Interrupt feuern kann. Falls du die SPL nutzt, dann gibt es in der SystemInit schon ein #define VECT_TAB_OFFSET, welches du nur anpassen musst (auf 0x2000 statt 0x0). Wie man mit dem ST-Link Utility (mit dem Embitz daherkommt) eine Binary an eine bestimmte Adresse flashen kann weiß ich nicht, weil ich das Programm noch nie genutzt habe aber das ist ganz sicher möglich. Den Bootloader flashst du ja auch ganz normal wie jedes andere Programm auch an den Anfang des Flashes. Lediglich deine Applikation landet an anderer Stelle.
Die STM32, die ich kenne, können USB-DFU ganz ohne eine einzige Codezeile. Man muss nur BOOT0 auf HIGH ziehen, zack, los gehts. Man muss natürlich die Beschaltung haben, die im Datenblatt steht. Der interne Bootloader macht das. Beispielweise bei den Typen STM32F072 und STM32F303ZE ist das so. Hast du mal geprüft, ob deine das nicht eh auch kann? Dann kannst du die die ganze Aktion nämlich schenken. Vor allem benötigt der interne Bootloader genau 0,0 Flash.
> Man muss nur BOOT0 auf HIGH ziehen, zack, los gehts
Das trifft nur auf die größeren Modelle zu.
Wollte noch diesen Bootloader in die Runde werfen: https://github.com/devanlai/dapboot Habe keine Erfahrung damit, aber diese WebUSB-Geschichte klingt ganz interessant.
Stefan U. schrieb: >> Man muss nur BOOT0 auf HIGH ziehen, zack, los gehts > > Das trifft nur auf die größeren Modelle zu. Mir riecht das zuviel nach Bauernregel. Und Bauernregeln haben in der Elektronik nichts zu suchen. Der STM32F072 ist ein F0, d.h. von der Billigserie. Als "größeres Modell" würde ich den nicht sehen. Bei uns hat der ATMEGAs ersetzt. Der STM32F072 kann das. So ganz stimmen kann deine Aussage also nicht. @Hanna: Bitte nenne doch mal das konkrete Device. Dann kann man nachsehen und Klarheit schaffen.
> Mir riecht das zuviel nach Bauernregel. Du hast Recht, ich denke immer nur an die STM32F1 Serie weil ich mit allen anderen STM32 Serien noch nie zu tun hatte.
Hmm schrieb: > Mir riecht das zuviel nach Bauernregel. Und Bauernregeln haben in der > Elektronik nichts zu suchen. Der Thread-Titel klingt nach einem verunglückten Versuch, STM32F103C8T6 zu schreiben. Der ist auch sehr verbreitet bei China-Billig-Boards. Im Titel des Datasheet steht "Medium Density". Im Reference Manual steht auf S. 60: * In low-, medium- and high-density devices the bootoader is activated through the USART1 interface. * In XL-density devices the boot loader is activated through the following interfaces: USART1 or USART2 (remapped). * In connectivity line devices the boot loader can be activated through one of the following interfaces: USART1, USART2 (remapped), CAN2 (remapped) or USB OTG FS in Device mode (DFU: device firmware upgrade). Also nur USART1.
Hanna schrieb: > Hat irgend jemand diesbezüglich einen Hinweis oder Software für mich die > diese Option ohne HAL ermöglicht? Also nochmal alles ganz in Ruhe: 1. Du hast einen STM32Fxxx (den genauen Typ hast du nicht genannt). 2. Also sieh in den Appnotes von ST zu den Bootladern (Nummern hab ich nicht auswendig gelernt) nach, welcher Chip welchen Bootlader tatsächlich enthält. 3. Wenn dein Chip einen Bootlader enthält, der mit dem USB umgehen kann, dann kümmere dich darum, wie dein Kunde diesen gezielt gestartet bekommt - und zwar auch dann, wenn beim Firmware-Update etwas schief gelaufen ist und die alte Firmware perdü ist. 4. Wenn dein Chip einen Bootlader enthält, der USB eben NICHT kann, dann gehst du anders vor: 5a) du schreibst ein Programm für den PC, das per irgendeiner sinnvollen Übertragung (heutzutage zumeist USB-->Seriell) mit dem Botlader umgehen kann. Und dieses Programm zusammenmit einem billigen Adapter USB-Seriell gibst du deinem Kunden. 5b) du schreibst dir einen eigenen Bootlader, der etwa so, wie Christopher es weiter oben bereits umrissen hat, am Anfang deines Flashes steht und in der Lage ist, den Rest deiner Firmware zu löschen und mit neuem Zeug zu beschreiben. Dessen Speicherplatz geht natürlich von dem Umfang des Flashes ab, so daß deine FW halt ein bissel kleiner sein muß - und obendrein mußt du dir Gedanken machen über die benötigten Interrupts, denn es wäre extrem töricht, beim FW-Update den gesamten Flash neu zu schreiben. Es könnte nämlich was schief gehen und dann ist dein Gerät erstmal gebrickt. Klaro? Es gibt noch was zu beachten: 6. Entweder kann dein Bootlader nicht nur VCP, sondern auch Massenspeicher, dann hat es dein Kunde leichter, weil er bloß per Dateimanager oder so die FW auf diesen externen Massenspeicher kopieren muß. Oder dein Bootlader kann eben nur VCP, dann mußt du wieder ein Programm für den PC schreiben, was mit dem BL geeignet kommuniziert. 7. Gehe mal in dich und frage dich, ob es denn UNBEDINGT ein STM32 sein soll. Grund: Bei NXP gibt es einige µC, die einen solchen Bootlader drinhaben, der mit USB klarkommt und sich als Massenspeicher ausgeben kann. Damit hast du das Updateproblem für deinen Kunden sehr vereinfacht. Nen passenden USB-VCP-Treiber für den Normalbetrieb für z.B. die LPC13.. und LPC17.. hab ich grad vor kurzem hier irgendwo gepostet. W.S.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.