Hallo, Etwas Länger, sorry. Erst kurz die Beschreibung worum es geht: Ich will mich in ein existierendes Bussystem einklinken, das klappt auch schon Prima. Es gibt fertige Software für Programmierung und Firmware Update. Die möchte ich auch nutzen um komplett Transparent zu bleiben. Bis auf das Firmwareupdate habe ich alles im Griff. Das Chart im Anhang zeigt wie ich mir das denke. Nun zu meinee Aufgabenstellung: Die eigentliche Busanbindung ist für jedes "Geräte" gleich, ob Taster, Bediengerät, oder Aktor. Das Programm ist im Moment in 2 Teile Unterteilt, die im Moment aber in einem Stück entwickelt und geflash werden. Teil 1 ist der Protokoll Bereich (PA im Anhang) und User Bereich (UA in Anhang, aber nicht im Chart vorhanden). Nun würde ich gerne UA und PA getrennt entwickeln und auch flashen können. Also PA und UA getrennt flashbar. Damit das geht muß ich für den UA Bereich eine Sprungtabelle anlegen und diese beim Start vom PA Bereich laden. Da nicht genug Speicher vorhanden ist um das im Ram komplett Zwischenzuspeichern, dachte ich an folgendes vorgehen: - Wird der UA Bereich neu geflashed, sorge ich nur dafür, das die Sprünge aus der PA nicht ins leere gehen (Pseudo Function Table erzeugen), Lösche den UA Bereich und schreibe die in Häpchen von 128 Byte empfangene Daten in den UA Bereich. Danach einen Reset (Details siehe Anhang). - wird der PA Bereich neu geflashed, brauche ich einen Zwischenspeicher, da der PA Bereich ja die Daten noch empfangen muß. Daher gleiches vorgehen wie beim UA, PA wird also in UA gespeichert, und nach dem Reset vom Bootloader in den PA kopiert. Anschliesend muß wieder der UA geflashed werden, das ist aktzeptabel ! Hierdurch habe ich IMMER eine Funktionierende PA, geht der Empfang schief muß ich Ihn ja nicht kopieren ! - Einen Ersatz des Bootloaders strebe ich nicht an. So, nun meine Fragen: :-) (Einfach nur die Nummern übernehmen bei der Antwort) 1) Der Bootloader ist so klein, das er vermutlich bequem in 512 Byte passt, daher kann ich den ja als "normales Programm" entwickeln und einfach den kompletten ".txt" in den Bootloader verschieben. Oder ist es besser das trotzdem als "BOOTLOADER section im Programm zu definieren ? 2) Vermutlich ist es das beste immer im Bootloader zu starten, Gültigkeit der PA zu prüfen und dann mit eine "jmp 0000" in Programm zu springen und dadurch den PA zu starten. Müsste ich das was beachten ? Der Bootloader hat ja schon Stack usw Initialisert. Oder wird das dann eben nochmal vom PA erledigt und überschrieben. 3) PA wird ja wieder als "Normales" Programm entwickelt und der Einfachheit halber per ISP geflashed. Überschreibe ich mir dann nicht gleich wieder meinen Bootloader beim Programmieren über ISP ? 4) den UA Bereich will/muss ich ja dann ohne jegliche Initilisierung und main Funktion schreiben, ist also nur eine Funktionssammlung. Wie gebe ich das beim gcc an ? 5) ein teilweises Löschen des Flash und neu schreiben sollte ja kein Problem sein laut Datenblatt. Ich definier dann eben das die PA immer bei 0x0000 steht, die PA bei 0x0400 und der Bootloader steht ja immer am Ende. Muss ich hierbei was beachten ? 6) gibt es eine einfach Möglichkeit, statt eine HEX Datei zum flashen eine Binäre Datei zu erstellen, die danach 1:1 den zu Programmierenden Daten entspricht ? Das geht vermutlich mit "obj-copy" ? 7) Ist das so überhaupt machbar ? 8) Wie lege ich die Sprungtabbelle der Funktionen vom PA an den Anfang der zu flashenden Datei. Das ist ja mein einziger Fixpunkt. 9) Meine Funktionszeiger in der Sprungtabelle für den PA müssen ja relativ zum Anfang des PA sein, wo der PA später im Flash steht weis der gcc ja nicht ! Muß ich da was beachten, oder wäre das automatisch so ? Theoretische Speichermap: ---------------------- | PA Bereich | 0x0000 | | | | | | ---------------------- | UA Sprungtabelle | 0x0400 ---------------------- | UA Bereich | | | | | | | | | ---------------------- | Bootloader | 0x???? ---------------------- Ich hoffe Ihr könnt mir da ein paar Tips geben. Als Proz kommt im Moment ein atMega8515 zum Einsatz. Danke Juergen
zu 1) Einfacher ist es, vor Allem wenn man Interrupts im Bootloader benötigt, die Startaddresse von .text zu verschieben und keinen extra "Bootloader"-Section einzuführen. 2) Normalerweise ist nicht viel zu beachten, die Stack-Intitialisierung wird ja im "PA"-Startupcode nochmals gemacht. Man sollte jedoch sicherstellen, das man SFRs, die im Bootloader vom Reset-default abweichend eingestellt werden vor "JMP 0" wieder auf Reset-Werte zurücksetzt. Das spart Sucherei in der Anwendung, falls jemand anderes diese programmiert und davon ausgehen, das beim Start alle Register auf Reset-Default stehen. 3) Üblicherweise wird bei ISP vorher ein Chip-Erase ausgelöst, um den Flash-Speicher auf "alles 0xff" zu initialisieren. Der Bootloader wird somit auch gelöscht. Abhilfe vielleicht mit einem ISP-Programm, das nur die benötigten Speicherbereiche initialisiert - ist mir aber keines bekannt. 4) kann ich nicht wirklich viel zu schreiben, bei AVR nie gemacht. Testweise den Objectcode mit -nostartupfiles linken und sich map-files und disassmbly der elf-Datei anschauen. 5) ist abhängig davon, wie man den Bootloader und die Ansteuersoftware des Bootloaders implementiert. Beachtenswert ist vielleicht (aber offensichtlich), dass man die beiden Bereich bei Page-Bounderys (Seitenaddresse) trennt. 6) im Makefile kann man das Format schon einstellen und so direkt "passend" von elf nach ihex oder binary konvertieren. Im nachhinein objcopy -I ihex -O binary rein.hex raus.bin. 7) Erscheint mit machbar. Sind wahrscheinlich auch nur ein paar Zeilen im Quellcode, Makefile und evtl. eigenem Linkerscript, aber düfte einiges an Zeit kosten alles "richtig" einzustellen. 8) Festlegen von Speicheraddressen für Daten funktioniert meines Wissens "sauber" in dem man die Sprungtabelle einer memory-section zuweist, für die man dem Linker die Addresse angibt. Evtl. mit eigenem Linker-Script auf Grundlage der standard Linker-Scripte. 9) Der Programmteil, der die Funktionen bereitstellt die in der Sprungtabelle eingetragen sind, kennt auch die Addressen und kann diese entspechend eintragen. Sollt also funktionieren. Bin nicht sicher, ob ich die Aufgabenstellung 100% verstanden habe, aber hoffe, die Antworten helfen zumindest ein wenig weiter. Martin Thomas
Hallo, erst mal danke für die Antworten. 4 ?) Ok, sehe ich mir an. Weis jemand zufällig wie man das macht ? 8+9 ?) Kannst Du mir das etwas näher Erklären ? Das hab ich nicht ganz verstanden ! 1) Ok, ich verschiebe die .text 2) Mit SFRs meinst Du vermutlich die Interrupt und Controll Register, jo Sehr gute Idee 3) Hmm, das wird problematisch. Den Bootloade rladen ist ja Ok, aber einmal muß ich das PA und den Bootloader haben.... Da muß ich mir was überlegen. 1. Bootloader, dann PA, dann ist aber wieder Bootloader weg... Grübel... 5) Ja Page bounderies ist klar, danke für den Hinweis 6) Super das hab ich gesucht 7) Ja leider, deswegen hab ich hier auf Hilfe gehoft Gruss Juergen
Versuch "näherer" Erklärung zu 8: Nur ein paar Stichworte zum Linken an einer festgelegten Addresse: Die Sprungtablle (das Array mit Funktionszeigern) versieht man mit einem section-attribute (vgl. gcc-Manual). Im Linker-Skript kann man dieser section eine feste Addresse zuweisen (vgl. GNU Linker-Manual). zu 9: Wenn in UA die Funktionen der Sprungtabelle implementiert sind, sind deren Addressen für die Einträge in der UA-Sprungtabelle beim Linken von UA bekannt. Aber an der Stelle mag ich die Aufgabe falsch verstanden haben, da ich dabei kein Problem erkenne. zur 3: Man programmiert zuerst den Bootloader per ISP und legt dann den ISP-Progammer zur Seite. Der Bootloader wird so implementiert, dass PA und UA getrennt voneinander in den entsprechenden Speicherbereich programmiert werden können. Evtl. die Programmierfunktion für einen der Bereiche per Bootloader schützen, falls der Endanwender nur den anderen Bereich ändern darf (z.B. nur einmal aufrufbar machen, Bootloader prüft ob einige aufeinanderfolgende Speicherstellen !=0xffff und verweigert Überschreiben dieses Bereichs).
Zu 8) Da bin ich gerade dran. Meine Sprungtabelle steht (ist eigentlich ganz einfach) Jetzt bau ich mir ne fest im Rom auf und "zwinge diese" auf ne feste Adresse. Noch PA und UA als ein Block, wenn das geht rupf ich beide auseinander :-) Schritt für Schritt eben. Danke das Hilft sehr weiter ! Zu 9) Mein Problem ist hier: Wenn ich nun UA alleine ohne Startup code Linke, und dem Linker sage "die Sprungtabelle auf den Anfang". Welche Adresse geb ich Ihm dann vor, ich nehme an 0x0000, da diese ja relativ zum Anfang des UA Binaries sein muß..... Ich nehme an die Sprungtabelle des UA muß am Anfang stehen, ist ja mein einzig Sinnvoller Fixpunkt ?! Zu 3) Das Problem ist, das der Bootloader selbst keine Daten empfangen kann, sondern nur Daten verschieben von UA in PA und feststellen ob die PA gültig ist und gestartet werden kann. Sonst müsste ich die PA in den Bootloader packen, was das Update erschwert. Vermutlich werde ich den Bootloader so lösen, das ich PA und Bootloader in einem File Linken kann für den ersten Flash, dann kann ich beides auf einmal Programmieren und danach bei Bedarf den PA ersetzen. Quasi eine Inbetriebnahme Firmware mit PA und Bootloader. Per DEFINE kann ich die PA dann auch ohne Bootloader erzeugen. Das sehe ich mir nach 8 an, zum schluss kommt 9 :-) Mann darf den Bootloader hier weniger als Loader sehen, sondern mehr als Bios. Danke für die Hilfe soweit.
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.