Für das EEPROM gibt es ja neben eeprom_write_block auch
eeprom_update_block, welches nur schreibt, wenn tatsächlich andere Daten
übergeben werden, als schon vorhanden waren. Das schont das EEPROM.
Gibt es so etwas (fertig) auch für den Flash? Ich möchte, dass mein
Bootloader nur schreibt, wenn die neue Firmware sich auch wirklich von
der vorhandenen unterscheidet. Ideen?
Bootlader fragt den Server nach der neuesten Version und bekommt eine
Versionsnummer. Nun muss er nur noch mit der aktuell installierten
Version vergleichen und kann entscheiden, was zu tun ist. Spart Zeit.
Ne, mein Bootloader kann keine Versionsnummern aus der Firmware
auslesen. Ich möchte nur, dass die Bytes/Pages geschrieben werden,
welche sich unterscheiden. Wie beim EEPROM.
Franz schrieb:> Ne, mein Bootloader kann keine Versionsnummern aus der Firmware> auslesen. Ich möchte nur, dass die Bytes/Pages geschrieben werden,> welche sich unterscheiden. Wie beim EEPROM.
Es gibt zwei Möglichkeiten:
1)
Dein µC hat nicht genug RAM über, um den Bootloader zu buffern. Dann
geht's nicht.
2)
Er hat genug RAM über. Dann ist die Sache schneller programmiert, als es
dauert, ein Posting hier zu verfassen...
Warum hast du dich trotzdem für das Posting entschieden?
c-hater schrieb:> Warum hast du dich trotzdem für das Posting entschieden?
Aus dem Zusammenhang:
Offensichtlich will er sein Flash schonen ...
Franz schrieb:> Das schont das EEPROM.
Franz schrieb:> Ich möchte, dass mein> Bootloader nur schreibt, wenn die neue Firmware sich auch wirklich von> der vorhandenen unterscheidet. Ideen?
Nun, ein Bootloader könnte das durchaus leisten, das RAM eines
AVR ist beim Booten sicher frei genug um eine Flash Page zu
puffern und zu vergleichen ob Programmieren erforderlich ist.
Aber die Bootloader-Schreiber werden so etwas nicht tun weil
der Code dafür den Bootloader aufbläht was evtl. den Rahmen
des Möglichen oder des Erwünschten (Flash-Speicherplatz)
sprengen würde.
Intelligente Tools machen das (Schonen) von aussen im Rechner
indem sie den alten Flash Inhalt lesen und mit dem neuen Code
vergleichen, ohne den Bootloader dafür zu "belästigen".
Holger schrieb:> Seit wann muss beim AVR das ganze Image im RAM gepuffert werden?
Es muss nicht unbedingt RAM sein, aber irgendein Speicherbereich muss
das komplette neue *BOOTLOADER*-Image aufnehmen können. Das kann auch
EEPROM sein oder freie Bereiche im restlichen Flash.
Das liegt in der Natur der Sache: schließlich wird der "alte"
Bootloadercode in funktionsfähiger Form gebraucht, um den Code des neuen
Bootloaders erstmal von der Quelle heranzuschaffen, nur komplette
Vollidioten fangen schon beim Download an, den alten Bootloadercode in
Teilen zu überschreiben...
Einzig bei sehr primitiven (also hinreichend kleinen) Bootloadern, die
vollständig in eine Flashpage passen, kann man tricksen. Natürlich auch
in diesem Fall nicht gegen die Gesetze der Logik, das komplette
Bootloaderimage muss natürlich auch in diesem Fall gepuffert werden
können. Aber in diesem Sonderfall kann man sich dafür den kleine
RAM-Puffer nutzbar machen, den die AVR8 für das Flashen zur Verfügung
stellen und der ausserhalb des normalen SRAM liegt.
Den braucht man für das Update der wichtigsten Page des Bootloadercodes
(die mit der spm-Instruktion) übrigens sowieso. Gäbe es diesen Puffer
nicht, wäre es sogar prinzipell unmöglich, einen Bootloader mittels
eines Bootloaders upzudaten.
Arduinoquäler schrieb:> Nun, ein Bootloader könnte das durchaus leisten, das RAM eines> AVR ist beim Booten sicher frei genug um eine Flash Page zu> puffern
Das reicht nicht. Der komplette Bootloader muss gepuffert werden können,
zumindest alle Pages mit Änderungen (genauer: mit Bits, die von 0 auf 1
zu ändern sind). Allerdings muss der Puffer nicht unbedingt im SRAM
liegen. Unbenutzter Flash oder EEPROM geht auch.
c-hater schrieb:> aber irgendein Speicherbereich muss> das komplette neue *BOOTLOADER*-Image aufnehmen können.
Erklärt mir mal jemand warum man ein neues Bootloader-Image
braucht wenn man - wie der TO beabsichtigt - nur sein übriges
Flash updaten will, und das auf "schonende" Art und Weise
mittels Compare einer Flash Page mit einem RAM Buffer Inhalt?
Ich versuche gerade, das in meinen Bootloader zu implementieren.
Da stellt sich die Frage, ob man boot_page_fill auch vor boot_page_erase
ausführen kann. Normal ist ja die Reihenfolge:
boot_page_erase (1x pro Page)
boot_page_fill (Word für Word bis die Page voll ist)
boot_page_write (1x pro Page)
http://www.atmel.com/webdoc/avrlibcreferencemanual/group__avr__boot.html
Eigentlich schreibt boot_page_fill ja nur in einen "bootloader temporary
page buffer" und erst boot_page_write schreibt wirklich. Man könnte
Letzteres ja unterbinden, wenn man feststellt, das die neuen Daten
identisch mit dem vorhandenen Flashinhalt ist.
Leider ist boot_page_erase da aber schon ausgeführt und der Pageinhalt
beim Teufel.
Die Lösung wäre, boot_page_erase erst kurz vor boot_page_write
aufzurufen...
Hat jemand mal damit experimentiert?
Ah, in Sektion 27.8 des Datenblatts (Mega328) steht sogar direkt, dass
es geht. :) Bin gespannt, ob ich es hinbekomme.
Platz ist genug. 1kB für UART-Kram, Flashfunktionen und rudimentäre
Inits der Ports, das reicht dicke.
Shit. Es gibt ein Problem, das das Datenblatt so ein bisschen "nebenbei"
erwähnt: "Note that it is not possible to write more than one time to
each address without erasing the temporary buffer."
Der "temporary buffer" wird nach dem Schreiben der Page automatisch
gelöscht.
Wenn ich mir aber das Löschen/Schreiben der Page erspare (weil nicht
nötig- bei unveränderten Daten), dann kann ich also nicht einfach weiter
die nächste Page in den Buffer schaufeln...