Datum: 12.04.2007 13:43
Hallo, im Anhang findet sich ein Bootloader, der seine Updates von einer MMC/SD Karte bezieht. Der Bootloader passt knapp in 2kB, so dass der Bootloader vom Mega8 bis zu den Großen verwendet werden kann. Ausstattung: - Unterstützung für FAT16 (Partitionstyp 0x06) - Überprüfung der "Geräte-ID", so dass automatisch die richtige Datei, und nur diese, von der Karte geladen wird - Überprüfung der Versionkennung, so dass nur aktualisiert wird wenn eine neuere Software auf der Karte vorhanden ist - CRC Überprüfung; das Hauptprogramm wird nur dann gestartet, wenn die CRC (befindet sich in den letzten beiden Bytes des Hauptprogrammes) korrekt ist. Einschränkungen: - Auf der Karte muss ein MBR vorhanden sein, und es wird nur die erste Partition überprüft (meine letzten 3 Karten die ich gekauft habe waren bereits so eingerichtet mit FAT16 Partition). Ggf. selber einen MBR auf die Karte schreiben Beschreibung: Im Bootloader wird eine Gerätekennng (DEVID) im makefile definiert. Für jedes Gerät sollte eine eigene Kennung vergeben werden. Im Hauptprogramm wird diese Gerätekennung, die Softwareversionsnummer und 2 leere Bytes, in die später die CRC kommt, über eine Section ans Ende des Hauptprogramms geschrieben. Nach dem erzeugen des Hauptprogramms muss noch mit dem ebenfalls beiliegenden Tool "crcgen" die CRC in die hex-Datei geschrieben werden. Nun wird noch die hex-Datei auf eine MMC kopiert (Dateiname egal) und fertig. Der Bootloader erkennt dann an der Dateigröße und der DEVID dass es sich um ein Update für dieses Gerät handelt. Nachdem die Versionsnummer (im Makefile des Hauptprogramms hinterlegt) überprüft wurde beginnt der Updatevorgang. Anschließend wird noch die CRC im Flash überprüft und das Hauptprogramm gestartet. Zu tun: Der Bootloader passt derzeit ganz knapp in 2 kB, für ein paar Statusausgaben (Display, LEDs, etc) ist kein Platz mehr. Vielleicht könnte sich jemand den Code ansehen der mehr von "effizientem Programmieren" versteht als ich, und noch das ein oder andere Byte herauskitzeln. So, dann viel Spaß beim Testen, Stefan
Datum: 12.04.2007 15:58
Sieht gut aus! (sehr flüchtig draufgeguckt) Ich brauche zwar keinen solchen Bootloader, aber kann mir vielleicht was für meinen abgucken. ;-) Zum Thema unter gcc kleiner kriegen siehe hier: Beitrag "Tricks, wie ich mein Compilat kleiner kriege" Bin noch nich ganz durch damit, werde bestimmt noch was ergänzen, aber besonders die "umstrittenen" -mint8 und -mtiny-stack bringen viel.
Datum: 12.04.2007 16:28
Eins fällt mir doch noch auf: In deinem .lss File sieht man, daß du dir die Bibliotheksfunktion udivmodsi4 "eingefangen" hast, eine allgemeine Division. Die ist recht teuer. Sie wird 2 mal benutzt: Einmal in fat16_readfilesector für Teilen durch SectorsPerCluster. Versuch' da vorher einen Zweierexponenten draus zu gewinnen, dann ist hier ein Rechtsschieben möglich. Das zweite Mal ein paar Zeilen tiefer, ich durchschaue aber nicht warum.
Datum: 12.04.2007 20:14
Hallo! Danke für die Tips, bin nun schon auf 1976 Bytes unten, vorher waren es etwa 2040. Das mit der Division muss ich mir mal genauer ansehen... Stefan
Datum: 12.04.2007 22:53
Kleine Anmerkung, habe ich gerade rausgefunden: <avr/boot.h> ist nicht ganz -mint8 fest. Der Check
#elif (FLASHEND > USHRT_MAX) |
tut nicht mehr das gewünschte, weil USHRT_MAX sich halbiert. An dieser Stelle sollte besser UINT16_MAX stehen. Mal sehen, ob ich den Autor ausfindig machen kann. Als Abhilfe kann man die internen __boot_page_XXX_normal Funktionen direkt verwenden. (Oder die jeweils anderen, je nach Controller)
Datum: 12.04.2007 22:54
So, wie nicht anders zu erwarten, hier schon mal eine neue Version. Der Bootloader ist nun 1952 Bytes groß, und es ist noch ein neues, äußerst informatives Merkmal hinzugekommen: Oben in main.c kann man einen Portpin definieren, an der eine Led angeschlossen ist. Die LED wird aktiviert, sobald der Bootloader startet und die MMC Karte durchsucht wird. Wird ein passendes Update gefunden, wird selbiges installiert, währenddessen die Led flackert. Nach diesem Vorgang wird der CRC-Test im Applikationsbereich durchgeführt. Verläuft der Test positiv verlischt die Led und das Hauptprogramm wird gestartet. Andernfalls bleibt die Led aktiv und der Bootloader hält an. So wird verhindert dass eine fehlerhafte Applikation gestartet wird, und man hat eine direkte Rückkopplung, wie der Aktualisierungsvorgang verlief. Ausblick: Evtl. könnte man Pin 3 des 10-pin ISP Steckers misbrauchen und auf diesen z.B. den SS Pin auflegen. Dadurch wäre es möglich, eine MMC-Karte direkt an den ISP Header anzuschließen, zumindest bei den Prozessoren deren MISO/MOSI Pins gleichzeitig für ISP und SPI verwendet werden (z.B. Mega16). Mal sehen, evtl. entwickle ich bei Gelegenheit ein kleines Adapterplatinchen auf der der MMC-Sockel, ein 3.3 V Spannungsregler, die Spannungsteiler und ein 10-pin Header drauf sind. So muss man nicht immer das Notebook zum Gerät oder das Gerät zum Rechner tragen, sondern schließt einfach kurz die MMC an, Reset drücken, kurz warten, fertig. Gruß Stefan
Datum: 15.04.2007 11:32
Hallo Stefan, Dein Bootloader ist wirklich nicht schlecht, Kompliment!! Eine Frage, wäre es schwer, den Bootloader auf einen Mega128 umzuschreiben?? mfg Robert
Datum: 15.04.2007 23:30
Tach, nein, wäre nicht schwer... Ich hatte das ganze ursprünglich für einen Mega128 entwickelt, weil ich aus dem Bauch heraus vermutet hatte dass der Bootloader mehr als 2 kB Platz braucht. Nachdem ich sah dass es knapp in 2 k passt, habe ich den Bootloader mit Defines etc. versehen, so dass er universell verwendbar ist. Du musst im Bootloader-Makefile zunächst BOOTLOADERSTARTADR entsprechend setzten, je nachdem wie groß du die Bootloadersektion mit den Fusebits einstellst und BOOTLDRSIZE ebenfalls entsprechend anpassen. In mmc_lib.h müssen die Port Pins angepasst werden an denen die MMC hängt. Im Hauptprogramm muss dann ebenfalls noch im makefile BOOTLDRSIZE und BOOTLDRINFOSTART angepasst werden, damit der Bootloader die "Hundemarke", Versionnummer und CRC finden kann. Viel Spaß, Stefan
Datum: 17.04.2007 23:48
@ Stefan
Du hast nur einen Buffer fat_buf. Ein Sektor ist 512 Bytes
groß. Warum also beide als Parameter übergeben ?
void mmc_read_buffer(void)
{
unsigned char *buf;
unsigned short len;
buf = fat_buf;
len= 512;
while (len)
{
spi_send_byte(0xFF);
len--;
*buf++ = SPDR;
}
}
Datum: 19.04.2007 19:57
@ Stefan Hab mal ein bisschen rumgespielt. Aber leider nicht ausprobiert. Nur mal was zum nachdenken ! Ein bisschen ausklammern, ein % entsorgt. Über die Größe der Clusternummern nachdenken. Startpunkt war 1972 Bytes mit WinAVR 3.4.6. Rausgekommen ist 1890 Bytes. Gut, das mit void mmc_read_buffer(void) könnte man sich ja noch mal überlegen ;) Gruß Holger
Datum: 20.04.2007 19:04
Und jetzt komme ich auf 1716 Bytes. Soll ich weitermachen ?
Datum: 20.04.2007 21:27
>Soll ich weitermachen ? Na ich bitte darum ! :-) >Und jetzt komme ich auf 1716 Bytes. Hm, mein Compiler sagt 1724, aber was soll's, trotzdem um Welten kleiner. Super! Von manchen Sachen kann man zwar deren "logische Herkunft" nicht mehr so gut erkennen, z.B. sowas
if ((entry_num * sizeof(direntry_t) / 512) >= RootDirRegionSize) |
wird ersetzt durch
if ((entry_num / 16) >= RootDirRegionSize) |
, aber was solls, den Zweck das Compilat kleiner zu kriegen erfüllt es ja deutlich. Also wenn noch was rauskommt, immer her damit. Dann kann ich mir schonmal gedanken drüber machen ob/was man noch an sinnvollen Funktionen einbauen kann. Bis dann, Stefan Ach ja, hast du auch ausprobiert ob das ganze funktioniert ? Kann das derzeit nicht testen, weil ich für eine Woche im Ausland bin...
Datum: 20.04.2007 22:07
Hi Stefan, >Ach ja, hast du auch ausprobiert ob das ganze funktioniert ? Kann das >derzeit nicht testen, weil ich für eine Woche im Ausland bin... Ist bei mir noch rein theoretisch. Probiert habe ich es noch nicht. Mach ich am Wochenende aber auf jeden Fall. >Von manchen Sachen kann man zwar deren "logische Herkunft" nicht mehr so >gut erkennen, z.B. sowas >if ((entry_num * sizeof(direntry_t) / 512) >= RootDirRegionSize) >wird ersetzt durch >if ((entry_num / 16) >= RootDirRegionSize) sizeof(direntry_t) ist nun mal 32. Das wirds wohl auch immer bleiben. Deine Klammersetzung zwingt den Compiler aber erstmal entry_num * sizeof(direntry_t) auszurechnen und danach durch 512 zu teilen. Selber ausrechnen ist hier der bessere Weg. Das meiste haben die Bitschubsereien mit SectorsPerCluster gebracht. Echte Multiplikation bzw. Division vermeiden ! Dann die Funktionsparameter nicht selbst zum rechnen zu benutzen. Pushs und Pops im *.lss sind rapide gesunken. Als Abschluss: die minimal benötigten Datentypen für einen Wert einsetzen. Und wenn man einen Bootloader wirklich klein kriegen will muss man heilige Kühe schlachten. Bei MMC oder FAT16 Lib-Funktionen so weit wie möglich auf Übergabeparameter verzichten. Mehr habe ich nicht gemacht ;)
Datum: 20.04.2007 22:39
Das hätte ich jetzt fast vergessen !
@ Werner
>In zwei Jahren ist er weg ;-)
Geh spielen. Heute darfst du mal für ne Stunde raus.
Datum: 21.04.2007 16:45
So, alles aufgebaut und getestet. Funktioniert prima. War noch einiges an Bastelarbeiten zu erledigen: Bei CMD1 wurde nicht lange genug gewartet (bei 16MHz). Hab den Timeoutzähler dort entfernt. Wenn von der Karte nix kommt fliegt sie jetzt schon bei CMD0 raus. Eine meiner SD Karten möchte doch glatt zwei mmc_init() hintereinander haben. In fat16.c kann man sich jetzt aussuchen ob Karten mit oder ohne MBR zum Einsatz kommen. Ohne MBR gehts unter 1700 Bytes ;) Aufpassen: Im Anhang wird ein ATMega32 benutzt ! Hab auch die Sampleapp für ATMega32 dazugepackt.
Datum: 22.04.2007 14:31
Hervorragend, konnte es leider immer noch nicht testen, weil ich noch nicht zu Hause bin, werde ich aber nächste Woche tun. Ich teste nächste Woche noch an einer kleinen Schaltung, mit der man eine mmc-Karte an den ISP Stecker anschließen kann. Das Problem dabei ist natürlich dass ein Pin (Chip Select) fehlt. Testhalber habe ich einfach mal CS der MMC fest auf GND gelegt. Dabei muss man nach dem Einschalten (Betriebsspannung) 2x, danach immer 8x Reset drücken, dass der Zugriff auf die MMC klappt. Mal sehen ob man das softwaretechnisch irgendwie gebacken kriegt. Ich denke dass das Problem in der fehlenden Bytesynchronisation durch CS liegt. Ich werde nächste Woche mal versuchen, die CS Leitung durch die Resetleitung über einen Transistor zu schalten. Wenn das alles klappt mach ich eine Platine, auf der ein MMC Sockel, die Spannungsbegrenzung /-regler, eine Resettaster, ein ISP 10 Pin und ein ISP 6 Pin Header drauf ist. So hat man ein einfaches, günstiges kompaktes leicht zu handhabendes Programmiergerät. Ich muss z.B. immer mein Notebook mitsamt Evertool und Kabel in den Heizraum tragen um ein Update in meine Heizungs zu kriegen. Noch mal zum MBR/VBR: Meinst du es ist noch möglich den Bootloader selber erkennen zu lassen ob ein MBR vorhanden ist oder nicht und entsprechend zu reagieren ? Bis denn, Stefan
Datum: 22.04.2007 14:34
Noch was: Ich habe ja alles bisher nur mit einem Mega 16 gtestet. hast du für Deinen Mega 32 auch diese CRC Erzeugungssoftware benutzt, und hat's da funktioniert ? Stefan
Datum: 22.04.2007 17:48
>Noch mal zum MBR/VBR: Meinst du es ist noch möglich den Bootloader >selber erkennen zu lassen ob ein MBR vorhanden ist oder nicht und >entsprechend zu reagieren ? Mit bsFileSysType könnte man das machen, bzw. habe ich das schon mal gemacht. Da steht eigentlich immer "FAT12", "FAT16" drin. Bei meinen Karten jedenfalls. Wenn nix drin steht ist das natürlich Panne :( Sektor 0 auf bsFileSysType[0]=='F' und bsFileSysType[4]=='6' checken. Stimmen beide nicht hat man einen MBR, einen FAT12 oder FAT32 Bootsektor vor sich. Dann einfach auf Teufel komm raus einen MBR annehmen, und Sektor an bootsecoffset lesen. Dort wieder bsFileSysType[0]=='F' und bsFileSysType[4]=='6' checken. Wird wieder nix gefunden wars ne FAT12 oder FAT32 formatierte MMC/SD. Oder gar nicht formatiert. >Ich habe ja alles bisher nur mit einem Mega 16 gtestet. hast du für >Deinen Mega 32 auch diese CRC Erzeugungssoftware benutzt, und hat's da >funktioniert ? Ja, klappt prima das Proggi.
Datum: 23.04.2007 21:40
Ich habe die einfache automatische MBR/VBR Erkennung für FAT16 eingebaut. Man hat aber immer noch die freie Wahl in fat16.c :) // !! define only ONE of these !! //#define USE_MBR //if card has a master boot record, partitiontable //#define USE_VBR //if sector 0 is a bootsector #define USE_MBR_VBR_AUTO //auto mode Dann habe ich noch ein paar Übergabeparameter entsorgt die entweder gar nicht benutzt oder als Variable bereits global definiert wurden. Ein wenig an Schleifen rumgefummelt. Der Lowscore mit #define USE_MBR_VBR_AUTO //auto mode steht jetzt bei 1678 Bytes, und es funktioniert immer noch ;)
Datum: 24.04.2007 10:02
Ihr (speziell Holger) macht ja prima Fortschritte! Was hältst Du davon, Deine "Erfolgsrezepte" in der Wiki-Seite zu diesem Thread hinzuzufügen: Beitrag "Tricks, wie ich mein Compilat kleiner kriege" http://www.mikrocontroller.net/articles/AVR-GCC-Co... Ich habe gesehen, das ihr -mtiny-stack verwendet, aber den Stack nicht wie in dem Thread gelernt auf eine glatte Page initialisiert. Damit ist der verbleibende Platz recht zufällig. Die Option -mint8 wäre noch möglich, ich habe damit mittlerweile gute Erfahrungen gemacht, wenn man die Wirkung im Hinterkopf behält und Typen fester Größe auf <stdint.h> verwendet. Bringt ziemlich viel. Unter 1 KiB wird der Code aber vermutlich nicht kommen. :-( Mit meinem Bootloader habe ich allerdings auch bei ca. 1600 Bytes angefangen, jetzt bin ich auf 1014 runter. Nach Holgers aktuellen Tricks muß ich nochmal Ausschau halten. Das man die Übergabeparameter besser nicht modifiziert (sondern Kopien davon) war mir neu. Dank und Gruß Jörg
Datum: 24.04.2007 19:08
@ Jörg >Die Option -mint8 wäre noch möglich, Geht nicht :( Dann kennt er RAMPZ nicht mehr ! Das brauchen wir aber halt nun mal. An die Compiler internen Header Files trau ich mich besser nicht ran. Wer weiss was das wieder für Nebenwirkungen (in meinen anderen Programmen) hat. >Das man die Übergabeparameter besser >nicht modifiziert (sondern Kopien davon) war mir neu. Mir auch, aber die Pushs, Pops sind erheblicher weniger geworden ! Klappt aber irgendwie nicht immer. Möglicherweise stimmts auch einfach nur nicht. Vieleicht waren es doch nur die anderen Optimierungen. @ Stefan Können wir die CRC auch von oben nach unten berechnen ? Bringt nochmal 6 Bytes bei Umwandlung einer for() in eine while() Schleife ;)
Datum: 24.04.2007 21:28
Jetzt gehts mit 1642 Bytes. void flash_update(void) erzeugte komischerweise 6 Pushs und 6 Pops. Habs einfach in die main loop eingefügt. Pushs, Pops waren dann weg. void fat16_readfilesector(uint16_t startcluster, uint32_t filesector) benutzt keine absolute Sektornummer sondern eine relative Sektornummer im File. Bei AVR/ATMega reicht da auch uint16_t ;) void fat16_readfilesector(uint16_t startcluster, uint16_t filesector) Statt break eine Schleife direkt mit return beendet. Spart die Abfrage hinter der Schleife. Ich denke das wars dann jetzt aber auch.
Datum: 24.04.2007 23:18
@Holger: RAMPZ kenne ich als Mega8-User nicht. Keine Ahnung, warum das zum Problem wird. Man kann verschiedene C-Files auch mit unterschiedlichen Flags kompilieren, das Problem so vielleicht "auslagern". Das mit den Übergabeparametern habe ich jetzt in meinem Bootloader probiert, leider kein Effekt. :-( CRC rückwärts geht zwar, liefert aber ein anderes Ergebnis. Müßte die PC-Software drauf Rücksicht nehmen. Ich vewende übrigens einen anderen CRC, nicht aus den WinAVR-Headern. Der erzeugt kleineren Code:
// incremental CRC static uint16_t crc16(const uint8_t byte, uint16_t crc) { uint8_t i; crc ^= byte; for (i=8; i>0; i--) { if (crc & 0x0001) crc = (crc >> 1) ^ 0x8408; // reverse 0x1021 poly else crc >>= 1; } return crc; } |
Datum: 25.04.2007 18:16
main.c: Mache die Funktion check_file() static inline. Wird nur ein mal aufgerufen. Spart den call und den return. Evtl. kann auch die Registerbelegung vom Compiler besser Optimiert werden. dto. für wait_start_byte() in mmc_lib.c mmc_lib.c: in mmc_start_read_block. Spart shift-loop
adr <<= 1; cmd[0] = 0x40 + MMC_READ_SINGLE_BLOCK; cmd[1] = (adr & 0x00FF0000) >> 0x10; cmd[2] = (adr & 0x0000FF00) >> 0x08; cmd[3] = (adr & 0x000000FF); cmd[4] = 0; |
Man kann sicher noch mehr "einmalig" aufgerufene Fuktionen als "static inline" definieren und somit den call/return sparen wenn man (Igitt) die anderen C Files included statt linkt.
Datum: 25.04.2007 18:49
@ Werner
Klasse Tipps. Code ist jetzt nur noch 1602 Bytes.
Besonders das einsparen von shifts bringts.
>dto. für wait_start_byte() in mmc_lib.c
Bringt leider nichts. Codesize unverändert. Vieleicht
besser Funktion im Code einsetzten wo sie benutzt
wird.
@ Jörg
Ich probiere auch deine CRC Routine auf jeden Fall noch aus.
Datum: 25.04.2007 21:27
Zusammenfassung: @ Jörg Deine CRC Routine brachte zwei Bytes Ersparnis. Dafür das PC Programm umschreiben ? Hmm naja, vieleicht später mal. @ Werner #include "fat16.c" #include "mmc_lib.c" in main.c bringt gar nichts :( wait_start_byte() als Code einsetzen brachte nichts. Code wurde größer. Da filesector sich als uint16 erwiesen hat konnten in fat16_readfilesector() nochmal 8 Bytes rausgeholt werden. Stand der Dinge ist nun 1596 Bytes. Noch jemand ne Idee ?
Datum: 27.04.2007 01:55
N'abend! Hab gerade mal Deine letzte Version ausprobiert. Leider funktioniert der Bootloader hier garnicht mehr :-( Wenn ich den Mega 16 zurücklese stimmen die ersten 1024 Bytes mit der Updatedatei überein, aber danach steht "Müll" anstatt 0en drin. Werde mal suchen woran das liegt... Gruß Stefan
Datum: 27.04.2007 09:53
man kann noch ca. 60 bytes sparen wenn man auf ISR's verzichtet, den GCC Startup Code, den GCC bad_interrupt_vector entfernt und function main() direkt am Reset Einsprung des Bootloaders platziert. Alle globalen Variablen die initialisiert werden müssen (auf 0) muß man dann von Hand initialisieren. So mache ich dies bei meinem ATMega8 Bootloader (ähnlich AVR910) der ohne Assembler (also pures C) zu benutzen in 256 Words reinpasst. Gruß Hagen
Datum: 27.04.2007 17:00
@ Stefan Also der Bootloader funktioniert bei mir noch. Das per Bootloader geladene Programm auch, aber du hast recht. Der Bereich bis Flashend ist nicht 0. Da wiederholt sich immer wieder irgend ein Müll.
Datum: 27.04.2007 18:35
So, jetzt klappt es bei mir wieder und die Daten hinter dem Testprogramm sind wieder alle 0. Es lag am einfügen von flash_update() in die main loop. Sorry :( 1618 Bytes ist ja auch nicht schlecht.
Datum: 27.04.2007 21:56
Mein letzter Stand ist jetzt 1580 Bytes. Inhalt vom ATmega nachdem der Bootloader geflasht hat natürlich ausgelesen und angesehen. Das Testprogramm läuft. Bis hier hin klappts.
Datum: 28.04.2007 14:53
Fein! Nachdem ihr nun soviel Platz geschaffen habt, habe ich selbigen genutzt: Der Bootloader unterstützt nun FAT16 und FAT12, so dass auch ältere, kleine Karten, die eigentlich für fast nichts anderes mehr genutzt werden können, verwendet werden können. Selbst wenn man per Hand auf einer 16 MB Karte eine FAT16 Partition erstellt, baut Windows diese beim Formatieren in eine FAT12 Partition um, so dass kleine Karten bisher nicht verwendet werden konnten. Weiterhin ist es nun möglich, des CS Pin der Karte fest auf GND zu legen, so dass man eine Karte bei bestehenden Schaltungen einfach an den ISP Stecker anschließen kann (bei 5 V Systemen natürlich mit weiterhin mit Pegelanpassung dazwischen). Ich werde demnächst wie schon angedroht eine kleine Platine fertig machen, auf der ein Kartensockel, ISP 6 Pin, ISP 10 Pin, Resetknopf und Pegelwandler vorhanden ist. Viel Spaß Stefan P.S. Den Bootloader im Anhang habe ich mit einer 512 MB Karte FAT16 mit MBR, mit einer 16 MB Karte FAT12 mit MBR und einer 16 MB Karte FAT12 ohne MBR erfolgreich getestet.
Datum: 28.04.2007 20:59
Hallo Stefan, das Projekt ist genau was ich suche (Beitrag "Bootloader für Mega 128 mit SD Karte") Wärst Du bereit mir eine Version für den MEGA 128 mit einer kurzen Installationsanleitung zu erstellen? Bei Interesse könnten wir uns über weiter Details unterhalten. Meine Anwendung ist ein Hobbyprojekt, deshalb brauchst Du Dir über Gewährleistung und Dergleichen keine Gedanken machen. Funktionieren sollte es aber schon. Viele Grüße Jürgen
Datum: 28.04.2007 21:02
Hab' mal eben aus dem Projekt einen kleinen Artikel gemacht: http://www.mikrocontroller.net/articles/MMC/SD_Boo...
Datum: 29.04.2007 01:03
Hallo Jürgen, Deiner Anfrage unter dem angegebenen Link entnehme ich, dass du Bascom benutzt. Ich weiß leider nicht ob und wie man damit Memory-Sections erstellen kann, denn das ist für das Hauptprogramm zwingend erforderlich. Den Bootloader für den Mega128 könnte ich Dir schon kompilieren, kann ihn aber nicht testen, weil ich für mein STK500 nicht diesen Adaptersockel für den Mega128 habe. Gruß Stefan
Datum: 29.04.2007 16:06
Hallo Stefan, vielen Dank für Deine Hilfsbereitschaft. Leider finde ich in Bascom keine Möglichkeit an einer bestimten Adresse eine Memory-Sections zu erstellen. Ich könnte aber die erforderlichen Daten von Hand an der entsprechenden Stelle eintragen. Zum Testen wäre es einfacher, wenn der Bootloader auch Versionsnummer gleich der bereits installierten Version akzeptieren würde. Wenn es dir nicht zu viel Mühe bereitet, könnten wir ja mal einen Versuch machen. Als Funktionsanzeige wäre bei mir der PORTB.4 geeignet. Viele Grüße Jürgen
Datum: 29.04.2007 16:28
Hallo Stefan, Mmc_chip_select liegt auf Portb.0 (SS) Mmc_data_input liegt auf Portb.3 (MISO) Mmc_data_output liegt auf Portb.2 (MOSI) Mmc_clock liegt auf Portb.1 (SCK) Gruß Jürgen
Datum: 29.04.2007 20:56
Im Anhang ist das Projekt nochmal, es gibt jeweils einen Unterordner "atmega128". Kann jetzt aber nicht verspechen dass es klappt, weil ich das mangels Mega128 nicht testen kann. Bitte sag' aber in jeddem Fall bescheid. Gruß Stefan
Datum: 01.05.2007 15:26
Hallo Stefan, leider beschreibt der Bootloader nur die ersten 64kb, d.h. er schreibt 64kb und die weiteren 64kb schreibt er nochmals über die ersten. (So sieht es zumindest aus.) Das Ergebnis sieht dann wie folgt aus: 00000 - 0F7F7 = 00 0F7F8 = 78 0F7F9 = 56 0F7FA = 34 0F7FB = 12 0F7FC = 00 0F7FD = 01 0F7FE - 0FFFF = 00 10000 = 10 10001 = 00 10002 = F8 10003 = 00 10004 - 1F7FF = FF (nicht beschrieben) 1F800 = 0C (Beginn des Bootloaders) Ich vermute das RAMPZ Register muss noch entsprechend verwendet werden, damit die richtige Page beschrieben wird. (ATmega128 Datenblatt Seite 12 RAMPZ0 = 0: lower 64 k RAMPZ0 = 1: higher 64 k wird von ELPM/SPM verwendet.) Im Main Programm verwendest Du den Portb.4 für die Flash-LED. Leider kann ich hier keine Reaktion erkennen. Im Programmspeicher findet jedoch die oben beschriebene Änderung statt. Bei meiner Hardware sind folgende Ausgänge mit einer LED verbunden und können für Kontrollanzeigen verwendet werden. Pinf.3 Pinf.7 Pine.4 Pind.7 Pind.6 Pind.4 Ping.4 Pinb.4 Bei Portx.x = 0 leuchtet die LED Viele Grüße Jürgen
Datum: 03.05.2007 02:20
Hallo Jürgen, habe den Fehler gefunden: memcpy_P funktioniert nur bis zur 64 k Grenze, und einige Variablen müssen von 16 Bit auf 32 Bit erweitert werden. Ich habe mir heute mal ein Design mit einem Mega128 aus der Bastelkiste gekramt mit dem ich das testen kann. Im Moment liegt der Bootloader für den Mega128 leider über 2048 Bytes, nämlich bei etwa 2150. Ist zwar weiter kein Problem, weil der Mega128 Bootsections bis 8 k kann, aber wäre schade die Bootloadersectiongröße wegen ein paar Bytes vergrößern zu müssen. Wenn's soweit stell ich selbigen hier rein. Eventuell mach ich ein Flag rein, mit dem man den FAT12 teil per Define abschalten kann (also nur FAT16), so würde es wieder in die 2 k passen. Oder vielleicht schauen die anderen Kolegen aus dem Thread nochmal drüber und kriegen das Ding noch kleiner ;-) Gruß Stefan
Datum: 03.05.2007 22:46
Hallo Stefan, mich stören die 2150 Byte nicht, da ich zur Zeit erst etwa 30% des verfüg- baren Speichers nutze. Es würden also auch die 64kb reichen. Gruß Jürgen.
Datum: 04.05.2007 22:29
So, hier nochmal der Bootloader für den Mega128. Er ist nun für eine Bootsectiongröße von 4096 Bytes (2048 Words) ausgelegt (auch im Hauptprogramm beachten!) und ist 2106 Bytes groß. Vielleicht kriegt das ja noch jemand um 58 Bytes kleiner... Gruß Stefan
Datum: 04.05.2007 22:38
Danke fürs portieren des Bootloaders auf den Mega128. Ihr seit spitze :) Hab leider noch keine Zeit gehabt, ihn anzupassen, da ich keine Hardware noch habe. 58 Bytes kleiner wären halt schon schön ;) mfg Robert
Datum: 04.05.2007 23:30
@ Stefan Merkwürdig, einmal make clean, danach make all und die Codesize ist nur noch 2046 ;)
Datum: 04.05.2007 23:55
holger: hmmm, andere (ältere/neuere) Compilerversion ?
Datum: 05.05.2007 00:01
avr-gcc (GCC) 3.4.6 Ich hab dein makefile nicht verändert und auch (noch) nicht am Quellcode rumgefummelt.
Datum: 05.05.2007 00:05
Datum: 05.05.2007 00:31
10 Bytes in mmc_lib gespart. Gute Nacht ;)
Datum: 05.05.2007 09:48
/* for (i=0; i<6; i++) {//Send 6 Bytes spi_send_byte(cmd[i]); } */ i=6; while(i) {//Send 6 Bytes spi_send_byte(cmd[i]); i--; } |
Ähm, werden so die Kommandosequenzen nicht falsch rum gesendet ? Stefan
Datum: 05.05.2007 11:19
Tschuldigung, war schon etwas spät :(
Sollte so aussehen:
unsigned char *buf = cmd;
i=6;
while(i)
{//Send 6 Bytes
spi_send_byte(*buf++);
i--;
}
Datum: 05.05.2007 16:59
Ach Klasse, hab auch noch eine Kleinigkeit gefunden, nun sind's genau 2048 Bytes ;-)... Noch was anderes: Wer ist "richtig fit" mit make ? Die Frage ist ob make eine Differenz aus zwei Hex-Werten berechnen kann, so könnte man
BOOTLDRSIZE = 0x800 #FLASHSIZE - BOOTLDRSIZE - 8 BOOTLDRINFOSTART = 0x37F8 |
z.B. ersetzten durch
FLASHSIZE = 0x4000 BOOTLDRINFOSTART = <0x4000 - 0x800 - 0x8> //Das müsste berechnet werden |
? Dann bräuchte man im makefile nicht mehr die Adresse der "Hundemarke" selber ausrechnen... Stefan
Datum: 06.05.2007 12:19
Nachdem ich nix besseres zu tun hatte (Steuer ist gemacht ;-) ), hab' ich das ganze nochmals etwas "geschrumpft". Die Version aus "new.zip" nun mit 1836 Bytes. Allerdings nichts getestet, aber die Änderungen stammen im wesentlichen aus meiner Portierung des MegaLOAD bootloaders auf den AVR-GCC. Falls es Probleme gibt, bitte zuerst im Makefile: Das "neue" gcrt1.S aus dem Makefile entfernen und die Zusätze von "-nostartfiles -nodefaultlibs" bei den ALL_???FLAGS entfernen und nochmals probieren und hier das Ergebnis posten. P.S. Die Quelldateien sind "nicht aufgeräumt". Damit ist gemeint, daß die Orginalzeilen nur auskommentiert sind. Viel Spass Werner
Datum: 27.06.2007 22:16
Hallo! Ich bin in der uC Materie ganz ganz neu. Aber dieses Projekt finde ich sehr interessant und möchte es von anfang an nutzen. Habe ich das richtig verstanden, dass man den Chip für Softwareupdates nicht mehr rausnehmen muss, sondern nur alte Karte raus neue Karte rein fertig? Wenn ja wie geht das denn jetzt? Ist der Bootloader auf dem Controller und der liesst sein Programm (zum Beispiel LED an) von der MMC Karte??? LG Max
Datum: 28.06.2007 22:31
1. Ja, aber entweder Neustart oder Reset des µC ist nötig 2. Siehe im Datenblatt oder im Forum unter Bootloader 3. Ja, aber was meinst du mit "Programm zum Beispiel LED an" ? Stefan
Datum: 30.06.2007 15:41
zu 3.) Wo liegt der Ausführcode? Wird der Code auf den uC gespielt oder holt er sich den von der MMC Karte. Also muss man die MMC Karte drin lassen oder kann man sie rausnehmen. Denn wenn nicht kann man ja größere Programme schreiben! :) Ich frage deswegen, weil ich dann die Möglichkeiten habe meinen Kollegen einfach eine neue Hex zu schicken, die sie dann auf die MMC spielen können.
Datum: 30.06.2007 15:50
AVRs können NUR Code aus dem Flash ausführen. Aber egal wie, die Möglichkeit jemanden ein Update zu schicken welches dieser dann auf eine MMC kopiert um ein neues Programm in den µC zu bekommen hast du. Stefan
Datum: 06.07.2007 19:37
Hi! Ich schaue mir das hier gerade so an und muss sagen, dass wäre genau das richtige als Erweiterung für das MMC2IEC-Projekt bei dem ein Mega32 mit SD-Karte als C64-Diskettenlaufwerk benutzt wird. Ich habe noch nie Bootloader mit den AVR's benutzt. Daher habe ich da mal ein paar Fragen. Erstmal, wie sieht das aus, die Rede war hier nur von den alten WinAVR Versionen, wie gut klappt das mit der 20070525? >Nun kann das Hauptprogramm compiliert werden. >Die entstehende .hex Datei (binary Format!) Ja was denn nun, .hex oder binär? Kann ich AVR-Studio überhaupt dazu bringen, ein .bin zu erzeugen oder muss ich das nach dem compilieren noch konvertieren? >wird anschließend noch mit dem Kommandozeilentool crcgen.exe behandelt >(z.B. crcgen myflashfile.hex). Wo finde ich das und gibt es das auch mit GUI für XP? Und was macht das überhaupt genau? Einen Header mit der CRC32 davor hängen? Die .hex dabei in einen .bin konvertieren? >Der Aufruf dieses Programmes kann auch vom makefile aus geschehen. Da ich das AVR-Studio benutze, wie würde man das in die Projekt-Optionen einfügen? Sowieso, hat zufällig schon jemand eine Projekt-Datei für AVR-Studio erstellt mit welcher man den Bootloader compilieren kann? >Das Update benennt man am besten etwa in der Form MeinApparat-v1.0-bin, >darf aber beliebig (lang) sein . Was macht der Bootloader genau? Sucht nach der ersten .bin im Hauptverzeichnis auf der Karte und schaut nach, ob die geeignet ist? Daher ist der Name auch egal, weil sowieso nur nach der Erweiterung gesucht wird? Also muss man die alten Dateien auch immer löschen weil eine später aufgespielte "xxx1.1.bin" nicht gefunden wird? Gibt es eigentlich irgendeine Art von Lizenz für den Code? Freeware? GPL? PuplicDomain? Gruss, Rudolph
Datum: 06.07.2007 20:06
Okay, crcgen gefunden, es hilft, wenn man nicht nur das letzte Archiv runterlädt und aufmacht... :-)