Forum: Projekte & Code Serial Bootloader für STM8S103F3P6 (Linux)


von Ralph S. (jjflash)



Lesenswert?

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.

von Ralph S. (jjflash)


Lesenswert?

... 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".

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

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 !!!)

von Ralph S. (jjflash)


Angehängte Dateien:

Lesenswert?

... 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.

von STM8 noob (Gast)


Lesenswert?

Danke!

BTW, muss man bei den Interrupt-Vektoren des eigenen Programms noch 
etwas verbiegen oder geht das Automagisch?

von Ralph S. (jjflash)


Lesenswert?

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