Weil ich gerne mit so wenigen Kabeln wie möglich hantiere, habe ich bisweilen auch gegen Bootloader bei MCU's nichts. Bei den STM32 sind serielle Bootloader integriert, für die AVR's gibts Unmengen nur für den STM8S103F3P6 (der ultrabillige Chip den es auch auf einem minimalistischen Board fast ohne alles dafür für 65 Cent gibt) gibt es keinen Bootloader (und er ist auch einer der wenigen Vertreter der STM8 Familie die keinen Bootloader integriert hat). Also habe ich einen selbst geschrieben (und mich dadurch etwas tiefer mit der Maschinensprache und dem Chip selbst auseinandersetzen müssen). Der Assemblercode ist sicher verbesserungsfähig, aber er tut (nur leider nicht so schnell wie ich es gerne hätte, was jedoch zum großen Teil der Programmierzeit geschuldet ist, wenn der STM8 sich selbst flasht). Der Bootloader ist mit "naken_asm" geschrieben, von dem ich zuvor noch nie etwas gehört habe. Sehr minimalistisch (u.a. keinen Linker), aber für das was ich vorhatte ziemlich richtig. http://www.mikekohn.net/micro/naken_asm.php Das Hostprogramm, das den STM8 mit dem Hexfile füttert ist mit FreePascal geschrieben (hey, ich hatte dafür schon die Auswertung des Intel-Hex Files in der Schublade und wollte das nicht neu machen). Außerdem funktioniert es. FreePascal findet man hier: http://www.freepascal.org/download.var Das im Zip-Paket enthaltene stm8_bootflash ist für Linux 32-Bit geschrieben, wer es für ein 64 Bit System benötigt muß es sich selbst übersetzen. Leider gilt auch für meinen STM8 - Bootloader das "Henne-Ei Problem", man braucht einen Programmer um einen Programmer oder einen Bootloader zu flashen. Der STM8 Bootloader konnte unkompliziert mit STM8FLASH und einem China-Clone ST-Link v2 geflasht werden. STM8FLASH gibts hier: https://github.com/vdudouyt/stm8flash Auf einem der Bilder sieht man, wie ein einzelner STM8 Chip mit dem ST-Link v2 verbunden werden muß. Der Bootloader wird mittels: stm8flash -c stlinkv2 -p stm8s103f3 -w bootloader.ihx in den Chip geflasht. Fortan steht der Bootloader zur Verfügung und kann mittels serieller Schnittstelle geflasht werden. Wird die DTR-Leitung einer seriellen Schnittstelle über einen Kondensator mit dem Resetanschluss des STM8 verbunden, so gelangt der STM8 automatisch in den Programmiermodus. Werden nur RxD und TxD verbunden, so muß kurz nach dem Flashprogrammaufruf am STM8 ein Reset durchgeführt werden. Prinzipiell ist der Bootloader sehr "Arduino-Style", da der Bootloader eine gewisse Zeit nach einem Reset wartet und testet, ob ein Zeichen (hier "u") eingegangen ist oder nicht. Ist ein Zeichen eingegangen wird der Flashmodus aktiv, wenn nicht, wird das im STM8 enthaltene Userprogramm ausgeführt. Gebrauch des Flashprogramms: stm8_bootflash Schnittstelle Hex-File [optional: notxbar] Beispiel: stm8_bootflash /dev/ttyUSB0 blinky.ihx Wird der Bootloader von einer IDE aufgerufen, so kann es sinnig sein, diesen ohne den Konsolenfortschrittbalken zu starten (bessere Ausgabe in einer IDE): stm8_bootflash /dev/ttyUSB blinky.ihx notxbar Viel Spaß damit (wers brauchen kann), Ralph PS: der Schaltplan zeigt, wie man den STM8 an einen (ultrabilligen China-Chip) anbinden kann. Vllt. mache ich mal ein EVAL-Board im Stile eines Arduino Nano daraus.
... was ich vergessen hatte: Natürlich belegt der Bootloader User-Speichercode im Flash (jedoch recht wenig). Für ein Programm stehen von den insgesamt 8192 Bytes die der STM8 bietet, einem Anwenderprogramm 7744 Bytes zur Verfügung. Die Differenz zu den 8192 Bytes (448 Bytes) benötigt der Bootloader selbst. Programm die mit SDCC für STM8 geschrieben sind funktionieren tadellos und "natürlich" wird Code ab der Speicheradresse $8000 korrekt abgelegt. Der Reset-Vektor an $8000 wird auf das Ende des Flash Speichers "verbogen".
A day later .... schon das erste "Update" Ich hab mich schwer über die Flashdauer des Bootloaders geärgert und mir das "genauer" angesehen gehabt: Leider hatte die erste Version KEINEN Block Save im Flashspeicher vorgenommen gehabt. Nachdem die Anweisung zum blockweisen schreiben korrekt war stellte ich fest: Ein blockweises Schreiben im Flashspeicher geht nur dann, wenn das Kopieren in den Flashspeicher von einer Programmroutine aus erfolgt, die zwingenderweise im RAM liegt ! wurgs dachte ich, hilft aber nichts. Also hab ich eine kleine Speicherkopierfunktion geschrieben und kopiere den Teil, der das Blockspeichern vornimmt ins RAM und starte dort die Kopierfunktion. Hat super geklappt, der Bootloader "rast" jetzt im Vergleich zu vorher. Ein Upload von 6596 Bytes erfolgt in 3,2 Sekunden. Die maximale Speichergröße des Userprogramms beträgt nach wie vor 7744 Bytes (der Bootloader belegt somit 448 Bytes !!!)
... wie die Zeit doch vergeht: Ich dachte nicht, dass ich den Bootloader schon vor 2 Jahren geschrieben hatte. Jetzt gibts das nächste "Update" und leider wurde beim Upload-Tool ein weiterer Optionsparameter notwendig und von daher müssen dann bestehende Makefiles angepasst werden. Seit längerer Zeit habe ich ich auch ein STM8S105K4 Board herumliegen, das ich jedoch nie verwendet oder in Benutzung hatte... bis auf jetzt eben. Also wollte ich den Bootloader auch für den 105er haben. Wie das so ist, dauert etwas, von dem man dachte dass es kurz ist dann doch länger. Ich hab für die Modifikationen 2 Abende gebraucht, aber jetzt klappts. Der Bootloader funktioniert mit den auf Ebay erhältlichen billigsten Experimentierboards (allerdings haben sich die Preise für die Boards seit 2 Jahren verdoppelt und die für die Chips verdreifacht... aber immer noch billig). https://www.ebay.de/itm/ARM-STM8S103F3P6-STM8-Minimum-System-Development-Board-Module-For-Arduino/132486311875?hash=item1ed8ccafc3:g:YyQAAOSwjRtbNEld:rk:2:pf:0 https://www.ebay.de/itm/STM8S-STM8S105K4T6-Development-Board-Module-MCU-Learning-Core-Board-Small-System/263351137116?hash=item3d50f3735c:g:vqAAAOSwySlaHmbR:rk:2:pf:0 Somit sind nun zwei getrennte Bootloader verfügbar (eben einer für STM8F003 / STM8F103 und einer für STM8F105). Leider stellt man fest, dass die 103er sogenannte Low density Bausteine sind und ihren inneren Flash in Pages zu je 64 Bytes zusammenfasst, die 105er Bausteine sind Medium density Bausteine und die werden mit 128 Bytes per Page zusammen gefasst. Das machte erforderlich, dass dem Upload-Tool gesagt werden muss, für welchen Baustein etwas hochgeladen werden soll. Ein Aufruf des Tools erfolgt nun so:
1 | Syntax: |
2 | stm8_bootflashv2 device port filename [notxbar] |
3 | |
4 | device : MCU - device |
5 | port : port were the adapter is connected |
6 | filename : file to be uploaded |
7 | notxbar : optional, no bar graph is shown |
8 | (use it by call from an IDE) |
9 | |
10 | Example : stm8_bootflashv2 stm8s103f3 /dev/ttyUSB0 helloworld.ihx |
-------------------------------------------------- Das Makefile im ZIP-Ordner wertet die Optionen: all, host, f103, f105, host, flash103, flash105, clean Zum Übersetzen wird für das Uploadprogramm ein installierter FreePascal Compiler, für die Bootloader ein installierter Naken-Assembler vorrausgesetzt. http://www.mikekohn.net/micro/naken_asm.php Die Optionen im einzelnen sind: all: erstellt die beiden Bootloader-Hexdateien host: erstellt das Uploadprogramm (ein installierter FreePascal Compiler wird vorrausgesetzt) f103: erstellt nur den Bootloader für STM8S103F f105: erstellt nur den Bootloader für STM8S105K4 flash103: flasht den Bootloader in den STM8S103, ein angeschlossener ST-Link wird vorrausgesetzt flash105: dto. für STM8S105 clean: räumt auf Für diejenigen die sich den Pascal Compiler extra installieren wollen ist das Binarie des Uploadtools in den Ordnern bin32 und bin64 enthalten (zu verwenden je nachdem ob ein 32 oder 64 Bit Linux verwendet wird). Die Ordner bin und ihx enthalten nach einem Makeaufruf die aktuell compilierten Dateien. ------------------------------------------------------------ Die Bootloader sind verwendbar mit Programmen, die mittels SDCC übersetzt wurden. Prinzipiell ist gültig, dass die ersten 4 Bytes eines Programms einen Sprungbefehl zu einem Hauptprogramm enthalten oder den von SDCC erstellten Code enthält:
1 | 45 .area HOME |
2 | 008000 46 __interrupt_vect: |
3 | 008000 82 00 80 07 47 int s_GSINIT ; reset |
4 | 48 ;-------------------------------------------------------- |
5 | 49 ; global & static initialisations |
6 | 50 ;-------------------------------------------------------- |
7 | 51 .area HOME |
8 | 52 .area GSINIT |
9 | 53 .area GSFINAL |
10 | 54 .area GSINIT |
11 | 008007 55 __sdcc_gs_init_startup: |
12 | 008007 56 __sdcc_init_data: |
13 | 57 ; stm8_genXINIT() start |
14 | 008007 AE 00 00 [ 2] 58 ldw x, #l_DATA |
15 | 00800A 27 07 [ 1] 59 jreq 00002$ |
16 | 00800C 60 00001$: |
17 | 00800C 72 4F 00 00 [ 1] 61 clr (s_DATA - 1, x) |
18 | 008010 5A [ 2] 62 decw x |
19 | 008011 26 F9 [ 1] 63 jrne 00001$ |
20 | 008013 64 00002$: |
21 | 008013 AE 00 00 [ 2] 65 ldw x, #l_INITIALIZER |
22 | 008016 27 09 [ 1] 66 jreq 00004$ |
23 | 008018 67 00003$: |
24 | 008018 D6 80 23 [ 1] 68 ld a, (s_INITIALIZER - 1, x) |
25 | 00801B D7 00 00 [ 1] 69 ld (s_INITIALIZED - 1, x), a |
26 | 00801E 5A [ 2] 70 decw x |
27 | 00801F 26 F7 [ 1] 71 jrne 00003$ |
28 | 008021 72 00004$: |
29 | 73 ; stm8_genXINIT() end |
30 | 74 .area GSFINAL |
31 | 008021 CC 80 04 [ 2] 75 jp __sdcc_program_startup |
32 | 76 ;-------------------------------------------------------- |
33 | 77 ; Home |
34 | 78 ;-------------------------------------------------------- |
35 | 79 .area HOME |
36 | 80 .area HOME |
37 | 008004 81 __sdcc_program_startup: |
38 | 008004 CC 80 24 [ 2] 82 jp _main |
Der Bootloader kopiert die ersten 4 Bytes eines Userprogramms an das Flashende des Controllers und ersetzt die ersten 4 Bytes durch einen Sprungbefehl auf den Bootloadercode. Nach einem Reset wird in den Bootloader gesprungen und erfolgt innerhalb einer bestimmten Zeit keine Uploadanforderung wird das im Flash gespeicherte Userprogramm gestartet.
Danke! BTW, muss man bei den Interrupt-Vektoren des eigenen Programms noch etwas verbiegen oder geht das Automagisch?
Nein, du mußt nichts verbiegen. Wie der Auszug oben zeigt wird der Code an genau der Stelle abgelegt für den der Compiler es erzeugt hat. Lediglich die ersten 4 Bytes sind an einer anderen Stelle (Reset). Das heißt du kannst einen mit SDCC erstellten Code mittels ST-Link Programmer oder mit dem Bootloader hochlafen. Er wird laufen. Zu beachten ist hier, dass beim Hochladen mittels ST-Link Programmer der Sprung auf den Bootloader überschrieben wird und somit der Bootloader nach eunem Flashen mit ST-Link nicht mehr funktioniert (und müsste dann neu aufgespielt werden).
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.