Autor: Karl-Heinz Kübbeler   (kh_kuebbeler@web.de) , Mai 2016

Dies ist eine Assemblerversion von optiboot Version 6.2!
Der Platzbedarf konnte bei gleicher Funktionalität so minimiert werden,
dass die EEprom Programmierung jetzt auch in der kleinen Version (510 Byte)
möglich ist, weshalb die Option SUPPORT_EEPROM=1 bei der Assembler-Version
standardmässig gewählt ist. 
Die Taktfrequenz ist in der Makefile voreingestellt, kann aber mit
der Option F_CPU=xxxxxxx beim make Aufruf eingestellt werden.

Beispiel:
***********************************************
make atmega328p AVR_FREQ=8000000 BAUD_RATE=9600
***********************************************
Hiermit werden die Bootloader Daten für einen ATmega328P bei 8 MHz Takt und
einer seriellen Kommunikation mit 9600 Baud erzeugt.


Für einen Arduino UNO reicht der Aufruf für die Erzeugung der Programmdaten:
***************
make atmega328p
***************

Durch den ähnlichen Aufruf:
*******************
make atmega328p_isp 
*******************
werden die Daten zum ISP-Programmiergerät übertragen und die Fuses programmiert.
Man sollte beachten, dass der Flash Speicher vor der Programmierung 
des Bootloader Codes komplett gelöscht wird. Jedes Applikationsprogramm
muss nachher erneut über die serielle Schnittstelle in den Flash Speicher
geschrieben werden.
Vor dem Schreiben des Bootloaaders (make ..._isp Typ Aufruf) muss das 
Programmiergerät in der Datei Makefile.isp eingetragen sein.
Als Software für den ISP-Programmer wird normalerweise avrdude verwendet.
Eine Liste von Beispiel-Konfigurationen findet man in der makeall Datei.
Die Makefile passt inzwischen die Fuses des AVR und die Lage des Bootloader
Programms im Flash-Speicher automatisch an die Programmgrösse an.
Die automatische Grössenanpassung sollte auf Linux-Systemen laufen,
bei Windows Systemen ist es völlig ungetestet.
Getestet habe ich diese Assemblerversion des optiboot Loaders nur mit einem
Arduino-UNO Board und einem Arduino-Nano Clone.


Die optionale Software-UART Lösung für die serielle Kommunikation braucht etwas
mehr Platz als die Nutzung einer vorhandenen seriellen Schnittstelle,
passt in allen getesten Fällen aber auch in die 510 Byte.
Die unteren Baudraten sind mit der Software-Lösung meistens besser realisierbar.
Bei 20MHz AVR Takt sind Baudraten über 3250 Baud einstellbar, bei niedrigeren Taktraten
als 20 MHz sind auch noch kleinere Baud Werte möglich.
Mit dem Hardware UART des AVR sind bei 20MHz Takt 9600 Baud einstellbar, bei 16MHz sind
auch noch 4800 Baud wählbar. Wenn die CPU Taktrate hoch genug ist, ist als Standardwert
115200 Baud eine gute Wahl.
Unter bestimmten Umständen ist auch 1 MBAUD mit der Hardware Schnittstelle wählbar.

Bisher ungetestet ist die Option VIRTUAL_BOOT_PARTITION.
Normalerweise wird der Start-Vektor mit den Fuses (BOOTRST-Bit) auf den 
Boot Loader Reset eingestellt. Mit der VIRTUAL_BOOT_PARTITION Option kann der
Reset Vektor auf dem Applikations Reset (0x0000) bleiben.
Statt dessen  soll der Reset Interrupt-Vektor auf den Bootloader umgelegt werden.
Die Vektor-Addresse des Reset Vektors soll dann in einen anderen Interrupt Vektor
eingetragen werden und vom Bootloader beim "Timeout" benutzt werden.
Dabei werden die Programmdatem beim Flashen verändert und bei der anschliessenden
Kontrolle (verify) als ursprünglich simuliert.
Eine der Schwierigkeiten für den Bootloader besteht bei Flash-Speichergrössen
von mehr als 8K darin, dass auf den Vektoradressen sowohl JMP als auch RJMP Befehle 
benutzt werden können. 
Derzeit geht der Bootloader davon aus, daß  bei mehr als 8 kByte Flash Speicher nur 
JMP Befehle in der Interrupt Vektor Tabelle verwendet werden.

=======================================================================================
Verwendete Optionen
=======================================================================================
AVR_FREQ		definiert die Frequenz (Hz), mit der der AVR Mikrocontroller laufen soll.

BAUD_RATE		definiert die Baud Rate, mit der die serielle Schnittstelle laufen soll.

SOFT_UART		gibt an, dass anstelle der Hardware UART-Schnittstelle eine Software-Lösung
			benutzt werden soll. Damit können nahezu beliebige Bits für die
			serielle Ein- Ausgabe benutzt werden.

UART_RX			Hier können Sie das Eingabe Port Bit für die SOFT_UART Lösung angeben.
			Sie müssen nur den verwendeten Pin mit zwei Zeichen angeben.
			Das erste Zeichen muss ein Buchstabe in gross Schreibweise (A-L)
			sein, der den verwendeten Port angibt. Das nachfolgende Zeichen
			muss eine Ziffer (0-7) sein, die die Bit Nummer des Ports angibt.

UART_TX			Wie bei der seriellen Eingabe (RX) kann auch das Ausgabe Port-Bit
			für die serielle Ausgabe angegeben werden, wenn die SOFT_UART Option
			gewählt ist. Das Format ist das gleiche wie bei der seriellen Eingabe.
			Es ist auch die Angabe verschiedener Ports zulässig!

UART			gibt die Nummer der verwendeten UART-Schnittstelle bei der Hardware UART
			Lösung an. Möglich ist ein Wert von 0-3, wenn beim gewählten AVR vorhanden.

LED_START_FLASHES	gibt an, wie oft die LED vor der seriellen Kommunikation blinken soll.
			Bei 0 wird nicht geblinkt, bei 1 nur einmal (ohne Programmschleife).

LED_DATA_FLASH		Lässt die LED beim Warten auf den Empfang ein serielles Zeichen aufleuchten.

LED			gibt mit zwei Zeichen den Port und die Bit-Nummer (0-7) des LED-Ports an.
			Das erste Zeichen ist der Port-Kennbuchstabe (A,B,C,D,E,F,G,H,J,K,L).

C_SOURCE		gibt an, dass anstelle der Assembler-Version optiboot.S die C Quelle
			verwendet werden soll (verbraucht mehr Platz im Flash).

SUPPORT_EEPROM		gibt mit einem Wert ungleich 0 an, dass der Bootloader auch EEprom's
			beschreiben können soll. Bei der Assembler Version ist die Funktion
			standardmässig gewählt, kann aber mit SUPPORT_EEPROM=0 abgewählt werden.
			Es kommt aber zu einer Fehlfunktion, wenn bei der fehlenden EEprom
			Unterstützung trotzdem EEprom Daten vom Rechner übertragen werden!

BIGBOOT			war früher erforderlich, um die Grösse von 512 Byte auf 1024 Byte umzustellen.
			Die Grössenanpassung wird jetzt aber automatisch durchgeführt.
			Deshalb kann diese Variable benutzt werden, um das optiboot Programm
			künstlich grösser als erforderlich zu machen. Damit kann die automatische
			Grössenanpassung getestet werden oder auch die Startadresse des
			Bootloaders auf eine niedrigere Addresse zu legen.

VIRTUAL_BOOT_PARTITION  Diese Option verändert zwei Interrupt Vektor Sprung-Adressen,
			damit beim Reset der Bootloader gestartet wird.
			Ein anderer Interrupt-Vektor wird dann benutzt, um die Original
			Startadresse des Applikations-Programms zu sichern.
			Der Sprungbefehl bzw. die Adresse von diesem Vektor wird in den
			letzten beiden Bytes des EEprom-Speichers gesichert.
			Damit ist eine Kontrolle der geladenen Flash-Daten (verify) so lange
			möglich, wie die EEprom-Daten nicht vom Anwenderprogramm
			überschrieben werden.

Vorschlag:
==========
Beim optiboot Loader wird der Grund des Resets (MCUSR) im Register 2 an das Anwenderprogramm
weitergereicht. Hier wäre zu überlegen, ob man zusätzlich nicht auch ein Hardware-Register
des ATmega (z.B. GPIOR0) benutzt werden kann. Hier könnte auch ein C-Programm leicht zugreifen.
Die GPIORx Register haben weiter keine Funktion und eignen sich nach meiner Meinung gut
für solche Aufgaben.
Bei Prozessoren ohne diese Register-Gruppe wird das Zähler Register OCR2
als Alternative zu einem GPIORx Register benutzt werden.

Die AVR Prozessoren ATtiny84, ATmega8, ATmega328 und ATmega1284 sind derzeit mit der
Assembler-Version von Optiboot getestet.

An Rückmeldungen zum Thema "Assembler Optiboot" wäre ich durchaus interessiert.
