Dein Portmon.Log sagt mir folgendes: - korrekter Verbindungsaufbau - das erste mal sendet der PC das 0xFD00 Kommando und AVR antwortet auch korrekt mit 0xC1 Fehlercode. Dieses Kommand ist das "Keep Alive" Kommando das einerseits dazu dient das die PC-Software erkennt das der AVR noch errichbar ist und andererseits den Watchdog Timer im AVR zurücksetzt. Dh. wenn man UseWDT=1 hat so würde beim Ausbleiben dieses Kommandos oder eben andere Kommandos der AVR nach ca. 2 Sekunden einen Watchdog RESET durchführen. - das zweite Keepalive Kommando das gesendet wurde wird aber durch den AVR eben nicht mehr beantwortet. Daraufhin trennt die PC-Software korrekterweise die Verbindung zum AVR. Du hast also irgendeine ungewollte Verbindungsunterbrechung gehabt. Das das nun an der leicht inkorrekten BootCodeSize gelegen haben soll, die ja bei 512 Bytes Bootsection eh keinen Einfluß hätte, kann ich mir eben nicht so recht vorstellen. Außnahme wäre halt die Aktivierung der UseSpecialXXX Funktionen, nur müsstest du dann eine Kompilierwarnung erhalten. >PS:Kann es daran liegen das ich im Moment den internen Osczilator >verwende? Eigentlich nicht, es sei denn du hast UseAutoBaud=0, XTAL zb. auf 8MHz aber nicht die CKDIV8 Fuse programmiert. Dh. der AVR läuft real mit 1MHz und die konfigurierte Baudrate wäre 8 mal langsammer als real nötig. Aber das ist ja bei dir nicht der fall da du einen Connect bekommst. Am besten ist es meinen Empfehlungen fürs erste zu folgen, hier im Thread nachzulesen. Und ich empfehle immer UseAutoBaud=1 und UseWDT=1 zu setzen. Mit UseAutoBaud=1 ist der MCU Takt fast irrelevant, falsche Fuses oder falsche XTAL Einstellung würden dann nur den Verbindungstimeout negativ beeinflussen. Gruß Hagen
Gast
#1251632
Hallo Hagen,
danke für die ausführliche Antwort.
>>UseSpecialXXX
ist bei mir deaktiviert
Auf die Antwort von Dir habe ich es nochmals versucht die BootCodeSize
zurückzuändert.
Doch "leider" funktioniert es jetzt trotzdem, d.h. wahrscheinlich hatte
ich tatsächlich ein anderes Problem und es hat sich zufällig mit
dem ändern der BootCodeSize in wohlgefallen aufgelöst.
Schöne Grüße
Hannes
Hallo Hagen, jetzt hätte ich aber noch ein Frage. Ich habe schon andere Bootloader getestet z.B. den von Peter Dannegger (Auch sehr gut, nur das Verschlüsseln etc gefällt mir bei Deinem besser) Damit ich jedoch ohne Reset mittels Bootloader flashen konnte, mußte ich in meine Applikation eine Routine einbauen, welche auf RX horchte und beim Empfang von 0xFF durch einen WD einen Reset ausführte. Funktionierte auch einwandfrei. Jetzt ist nur die Frage, wie funktioniert das bei Dir, dass Du in den Bootloader kommst während das Programm läuft. Ich habe zwar die Funktion mit dem WD noch eingebaut, aber die horcht auf RX und nicht auf den 1Wire Port PD5 welchen ich verwende. Ich kann mir die Funktionsweise nicht erklären?!? Wenn das Programm läuft ist doch der Bootloader komplett ohne Funktion oder? Schöne Grüße Hannes
Hallo Hagen, sorry aber anscheinend brauche ich es, dass ich was in das Forum schreibt damit bei mir entweder der Groschen fällt, oder es einfach funzt ;-) Hab jetzt doch gefunden warum der autoconnect geht, anscheinend aktivierst Du den WD im BL und wenn dieser nicht explizit von der Applikation deaktiviert oder bedient wird erfolgt ein Reset. Jetzt habe ich am Anfang meiner Applikation einfach den WD deaktiviert :-) Trotzdem schöne Grüße Hannes
Hi Hagen, hab einen ATMEGA32 mit internen Takt , funkt da der bootloader? wie muss ich denn den einstellen?
Andy F. schrieb: > hab einen ATMEGA32 mit internen Takt , funkt da der bootloader? Natürlich ! > wie muss ich denn den einstellen? Was willst du jetzt wissen ? Wie du die Fuses programmieren mußt oder welche Einstellungen im Bootloader ? Bei den Fuses empfehle ich dir das Datenblatt vom Atmega32, und beim Bootloader die wirklich ausführliche Anleitung, bzw. die Kommentare im Bootloader selbst. Keine Angst, so schwierig ist das garnicht !Sollte es wieder erwarten nicht funktionieren, poste einfach deine Einstellungen nochmal ! Gruß Stefan
Hab die Fuses wie im Bild eingestellt und die Baudrate auf 2400 gestellt und dann kommt immer der Fehler Cannot setup baudrate to 2400 Den Port hab ich auf AUTO gestellt. Wenn der PORT COM1 ist, tut sich nach minuten nichts. kann das sein weil die baudrate zu größ ist? denn wenn ich mit dem Mega32 was sende muss beim Hyperterminal 1200baud eingestellt sein.
Hat jemand schon den Bootloader an einem ATMEGA32 mit internem Takt zum Laufen gebracht?
Hier der Log vom Programm hab jetzt ext quarz mit 16Mhz am Mega32 im AVRootloader.asm hab ich bei Clock 16mhz eingestellt und trotzdem kommt: 06.05.09-16:36:57-125 > Connecting on port COM1... 06.05.09-16:36:57-843 > Error: can not setup baudrate to 19200 06.05.09-16:36:57-906 > Error: can not setup baudrate to 19200 06.05.09-16:36:57-953 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-000 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-062 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-109 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-156 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-218 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-265 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-312 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-359 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-421 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-468 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-515 > Error: can not setup baudrate to 19200 06.05.09-16:36:58-578 > Error: no Device found
Was hast du da für einen COM Port bzw. Betriebsystem ? Die fehlermeldung ist eindeutig, das Program kann über das Windows API beim ausgewählten COM Port die eingstellte Baudrate nicht aktivieren. 19200 ist Standard und sollte von jedem COM Port unterstützt werden, von deiner Hardware aber anscheinend nicht. Überprüfe deine Hardware, deren Treiber, dein Betriebsystem oder benutze eine Baudrate die dein Gerät auch unterstützt. Gruß Hagen
@Hannes: Die PC-Software unterstützt eine ganze Reihe an Möglichkeiten um den Bootloader im AVR automatisch zu starten. 1.) Du kannst den RTS Pin der RS232 an den RESET des AVRs oder einen anderen Pin legen. Angenommen du legst ihn an den RESET Pin dann kannst du in der AVRootloader.ini mit den Einstellungen bei RTSPulse und RTSInterval das exakte Timing, den Zeitpunkt, Logiklevel und Periode wie die PC-Software die RTS Leitung der RS232, die am RESET liegt, steuert einstellen. Statt RESET Pin ginge natürlich auch ein anderer Pin der dann aber innerhalb deiner Anwendung ausgewertet werden muß um in den Bootloader zu springen oder per WDT einen RESET zu erzwingen. 2.) Wenn deine Awendung selber den UART benutzt dann kannst du auf eigene, definierbare Kommandos zum Starten des Bootloaders reagieren. Dazu werden in AVRootloader.ini die Werte in AppCmd und AppCmdResponse und Timeouts.AppCmd konfiguriert. Die PC-Software sendet bei einem Verbindungsaufbau als aller erstes den Wert=String in AppCmd. Zb. AppCmd=startboot/0A/0D sendet den String startboot gefolgt von Zeilenumbruch und Linefeed. Sonderzeichen also in der Form / + 2 HEX zeichen. Sollte nun in AppCmdResponse ebenfalls was konfiguriert worden sein so wartet die PC-Software nach Absenden des AppCmd auf diesen AppCmdResponse. Zb. steht in AppCmdResponse=bootstart. Nach senden von startboot wird deine Anwendung erstmal den Wert bootstart absenden und dann zb. per WDT mit 17ms Timout den Bootloader starten. Es entsteht durch den 17ms WDT eine kleine Zeitverzögerung und diese würdest du in Timeouts.AppCmd=20 mit 20ms vorgeben. Also nach dem Empfang des AppCmdResponse wird die PC-Software erstaml 20 Millisekunden warten bevor sie mit dem eigentlichen Verbindungsversuch zum Bootloader beginnt. Steht in AppCmdResponse nichts drinnen so wartet die PC-Software logischerweise nicht auf dieses sondern setzt bei der Warteschleife für Timeouts.AppCmd fort. Ist dieses auf 0 so wird auch nicht gewartet. Ich würde bei dieser Methode mit WDT in kürzester Periode arbeiten und Timeouts.AppCmd=20 setzen um das Gesamttiming zu verbessern. Statt in AppCmd mit einem kompletten Komando zu arbeiten könntest du auch einfach zb. AppCmd=/55 setzen. Die Software sendet also den Wer 0x55 ab. Im 1-Wire Modus und ohne eigene UART Software an diesem Pin würdest du den PinChange IRQ für diesen Pin benutzen. Innerhalb dessen ISR schiebst du in ein Register die Daten rein und wenn dieses Register eben 0x55 enthält, oder ähnliche Bitkombinationen, startest du den Bootloader. So arbeite ich meistens noch mit der Erweiterung das ein parallel laufender Timer diese Variable nach einer Zeit auf 0 zurücksetzt. Du kannst das natürlich erweitern wie du möchtest. 3.) sobald die PC-Software den COM Port öffnet und solange er geöffnet ist wird die DTR Leitung der RS232 auf H Pegel gesetzt. Dies diente primär als Mini-Stromversorgung für einen eventuell angeschlossenen Pegelwandler, oder Pullup (max. erlaubte Ströme beachten). Auch diesen Pin könntest du für diesen Zweck benutzen. Er ist aber nicht per Konfiguration im Verhalten einstellbar. Gruß Hagen
>Wenn das Programm läuft ist doch der Bootloader komplett ohne Funktion >oder? Ja sicher, es läuft ja deine Anwendung. Ergo, wenn aus deiner Anwendung heraus der Bootloader gestartet werden soll dann musst du auch in deiner Anwendung den Bootloader-Pin überwachen und je nach obiger Methode darauf reagieren. Zusätzlich könntest du auch im AVRootloader.asm über die Einstellung UseBootMode=? noch das Event festlegen bei dem der Bootloader durchstarten soll. Zb. bei UseBootMode=3 würde der Bootloader nur durchgestartet wenn entweder der WDT einen Reset ausgelösst hat oder der AVR unprogrammiert ist, also noch keine Anwendung drauf ist oder der Bootloader per direktem RJMP/JMP/CALL/RCALL gestartet wurde. Bei allen anderen RESETs, wie Brownout, USB, JTAG, OnChipDebug, Ext. RESET, Powerup würde der Bootloader sofort die installierte Anwendung starten. Somit wartet der Bootloader dann nicht mehr und die Startupzeiten deiner Anwendung beträgt diejenige die du über die Fuses eingstellt hast plus par MCU Takte (ca. 16 Takte) Aber Vorsicht, überlege dir dann genau den Programablauf. Wenn deine Anwendung zb. den WDT deaktiviert und danach einen Programfehler hat, zb. Endlosschleife dann wirst du den Bootloader nicht mehr starten können und somit keine neue Anwendung über den Bootloader flashen können. Denn der Bootloader reagiert ja nur auf einen WDT Reset oder RJMP und beides trifft nicht mehr ein da deine derzeitig installiert Anwendung einen Bug hat. Gruß Hagen
Hallo Hagen! Ich kämpfe gerade an zwei Fronten mit deinen Quellen ;-). Zum einen machen die DEC Hash Funktionen in einer C++ Lib Probleme und ermittelt mit jedem Start einen anderen Hash bei gleichen Ausgangswerten und Konfigurationen und zum anderen mit deinem Bootloader. Zum zweiten mal ein wenig ausführlicher: Ich habe eine eigene Client Anwendung geschrieben, welche sich mit dem AVR über ein eigenes Protokoll unterhält. Dieses enthält ein Reset über den WDT um in deinen Bootloader zu kommen. Dieser hat 3 gesetzt, also wartet er auch brav nach dem vom WDT ausgelösten Reset. Leider gibt es Verzögerungen beim Schliessen des COM Ports in meinem Client, instanziieren der Interface Klasse und anstossen des Verbindungsaufbaus über dein Interface. Dadurch klappt das Update nur in max 1 von 40 Fällen. Von daher würde ich es gerne so umstellen, dass ich dein Interface damit beauftrage anhand meines Protokolls den Reset auszulösen und damit alles von dem Interface aus anstossen. Von daher wäre nun die Frage: Die in 2. genannten INI Einstellungen, kann ich die auch bei deinem Interface angeben? Wenn ja: wo? Ansonsten wollte ich mal fragen, ob es möglich wäre das Interface vllt. auf IStream oder ähnliches zu erweitern, so dass ich nicht gezwungen bin die Firmware auf den Rechner abzulegen für die Übergabe an dein Interface? Ich lade die Firmware in meinem Client runter bzw. der Client bringt die letzte Firmware mit und somit würde ich die gerne "intern" weitergeben ohne über externe (ausserhalb der App) Speicher zu gehen. Und ansonsten nochmal dickes Lob an deine ganzen Projekte und Arbeiten: die sind wirklich Klasse und von daher nochmals ein dickes Lob & Danke, vor allem da du sie auch allen zur Verfügung stellst.
Hallo Hagen, bitte entschuldige das ich so spät antworte. (ich hatte das Verbindungsproblem) Also ich habe jetzt in der PC-Software den Auto-Modus deaktiviert und wie von dir empfohlen den COM-Port direkt angegeben. Einstellungen komplett so wie von dir empfohlen - und es funktioniert prima. Wahrscheinlich gab es Timingprobleme des Rechner beim durchscannen der Ports.(COM3:USB-Serial-Port) Vielen Dank für deine Hilfe und die Zeit die du hier investierst. Grüße bandgap
Hagen Re schrieb:
> Was hast du da für einen COM Port bzw. Betriebsystem ?
hab Xp sp3
@Andy F. meine Frage war eher rethorischer Art, also ein Hinweis für dich das dort der Fehler nach meiner Meinung zu suchen ist. Solange der Fehler kommt das er die Baudrate nicht einstellen kann (ein Fehler der vom Treiber/OS kommt und nicht von meiner Software) wird meine Software nicht in der lage sein den COM Port zu öffnen. Dh. es kommt im Programablauf noch nichtmal zu den ersten Verbindungsaufbauschritten da schon das Öffnen und Initialisieren des COM Port durch diesen Fehler abgebrochen wird. Sogesehen brauchen wir erst hier weiter machen wenn du dieses Problem gelösst hast. Hast du schon mal in den Gerätemanager geschaut und verifiziert das das System den COM Port auch als aktiv anzeigt ? Gruß Hagen
@Robert, >Wahrscheinlich gab es Timingprobleme des Rechner beim durchscannen der >Ports.(COM3:USB-Serial-Port) das war eben auch meine Vermutung. Timingprobleme wird es immer geben, genauer gesagt sind es Synchronisationsprobleme. Die Anforderungen sind halt dergestalt das ein Kompromiß aus Baudrate, MCU Takt, Wartezeit im Bootloader, Timing im HW-Kommunikationskanal, Verzögerungen in den Treiber dieser Hardware, Timnings/Prioritäten im Tasksheduller des OS und am Ende dieser Kette meine Software und das benutze Protokoll für den Verbindungsaufbau. Sobald sich eine dieser Variablen ungünstig verändert so entsteht der Fall das theoretisch ohne Probleme ein Connect möglich wäre aber durch ungünstige sich überschneidende Intervale es nicht zum richtigen Zeitpunkt zu einem Connect kommt. Es gibt nur eine Antwort des Programmieres auf solche Probleme: entweder Umstellung auf Ereignisbasierte Systeme, dh. wir lösen explizit und exakt ein Eregnis aus das deterministisch exakt zu einer reproduzierbaren Reaktion führt: in diesem Falle Bootoader startet, oder wie senden quasi mit Dauerfeuer unseren Loginversuch bis der AVR antwortet. Letzeres ist aber unmöglich wenn man eine ganze Reihe von COM Ports scannen möchte, da es dann eine Frage der zeitlichen Dauer des Scannings wird. Naja, lange Rede kurze Lösung: im AUTO Modus in der AVRootloader.ini bei solchen Problemen den ConnectTrials Wert erhöhen, oder gleich die richtige Schnittstelle auswählen. Interesanterweise sind es immer die blöden USB-RS232, oder TCP/IP-RS232 Wandler die diese Probleme machen. Bei Benutzung der nach MS absolut veralteten RS232 gehts bei mir immer ohne Probleme, egal welche Baudrate, Konfiguration etc.pp. Gruß Hagen
@Thomas: vom Aufwand her und der Stabilität empfehle ich dir den RESET durch meine PC-Software/DLL auslösen zu lassen. Die PC-Software lädt die Einstellungen dazu aus der AVRootloader.ini Datei und übergibt sie dem Interface als Parameter. Dh. für dich du kannst diese Parameter in deiner Konfiguration speichern wie du es möchtest, lädst diese selber und übergibts sie dem AVRootloader Objekt. 1.) dein Application Interface/Objekt alloziert bei OpenCOM() ein Interface auf die Kommunikationsschnittstelle. Dieses Interface muß zb. de Baudrate schon korrekt eingestellt bekommen haben durch deine Anwendung. Gleiches gilt für die anderen Parameter dieser Kommunikationsschnittstelle, eg. COM Port. 2.) bei den jeeiligen Aktionen die nun das AVRootloader Interface ausführen soll fragt es bei deinem Application Interface die fehlenden Parameter ab. Siehe in AVRootIntf.pas die Dekalration von IApplication. Alle .GetXXX Methoden sind exakt diese Abfrage Methoden von Parametern. Die findest dort auch die Methoden .GetTimeouts um alle Timeouts aus der Sektion [Timeouts] der INI Datei an den AVRootloader zurückzugeben, oder die Methoden .GetAppCmd und .GetAppCmdResponse um die Kommandostring für deine installierte Anwendung auf dem AVR um in den Botloader zu kommen, abzufragen. Der einzige Wermutstropfen bei der Sache ist die Festlegung auf eine jeweilige Baudrate. Deine AVR Anwendung läuft mit einer vorgegebenen Baudrate und diese muß auch für den Bootloader benutzt werden. Ein Einbauen der IStream Schnittstelle halte ich für möglich aber im Sinne von zeitlichen Aufwand in Relation zum Nutzen für mich und andere für unökonomisch. Kurz gesagt: wenn dein Preis den du zahlst hoch genug ist baue ich die den Bootloader so um das du damit zum Mond fliegen kannst, aber das lohnt sich nicht. Statt einem IStream ist es ja jetzt so das du eine HEX Datei zur Verfügung stellen musst ohne Änderungen am jetzigen System. Damit geht die Verschlüsselung und alles andere. Möchtest du dich nicht auf die schon fertige Umsetzung mit AppCmd/AppCmdResponse und den RTS Geschichten verlassen dann besteht durchaus auch die Möglichkeit das du über mein ICOM Interface, also AVRootloader.COM: ICOM selber auf Lowlevel Ebene deine Daten für deine AVR Anwendung sendest. Du hast alle Funktionen in ICOM die nötig sind um über zb. die RS232 Daten zu senden und zu empfangen. Es spricht also nichts dagegen das deine Applikation gemsicht mit AVRootoader über die gleiche geöffnete ICOM Schnittstelle mit dem AVR kommunizieren. Desweiteren enthält das AVRotloader Interface ein SubInterface mit Namen .Command: ICommandSet. Dieses impelemtiert die Bootloader-Protokoll-Kommandos. Auch diese kannst du benutzen um jedes einzelene Bootloader Kommando auszuführen statt sich auf die HighLevel Methoden wie .Program() .Erase() usw. verlassen zu müssen. Und finally könntest du ein eigenes Kommunikationobjekt benutzen das nur die ICOM Schnittstelle implementieren müsste. Somit kannst du quasi deinen eigene Zwischenschicht bauen damit der AVRootloader zb. auf den LPT oder andere Kommunikationshardware Zugriff bekommt. Bei IApplication.OpenCommunication(): ICOM würdest du diese, deine Implementierung der Schnittstelle zum neuen Gerät dem AVRootloader mitteilen. Defakto hast du also in AVRootIntf.pas alles was du benötigst um meine PC-Software fast 1 zu 1 nachbauen zu können (fast:). Die AppCmd/AppCmdresponse Geschichten habe ich hier im Thread erst vor kurzem ausführlich beschrieben. Gruß Hagen
Für all diejenigen die nicht den komplexen Weg über meine Interfaces und die DLL gehen wollen oder können gibt es auch noch den Weg über mit Übergabe von parametern an meine AVRootloader.exe das Program zu steuern. Nachzulesen hier im Thread und in der AVRootloader.txt Datei. Mit der Einschränkung der weniger flexiblen Einstellungsmöglichkeit kann man über diese Paramater im Grunde auch alles machen. Gruß Hagen
Gast
#1257603
@ Hagen Re: Ich hab' jetzt nicht den ganzen langen Thread durchforstet, daher frag' ich dich einfach: entweder habe ich Tomaten auf den Augen oder ich check's nicht, aber dieselbe Einstellung wie auf dem Bild funktioniert auf mehreren mega644P problemlos, '.inc' - File vom mega32 aktiviert (644 deaktiviert) läuft nicht auf dem mega32 (16MHz) (siehe Protokoll). Benutzt wird RS232 mit max232, µC und Verbindung ist OK. Kannst du mir sagen was ich übersehen habe?
Was mir als erstes auffällt: Die BootCodeSize unterscheidet sich nicht um 2 Bytes. Diese sollte auf 0 gesetzt werden, dann erneut erstellen. Danach den [used] Eintrag des Code Segmentes dort eintragen. Danach erneut erstellen, dann sit der Eintrag unter [Used] zwar 2 Bytes grösser, aber das sollte man ignorieren. Somit sollte es eigentlich eine Differenz geben von 2 Bytes. @Hagen: Das Update klappt nun alles, ich hatte einfach noch eine alte Version und dadurch gab es die GetAppCmd, etc noch nicht in IApplication. Dadurch kam es überhaupt zu der Frage. Wegen den DEC Sachen mache ich einen Thread in der DP.net auf nächste Woche. Danke nochmals!
Ich habe doch noch eine Frage: Ich habe nun das Versioning mit eingeschaltet. Ich kann im AVR Code die App Version ermitteln, das zeigst du ja in dem Beispielcode. Genauso über die Interfaces auf PC Seite, aber ich habe noch nicht rausgefunden: wo wird die App Version festgelegt und wo kann diese ändern? Muss ich in meinem "user Code" einen bestimmten Offset mit einem uint32_t freihalten oder wird es im BootLoader gespeichert? Wenn letzteres: wenn ich meine Update eigentlich immer ohne BootLoader ausliefere, wie kann diesen dann aktualisieren? Oder kann ich dies vom User Code aus im AVR?
Im AVR wird sie 4/6 bytes vor BootStart gespeichert, also im FLASH der Anwendung logischer Weise und das in den letzten nutzbaren Bytes des FLASHs. Man kann diese also auch mit einem hardcoded Addresszugiff in der eigenen Anwednung auslesen (Adresse wird in der PC-Software bei den Infos angezeigt). 4 Bytes vor Bootstart wenn der AVR eine eigene Bootsection unterstützt, 6 bytes vor Bootstart wenn wir einen ATTiny oä. ohne Bootsection benutzen. 6 Bytes weil ja noch der rjmp Main mit rein muß. Die AppVersion wird also genauso wie bei den Tinys die Vektoren durch die PC-Software beim Programmieren eines neuen HEX Files in dieses HEX File live rein gepatcht. Man ändert die AppVersion also nicht auf direkte Weise sondern beim flashen einer neuen Anwendung. Irgendwie auch logsich da sich diese Version ja auf eine Anwendung, eh. Version eines HEXs bezieht. Sollten diese 4/6 Bytes im HEX File nicht alle auf 0xFF stehen gibt es eine Fehlermeldung das die PC-Software nicht patchen konnte. Logisch da sie davon ausgehen muß das diese Bytes dann von der Anwendung benutzt werden und ergo die Anwendung zu groß für den zur Verfügung stehenden FLASH ist. Ist die Verschlüsselung aktiviert so gelten auch die 4 Checkboxen welchen Teil der AppVersion der Bootloader überprüfen soll. Dh. eine Überprüfung der aktuellen Version mit den Teilen der neuen Version und ein eventuelles Unterbinden des Updates funktioniert nur mit der Verschlüsselung. Auch das ist im Grunde logisch da nur so eine kryptographische Sicherheit und damit unmanipulierbare Versionsnummernprüfung überhaupt erst möglich ist. Also ohne Verschlüsselung ist die AppVersion bei einem Update auf einen beliebigen Wert einstellbar, mit Verschlüsselung überprüft der Bootloader erstmal die Teile der neuen Version die man zur Prüfung per Checkboxen aktivert hat. Diese müssen dann gleich oder höher der aktuell installierten Version sein oder der AVR lässt kein Update zu. In den Interfaces gibt es die Methode IApplication.GetAppVersion(Masked: Bool): Integer. Diese Funktion sollte die neue Version als 4 Bytes Integer zurück geben. Wenn Masked = TRUE ist dann die gleiche neue Version aber diejenigen Bytes die nicht überprüft werden sollen müssen auf 0xFF gesetzt werden. Dh. dann auch das jedes der 4 Bytes einen Wertebereich von 0 bis 254 hat und der Wert 255 reserviert ist. SO ähnlich arbeiten unsere IP Adressen. Wenn also ein ACY File mit .DoCompile() oder .DoProgram() erzegt werden soll so wird auch .GetAppVersion() zweimalig aufgerufen. Einmal Masked=FALSE um das HEX File zu patchen und einmal Masked=TRUE um die zu überprüfende Versionsnummer in den ersten verschlüsselten Initialisierungdatenblock zu kodieren. Beide Versionsnumer, also die schlußendliche im HEX File hineingepatchte und die teilweise zur Überprüfung im Initialisierungblock sind verschlüsselt und können damit im fertigen ACY File nicht manipuliert werden. Die aus dem Initialisierungblock, der bei Verschlüsselung immer als erstes an den AVR gesendet werden muß, wird nun mit der schon installierten überprüft. Schlägt dies fehl akzeptiert der AVR keine weiteren Datenpackete und unterbindet so das Programmieren des FLASHs. Hat ein Angreifer keinen Zugriff auf die Register des AVRs so kann er nur noch per Brute Force versuchen das 128 Bit Passwort zu knacken. Da dies aber weitaus weniger wahrscheinlich zum Erfolg führt als den AVR als Hardware, also seine Fuses/Die anzugreifen, ist dies relativ sehr sicher. Mehr ist kryptographisch als Schutz nicht rauszuholen aus den AVRs, in Software. Dieses Initialisierungpacket ist 16 oder 24 Bytes groß. 24 Bytes wenn UseVersionng aktiviert. Die ersten 8 Bytes sind reine Zufallsbytes und randomisieren somit wie ein Initvector die komplette Verschlüsselung auf Grund der Verknüpfung aller Datenblöcke des HEX File über ein Feedbackregister intern. Dh. wird das gleiche HEX File mit gleichen Enistellungen (Passwort etc.pp) merhmals verschlüsselt so wird der Output sich immer komplett unterscheiden. Dieser zufällige IV stellt also sicher das eine ganze Reihe von kryptologischen Angriffen effektiv unterbunden werden, zb. Austausch von verschlüsselten Datenblocken, Manipulation einzelner Bits im Datenblock, Choosen Plain Text Angriffe um das Passwort in Erfahrung zu bringen, Differentielle Krypoanalyse usw. usf. In den letzten 8 Bytes dieses Initialisierungsblockes stehen 4 Bytes die aktuelle Versionsnummer des Bootloaders, der AVR Typ also alles was bei BootInfo steht. An hand dieser Werte überprüft die Entschlüsselung ob die nachfolgenden Daten exakt für diesen Bootloader und AVR bestimmt sind. Die letzten 4 Bytes sinde eine Signatur die identisch zu den ersten 4 Bytes des gewählten Passwortes sein müssen, nach der Entschlüsselung. Somit eine geheime Signatur mit unbekannten und nicht festen Inhalt da sie vom Passwort direkt abhängig ist und gleichermaßen eine 32 Bit Prüfsumme. Da der XTEA Algorithmus eine 64 Bit breite Blockverschlüsselung ist heist die das sie in meinem Doppel-CBC-Feedback-Modus wie eine 64 Bit sichere Prüfsummenfunktion arbeitet. Die Daten, also alle Datenblöcke einer Datenübertragung sind am Ende mit einem solchen 8 Bytes Zusatzdatenblockes abgesichert. Ergo benutzt die Verschlüsselung eine Prüfsumme vergleichbar zu einer 64 Bit breiten CRC die mit einer Wahrscheinlichkeit von 32Bit sicher ene Aussage treffen kann ob die vorherigen Daten korrekt und unmanipuliert übertragen wurden. Bei den Datenpacketen zur Programmierung des FLASH steht statt der 4 Bytes BootInfo in diesem Datenblock dann eine 24 Bit Adresse drinnen. Das ist diejenige FLASH/EEPROM Adresse an den die vorher empfangenen Daten, und die im SRAM Buffer entschlüsselt worden sind, programmiert werden sollen. Dh. auch die Addressinformation wird durch das kryptographische Protokoll geschützt und nicht manipulierbar gesichert. Es hat den Vorteil das man Datenblöcke mit sich wiederholbaren Muster nur einmal übertragen kann und in den eigentlichen FLASH/EEPROM Programmierroutinen mehrmals linear hintereinander ab einer Startadresse programmieren kann. Möchte man zb. 512 Bytes mit dem Inhalt 0x01 0x02 programmieren so überträgt man effektiv nur 2 Bytes, nämlich 0x01 und 0x02, plus die 3 Bytes Startadresse. Dann ruft man die Programmfunktion für den EEPROM/FLASH einmalig auf und teilt ihr mit das sie 256 mal diese 2 Bytes ab der Addresse programmieren soll. Teilweise wird dieses Feature auch schon in der PC-Software benutzt, als Art Komprimierung und Beschleunigung der Datenübertragung. Mit IAVRootloader.Device.AppVersion: Integer, fragt man vom aktuell verbundenen bzw. zu letzt verbundenem AVR die Versionsnummer ab. Ist diese 0xFFFFFFFF und .Device.Supports & sfVersioning <> 0 dann wurde im AVR noch nichts installiert. Soweit zur Versonsnummer, der Verschlüsselung, wie und warum es so funktioniert. Gruß Hagen
@Thilo, folge mal Thomas seiner Vermutung, das ist auch meine. Gruß Hagen
Übrigens, die oben beschriebene Art der Versionsüberprüfung kann auch angewendet werden wenn man nur den EEPROM per sicheren ACY updaten möchte. Dh. ein kompiliertes und verschlüsseltes ACY File das nur EEPROM Daten enhält kann über die Versionsprüfung auf einen AVR serialisiert werden. Nur AVR mit der gleichen oder geringeren Versionsnummer der Anwednung akzeptieren dann diese neuen EEPROM Daten. Das war auch einer der Gründe es so zu machen wie es jetzt ist. Ach und nochwas: das interne Feedback Register wird innerhalb der merhfachen Übertragung verschiedener nachfolgender Datenpackte nicht zurückgesetzt. Dh. auch wenn die PC-Software unser HEX File in kleinere Packate a maximal SRAM Buffer der zur Verfügng steht zerlegt und dabei jeden mit einem 8 Bytes Prüfsummenblock absichert, so besteht für einen Angreifer keine Möglichkeit durch Austauschen dieser Kommunikationsbedingten Zerlegung die Packete auszutauschen oder um zu sortieren. Dh. sie müssen damit sie korrekt entschlüsselbar sind in der exakten Reihenfolge gesendet werden. Gruß Hagen
Gast
#1257692
Hagen Re schrieb: > @Thilo, folge mal Thomas seiner Vermutung, das ist auch meine. > > Gruß Hagen Habe ich getestet. Keine Änderung. Auch ein vorsichtshalber neuer µC brachte keine Änderung. Wie gesagt: Austausch gegen einen m644P, Codegröße und .inc angepasst, funktioniert. Mega32 nicht.
@Thilo: mein Auftraggeber sagt immer: mache nicht deine Probleme zu meinen ;) Du musst irgendwo einen Fehler gemacht haben. Gehe also alles nochmal wie hier irgendwo im Thread beschrieben step by step durch. Letztens erst trat der Fall auf das die RX/TX Pin/Port Einstellungen nicht mit den benutzen Pins übereinstimte, hast du das überprüft ? Fuses richtig ? Korrektes Include ? Mal in AVRootloader.ini [Timeouts] Options = 2 gesetzt und den Inhalt des Protokollfensters hier gepostet, nach einem Verbindungsversuch ? Arbeitest du mit internem RC Oszillator oder externen Quarz ? Wenn extern schwingt dieser ? Fuses richtig ? Gruß Hagen
Gast
#1257713
>mein Auftraggeber sagt immer: mache nicht deine Probleme zu meinen ;)
Hast ja Recht ... ;)
Ich kann's mir eben nicht erklären.
Ich nehme den m32 aus der Schaltung, stecke den m644 'rein, .inc und
Codegröße angepasst, sonst alles gleich => läuft problemlos.
Protokollfenster, Einstellungen und Fuses habe ich weiter oben als .jpeg
gepostet.
Danke für die Mühe! ;)
Edit: ich werde mal die Schaltung auf m644P aufrüsten.
Jetz habe ich das erstmal gesehen ! Der Output ist also von deinem M32. Er programmiert deinen M32 bricht dann aber beim Verify mit einem Lesefehler, eg. Timeout ab. Ändere mal in AVRootloader.ini [Timeouts] Buffer= auf einen höheren Wert ab. Dh. im Grunde läuft bei dir alles korrekt bis einschließlich Connect. Dann gibts einen Timeout Fehler der nicht auftreten sollte. Setze mal [Timeouts] Options=2 und dann nochmal das Protokoll hier posten. Diese Option aktiviert den Debugmodus aus dem ich dann im Protokoll mehr heraus lesen kann. Gruß Hagen
Hallo Hagen! Das Problem mit dem Verify Timeout hatte ich auch, ich habe aber nun einfach das Verify abgeschaltet und mache dies nun auch nicht mehr. Aber ich habe noch ein Problem und zwei Fragen: 1. DoConnect() hat einen Working Parameter - was bedeutet dieser? Du bist in dem Thread nicht darauf eingegangen und hast ihn in deinen Beispielen mal auf true gesetzt und mal auf den default (false). 2. ProcessMessages hat nun ja einen boolschen Rückgabewert. Wenn ich das richtig sehe, dann kann ich dort true zurück geben um die aktuelle Aktion abzubrechen und false wenn alles wie gehabt weiter werkeln soll. Richtig? 3. Ich habe noch das Problem, dass er mir beim DoConnect() eine Exception aus deiner DLL wirft ohne Message (ist leer). Diese wird danach auch über Output gemeldet mit dem Code für einen Fehler (ocError), aber weiterhin ist Msg leer. Danach ruft die DLL wieder OpenCommunication auf, was dann natürlich schief geht, da der Port schon noch von dir geöffnet ist (Access Denied, Code 5 von Windows zum CreateFile() des COM Ports). Und dies dreht sich dann endlos, angefangen mit der Exception aus DoConnect ohne Message. Mit jedem Versuch setzt die DLL trotzdem erfolgreich mein App Command ab zum resetieren des AVR, was dieser auch richtig macht - also irgendwer in deiner DLL weiss noch um den offenen COM Port ;-). Das Programm von dir macht es ohne Probleme, aber braucht mehrere Anläufe zum absetzen des App Commands, vllt. gibt es intern auch diese Probleme? Alle o.g. Probleme treten nicht auf, wenn ich mich direkt verbinde und Update, also ohne App Command, was z.b. direkt nach brennen des Bootloaders der Fall ist. Und eine letzte Frage, rein informativ: woher unterscheidest du bei der AppCommand Funktion ob ich die Daten die du senden musst nun 2 Byte oder 1 Byte pro Zeichen sind? Nachtrag: Wenn ich, wie von dir öfters beschrieben, in deinem Programm die Options auf 2 setze, dann schafft er es nicht mehr, sich zu verbinden. Die RxD Leitund des MC flasht die ganze Zeit, er selber resetet auch ordentlich (AppCommand klappt) und bleibt im BootLoader, aber er bekommt keine Verbindung zu stande. Bei Options=0 schafft er es, er flasht vllt. erstmal eine Minute rum mit der RxD, aber er schafft dann aber eine Kommunikation aufzubauen. Ich kann bei Interesse dir auch alles mal zippen, von der Config deines Progs, bis zu meiner Software, Client etc. Zum selbst ausprobieren sollte ein beliebiger (bei mir ATMega 8) AVR 8 Bit reichen mit serieller Verbindung.
Gast
#1258840
Hallo Hagen,
hier das Protokoll mit Buffer=5 und Options=2:
------------------------------------------------------
11.05.09-17:35:04-375 > Connecting on port COM1...
11.05.09-17:35:38-671 > Device connected
11.05.09-17:35:38-671 > Program...
11.05.09-17:35:38-671 > execute compiled data
11.05.09-17:35:38-671 > 1.0.0.0
11.05.09-17:35:38-671 > selected options in compiled file:
11.05.09-17:35:38-687 > - programming FLASH
11.05.09-17:35:38-687 > - erase FLASH during programming
11.05.09-17:35:40-843 > Cmd.SetBuffer.ReadByte() ICOM: read error.
11.05.09-17:35:40-906 > Device disconnected
------------------------------------------------------
>Dh. im Grunde läuft bei dir alles korrekt bis einschließlich Connect.
Richtig. Connect funktioniert prima.
Ok, Fehler zu erst: Option=1 um den Debug Modus zu aktivieren Option=2 um den alten Connect zu aktivieren Option=3 für beides. @Thilo: also Option auf 1 setzen und nicht 2. Da bin ich durcheinander gekommen. Der alte Connect bis Version 4 glaube ich, benutzt nach dem Senden des BootSign keine 16 Bit CRC über diese BootSign. Beim neuen Connect, also diese Option nicht gesetzt, wird über die BootSign noch eine CRC berechnet und gesendet. Der neue Bootloader erwartet also diese CRC und akzeptiert nur mit gültiger CRC einen Connect Versuch. Der alte Bootloader kann auch mit dem neuen Verfahren zurecht kommen, wird aber in der nachfolgenden Command FSM am Anfang aus dem Tritt geraten. Wenn man also mit der neusten PC-Software eine Verbindung zu einem älteren Bootloader machen möchte dann empfehle ich diese Option auf 2 zu setzen. Unter Umständen geht das aber auch ohne diese Option. @Thomas: sieht so aus als ob dein RS232 Timing sehr ungünstig ist, neben den anderen oben besprochenen Dingen. >1. DoConnect() hat einen Working Parameter - was bedeutet dieser? Es gibt zwei Grundmodis, moConnected und moWorking. moConnected heist einfach manuell verbunden und muß auch manuell mit DoDisconnect() getrennt werden. Der Unterschied zwischen moConnected und moWorkng liegt in deiner Callback Methode IApplication.Changed begründet. Ist IAVRootloader.Mode = moConected dann solltest du andere Bedienelemente enablen als im moWorking Modus. Als Beispiel hättest du einen Program Button der in der Callback Methode .Changed disabled werden sollte wenn der .Mode auf moWorking steht. Mit dem Bool Parameter in .DoConnect() teilst du also im Vorhinein mit ob du nur eine Verbindung aufbauen möchtest oder ob du eine Verbindung aufbauen möchtest und gleich danach irgendeine Aktion durchführen möchtest, also DoProgram() usw. .DoConnect() und .DoDisconnect() Aufrufe können verschachtelt sein, als 2 DoConnect()s benötigen 2 DoDisconnect()s. Wird eine Methode wie .DoProgram() aufgerufen ohne vorher connected zu sein so wird intern autom. DoConnect() aufgerufen und nach Beendigung DoDisconnect(). >2. ProcessMessages hat nun ja einen boolschen Rückgabewert. Korrekt. Alle deine Aufrufe von Methoden der Interfaces sollten zu äußerst mit einem try except Schutzblock gekapselt sein. Wird in .ProcessMessages TRUE zurück gegeben dann wird intern eine EAbort Exception ausgelösst auf die du dann in deinem äußersten Schutzblock reagieren solltest. Exception sind Außnahmebedingungen und die meisten Programmierer verstehen ihr Konzept gründlich falsch. Es ist keine reine Fehlerbehandlung sondern eben Ausnahme Bedingungen und was als Ausnahme gilt ist reine Definitionssache. Sogesehen benutze ich die Exceptions nicht nur als Fehlermeldungen sondern bewusst auch zur sauberen Terminierung von Aktionen. Zb. eben das Abbrechen einer Aktion durch den Benutzer. Das funktioniert solange gut wie man als programmeirer die zu äußerst liegenden Codeblöcke auch mit try except Schutzblöcken sichert. >3. Ich habe noch das Problem, dass er mir beim DoConnect() eine >Exception aus deiner DLL wirft ohne Message (ist leer). Die .OpenCommunication() Methode hat einen Parameter Index. .OpenCommuication() wird bei einem Connect Versuch in .DoConnect() quasi als Callback aufgerufen. IAVRootloader ruft .OpenCommunication() mit dem Index beginnend bei 0 auf. Kehrt .OpenCommunication() mit nil zu IAVRootloder zurück bricht dieser den Connect Versuch ab. Bricht .OpenComunication() mit einer Exception EAbort ab so wird IAVRootloader den Index um +1 inkrementeren und wider .OpenCommunication() nun mit Index =1 aufrufen. Somit kann über .OpenCommunication() eine nicht so ganz offensichtliche "Schleife" aufgebaut werden und der ansich für dich nicht frei zugreifbare Connect im IAVRootloader gesteuert werden. Letzendlich dient es dazu im AUTO Modus, einem Scan der COM Ports, alle COM Ports der Reihe nach ihrem Index durch zu iterieren bis ein gültiger Connect zustande kommt. Dieses Vorgehen habe ich nachträglich als Feature implementiert und deshalb die nicht ganz so offensichtliche Arbeitsweise. Hier mal mein Sourcecode der .OpenCommuniation() Methode in meiner PC-Software
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
Es ist ja so das das IAVRootloader Interface keinerlei Zugriff auf den eigentlichen COM Port über das ICOM Interface bekommt. IAVRootloader kann nur lesen und schreiben in dieses Interface/Port aber eben nicht festlegen welchen Port, welche Hardware oder Einstellungen möglich sind. Diese Aufgaben sind dem eigenen IApplication Interface vorbehalten. Dies ist eine restriktive Form der Softwareprogrammierung, die konsequente Modularisierung, Aufgabenteilung und Protektisierung um unabsichtliche logische Fehler durch den Programmierer zu verhindern. Leider führt dies dazu das manchesmal, wenn zu regide angewendet, das spätere konzeptionelle Richtungsänderungen schwerer ohne größere Änderungen umsetzbar sind. Gruß Hagen
>Ich kann bei Interesse dir auch alles mal zippen, von der Config deines >Progs, bis zu meiner Software, Client etc. Zum selbst ausprobieren >sollte ein beliebiger (bei mir ATMega 8) AVR 8 Bit reichen mit serieller >Verbindung. Danke für dieses nette Angebot, und ich wäre wirklich interessiert wenn da nicht das Zeitproblem ist. Im Grunde habe ich ja selber schon alles mal verwendet und weiß also wie es funktioniert ;-) Wenn du sichergehen möchtest das ich mal über deine Arbeit drüber schaue um dir Verbesserungen vorschlagen zu können dann würde ich das natürlich auch machen. >Und eine letzte Frage, rein informativ: woher unterscheidest du bei der >AppCommand Funktion ob ich die Daten die du senden musst nun 2 Byte oder >1 Byte pro Zeichen sind? Diese Frage habe ich nicht ganz verstanden. In AppCmd/AppCmdResponse wird ein String drinnen stehen der minimal 1 Zeichen bis zu x Zeichen lang sein kann. Die Escaped Sequenzen also 3 Zeichen ala /3F werden umgewandelt und raus kommt der fertige String der gesendet eg. empfangen werden muß. Nun, IAVRootloader sendet AppCmd und wartet auf den Empfang des AppCmdResponse. Dessen Länge in Bytes ist ja dann schon bekannt und somit ist es einfach diese X Zeichen vom COM Port zu lesen und mit AppCmdResponse zu vergleichen. Real ist es natürlich ein bischen anders da ich dort Zeichenweise beginnend mit dem ersten Zeichen des gültigen AppCmdResponse vergleiche und einen Zeichen-Index bei Erfolg inkrementiere. Dh. sowas wie eine sliding Window Vergleichsroutine. Hm, könnte es sein das du dich auf die Deklaration mit WideString beziehst und die Unterscheidung zwischen Singlebyte/Multibytes String meinst ? Ganz einfach: alle WideStrings werden als nicht translierbare Singlebyte Strings interpretiert. 2 Bytes ASCII Formatirungen also garnicht berücksichtigt. Der Grund für die Verwendung von WideStrings ist einfach der das nur dieser Typ für dynamische Strings über Prozess/Thread/Task-grenzen hinweg im MS DCOM/COM/AQctiveX Standard erlaubt, eg. sinnvoll sind. Würde ich meine DLL also in ein echtes ActiveX/COM Objekt umbauen wollen so müsste ich nichts am bestehenden Code abändern aus dem Fakt der dynamischen Allozierung. Dann wäre diese DLL als Inprozess/Outprocess COM Server sofort benutzbar als ActiveX/COM Objekt in anderen Sprachen die sich an die Regeln halten. Die Alternative zu Widestrings als "binärer dynaqmsicher Datenkontainer" wären andere Interfaces/Objekte zu benutzen, wie IStreams usw. Das ist aber viel komplizierter als mit WideStrings zu arbeiten. Neuerdings gäbe es noch die Varianten aber in diese ein Bytesarray zu allozieren kostet im Source mehr als eine simple Zuweisung wie bei den WideStrings in Delphi. WideString sind in Delphi kompatibel zu deren eigenen AnsiStrings. Gruß Hagen
Hallo Hagen! Danke für die Erklärungen, nun bin ich ganz gut informiert und vieles ist nun auch sehr gut verständlich. Ich hatte bei der DoConnect Exception mich schon recht gut gewundert, wie eine DLL mir eine Delphi kompatible Exception werfen kann, da afaik Delphi dies nicht ordentlich handelt mit externen Exceptions. Wäre es eine EAbort Exception, dann hätte man ja vllt. wenigstens den Classname ermitteln können, aber die gefangene ist einfach Exception, von daher kann es von Delphi vllt. eine neu generierte sein nach auffangen der von dir generierten. Ich werde zumindest demnächst nochmal weiter debuggen und schauen woher das ganze stammt, es wäre doch wohl gelacht, wenn ich das nicht zum stabilen laufen bekommen würde. Ich kenne das mit der fehlenden Zeit selbst ganz gut, aber derzeit kann ich mich mal gut dem Projekt widmen - da es ein privates Projekt ist, ist das eine schöne Urlaubsbeschäftigung. Ich würde dich nur im Notfall bitten dir den Quellcode anzuschauen - ein Notfall wäre, wenn ich nach 3 Tagen debuggen noch immer keinen Anhaltspunkt habe, warum das nicht klappt oder die Exception mir weiter um die Ohren fliegt. Das Angebot war eher dazu gedacht, dass du die Fehler besser nachvollziehen kannst, da ich mit dem Verify das gleiche Problem hatte und dazu noch halt diese Exception + hackliger Verbindungsaufbau mit deinem Programm. Aber erstmal stehle ich dir ja schon genug Zeit mit den Beiträgen hier. Und zu der AppCommand Frage, diese zielte eher darauf ab, da du ja einen WideString haben willst. Dies ist zwar durch das ActiveX beste Wahl, aber wenn ich dir nun einen zurück gebe, z.B. "test", dann wäre es im Speicher folgender aufbau: 00 74 00 65 00 73 00 74. Woher weisst du nun, dass du nur 74 65 73 74 senden musst und ich nicht vllt. Binärdaten nutze in meinem Protokoll und du von daher 00 74 00 65 00 73 00 74 versenden müsstest? Grüße, Thomas
Ok, ganz einfach würdest du mit WideString die Bytes 00 74 00 65 00 73 00 74 versenden wollen dann stünde im WideString folgendes drinnen 00 00 00 74 00 00 00 65 00 00 00 73 00 00 00 74, expandiere also jedes der Bytes um ein weiteres Nullbyte. Per see wandle ich alle WideString Parameter von und nach ANSI Strings. Ich benutze also intern selber nur die LongStrings/eg. AnsiStrings vom Delphi. WideString dient nur dazu um in den Interfaces CMO/ActiveX konform zu sein und eben nicht die aufwändigeren Alternativen nutzen zu müssen. Beim Debuggung mit Delphi musst du aufpassen. Der JIT Debugger von Borland zeigt dir auch abgefangende Exception an und hält auch dann. Diese Exception könntest du leicht als Exception für dich interpretieren werden aber intern in jedem Falle behandelt und interessieren dich somit überhaupt nicht. Das liegt darin begründet das der Debugger zwar sich in die globale Exceptionchain einlinken kann er aber eben nicht zum Zeitpunkt des Auslösens einer Exceptions in der Lage ist zu ermitteln bis zu welchem übergeordneten Sourcecode Bereich die Nicht Bearbeitung dieser Exception reicht. Normalerweise bist du als Programmierer nur an denjenigen Exceptions interessiert die bis in deinen Source hinein unbearbeitet bleiben und dort abgefangen und behandelt werden sollten. Zum Auslösezeitpunkt einer Exception könnte es aber so sein das in meinem Source ich später diese Exception abfange, sie behandle und eine andere neue Exception als Folge davon raise. Möchte man aber nun einen Haltpunkt an exakt der Codestelle an der eine Exception ausgelösst wurde dann kann zu diesem Zeitpunkt der Debugger eben nicht wissen das es sich um eine Exception handelt die garnicht bis in deinen Source hinein reichen wird da ich sie in meinem Source vollständig behandle. Exceptions sind heutzutage ein Feature des Windows Betriebsystemes, mit klar definierter Struktur und einigen hilfreichen API Funktionen. Borland Delphi kannte noch vor dem Windows OS Exceptions, diese wurden aber ganz anders umgesetzt. Egal, worauf ich hinaus will ist das Fakt das der Borland Debugger auch andere Programme geschrieben in anderen Sprachen und deren Exception Handling debuggen kann, solange sie sich am MS Window Standard halten. In diesem Falle, und eben bei Interprozess-Debugsessions stehen aber bestimmte Infos nicht mehr zur Verfügung. Also zb. der Klassennamen der Objektimplementierung einer Delphi Exception, selbst wenn sie in einer DLL mit Delphi geschrieben ausgelösst wird. Das liegt einfach daran das die Delphi Exception Klassen eben ein Feature nur von Delphi sind und nicht kompatible Objektstrukturen zu anderen Sprachen, es gibt da ja keine Standards. Der debugger kann die also anzeigen wo und das eine Exception ausglösst wurde im Sinn der Funktionalität die das OS/Hardware zur Verfügung stellt aber eben keine Informationen über den OOP Überbau den ein Source benutzt um diese Exception in Objekte zu verkapseln. Nebenbei bemerkt hätte der Delphidebugger sehr wohl die Möglichkeit auch den Klassennamen von Exceptions aus anderen Prozessen/DLLs die selber mit Delphi geschrieben wurden zu ermitteln und anzuzeigen. Die Windows OS Exception Strukturen können nämlich durchaus erweiteret werden, werden sie sogar, nämlich um zb. Zeiger auf die Exception Objekte, und damit die OOP-mäßige Kapselung dieser Exceptions. Nur kommt man da an die Grenze zwischen planmäßiger definierter Benutuung einer Schnittstelle und einem Hack zum Auslesen anderer Prozessspeicher. Sogesehen: die Aussage Delphi/Debugger würde dies nicht richtig handhaben ist falsch ;) Er darf es gar nicht anders handhaben auch wenn es möglich wäre, es existiert keine klar umrissene Schnittstelle solche Informationen über Prozessgrenzen und Sprachgrenzen hinweg abfragen zu können. Gruß Hagen
Übrigens Exceptions dürfen auch in COM/ActiveX Interfaces über die Grenzen der DLL/Prozesses/Tasks usw. weitergereicht werden. Man sollte dies nicht machen aber zulässig ist es. Deshalb oft bei den COM/ActiveX die umständliche alte Arbeitsweise über ein HRESULT als Rückgabe einer Methode. Die Punkte an denen manchesmal der JIT Debugger mit "externe Exception" aussteigt sind von ganz spezieller Natur. Meistens sind es nämlich Exception innerhalb des Kernels vom Windows ausgelösst um spezielle Tricks zu ermöglichen. Exceptions sind nämlich hervorragende Mittel um Hacking/Debugging zu erschweren. Nun, diese "seltene" Fälle in denen der JIT Debugger aussteigt liegen darin begründet das diese Exception sich eben nicht an den Standard in der Exceptionbehandlung halten den MS vorgegeben hat. Man kann also einen Debugger der selber ein Exceptionhandling benutz dahin gehend austricksen das man in seinem eigenen Code dessen Excpetionchain so umbiegt das eine Exception ausgelöst im eigenen Code sich so verhält als wäre sie innerhalb des Debuggercodes ausgelösst. Das führt dazu das der eigene Code die Kontrolle über den Debugger erlangen kann und diese abschießt. Aber das ist Hardcore und sprengt diesen Thread ;) Gruß Hagen
Hallo Hagen! Jo, danke. Manches davon war mir noch nicht bewusst - ich habe bisher auch meistens immer beide Seiten programmiert bei irgendwelchen Interfaces oder anderen Schnittstellen, so dass ich dort meistens mit results gearbeitet hatte. Ich meinte bei meinen Ausführungen nicht EExternalException sondern bezog mich mit "externe Exception" auf Exceptions aus nicht meinem Programmcode - somit u.a. aus deiner Interface DLL. Ich werde mal debuggen und schauen. Wenn es Problem gibt, dann melde ich mich nochmals. Vielen Dank nochmals für deine Zeit und wie immer ausführlichen Erklärungen! Gruss, Thomas
>Ich meinte bei meinen Ausführungen nicht EExternalException sondern >bezog mich mit "externe Exception" auf Exceptions aus nicht meinem >Programmcode - somit u.a. aus deiner Interface DLL. Und eben diese siehst auch du in deinem Debugger. Ich empfinde diese ebenfalls störend in der produktiven Entwicklung, aber aus oben genannten Gründen kann der Debugger dies nicht unterscheiden. Naja, möglich wäre es schon aber Borland hat keine GUI Schnittstelle integriert um dies selektiv abzuschalten. Wahrscheinlich weil sie es nicht sauber überprüfen können obwohl es doch sehr einfach wäre das Modulhandle und damit die virtuelle Adresse des Modules in der die Exception ausgelöst wird als Filterbedingung zu benutzen. Problematisch bei einem solchen Filter ist eben der Fakt der realen Behandlng einer solchen Exception. Wird sie im fremden Modul vollständig behandelt bräuchtest du sie auch nicht sehen. Passiert dies nicht und du stepst nicht durch dann landest du in deinem Source an einer Stelle die du dir nicht erklären kannst wie du dahin gekommen bist. Aus deiner Sicht ist die Kausalität nicht mehr vorhanden und ergo suchst du in deinem Code bis in alle Ewigkeit nach dem Auslöser dieses Verhaltens. Borland hat da wohl pragmatisch reagiert und zeigt alle Exceptions an weil sie eventuell direkt in deinen Code springen könnten und baute somit auch keine Filterung für solche Exceptions ein. Das was du nun als Exception bekommst sind meine internen EAbort's die ich zur Flußsteuerung benutze. Diese werden behandelt und wie ich es oben schon sagte sehe ich Exception bischen weiter gefasst als nur pure Fehlerbehandlungen. Gruß Hagen
Hallo Hagen! Zwischenzeitlich kann ich erfreuliches berichten: es läuft. Ich hatte diese Verbindungsprobleme aus dem gleichen Grund wie dein Programm: Options war noch 2 und nicht halt 1. Nun mit der neuen Connect Methode von dir (also Options 0 oder 1) klappt nun auch alles wieder vorzüglich. Ich war auch schon recht verwundert, da ich zuvor ein paar Updates ohne Probleme fahren konnte. Die Exception war somit einfach nur die Meldung über den ausgebliebenen Verbindungsaufbau. Komisch bleibt aber weiterhin warum deine Output() Funktion anspringt mit einer leeren Message und dem Code für einen Fehler. Du stellst doch den ausbleibenden Verbindungsaufbau fest (Timeout), somit bist du doch Herr bzw. Generator der Meldung. Alle meine weiteren Probleme die ich vorhin geschildert hatte waren nur Folgefehler (Index war dann 2, erneuter Aufbau, anderer Port/Enumeration, dadurch dann Code 5, Access denied - nun ist dies alles klar). Also, ergo, alles in Butter und derzeit läuft das Update schonmal grundsätzlich. Nun bleibt nur noch die Frage, warum meine AppVersion immer so komisch aussieht, obwohl ich doch alles gesetzt habe und auch mein klein genug ist (noch rund 2,5 kB frei, 1 kB für Bootloader, also 1,5 kB frei). Deine App und das Interface ermitteln die App Version korrekt, nur die von deinem test Beispiel übernommene Code ermittelt wohl Müll. Auch der gesicherte MCUSR ist müllig. Aber das sind Kleinigkeiten, die löse ich noch mit der Zeit. /Nachtrag: Sprich ermitteln der AppVersion auf dem AVR mit dem Client Code schlägt fehl. Special Read ist an, sonst würde er ja ins Nirvana springen (war mein vorheriger Fehler ^^). Das ganze Projekt wird eh wieder komplett veröffentlicht, es ist "nur" ein Update des bisherigen Projektes (http://blog.mütze1.de/?page_id=231). Also nochmals vielen Dank für deine Hilfe. Und ich werde mich ranhalten Beispielprojekte für das DEC Problem zu erstellen. Grüsse, Thomas PS: Ich nutze in meinen Programmen auch zu gerne SEH, weil es im OO programmieren einfach die beste Möglichkeit ist um den Programmablauf ausserhalb der Reihe zu steuern. Gerade Aktionsabbruch etc., Fehlerbehandlung, Flusssteuerung, etc.
>..Probleme fahren konnte. Die Exception war somit einfach nur die Meldung >über den ausgebliebenen Verbindungsaufbau. Komisch bleibt aber weiterhin >warum deine Output() Funktion anspringt mit einer leeren Message und dem >Code für einen Fehler. Du stellst doch den ausbleibenden >Verbindungsaufbau fest (Timeout), somit bist du doch Herr bzw. Generator >der Meldung... Korrekt, ich bin auch der Herr und Generator der Fehler die immer in einem solchen Projekt versteckt sind ;) Kurz, es könnte durchaus auch ein fehlerhaftes Verhalten sein auf das ich in meinem Überbau nicht stoßen konnte weil er sich von deiner Benutzung der Interfaces unterscheidet. Um dies beurteilen zu können und eventuell einen Hinweis auf meinen Fehler zu bekommen wäre es vieleicht doch sinnvoll wenn ich mir deine Sourcen anschaue. > Nun bleibt nur noch die Frage, warum meine AppVersion >immer so komisch aussieht, obwohl ich doch alles gesetzt habe und auch >mein klein genug ist (noch rund 2,5 kB frei, 1 kB für Bootloader, also >1,5 kB frei). Deine App und das Interface ermitteln die App Version >korrekt, nur die von deinem test Beispiel übernommene Code ermittelt >wohl Müll. Auch der gesicherte MCUSR ist müllig. Aber das sind >Kleinigkeiten, die löse ich noch mit der Zeit. Das gesicherte MCUSR muß unter WinAVR GCC exakt so geholt werden wie ich es gezeigt habe (könnte vielleicht auch von der WinAVR Version abhängig sein). In meinem Example benutze ich absichtlich die Zuordnung der einzelnen Funktion zu bestimmten Sections für den Linker. Damit stelle ich sicher das die Initialisierung durch den WinAVR Startup Code teilweise schon erfolgte aber der Stack noch nicht benutzt wurde. Das gesicherte MCUSR liegt ja an der ersten Speicherstelle im Stack. Hast du vor dem Auslesen nach meinem Vorschlag aber schon zb. eine Unterfunktion, also CALL, getätig ist dieser Inhalt nun mit der Rücksprungadresse überschrieben worden. Es ist halt nicht so einfach eine Methode zu wählen die einfach, schnell und Resurcenschonend funtioniert und dann noch keine Kollisionen mit zb. dem WinAVR Startup Code provoziert. Natürlich mus auch UseSaveMCUSR=1 gesetzt sein. Wie gesagt so wie es in meinem Example demonstriert wurde, exakt so, sollte es auch immer funktionieren. Und als Letztes könnte es auch der Fall sein das du schon den korrekten Inhalt des MCUSR siehst nur dieser für dich komisch aussieht. Einige AVRs speichern noch andere Bits in dieses Register, oder bei einem Powerup hast du gleich 3 Bits gesetzt, die für PowerUp, Ext. Reset und Brownout. Das war mir bis vor kurzem (bei der Entwicklung des Bootloaders) auch noch nicht so bewusst. Die Funktionen aus AVRootloader.h um die Versionsnummer auszulesen sind ein bischen umständlicher als notwendig, einfach aus dem Grund heraus unabhängig von der realen Speicheradresse der AppVersion zu sein. Sie ermittelt also zur Laufzeit die Adresse der AppVersion durch Auslesen der mit GetBootMsg zurückgelieferten Addresse. Damit wird der BootInfo Inhalt ermittelt um auf die Anzahl der FLASH Pages die der Bootloader benutzt zu kommen. Diese Anzahl wird mit der FLASH Page Größe multipliziert und von der höchsten FLASH Addresse plus -4/6 subtrahiert und schwups hast du die Adresse im FLASH an der die AppVersion steht. Nun, ziemlich kompliziert dafür sollte es universell sein. In deinem Falle, und ich mache es eigentlich auch immer so, lese einfach mit pgm_read_dword(0x?????) direkt mit fester hardcoded Adresse die AppVersion aus. Nicht schön aber effizient und funktionierend egal welche Lockbits gesetzt wurden. Ich musste nämlich feststellen das je nach WinAVR version der Compiler mit meinen Makros fehlerhaften Code erzeugt. Eventuell hast du auch nicht UseSpecialMsg=1, UseSpecialRead=1 gesetzt ? Diese Funktionen wären dann nötig. Erstens mal UseSpecalMsg=1 um diejenige Funktion zu aktivieren die die FLASH Addresse vom BootInfo: Label zurückliefert, inklusive Größe in Bytes davon. Dann UseSpecialRead=1 damit der eventuell vor dem Lesen mit LPM geschützte FLASH Bereich der Bootsection auslesebar wird. Je nach Fuses halt. Also ziemlich viel Aufwand und Resourcen und man sollte schon selber wissen ob einem dies auch Wert ist im Vergleich zu einem fixen pgm_read_dword(0x????) mit hardcoded und auf den aktuellen AVR bezogenen Source. Übrigens exakt dies ist der Grund warum die PC-Software die reale Adresse der AppVersion auch im Info Fenster anzeigt. Gruß Hagen
@Thomas, habe mir mal dein Projekt angeschaut, ich beneide dich für die Ausdauer eine so umfangreiche Dokumentation zu machen. Ist das kommerziell ? Und dann frage ich mich ob du als Muetze auch in der Delphi Praxis unterwegs bist und wir von anderer Seite her schon öfters mal Kontakt hatten ?
Hallo Hagen! Also die UseSaveMCUSR ist gesetzt und ich habe die Anweisung zum Wert holen direkt am Anfang der Main, aber bisher noch mit dem cli() zuvor. Ich habe das gerade mal verschoben und bin noch am probieren.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Wegen der App Version vom AVR aus auslesen - nun ja, was soll ich sagen, die UseSpecialMsg war nicht gesetzt, obwohl mir das beim anschauen deiner Sources bei dem Test Projekt schon aufgefallen und bewusst war, dass du die Funktion brauchst. Nun ja, mein Fehler. hust Und wegen dem Projekt: Das ist noch der alte Stand, neue Doku (umfangreicher, dann auch zweisprachig) ist fast fertig und die Software auch entsprechend. Das derzeitige ist wirklich noch alt. Aber ich denke mal, ich versuche mal meine ganzen Erkenntnisse zu deinem Bootloader die ich hier gewonnen habe vllt. auch nochmal zusammen zu fassen. Und ja, der bin ich (es kann nur eine Muetze1 geben ^^). Wir hatten schon öfters mit einander zu tun und deshalb ja auch schonmal den Hinweis auf einen Thread bei der dp.net (also DelphiPraxis.net) bezüglich ein paar Schwierigkeiten mit der DEC. Und das ganze Projekt ist nicht kommerziell. Eigentlich auch schön doof, da ich dazu erst gekommen bin, da mich ein Freund fragte, ob man da nicht was machen kann bezüglich dieser Steuerung beim Aquarium. Es gibt genug Systeme, z.T. mit weniger Umfang bzw. weniger Möglichkeiten, aber alle haben eins gemeinsam: Startpreis bei rund 150-200 €. Eigentlich könnte man das Projekt vllt. doch nochmal etwas professioneller aufbauen und die Geräte schonmal zusammenstellen, die Gewinnspanne bei einem fairen Preis von 50-100 Euro wären noch recht immens... Danke mal wieder für die guten Hinweise - vor allem da der AppVersion Fehler mal wieder bei mir lag - schlimmer noch: es war mir schonmal bewusst... Gruss, Thomas
Mache es so
1 | |
2 | |
3 | |
4 | |
5 | |
Damit erzeugen wir erstmal eine "Procedure" die ohne Stackframe oder Return kompiliert wird, also nur das nackige _MCUSR = *(uint8_t*)(RAMEND); enthält. Dieses Codestückchen wird nach einem Teil der Initialsierung durch den WinAVR Startup Code und bevor der Main() Code kommt durch den Linker relokiert. Somit ist sichergestellt: Du als programmierer der keine speziellen Sachen macht sondern ganz stink normal WinAVR benutzt hat keine Chance den Stack noch vor dem Auslesen des gesicherten MCUSR register zu zerstören. Das könnte in deinem Main der Fall sein ohne das du es dir bewusst bist. Nicht schön aber der einzigst gangbare Weg unter WinAVR mit der geringsten Fehlerwahrscheinlichkeit. Das ganze Problem entsteht weil wir das MCUSR Register eben löschen müssen (bzw. zumindest das WDR Bit) und es nicht wieder setzen können. Löschen wir das WDR Bit nicht so bleiben die nachfolgenden Schreibzugriffe um den WDT zu programmieren erfolglos. Da der WDT eine gültige RESET Source ist und die eigene Anwendung auch unabhängig vom Bootloader eventuell wissen muß welcher RESET ausgelösst wurde, wir dieses Regsiter also löschen müssen damit der Bootloader den WDT programmieren kann und der WinAVR eg. Programierer den Stack unbeabsichtigt zu früh überschreiben könnte, wir auch keine Register für unsere Zwecke mißbrauchen können, verbleiben nur sehr wenige Alternativen unser Ziel zu erreichen. Und der jetzige Weg ist der einige der in meinen Augen übrig bleibt und die wenigsten Seiteneffekte hat. Auf einigen AVR gibt es 3 zusätzliche Register im Addressbereich der Ports die man hätte dafür benutzen können aber exakt diese wertvollen Register wollte ich mir für meine Projekte aufheben, zumal nicht jeder AVR solche hat. Auch die Option UseBootMode baut darauf das das MCUSR Register im Bootloader gelöscht wird. Diesesmal nicht nur bezogen aud das WDR Bit sondern auch auf alle anderen RESET Sourcen. Denn je nach UseBootMode selektieren wir ein Event das bei nicht programmierten AVR, also ohne Anwendung, wenn wir es nicht löschen würden den Bootloader dann aussperrt. Der Bootloader würde dann zb. nur auf den Borwout RESET reagieren und nicht mehr auch wenn er garkeine Anwendung vorher schon installiert hat. Dh. UseBootMode stellt sicher das der Bootloader beim RESET und eben auch bei nicht vorhandener Anwendung ausgeführt wird. Diese zweite Möglichkeit tritt aber nur auf wenn der Bootloader quasi eine nicht vorhandene Anwednung aufruft dann durch die 0xFF im Anwedenungsflash wquasi wieder in sich selber reinläuft und bei diesem zweiten Aufruf auf ein MCUSR register trifft das 0 ist auf Grund dessen das es beim ersten Aufruf gelöscht wurde. Naja, ziemlich viel worte für diese einfachen Sachverhalte. Meine init_WDT() Procedure wird noch weiter vor verlegt, also noch früher ausgeführt nämlich noch bevor der WinAVR Startup Code den SRAM initialisert, also .data und .bss (preinitialisierte globale Variablen/Strings etc.pp.). Mit langsamen Takt und schnellem WDT ist das zu präferieren. Gruß Hagen
Übrigens das CLI() ist nicht notwendig, erst recht nicht wenn du meinen Vorschlag benutzt.
Gast
#1260208
Hi Hagen, habe die Options mal auf 3 gesetzt. Ergebnis siehe Protokollfile.
Gast
#1260249
Sorry für das riesen File! ;)
er bekommt keine Verbindung, bzw. der AVR antwortet nicht. Also verbinde RX-TX Pin vor dem AVR, natürlich ohne AVR. Versuche erneut einen Connect und es müsste im Protokoll zu sehen sein das er 1.) zum 1-Wire Modus wechselt, 2.) die Daten die er sendet einmalig auch wieder empfängt. Wenn dies nicht so ist dann stimmt irgendwas mit einem COM Port, Hardware, Windows Setup nicht. Gruß Hagen
Gast
#1260473
Hi Hagen, die Hardware ist OK. Ein Testprogramm mit USART des m32 funktioniert perfekt. Wie gesagt: im gleichen Steckplatz, mit gleichem Bootloader (nur .inc und Codegröße geändert) läuft es auf dem m644P ja. Nur der m32 will nicht. Ist kein Beinbruch, werde den m32 durch m644P ersetzen (ist ja keine Großserie).
@Thilo, Das sind zu wenig Informationen. Schaue dir mal deine Postings selber an. Du hast einen lauffähigen Bootloader für Mega644, tauscht diesen in deinem Board mit M32 aus, änderst logischerweise im AVRootloader.asm auf den M32, und es geht nicht. Protokoll zeigt auch das es nicht geht, der M32 antwortet nicht. Tja das ist das was ich an Infos habe. Ich kann dir versichern, mit den fortschreitenden Versionen wurde die Benutzerschar immer größer und auch das Feedback mit welchen AVRs in welcher Konfiguration der Bootloader schon eingesetzt wurde. Der M32 ist darunter. Es muß also bei deinem Aufbau irgendwas falsch laufen. Lösche alle Dateien bis auf die Sourcen und Konfigurationen. Dann kompiliere das AVRootloader.asm nochmal neu mit BootCodeSize=0 und dann nochmal mit dem Wert aus CSEG used. Stelle dann sicher das du auch wirklich das korrekte HEX File auf deinen M32 installierst und nicht eventuell eine der vielen anderen Kopien aus den vielen anderen Ordnern ;) Ich kenne die Arbeitsweise mancher Programmierer und da kann man schonmal mit den Kopien durcheinander kommen, ich muß ja auch öfters so arbeiten. Besonders weil AVRStudio in der Pfadangabe zum HEX File sich die alten Einstellungen merkt und nicht diejenge zum Projekt. Gruß Hagen
Hallo Hagen! Ich habe es nun auch endlich hinbekommen den MCUSR Code von deinem Bootloader sauber in meinen Code zu bekommen. Als erstes hatte mich an deinem folgenden Code schon immer verwundert, warum du eine init_MCUSR() deklarierst mit den schönen Attributen von wegen früher Ausführung und Init, aber das eigenliche Lesen wiederrum machst du in einer init_prots() ohne all' diese schönen Attribute. Nun ja, somit wird diese Routine wohl auch nicht aufgerufen. Dein Code den du vorgeschlagen hattest:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Und von daher habe ich es so umgeändert, dass es nun nur noch die eine Routine gibt, welche dann auch die Attribute hat von wegen init5 Aufruf, etc.
1 | |
2 | |
3 | |
4 | |
5 | |
Das läuft aber so noch nicht richtig, da die Variable ja eine globale ist und somit mit 0 initialisiert wird. Also muss man diese globale Variable davon noch ausschliessen - mal wieder mit Attributen.
1 | |
2 | |
Das ist aus dem Header, daher das "extern". Die Deklaration in der .c Datei kann man sich ja denken. Damit klappt dies nun einwandfrei und ich kann auslesen ob ich von deinem Bootloader komme, eigener WDT Reset, Brown Out oder direkt gestartet. Klappt nun einwandfrei. Das ganze Firmware Update etc ist nun auch stabil und läuft super integriert in meinem Client. Also, danke nochmals für den super Bootloader! Gruss, Thomas
Sorry muß heisen
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
Du musst dann nicht darauf achten ob gvaResetFlags mit 0 überschrieben wird oder volatile deklarieren. Der Init Code des GCC der die globalen Variablen mit 0 initialisert wird in einer Section gelinkt die noch vor der Section .init5 kommt. Dh. der obige Code sollte nach der Initialisierung des GCC aber vor der Main() aufgerufen werden. Gruß Hagen
Hallo Hagen! In deinem Test Projekt ist auch alles richtig drin. Nun ja, ich hatte mich halt auf das Beispiel aus diesem Thread gestürzt. Ich hätte da eine "declared but unused" Warnung vermisst... Ansonsten das mit der 0 Initialisierung des Startup Codes, das kann gut sein, da ich das mit dem Reset Code nebenbei mit ein paar anderen Änderungen an der Firmware gemacht hatte. Von daher werde ich das gleich nochmal wieder entfernen. Jetzt muss ich nur noch klären, warum die AppVersion über den Controller ausgelesen immer eine total komische Zahl ergibt. Dazu doch gleich mal eine neue Frage: Wenn ich über dein Interface eine neue Firmware flashe, diese aber nicht verschlüsselt ist und direkt ein HEX file gegeben wird (kein ACY), dann kann ich die gewünscht AppVersion in der Methode des Interfaces zurück geben, oder? Weil soweit ich verstanden habe, ist die Masked Option zum überprüfen vor dem Flash nur bei verschlüsselter Firmware von nöten, somit sollte er bei mir die neue Version nur abfragen. Sehe ich das richtig? Also bei dem Masked Parameter auf true, gebe ich dann 0 zurück und im anderen Falle die neue AppVersion? Gruss, Thomas
Bei Masked=TRUE solltest du in diesem Falle $FFFFFFFF = -1 zurück geben. Allerdings wird .GetAppVersion(True) ausschließlich nur dann aufgerufen wenn der IAVRootloader Daten verschlüsseln muß. Es gibt zwei Momente in denen das passieren kann, erstens man erzeugt and ACY File und der verbundene AVR unterstützt die Verschlüsselung, egal ob er auch unverschlüsselte Daten zulässt oder nicht. Zweitens, der AVR soll mit einem HEX File geflsht werden und erwartet zwingend verschlüsselte Daten. Dann wird IAVRootloader das HEX File intern und temporär in einem Stream speichern und ein verschlüsseltes ACY kompilieren. Ganz genau genommen wird intern bei einem HEX/EEP immer ein ACY Stream erzeugt, so als wenn man den Compile Button erzeugt. Meine .DoProgram() Methode arbeitet intern also immer mit einem ACY Script. Dies ist entweder im Speicher temporär erzeugt oder eine reale ACY Datei in den Speicher geladen. Wenn also Masked=True ist so sollte deine Methode entweder $FFFFFFFF zurückgeben und damit die Versionüberprüfung im AVR Bootloader defakto deaktivieren. 0 wäre grundsätzlich falsch da es bedeuten würde das du die kleinste Versionnummer benutzen möchtest. Wenn nun schon Version 0.0.0.1 installiert ist so würde der AVR Bootloader die Version 0.0.0.0 nicht akzeptieren und den programiervorgang abbrechen. Gibst du zB. $01FF02FF zuück so überprüft der AVR intern das die aktuell installierte Version klein oder gleich 1.?.2.? ist. Dh. installierte Version wie 1.0.2.0, 1.123.2.15 usw. wären gleich. Wäre die installierte Version aber 1.?.3.? oder 2.?.?.? dann wäre sie größer als die zu installierende Version. Gibst du ohne die $FF Masken die gleiche Versionsnummer wie bei Masked=FALSE zurück, also zb. 1.2.3.4 dann überprüft der AVR also auch alle 4 Zahlen mit der installierten Version. Ergo: gib -1 oder $FFFFFFFF bei Masked=True zurück und du hast keine Probleme da die Versionüberprüfung im AVR dann deaktiviert ist. Diese Überprüfung erfolgt nur bei verschlüsselten Daten. Beim Auslesen der AppVersion in der eigenen AVR Anwendung gibt es zwei Wege: 1.) der direkte Weg: pgm_read_dword(0x???????) oder pgm_read_dword_far(0x??????) wenn mehr als 64Kb FLASH vorhandeen, oder RAMPZ auf 1 setzen und mit pgm_read_dword() arbeiten. Die Adresse 0x?????? findet man im Info Fenster meiner PC-Software wenn man mit dem AVR verbunden ist. Dieser Weg funktioniert immer egal welche zus. Features im Bootloader aktiviert/nicht aktiviert wurden und egal welche Lockbits man im AVR gesetzt hat solange der LPM Opcode für die Applikation freigegeben ist. 2.) der indirekte Weg: über die Funtionen in AVRootloader.h. Dazu muß aber zwingend der Bootloader mit UseSpecialMsg=1, UseSpecialRead=1 und UseSpecialBootVect=1 konfiguriert sein. Wie diese Funktionen dann benutz werden um dynamisch die Adresse der AppVersion im FLASH zu berechnen habe ich in einem vorherigen Thread schon beschrieben. Ich würde den direkten Weg gehen, ist simpel, verbraucht weniger Code in der eigenen Anwendung und die UseSpecialXXX Funktionen müssen nicht zwingend in den Bootloader eingelinkt werden, was wiederum im Bootloader Code spart. Konzeptionell habe ich in AVRootloader.h nur deshalb diese Implementierung gemacht damit man dieses Header benutzen kann für die Programierung einer universellen Bootloader-Update-Anwendung. In diesem Moment würde der Bootloader sowieso die UseSpecialXXX Funktionen einlinken damit er durch diese Anwendung updated werden kann. Es ist dann hilfreich wenn diese Update-Anwendung auf universelle Weise die wichtigen Daten wie die BootMsg, BootInfo und AppVersion ermitteln kann, unabhängig vom jeweiligen AVR Typ und den anderen Einstellungen des jeweiligen Bootloaders. Gruß Hagen
Hallo Hagen! Danke mal wieder für die Ausführungen. Erstmal zu dem einfacheren Thema: Die AppVersion will ich weiterhin mit deinen Beispielquellen aus dem Test Projekt auslesen, da diese allgemeingültig sind. Ich müsste sonst desto mehr den Personen X erklären, welche das Projekt auf einem anderen Mikrocontroller nachbauen wollen. Von daher würde ich die direkte Methode vermeiden wollen. Und nun nochmal zum anderen Thema: Meine Frage war eher: wenn ich nun eine neue Version auf den AVR bringe, wie und wo kann ich die neue Versionsnummer festlegen? Also die Versionsnummer, welche dann auch im Atmel Flash abgelegt wird. Die Frage interessiert mich vor allem, da ich es bisher noch nicht gelöst habe. Gruss, Thomas
Ich gehe davon aus das du mein IAVRootloader Interface benutzt. Deine IApplication Impelemtierung muß die Methode .GetAppVersion(Masked: Booelan): Integer auch implementieren. Wenn Masked = FALSE dann gibts du die neue Versionnummer als 4 Bytes Wert zurück. Wenn Masked = TRUE dann gibts du die gleiche neue Versionsnummer zurück aber alle Bytes die nicht überprüft werden sollen werden mit $FF ODER verknüpft. Ich habe angenommen das dir das schon klar ist. Falls du dich nicht auf IAVRootloader beziehst und meine PC-Software meintest dann geht die so: Auf der 1. Page sind 4 Edit Felder mit der neuen Versionsnummer. In diese nun die Versionsnummer eingeben. Die 4 Checkboxen rechts daneben stelen die Maskierung in der Abfrage auf dem AVR dar. Jeweils die entsprechende Checkbox anhacken deren Versionsnummerbyte überprüft werden soll. Das Überprüfen der Versionsnummer ist aber nur aktiv wenn mit Verschlüsselung gearbeitet wird. Alternativ kann man die PC-Software auch per Kommandozeilenparameter aufrufen. Der Parameter -V definiert die neue Versionsnummer. zb. -V0102A0FE0C definiert die neue Versionsnummer 1.2.160.224 und der letzte HEX Wert 0C die Bitmaske der anzuhackenen Checkboxen und damit auch welche der 4 Bytes überprüft werden muß. In diesem Falle also die beiden höchstwertigen Zahlen 1.2. die überprüft werden sollen. Nun, diese neue Versionsnummer wird beim nächsten Programmieren des FLASHs über den Bootloader programmiert. Es gibt keine Schnittstelle im Protokoll diese Versionsnummer unabhängig zu programmieren. Defakto ist es ja auch logisch denn auch die Versionsnummer befindet sich im Anwendungsflash. Du kannst meinen AVRootloader.asm Source auch erweiteren um eine eigene kleine Spezialfunktion die direkt die AppVersion als DWord zurückgibt. Das könnte so aussehen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Diese Funktion gibt in den Registern r25:r24:r23:r22 die AppVersion zurück. In Special.inc muß dann am Ende die Vektortabelle geändert werden:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Nun noch UseSpecialVersion als Define in AVRootloader.asm eintragen und die Codegrößenberechnung am Anfang von Datei Special.inc erweitern. In AVRootloader.h dann folgende Erweiterungen
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
Vorteil dabei ist es das wenn man UseSpecialRead=0, UseSpecialWrite=0 setzt ,so denoch auf einheitlichem Wege über den Bootloader an die Version herankommt und dabei weniger an FLASH im Bootloader wie auch in der eigenen Anwendung verbraucht. Hm, ich weise nur ungern darauf hin das ich mich wiederhole. Alle diese Informationen findet man wiederholt hier im Thread erklärt. Ich nehme also an das ich nicht in der Lage bin einen Sachverhalt verständlich zu erklären oder meine ausführlichen Erklärungen nicht ordentlich gelesen werden ;) Gruß Hagen
Hallo Hagen! Nein nein - das mit der AppVersion hatte ich auch schon so probiert, um die neue Version zu setzen. Ich war mir nur nicht sicher, ob es der richtige Weg ist, da er bei mir immer wieder eine andere Versionsnummer zurück bekommen. Von daher war ich am zweifeln, ob das setzen so richtig ist. Von daher wollte ich nur eine Bestätigung, dass die Version so gesetzt wird (hatte ich ja auch so beschrieben zwei Beiträge von mir zuvor), nur das ich den Teil mit Masked = true etwas missverständlich dargelegt hatte - obwohl ich es schon so verstanden hatte wie du es zuvor und danach erneut beschrieben hast. Und mit der AppVersion setzen habe ich nach nun schon dreimaligen Lesen des gesamten Threads nie eindeutig rauslesen können, da es immer nur im Zusammenhang mit ACY bzw. vor allem verschlüsseltem Bootloader genannt wurde, aber nie für unverschlüsselte Bootloader. Ich hatte es ja schon richtig vermutet und wollte dies nur bestätigt haben, nur leider hattest du den ganzen anderen Teil nochmals ausführlich erklärt... Es tut mir leid wenn es zu Missverständnissen gekommen ist. Und ich entschuldige mich auch, wenn ich die Fragen vllt. ungenau stelle. Ich habe diesen Thread nun schon dreimalig komplett gelesen und versuche von daher nur noch offene Dinge zu fragen. Danke nochmals für das Beispiel mit der Anpassung des Bootloaders. Ich hoffe ich kann den Bootloader dann als ganzes (u.a. mit angepasstem Code von dir) mit beilegen. Aber ich denke auch, dass ich keine weiteren Fragen haben werde.
Hey schon gut, wollte mal nur Luft rauslassen ;) Die AppVersion wird durch dynamisches Patchen des HEX Files programmiert. Geht auch garnicht anderst, da ansonsten wegen den 4 Bytes im Bootloader eine ganze FLASH Page erst gelesen dann im Speicher geändert und wieder programmiert werden muß. Um also nicht eine solche zusätzliche Funktion in den AVR Bootloader programmieren zu müssen, oder eine FLASH Auslesefunktion im Protokoll zur Verfügung stellen zu müssen (Sicherheitsproblem), habe ich eben den Weg gewählt die AppVersion nur im Zusammenhang mit dem Programmieren der eigenen Anwendung aus dem HEX setzen zu können. Die .GetAppVersion(True) wird nur aufgerufen wenn ein HEX File zu einem ACY verschlüsselt werden muß. Ob dies als Datei gespeichert wird hängt nur davon ab ob der Compile Button gedrückt, .Methode .DoCompile() aufgerufen wurde oder der Program Button gedrückt, .Methode .DoProgran() aufgerufen wurde. Intern erzeugt die Software also in jedem Falle ein ACY als Speicherstruktur die entweder wie ein Script sofort ausgeführt oder als Datei gespeichert wird. Ob dieses ACY Script nun verschlüsselt oder unverschlüsselt erzeugt wird hängt vom Feature des Bootloaders im AVR ab. Je nachdem wird also .GetAppVersion(TRUE) aufgerufen oder nicht. Hoffe das dies verständlicher rüber kommt, kenne solche Kommunikationsprobleme zur Genüge in meiner täglichen Arbeit ;) Gruß Hagen
Gast
#1279168
Hi Hagen, betrifft >@ Hagen Re: >Ich hab' jetzt nicht den ganzen langen Thread durchforstet, daher frag' >ich dich einfach: >entweder habe ich Tomaten auf den Augen oder ich check's nicht, aber >dieselbe Einstellung wie auf dem Bild funktioniert auf mehreren mega644P >problemlos, '.inc' - File vom mega32 aktiviert (644 deaktiviert) läuft >nicht auf dem mega32 (16MHz) (siehe Protokoll). Benutzt wird RS232 mit >max232, µC und Verbindung ist OK. >Kannst du mir sagen was ich übersehen habe? Habe den Fehler gefunden. Es lag am USB-RS232-Treiber (FTDI-Chipsatz). Trotz der selben Hardware läuft der Treiber auf einem anderen Notebook nicht mehr sauber. Mit dem ursprünglichen Notebook funktioniert alles prima. Ich hoffe das hilft dir, falls ähnliche Fragen in dieser Richtung kommen. Gruß Thilo
Gast
#1296106
Kleiner Nachtrag: durch setzen der CKOPT - Fuse lässt er sich jetzt auch mit allen USB-RS232 Adaptern programmieren. Irgendwie scheint die Startup-Zeit (Quarz-Anschwingen) nicht ganz gepasst zu haben.
Hallo, Versuche leider ohne Erfolg, beim starten des Bootloaders Pin6 von PortD dauerhaft auf Low zu ziehen, muss dazu sagen das ich nicht wirklich viel Ahnung von ASM habe schreibe meistens alles in C
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
Register r16 ist benutzt für paral, kannst du an dieser Stelle nutzen, solltest du aber im weiteren Source unterlassen. Gruß Hagen
Gast
#1303047
Hallo, Gute Arbeit mit dem Bootloader, Hagen! Funktioniert sehr gut! Jetzt habe ich mal eine Frage: Ich habe mir einen Asuro Roboterbausatz gekauft wo ein Atmega8 drauf ist. Diesen Atmega8 kann man beim Asuro mit Infrarot programmieren. Die Entwickler habe da einen Bootloader draufgepackt der das Programmieren per Infrarot möglich macht. Dieser Bootloader ist aber nicht quelloffen und nur für Atmega8. Ich habe nun diesen Asuro Roboter durch einen Atmega32 erweitert und mit einer ISP und RS232 Schnittstelle bestückt. Auf dem Atmega32 ist AVRootloader drauf und das Programmieren über die RS232 Schnittstelle funktioniert sehr gut. Ich wollte nun deinen Bootloader so erweitern das ich die TX Signale über Infrarot sende. Dafür ist eine Infrarot-LED mit dem TX-Port und einem Timer-PIN vom Atmega32 verbunden. Über den Timer-PIN wird 36khz Frequenz moduliert und über den TX-PIN kommen ganz normal die TX-Daten. Wenn ich jetzt ein Programm schreibe wo ich etwas über IR-Senden will, aktiviere ich nur die Modulationsfrequenz und sende die Daten ganz normal über UART. Und es klappt Hardwaremäßig auch! Damit das ganze funktioniert habe ich mir gedacht das ich im Bootloader nur die Modulationsfrequenz am OC2 aktivieren muss damit das ganze auch über IR läuft. (Denn die TX-Daten sollten ja genauso wie bei einer Kabelverbindung kommen.Oder?) Ich habe das ganze eingefügt aber es funktioniert nicht? Was mache ich falsch? (Wie gesagt über Kabel funktioniert das ganze!) Hier die Änderung im Quellcode:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
@rubiktubik: Das wird leider so nicht funktionieren. Der Bootloader benötigt eine bidirektionale Verbindung und deine IR Strecke geht ja nur in eine Richtung. Du könntest alle Sendedaten im Bootloader in's Leere laufen lassen und nur die Empfangsdaten berücktsichtigen, das würde gehen, mit der Einschränkung das alle Lesefunktionen wie EEPROM oder SRAM lesen nicht mehr gehen. Auch dein IR Sender müsste von Anfang an exakt wissen für welchen AVR die gesendeten Daten bestimt sind da die vom AVR gesendeten Daten -> BootInfo nicht empfangen werden können. Auf alle Fälle ist es mit dem Stückchen Code nicht getan und ehrlich gesagt verstehe ich auch garnicht was du damit bezwecken möchtest. Was hast du denn für Software auf der IR Sendeseite ? Falls du es mit dem Asuro Bootloader probiert hast dann kann das garnicht funktionieren. Du müsstest mir schon deinen kompletten Aufbau erklären damit ich dir weiterhelfen kann. Gruß Hagen
Gast
#1303698
Hallo, Der Sinn der Sache ist das ich meinen Asuro per Infrarot programmieren kann. Normalerweise ist im Asuro der Atmega8. Mit diesem kann die Asurosoftware IR-Software was anfangen. Beim Atmega8 funktioniert das ganze so, dass auf eine IR-LED eine Modulationsfrequenz und ein TX Signal gegeben wird. (Siehe Anlage und Asurowiki) Ich habe jetzt einen Atmega32 an den Asuro gebaut. Auf dem Atmega32 habe ich deinen Bootloader drauf und ich kann per Kabelverbindung(RS232) den 32er programmieren. Ich mir das so gedacht das: Dein Bootloader sendet auch über TX und RX. Das heisst das ich nur noch im Bootloader die Modulationsfrequenz aktivieren muss und das gleiche Signal was normalerweise durchs Kabel geht, geht jetzt durch IR. Das was der Bootloader macht ist ja das Senden der Daten über RX und TX. Wo die letzendlich durchgehen(Kabel oder Infrarot) ist dann egal. Was ich natürlich nicht bedacht habe, ist das deine Windowssoftware zum erkennen eines gültigen(CONNECTED) Signals auch eine RX Leitung benötigt. Wenn ich die RX-Leitung auch noch über IR verbinde müsste es doch gehen? Hier die Asuroseite für die Asuroseite: http://www.asurowiki.de/pmwiki/pmwiki.php/Main/Infrarotschnittstelle Und die PC-Seite http://www.asurowiki.de/pmwiki/pmwiki.php/Main/InfrarotRS232Transceiver Im Anhang: die Beschaltung der IR-LED.
Die wesentliche Frage ist doch warum du überhaupt IR benutzen möchtest ? Sie ist langsammer, störanfälliger und kostet dir auch noch zusätzlichen Aufwand. Das was mich interessiert ist die Frage wie sieht die Gegenstelle hardwaretechnisch aus. Deine Links sind gut&schön aber wenig hilfreich für mich um sehr schnell einen Überblick zu erlangen. Immerhin kannst du ja nicht verlangen das ich mich jetzt Stunden mit deinem Problem befasse noch dazu wenn ich keinen Sinn darin sehe. Also: auf PC Seite wie wird dort der IR Port umgesetzt? Wenn er nur die RS232 nach IR umsetzt dann dürfte das sehr wohl gehen, denn so wie es aussieht hat der Asuro ja einen TSOP als Empfänger und eine IR SendeLED als Sender integriert. Es geht also halbduplex bidirektional. Du solltest den ATMega32 mit externen Quarz betreiben, UseAutoBaud=0 und BootBaudrate=2400 setzen. Eventuell musst du UseUartInvert=0 oder 1 anpassen je nach Pegel die vom TSOP ankommen. Auch die Anschaltung der IR-SendeLED ist entscheidend also an welchem Pin deren Anode hängt. Wenn das mit den Pegeln korrekt eingestellt wurde dann sollte das sogar funktionieren. Entscheidend ist die PC Seite. Am besten einen RS232 zu IR Umsetzer damit du meine PC Software benutzen kannst. Mal angenommen die Probleme mit den richtigen Pegeln, Baudrate, PC-Seite mit RS232<->IR Wandler sind gelösst dann wird das auch funktionieren. Denn der Rest ist eine halbduplex bidirektionale Kommunikationsstrecke und das benutzte Protokoll des Bootloaders unterstützt diese Kommunikationsart. Dh. in deinem Falle könntest du zb. auch das EEPROM lesen und schreiben über IR. Gruß Hagen
Hab gerade den PC teil gefunden. Scheint ja nicht so sauber zu funktionieren und die Hardware ist ja wirklich einfachst und damit störanfällig aufgebaut. Probier es, aber empfehlen würde ich dir sowas nicht da es nicht als "professionell" zu bezeichnen ist. Mit viel Fuggelei ist es aber sicherlich zum Laufen zu bekommen. Wenn ich das richtig sehe so musst du UseUartInvert=0 setzen, also mit physikalischen Pegeln der RS232 arbeiten. Öffne AVRootloader.ini und setze dort [Timeouts].Option = 1 damit du in der PC-Software siehst was empfangen wird bei einem Connect. Vom Aufwand her, der Stabilität usw. würde ich dir ja den RS232-1-Wire Modus des Bootloaders empfehlen. Der geht bis maximale Baudrate sauber und wie im 1-Wire.png Schematik zu sehen ist benötigt der auch wesentlich weniger Bauteile. Auf deinem Board benötigst du dann nur einen 2-Pin Stecker. Gruß Hagen
Gast
#1303905
Hallo, Danke für die schnelle Antwort. Es ist mir klar, dass das mit Infrarot nicht gerade die beste Lösung ist. Ich habe bei meinem Asuro auch ein paar Änderungen am Sender und Empfänger gemacht um das Signal sauberer und stabiler zu Übertragen. Der Sinn der Sache ist der das ich beim Programmieren immer ein Kabel an den Asuro anschliessen muss. Wenn ich also kurz was testen will, muss ich das Kabel anschließen, programmieren und zum ausprobieren wieder abschliessen. Beim nächsten Test (z.b. Ein Wert im Programm geändert) muss ich wieder das Kabel anschliessen usw. Was es beim original Atmega8 IR-Flashprogramm noch gibt ist die Funktion: "Transfer only new pages" ich denke mal das er nicht die ganze Datei komplett überträgt sondern nur kleine Teile die sich geändert haben z.b. ein Wert einer Variable. Dann ging das Programmieren recht schnell. Ich weiss nicht wie das bei dir funktioniert!? Aber danke für die Tipps!
Eine solche Funktion ist nicht implementiert wobei das Protokoll sowas unterstützt. Dh. man müsste nur die PC Software leicht umschreiben um sowas ebenfalls zu unterstützen der komplette Rest der Software könnte es jetzt schon. Das Problem mit einer solchen Funktion ist das auf der PC Seite die alte HEX und das neue HEX vorliegen müssen. Denn nur so kann die PC Seite ohne den FLASH erneut auslesen zu müssen die Differenzen zwischen Alt und Neu ermitteln. Aus meiner Sicht hat eine solche Vorgehensweise aber gravierende Probleme die man erstmal sauber lösen muß. 1.) was ist wenn das alte HEX File nicht mit den Daten im FLASH 1 zu 1 übereinstimmt ? Die Bootloader Software würde bei der Übertragung der Differenzen somit eher den AVR und dessen Program zerstören. Das müsste nun extra abgesichert werden. ZB. per Prüfsummen über den FLASH Inhalt der durch die PC Seite abgefragt wird. Diese Prüfsumme wird abgefragt jeweils vor dem Programmieren um zu erkennen ob das angegebene alte HEX File auch wirklich mit dem FLASH übereinstimmt und auch nach dem Programmieren um zu überprüfen ob der neue FLASH Inhalt auch 1 zu 1 mit dem neuen HEX File übereinstimmt. Nun, Prüfsummen haben aber ein Problem denn es gibt defakto keine Prüfsumme die zb. 16Kb FLASH mit 100% Sicherheit abprüfen kann. Die einzige Prüfsumme die das kann würde ebenfalls 16Kb groß sein und damit 1 zu 1 der FLASH Inhalt den man erwarten würde. 2.) Sicherheitsproblematik. Eine solche Funktion öffnet einem Abgreifer eine Tür die er für seine Angriffe ausnutzen könnte. Da mein Bootloader aber exakt diese Sicherheitsproblematik lösen soll wäre ein solches Vorgehen also indiskutabel. Hier muß man abwägen zwischen dem einen und dem anderen Feature das man sich wünscht. 3.) "Transfer only new Pages". Die Wahrscheinlichkeiten im Alltag ! Ich meine damit den Punkt das die Wahrscheinlichkeiten im Alltag so gelegt sind das wenn sich eine Page verändert sehr häufig alle nachfolgenden Pages ebenfalls ändern. Da dadurch zb. viele Funktionsadresse im HEX reallokiert/verschoben werden und somit auch zb. die ISR EInsprungpunkte sich verändern ist die Wahrscheinlichkeit sehr hoch das sich die ersten FLASH Pages ändern und auch alle nachfolgenden. Das ist aber nur eine Vermutung meinerseits und man müsste dies erstmal praktisch ermitteln. Was ich aber damit aussagen möchte ist das ich meine das eine solche Funktion im Alltag der Programmierung eher weniger als mehr Sinn macht. 4.) was ist mit Anwendungen die sich selbst modifizieren können. Dh. also solchen Anwendungen die veränderliche Daten im eigenen FLASH abspeichern können. Nungut, mit solchen Anwdendungen hätte man eh ein grundsätzliches Problem auch mit meinem Bootloader der diese Daten einfach überschreiben würde. Mit der hier diskutierten Funktion und der Problematik einer Prüfsumme über den FLASH würde das dann dazu führen das die PC Seite die korrekte alte HEX Datei als ungültig erkennen würde und das Programmieren somit verweigert. Im gewissen Sinne ist diese Funktionalität also eher eine Augenwischerei um den vorher gebauten Schaden durch die Wahl der IR Schnittstelle abzuschwächen. Alles in Allem also aus meiner Sicht viele Indizien die ihre eigene Sprache sprechen. Ich möchte das wirklich nicht schlecht machen aber mal pragmatisch darüber nachgedacht sollte man schon zu ähnlichen Gedanken kommen. Du sprachst die Problematik an das du jedesmal einen Stecker dranstecken möchtest. Nun was für einen Unterschied macht es mit dem IR-Dongle auf wenige Zentimeter heran gehen zu müssen um mit 75% Wahrscheinlichkeit ein neues Program flashen zu können ? Das dann mit 2400 Baud statt mit 115200 Baud, mit höherer Fehlerwahrscheinlichkeit. Ich für meinen Teil erwarte von einem Bootloader als aller erstes und wichtigstes "Stabilität". Gruß Hagen
Für 20 Euro würde ich daher ein fertiges Bluetooth Dongle kaufen das RS232 unterstützt. Das drangepappt an die RS232 des AVRs und auf PC-Seite über einen virtuellen COM Port gearbeitet. Schon erledigen sich mit wenig Investitionen all deinen Probleme ;) Wenn du noch den RTS Pin am RESET des AVRs anschließt ist es eine Frage von 5 Minuten um die Konfiguration der Bootloader Software anzupassen, und schwups brauchst du noch nichtmal irgendeinen Taster auf dem Asuro drücken um die neue Software aufzuspielen. Gruß Hagen
Gast
#1305243
Hallo Hagen, ich versuche gerade ein kleines Kommanadozeilen-Tool unter Linux zu basteln welches EE-Prom-Daten über den Bootlader lesen und schreiben kann. Evtl. schalte ich da noch ein graf. Frontend davor. Das Lesen geht schon, aber nur weil ich die Sache mit der CRC hier ignorieren kann bzw. fixe Werte setzen kann. Leider komme ich mit der 16Bit CRC arg ins schleudern. Was ist denn das nun genau für ein Algo? Gibt es einen init-Vector und einen finalen Vector? Aus dem AVR-ASM werde ich nur bedingt schlau. Meine C-Routine wirft mit dem Polynom 0xA001 bzw. 0x8005 und verschiedenen Anfangswerten immer was Anderes raus. :-( Ist da noch ein Trick dabei oder übersehe ich da was? Gruß Fabian
InitVector = 0x0000 FinitVector = 0x0000 Polynom = 0xA001 Die empfangene CRC einfach mit durch den CRC Algo jagen und es muß 0x0000 rauskommen.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
das ist der vereinfachte code. Gruß Hagen
Gast
#1305619
Hallo Hagen, vielen Dank für den Hinweis und deine Mühen! Werde das mal vergleichen. bei diesem(deinem) Code wird schonmal anders herum geschoben... (Daher auch mein gespiegeltes Polynom) Denke damit komme ich klar. Gruß Fabian
Gast
#1305641
Hallo Hagen,
ich nochmal kurz:
Damit scheit es zu gehen zumindest stimmt mal eine Summe.
Kann dein Kurzer Blick ein OK geben?
Optimieren kann man ja immer noch...
uint16_t crc16(unsigned char* data, int length, uint16_t crc)
{
uint16_t poly = 0xA001;
int c, i;
for (c = 0; c < length; c++)
{
crc ^= data[c];
for (i=8; i>0; i--)
{
if (crc & 1)
{
crc >>= 1;
crc ^= poly;
}
else
{
crc >>= 1;
}
}
}
return crc;
}
Vielen Dank und viele Grüße
Fabian
@Fabian, sieht korrekt aus. Ich würde es aber so machen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
Das dürfte dem Compiler bei der Optimierung auf die Sprünge helfen. Idealerweise uint16_t crc -> R25:R24 und damit von Anfang an im Result, data in R23:R22 wird nach R31:R30 = Z per MOVW kopiert und später mit LD temp, Z+ bei crc ^= *data++ compiliert. length in R21:R20 kann im Kopf der while Schleife erstmal subiw R21:R20 dekreetiert werden und da unit16_t, also ohne Vorzeichen würde das Carry Flag die Abbruch Bedingung darstellen. Am Ende wird crc da es schon in r25:r24 steht direkt als Resultat zurückgegegen. In der innersten Schleife dekremtieren wir i was dem WinAVR mit Sicherheit zu einem besserem Code verhilft. ABER! das ist das was ich als Programmierer vom WinAVR GCC verlangen würde, erwarten würde ich dagegen das er erstmal kein MOVW benutzt, er die wihle Abfrage umständlicher lösst, er data nicht in X,Y,Z optimiert und damit kein LD mit Postinkrement des Zeigers macht, er am Ende CRC nach r25:r24 doppelt umkopiert ;) Macht man es in Assembler so könnte es so aussehen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
Gruß Hagen
Gast
#1306526
Hallo Hagen, vielen Dank für deine optimierungs Tipps. Da der Algo zunächst ausschließlich unter Linux/PC laufen wird, ist das mit dem Optimieren (solage es keine geliebte lib-Funktion wird) nicht so extrem heilig. Trotzdem sind deine Tipps für mich interessant da ich AVR-Seitig tatsächlich viel mit dem AVR-GCC (allerdings auch hier unter Linux ;-)) arbeite. Ich denke, dass die Umstrukturierung auch dem Linux-GCC auf die Sprünge helfen wird (werde mir das mal anschauen). Ich finde es toll, dass es offensichtlich doch noch Leute gibt, die sich den Assembler-Output regelmäßig anschauen um unnötige Code-Mengen und Laufzeiten gliech mal im Keim zu minimieren! Ach ja das Tool läuft nun! Die Summe wird nicht nur einmal korrekt berechnet ;-) Da fällt mir noch eine kleine Frage ein: Kann man mit dem Delphi-Tool in der Kommandozeile einzig nur das EE-Prom schreiben und lesen jeweils über Hex-Dateien ohne dass das Flash angefasst wird? Das würde mir das Kompilieren des geschriebenen Tools in einer Linux-Emulation unter Windows(mingw od. Cygwin) ersparen. Meine Versuche haben immer dazu geführt dass immer das Flash mit programmiert wurde. Nochmals vielen Dank für die Unterstützung! Fabian
>Kann man mit dem Delphi-Tool in der Kommandozeile einzig nur das EE-Prom >schreiben und lesen jeweils über Hex-Dateien ohne dass das Flash >angefasst wird? Müsste eigentlich gehen. Du musst als Flashfile dann einen Leerstring angeben, zb. so AVRootloader.exe -PCOM1 -B115200 -Dc:\test\ -EMy.EEP -F -Apc Allerdings eben nur schreiben, das Lesen ist nicht vorgesehen. Diese Funktion habe ich gleichmal in die ToDo Liste aufgenommen da ich anscheinend diese Funktion übersehen habe einzubauen. Du bist also an einem Linux Kommandozeilen Tool am schreiben. Wird dies alle Funktionen meiner PC-Software umsetzen oder nur den EEPROM lesen und schreiben ? Ich wäre nämlich daran interssiert das unter Linux alle Funktionen des Bootloaders unterstützt werden. Gruß Hagen
Hallo Hagen, für meinen Anwendungszweck muss ich das EE-Prom auch lesen können(read modify write). Zunächst habe ich (auch aus zeitlichen Gründen) nur vor das EE-Prom zu unterstützen (Funktional geht das aber derzeit nur mit 512Bytes auf nem Atmega168 bei fixer Baudrate von 19200). Da ich mit dem PortMon einfach nachgeguckt habe, was dabei abgeht und erst dadurch step by step interpretiert habe was jeweils im einzelnen passiert ist der erste Ansatz super quick n dirty... Allerdings bin ich gerade etwas am Aufräumen und Umstrukturieren. Ein Update des Flashes wäre eigentlich langfristig durchaus interessant auch für meinen Anwendungsbereich. Dann habe ich gestern Abend noch wxWidgets näher beleuchtet... da gibts auch Designer dazu um Frontends zu "Malen". Mein bisheriges GUI für den speziellen Anwendungsbereich ist noch in GTK+ flach in C implementiert und kommuniziert nun über Dateien mit dem Kommandozeilentool. Meine zur Verfügung stehende Zeit ist aber (leider) eher Begrenzt, daher ist es ungewiss wie weit ich da noch weiter komme. Als Kommunikation mit der Seriellen habe ich mir den AvrDude Code serial_posix.c genommen um schnell zum Zug zu kommen. Das passt aber teilweise auch nicht so ganz in meine Vorstellung, funktioniert aber. Für die Parameter wollte ich noch wenigstens "optarg" (eine lib) einbauen um hier wenigstens etwas sauberer zu werden. Gruß Fabian
Hallo, ich bekomme ab und an diese fehlermeldung, nach 6-7mal versuchen geht es dann einwandfrei, ich benutze bluetooth spp. gruss rudolf. > Connecting on port COM4... > Device connected > Program... > execute compiled data > selected options in compiled file: > - programming FLASH > - FLASH data are encrypted > - erase FLASH during programming > Cmd.SetAddr.ReadByte() ICOM: read error. > Device disconnected
@Rudolf: sieht nach Timing Poblemen aus. Da du über BT gehts und bisher du der Erste bist kann man schwer konkrete Tipps geben. Der Bluetooth Stack unter Windows ist ebenfalls so eine "Krücke" wie viele der USB-RS232 Treiber. Ich empfehle dir also mal die Werte in der AVRootloader.INI bei [Timeouts] zu erhöhen. Anfangen mit dem Wert Base=50 und diesen mal auf 100 setzen. Beim nächsten Mal bitte mehr Angaben posten, ist bischen dürftig deine Fehlermeldung. Dazu erstmal in AVRootloader.ini [Timeouts] Options=1 setzen. Diese Debugoption wird im Protokollfenster mehr Infos anzeigen lassen, wie zb. auch die Baudrate, den AVR, ob 1-Wire oder 2-Wire usw. die du benutzt und hier leider nicht verraten möchtest. Übrigens, da mit dieser Debug-Option düfte jetzt seinen 50'zigsten Geburtstag feiern, also zumindestens so oft wurde das hier im Thread schon besprochen ;) Gruß Hagen
Gast
#1311303
Bei mir lag's daran, dass der Quarz nicht recht anschwingen wollte und daher keine vernünftige Reaktion vom µC kam. Setzen der CKOPT-Fuse brachte Abhilfe.
Hallo Hagen, jedes Kind bekommt neue Wünsche :-) Siehst du irgendeine Möglichkeit, das Ganze auch über CAN zum Laufen zu bringen? Ist leider die einzige Schnittstelle, die ich habe. PC<->CAN-Dongle<->CAN-Bus<->MCP2515<->Mega32
CAN ist physikalisch RS485 ähnlich. RS485 wurde schon praktisch umgesetzt. Das verbleibende Problem beim CAN wie auch zb. DMX ist die Protokollschicht. Wenn du die Möglichkeit hast den "normalen Protokoll-Betrieb" temporär zu deaktivieren und solang der Bootloader arbeitet auch deaktiviert zu belassen, dann geht mein Bootloader relativ einfach für diese Systeme anzupassen. Ich empfehle immer folgende Vorgehensweise: PC-Software möchte einen AVR flashen und sendet das AppCmd aus der INI. Dieses AppCmd wurde als CAN/DMX etc.pp. Packet formatiert. Es aktiviert in allen AVRs einen Silent-Mode. Dieser Mode deaktiviert das normale Protokoll und bleibt solange aktiviert bis sich 2 Sekunden auf dem Bus nichts mehr gerührt hat (automatische Umschaltung in den normalen Protokollmode). Wurde das AppCmd empfangen so starten alle AVRs ihren Bootloader. Jeder AVR hat ein eigenes BootSign und auf das wird nur lesend im Bootloader gewartet. Wurde das richtige BootSign empfangen startet der eine AVR seinen Bootloader durch und übernimmt die Kontrolle über den Bus. Alle anderen AVRs starten nach einem Timeout ihre normale Applikation durch. Diese setzt ihren Receiver/Driversource bei einem RESET in den Silent-Mode, warten also die 2 Sekunden Ruhe auf dem Bus ab. Mein Bootloader wird innerhalb von 2 Sekunden (WDT Timeout) solange er connected ist immer irgendwas über den Bus senden. Dh. wurde 2 Sekunden lang nichts über den Bus gesendet dann heist dies eindeutig das die Connection getrennt wurde und der Bus wieder frei ist. Ergo braucht man nur ein Start Kommando und das wäre in diesem Falle das konfigurierbare AppCmd. Ein Stop Kommando ist nicht nötig durch den 2 Sekunden Timeout und dieser stellt auch sicher das sich nicht alles irgendwie tot rennt, eg. blockiert. Statt mit dem BootSign als eindeutige ID zu arbeiten geht das natürlich auch mit zb. der CAN Node ID. In diesem Moment müsste aber das AppCmd dynamisch um diese ID ergänzt werden so das nur die AVRs in ihren CAN-Drivern den Bootloader starten mit der gleichen ID. Das würde eine Änderung in meiner PC-Software bedeuten. Der erste Vorschlag würde nur eine Änderung in deiner Applikationsoftware, eg. CAN Driver, bedeuten. Wir gehen also von folgendem aus: - AVRs haben schon deine Anwendung drauf - Anwendung enthält einen CAN Driver - CAN Driver hat einen Silent-Mode in dem er nur wartet bis der Bus 2 Sekunden still ist, danach akzeptiert er wieder CAN Packete - CAN Driver wartet auf AppCmd Packete und startet Silent Mode und Bootloader - aus dem RESET startet die Anwendung den CAN Driver im Silent Mode - AVRs haben lange und unterschieldiche BootSigns - Bootloader und CAN benutzen gleiche Baudrate Somit wird wenn es der PC-Bootloader signalisiert der komplette Bus unter Kontrolle des Bootloader gesetzt und dann läuft darüber eine einfache RS232/RS485 halbduplex Kommunikation. Im Falle das auf dem AVR noch nicht deine Anwendung geflasht wurde wird der Bootloader die ganze Zeit nur lauschend am Interface hängen. Bis er das Bootsign empfangen hat. Also auch nur ein geringes Risiko von Bus-/Protokollkonflikten. Wie und ob das mit einem intelligenten CAN-Treiber geht kann ich nicht beurteilen. Wichtig ist nur das er das AppCmd Packet erkennt, dann durch AVR deaktiviert wird, er also alle Daten 1 zu 1 durchlässt. Ich weiß das dies nicht der beste Vorschlag sein kann, aber es ist auf jeden Fall der am einfachsten zu realisierende Vorschlag mit den geringsten Änderungen. Besser wäre die PC-Software umzuschreiben und an das jeweilige Protokoll anzupassen. Aber das bedeutet Aufwand und in meinem Falle auch die nötige Hardware um das alles zu testen. Mal abgesehen von meiner Zeit ;) Gruß Hagen
Sehe gearde das der MCP2515 ein CAN->SPI Wandler ist. Das dürfte dann schwieriger sein da die AVR Bootloader Software umgeschrieben werden muß auf SPI statt RS232/RS485. Würde man ohne das CAN Protokoll, eg. Frames und Packets, arbeiten können wäre diese noch relativ einfach möglich. Denn dazu müsste man nur die Pin/Ports und UART Routinen getc/putc umschreiben. Dh. sowas wäre dann wie bei einem UART->SPI Wandler Chip der 1 zu 1 die UART auf SPI mappt. Gruß Hagen
Gast
#1316237
Hallo Hagen, wäre es nicht möglich drei Funktionen im PC Programm zu schreiben und als ByteIN, ByteOUT, RTS auszuführen, die dann exportiert werden ? Dann könnte sich jeder eine DLL schreiben, die dann einfach die Funktionen kurz vor der Hardware auf ein anderes Interface umbiegt. Somit müsste man nichts mehr an der PC Software ändern ? In der Anwendung hätte man dann procedure DLLLoad(); function ByteIN(...) : Boolean; function ByteOUT(...) : Boolean; function RTS() : Boolean; procedure DLLFree(); Somit könnte man auch den CAN-Bus mit relative kleinem Aufwand programmieren. Gruß Sven
@Sven: ganz so einfach ist das leider nicht :( Konzeptionell denke ich habe ich einen besseren Weg beschritten, der auch die nötige Komplexität berücksichtigt. Wer es also möchte und ein bischen Ahnung von ActiveX/COM/DCOM Interfaces hat kann die AVRootloader.DLL benutzen. Mit ihr hat man nun die Möglichkeit ein eigenes ICOM = Kommunikationsinterface vorzugeben. Dh. die komplette Bootloader Protokollschicht ist weiterhin gekapselt und für das ICOM Kommunikationsinterface existieren klar vorgegebene Schnittstellen die man nur programmieren muß. Grundsätzlich könnte schon jetzt ein anderer Programmierer über diesen Weg deine simple DLL zusammenbauen. Aber auch das wird im Falle des Problems CAN->SPI nicht wirklich viel weiterhelfen. Denn grundsätzlich müssten alle Daten in Packete gekapselt werden die mit den entsprechenden Headern versehen werden müssen. Diese Kapselung der Daten und die Daten in deren Headern bestimmen an welche CAN Node diese Packete adressiert sind. Es muß, wenn man es wirklich richtig machen möchte, das komplette Bootloader Protokoll neu geschrieben werden. Sowohl die PC-Software wie auch AVR Software. Das was bei deinem Vorschlag und meiner AVRootloader.DLL nämlich fehlt ist das Kenntlichmachen wann ein solches Packet beginnt und endet. Denn nur so könnte die externe DLL oder eben das custom ICOM Interface im AVRootloader.DLL auf Protokollebene erkenne wann ein Header mit Adress-/Datengröße Angaben zu erzeugen ist und wann ein Packet zu Ende ist und mit einer CAN/DMX Prüfsumme zu versehen ist. Nun kommt noch das Problem hinzu das die maximale Packetgröße ebenfalls vom Protokoll abhängig ist. Das könnte dazu führen das ein Datenblock zu groß für das Protokoll ist und dann transparent durch das ICOM bzw. deine DLL in kleinere Packete zerstückelt werden muß. Auch hier muß man dann dynamisch Header/Prüfsumme davor/danach einbauen. Schlußendlich ein Weg der die Sache nicht vereinfacht sondern verkompliziert im Vergleich zu einer Lösung die direkt die AVR Sourcen und PC Sourcen und Protokoll direkt verändert. Ich denke für ein Hobbyprojekt hat sich mein Bootloader in eine relativ universelle und professionelle Richtung weiterentwickelt. Irgendwan kommt man aber an einen Punkt der auf Grund der ehemaligen Konzeption nicht mehr überschritten werden kann, bzw. es keinen Sinn macht noch weiter zu gehen. Nun CAN-SPI wäre wohl dieser Punkt. Wenn es die packetbasierte und adressierbare Protokollschicht nicht gäbe wäre auch die Änderung auf SPI/I2C usw. im AVR Bootloader Source noch einfach umzusetzen. Solange die physikalische Verbindung RS232/485 konform und auf PC-Seite ein Mapping vom virtuellen COM Port zu einem physikischen Dongle existiert ist das alles noch in einem vertrettbaren Aufwand von 1-2 Tagen umsetzbar. Nur mal zusammenfassend was schon an Protokollen geht: * 1- oder 2-Wire in nachfolgenden Varianten * RS232, RS485, USB-RS232, USB-RS485, Bluetooth-RS232, TCP/IP-RS232, TCP/IP-RS485, DMX * alles mit oder ohne Pegelwandler, also physikalische oder logische Pegel Damit werden allen wichtigen RS-Schnittstellen unterstützt und das verifiziert. Selbst IRDA müsste schon gehen. Gruß Hagen
Theoretisch geht das auch über CAN Byte für Byte, man müsste eben für jedes Byte einen kompletten Frame schicken. Sinnvoller wäre es, die messages auch mit 8 Byte zu füllen. Die Hardware-Protokollschicht zu umgehen, ist unmöglich (behaupte ich jetzt mal)
Tja, habe mir schon gedacht, dass das aufwändiger wäre :-). Ich werde mir wohl selber bisschen was tricksen, nur mit der notwendigsten Funktionalität. Ist eh nur ein Notausgang, da die ganze Baugruppe komplett vergossen ist. Eigentlich ist die Software fertig, aber man kennt das - irgendwann findet man doch einen Bug oder eine neue Funktion, die noch rein soll.... Mal schauen.
>Die Hardware-Protokollschicht zu umgehen, ist unmöglich (behaupte ich >jetzt mal) Das hängt eben von der Hardware ab. CAN ist RS485 kompatibel und wenn der CAN Controller in der MCU als Software implementiert ist dann würde mein obiger Vorschlg auch gehen, denke ich mir so ;) So fit bin ich im CAN auch nicht, was ich aber in den par Minuten überlesen habe deutet darauf hin. Das grundsätzliche "Problem" meines Bootloaders ist dann eben die Umsetzung in Assembler. Das schränkt die Portierbarkeit eben ein. Aber das war konzeptionell auch nicht so vorgesehen und in der Prioritätenliste war die Kompaktheit des Bootloaders viel wichtiger um möglichst alle programmierbaren AVRs auch unterstützen zu können. Ein komplexeres Protokoll verbraucht auch mehr Resourcen oder ist von spezieller Natur und nicht mehr breitbandig von vielen Usern nutzbar, ist einfach so. Zweitens kommt der Punkt hinzu das ich meine PC-Sourcen nicht frei verfügbar machen möchte. Das hat nichts mit "auf den Sourcen hocken" zu tun sondern ist aus meiner Sicht auch ein "Erfolgsgeheimnis" warum dieses Projekt überhaupt funktionieren kann. Irgendwann werde ich diese Sourcen rausgeben und somit die Verantwortung der Pflege und Weiterentwicklung abgeben. Aber meine Erfahrung sagt mir das solche Projekte die möglichst sauber und schnell weiterentwickelt werden sollen immer eine zentrale Führungsperson benötigen. Das ist ja das Problem mit den vielen OpenSource Projekten die an ihren administrativen Plänkeleien dann schlußendlich im Chaos geendet sind. (egal ob Software oder Hardware Entwicklungen, beste Beispiele lassen sich sogar hier im Forum finden ;) Gruß Hagen
CAN in Software - das macht keiner freiwillig, dürfte auch schnell an die Grenzen des überhaupt machbaren kommen, vielleicht funktioniert es bei sehr kleinen Bitraten. Da denke ich gar nicht drüber nach. Ich werde die CAN/SPI-Routinen in den Bootbereich packen und die nach einer Prog-Message anspringen. Und dann gibts für jedes Byte einen Frame, beinhaltet Adresse im Flash und Datenbyte. EEprom brauch ich nicht (bzw. kann ich das in der der "normalen" CAN-Kommunikation)
>CAN in Software - das macht keiner freiwillig, dürfte auch schnell an So meinte ich das nicht. Eher in Richtung CAN-Hardware ist in der MCU und kann konfiguriert werden, extern RS485 Bus. >Ich werde die CAN/SPI-Routinen in den Bootbereich packen und die nach >einer Prog-Message anspringen. Und dann gibts für jedes Byte einen >Frame, beinhaltet Adresse im Flash und Datenbyte. EEprom brauch ich >nicht (bzw. kann ich das in der der "normalen" CAN-Kommunikation) Hier würde ich die Packetgröße auf die Größe pro FLASH Page oder eben zur Verfügung steheden SRAM Buffer hochsetzen. Alles andere bringt mehr Overhead für das Packethandling und reduziert die performance drastisch. Das Adresshandling wird zb. in meinem Protokoll ebenfalls separiert. Dh. es gibt einen interen Adresszähler der mit eigenem Kommando gesetzt wird und ansonsten bei den jeweiligen Programmierfunktionen für FLASH/EEPROM/SRAM lesen/schreiben automatisch inkrementiert wird. Das Mischen von Bootloader- und Anwendungscode erachte ich ebenfalls für nicht ganz so gut. Normalerweise sollte der Bootloader eigenständig zur Anwendung funktionieren und so wenig wie möglich spezielle Hardware Feature benutzen. Zb. IQRs verkomplizieren den Bootloader drastisch. Aber gerade IQRs sollten in der Anwendung für die Kommunikation benutzt werden. Ich würde daher in der Anwendung einen egenen CAN Driver mit IQRs und Buffering benutzen. Dieser reagiert dann auf einen Bootloader Frame indem der Bootloader gezielt gestartet wird. Dieser wiederum arbeitet ohne IQRs per Polling oder wenn mit IQRs dann mit seinen eigenen und nicht den der Anwendung. Baust du den Bootloader so das er mit den IRQs der Anwendung arbeitet dann hast du die komplette Funktionalität der geschützten Bootloader Sections ebenfalls deaktiviert. Dh. dein Bootloader ist nur noch ein Subsystem deiner Anwendung und jedesmal wenn sich gravierende Sachen in deiner Anwendungssoftware verändern, IRQs usw., ist der schon installierte Bootloader inkompatibel. Gruß Hagen
Gast
#1316642
Hallo Hagen, zuerst mal meine Hochachtung vor den Details und Features den Du ja schon in der ganzen Lösung eingebaut hast. Zurück zu der CAN Geschichte: Während ich dies schreibe enwickelt sich mein eigener Vorschlag zu nonsens. Man braucht doch nur ein eigenes Gateway bauen, welches nur RS232-CAN übersetzt. Damit läuft die ganze Applikation und der Bootloader transparent. Am Gateway stellt man dann eine Zieladresse ein und ein Reset Kommando o.ä. kann durch Dein Interface erfolgen. Das spezielle Kommando kann ja durch die normale Applikation im AVR implementiert sein und den Bootloader Modus aktivieren, wie Du es vorgesehen hast. Dann braucht man nur den Assembler Code etwas für die CAN Unterstützung anfassen und das Gateway bauen. Gruß Sven
@Sven: ansich wird das auch so gemacht, denoch >Dann braucht man nur den Assembler Code etwas für die CAN >Unterstützung anfassen und das Gateway bauen. dieses "etwas" ist es was mich stört ;) Der Bootloader ASM Source erzeugt so kompakten Code das dieses "Etwas" an Änderungen schon ne ganze Menge sein wird. Das Bootloader Protokoll ist eben auch Timing abhängig, zb. Baudrate Detection, Connection Aufbau, Responsezeiten beim FLASH/EEPROM programmieren usw. Ein Packetorientiertes Protokoll nimmt man immer dann wenn diese exakten Timings nicht erforderlich sind und der Schwerpunkt auf Multiclients/server/host liegt. Dies ist konzeptionell ja bei meinen Bootloader (PPP) eben nicht so. Der Gateway müsste nun eigenständig entscheiden können wo er Datenbytes erstmal in Buffern sammelt und dann den Frame drumherum bauen kann und wo er einem strikten Timing unterworfen ist und sofort auch kleinere Packete schnüren muß. Das geht ohne zusätzliche Infos von der PC-Software eben nicht. Wenn du hier den Thread verfolgt hast dann wirst du sehen das es größtenteils Timingprobleme sind. Wenn man also zb. den Startup des Bootloaders gezielter per Events oder eben zeitlich toleranter gestalten könnte wären dort weniger Probleme zu erwarten. Da er aber aktuell einer anderen Konzeption unterliegt, nämlich maximal nur 250ms auf einen Connect zu warten, ergeben sich eben gewissen Timinganforderungen. Das wäre nur ein Beispiel, ein weiteres wäre zb. das es ~4ms dauert eine FLASH-Page zu programmieren, die PC-Software nun ihrerseits weiß wieviele Pages programmiert werden müssen (auf Grund der vorher gesendeten Daten) und nun ihre Timeouts entsprechend setzt um einen flüssigen Ablauf und möglichst schnelle Programmierzeiten zu bekommen. Ergo ist meine Meinung das bei einem packetorientierten Protokoll sich auch der konzeptionelle Aufbau sowohl der PC-Software wie auch AVR Source stark verändert und es besser wäre dann gleich was Neues zu stricken. Nicht das es mit einer "Krampflösung" nicht funktionieren könnte aber effektiv betrachtet investiert man weniger Zeit und Nerven gleich von Anfang an bei der Neuentwicklung solche Anforderungen auch zu berücksichtigen. Finally: ich meine das der jetzige Bootloader nicht dafür geeignet ist und es sich auch nicht lohnt diesen in diese Richtung weiter zu entwickeln. Davon abgesehen werde ich nicht bereit sein meine Zeit dafür zu opfern. Gruß Hagen
Gast
#1317490
Wie man die ACY-file ohne Anschließen MCU zu vorbereiten?
Geht nicht und ist Absicht. Die PC-Software benötigt bestimmte Angaben, wie AVR Signatur und installierte Bootloaderversion um das ACY File daraufhin kompilieren zu können. Angedacht war das nach der Kompilation bei der Verschlüsselung auch noch live überprüft wird ob das Passwort stimmt (wurde aber nicht implementiert da ein Angreifer so eventuell durch Trial&Error das Passwort durchprobieren könnte). Wenn man das offline machen wollte so müsste die PC-Software die AVR Signatur, Bootloaderversion und Bootloadergröße per GUI beim Benutzer abfragen. Es ist also von der Arbeitsweise immer so vorgesehen das der Entwickler ein aktuelles Gerät/Hardware vor sich hat und sein kompiliertes ACY auch gleich tested. Gruß Hagen
Gast
#1317723
Danke, Hagen! Ich muß die verschlüsselte file ohne angeschlossen MCU generieren. Allen notwendig gegeben (passwort, signatur und dgl.m.) weiß ich und ich kann manuell einsetzen. Ob eine solche Möglichkeit existiert?
Hallo Hagen, Erstmal grosses Danke! richtig genial der loader. Jetzt bräuchte ich noch genau sowas für den ATXMEGA128A1. Weiter oben hattest du glaub ich schonmal den Prozessor erwähnt. Gibt es da schon was konkretes? Viele Grüße, Rolf
@Rolf, nein noch nicht.
Hallo, da ich ein entsprechendes Bootloader UI für Ubuntu brauchte, habe ein Programm geschrieben, welches den hier beschriebenen Bootloader bedienen kann. Es kann bis jetzt nur den Flash programmieren. Dies allerdings mit verschlüsselten .acy und unverschlüsselten .hex files. Außerdem wird auch nur der ATmega8 unterstützt. (Es wird aber nicht überprüft ob sich um einen solchen handelt.) Wahrscheinlich strotzt es vor Bugs. Allerdings funktioniert das Programmieren von einem Ubuntu 9.4 System aus. Das Programm ist mit Lazarus geschrieben und lässt sich entsprechend auch wür win kompilieren. Wenn man es mit den Parametern bootloader -nogui -tty -bd -file aufruft, kann man es auch normal über Kommandozeile aus zb der makefile heraus starten. Ich dachte, dass vielleicht auch andere Interesse haben an dem Programm. Viele Grüße, piowux
hier noch das Binary für Kompilierfaule..
@Hagen: ja, ich kann mich ARV (Gast) nur anschließen. Es wäre klasse, wenn man das .acy file direkt ohne anschließen des AVRs generieren könnte. Bei mir hat das den Hintergrund, dass dein Programm unter Linux und Wine zwar läuft, aber die serielle Schnittstelle halt nicht angesprochen werden kann. Für das Programmieren habe ich ja jetzt ein Programm. Nur das Erzeugen der acy Datei ist nicht möglich. Ich würde ungern immer die Virtual machine starten, nur um eine acy Datei zu erzeugen. Vielleicht kann man das ein bisschen absichern, indem man die Bootinfo aus einer Datei liest, deren Zeitstempel nicht zu alt ist? So ist dann wenigstens halbwegs sichergestellt, dass der entsprechende Chip vorliegt. Gruß, piowux
@Arne: Ich wäre sehr daran interessiert wenn deine bisherige Arbeit weiter perfektioniert würde. Melde dich bitte bei mir per PN und wir können dann besprechen wie ich dich besser unterstützen kann (Sourcen usw.). Zum Problem "offline ACY": Ich habe es mal in meine Todo Liste aufgenommen. Es bestehen drei Lösungen für dieses Problem. Per GUI wählt man AVR, Bootloader Größe etc.pp. vor der Compilierung aus. Drückt man also auf den Compile Button erschiene ein Dialog. In diesem Auswahlelemente für die fehlenden Daten die auch automatisch von einem connected Device befüllt werden können. Alternativ dann von einem AVRootloader.asm, also dem aktuellen Source des Bootloaders, geparst werden können. Dieser Dialog eröffnet also die Möglichkeit entweder manuell, automatisch aus verbundenen Device oder ausgelesen aus einem AVRootloader.asm alle Parameter zu setzen. So würde ich mir diese Änderung vorstellen damit ich mit diesen Änderungen und dem verbundenen Aufwand gleich mehrere Fliegen mit einer Klappe erschlagen kann (lohnt ansonsten ja nicht). Ist halt bischen Arbeit da ich einiges am Basic Code verändern müsste, mal schauen. Demnächst wollte ich sowieso noch ein weiteres Feature einbauen (merge zweier HEX Files um Bootloader HEX und App HEX in einem Rutsch programmieren zu können). Gruß Hagen
@Arne: Habe mir mal deinen Source angeschaut. Weist du ob Lazaraus auch Interfaces unterstützt ? Wenn ja dann wäre es doch viel besser wenn du mein Interfaces Source gleich direkt benutzt da ich meine das dieser portierbar nach Lazarus sein müsste. Dieser Source beinhalted alles ausser dem GUI. Dh. die komplette Protokollebene und Kommunikationsebene wäre fast fertig. Fehlte nur noch das GUI und das wäre Fleißarbeit. Ich habe versucht möglichst Delphi VCL und Windows API entfernt zu arbeiten (geht bei den Kommunikationsinterface natürlich nicht so einfach). Gruß Hagen
Gast
#1344688
Hi, Hagen! You have news concerning to "offline ACY"? Sorry, but my Deutsch is much worse than English.
@ARV: no sorry, upto date timing is critical.
Gast
#1345780
Hallo zusammen! Zuerst möchte ich mich für den tollen Bootloader und die darin steckende Arbeit bedanken! Allerdings habe ich jetzt ein seltsames Problem und könnte ein bisschen Hilfe gebrauchen. Zunächst (am Dienstag) habe ich den Bootloader für 1-Wire Betrieb mit nicht invertiertem Uart für einen Mega8 (8MHz, Autobaud, nicht verschlüsselt) kompiliert und auf den Controller geflasht. Zum Programmieren habe ich die Schaltung aus dem beigefügten Bild verwendet, direkt an eine echte RS232. Die Dioden waren BAT46, als Widerstand habe ich 3k3 verwendet, da grad kein 2k7 verfügbar war. Zwei Mega8 konnte ich so problemlos (auf jeweils verschiedenen Pins) ansprechen und flashen. Zugriff aur Ram/EEprom ging auch (nachdem ich dann die BOOTRST Fuse programmiert hatte) Am nächsten Tag wollte ich dann auch einen Mega32 mit Bootloader ausstatten, allerdings reagierte er nicht auf die Verbindungsversuche. Zunächst dachte ich an ein Problem mit dem Controller, egal ob Software- oder Hadrwareseitig, also hab ich nochmal die M8 vom vortag angeklemmt. Hier tat sich diesmal aber auch nichts, egal mit welcher Baudrate ich es versucht habe. Danach hatte ich befürchtet, dass es die Schnittstelle erwischt hat, darum habe ich im Terminal getestet, ob gesendete Zeichen am Eingang wieder reinkommen. Schnittstelle OK. Mein nächster Verdacht war, dass das Windowsprogramm aus irgendeinem Grund nichts mehr sendet. Das habe ich dann mit dem Oszilloskop auch ausschließen können. Sauberer +-12V Hub. Mit dem Programmieradapter am AVR Pin sieht man das gleiche Muster, allerdings eben im Bereich von 0-5V und mit nicht ganz so steilen, bzw. etwas verrundeten steigenden Flanken. So langsam gehen mir jetzt aber die Ideen aus, was noch falsch laufen könnte. Hat jemand eine Idee? Falls das hilft könnte ich versuchen, das Oszillogramm auf den Rechner zu kriegen und hochzuladen. Gruß, Timo
Gast
#1346887
Hallo Timo, ich hatte auch Probleme mit dem mega32 (siehe weiter oben), allerdings nicht one-wire. Das Setzen der CKOPT-Fuse brachte das Teil zum laufen, evtl. geht das bei dir auch?
Gast
#1347970
Hallo Thilo, CKOPT Fuse ist bereits gesetzt, hat bei mir aber leider keine Veränderung gebracht. Am meisten wundert mich bei der ganzen Sache ja, dass es mit den Mega8 am Anfang funktioniert hat.
Ändere mal in AVRootloader.inc den Wert bei BaudTolerance von 3 auf zb. 5 oder höher. Je nach MCU-Takt und ausgewählter Baudrate ist die Baudraten Toleranz von 3 zu optimistisch gewählt. Mein aktuelles Projekt hatte damit Probleme, tratt hier also zum ersten Mal als Problem auf, und eine Änderung auf 5 beseitigte es. Gruß Hagen
Ich erhalte seit einigen Tagen auf einmal diese Fehlermeldung beim Upload von Firmware: 15.08.09-10:49:30-578 > Connecting... 15.08.09-10:49:30-703 > Switch to 2-Wire mode 15.08.09-10:49:32-140 > Device connected 15.08.09-10:49:32-140 > Program... 15.08.09-10:49:32-234 > execute compiled data 15.08.09-10:49:32-234 > selected options in compiled file: 15.08.09-10:49:32-234 > - programming FLASH 15.08.09-10:49:32-234 > - FLASH data are encrypted 15.08.09-10:49:32-234 > - erase FLASH during programming 15.08.09-10:49:32-234 > - full verify FLASH after programing 15.08.09-10:49:32-328 > Cmd.SetAddr.ResCheck() Error: Invalid checksum 15.08.09-10:49:32-328 > Device disconnected Bisher ging es immer problemlos. Das komische ist: Meine eigene Software mit der DLL geht problemlos, nur die Avrootloader-Windows-Software gibt diese Meldung aus. Was könnte das bloß sein? Louis
Schwer zu sagen. Benutzt du das Versioning ? Probiere doch erstmal ohne Verify zu arbeiten und schaue ob der Fehler dann immer noch passiert. Gruß Hagen
15.08.09-10:49:30-578 > Connecting... 15.08.09-10:49:30-703 > Switch to 2-Wire mode 15.08.09-10:49:32-140 > Device connected Das deutet auf eine alte Bootloader Version hin. Installiere bitte die neuste Version 6. Erkennen kannst du das daran das er explizit auf 2-Wire-Mode umschaltet. Das hat die ältere Version so gehandhabt, die standardmäßig auf 1-Wire eingestellt ist und beim Verbindungsaufbau erkennt das 2-Wire vorliegt. Die neue Version (ab Version 4 glaube ich) geht exakt andersherum vor. Standardmäßig 2-Wire und erkennt bei Bedarf 1-Wire. Gruß Hagen
Hallo Hagen, versioning verwende ich nicht, ich habe einen Bootsign gesetzt um die verschiedene Hardware zu unterscheiden. Die neueste Version zeigt dieselbe Meldung... Ich habe nichts verändert, flashe die Datei schon seit Monaten. Ist schon seltsam, zumal es über die DLL geht. Louis
auch ohne Verify ? und BootSign korrekt ? Gruß Hagen
abo*
Args, ich bin noch nicht dazu gekommen das zu testen, wird noch nachgeholt. Louis
Gast
#1398980
Hallo Hagen, danke für deinen exzellenten Bootloader! Ich brauche eine zusätzliche Möglichkeit bei zwei gleichzeitig gedruckten Tasten am Gerät bei einschalten Bootloader starten. Nur Assembler gehört nicht zu meinen Stärksten… Tasten Abfrage habe ich so realisiert: ... .include "AVRootloader.inc" ;.listmac .list .org BootStart init: cli ;----------------------------- .def tmp = r28 .def tmp1 = r29 ldi tmp, $00 out DDRA, tmp ;PORTA als Eingang ldi tmp, 0b11111100 out PORTA, tmp ;PullUp in tmp, PINA andi tmp, 0b10001000 ldi tmp1, 0b10001000 eor tmp, Tmp1 ldi tmp1, 0 cpi tmp, 0b10001000 brne NoButtons ldi tmp1, 1 ;wenn gedruckt, immer auf PC warten (tmp1=1) NoButtons: ;sonst starten wie immer ;----------------------------- clr zerol .if Use1Wire u.s.w…. Frage: was soll ich am Besten ändern und, wenn möglich, wie? ich verwende "fixed baudrate, identifier scanning with timeout" also in dem Fall timeout soll unendlich dauern? Hochachtungsvoll Vladimir
Nachfolgend die zwei Stellen im ASM die du änderst:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
Bei Label check: - Watchdog, falls eingeschaltet, zurücksetzen - beide Pins abfragen, hier low-active - wenn nicht beide gedrückt mit jmpapp die Anwendung starten danach normale Baudrate Detection und BootSign Detection. Falls eines davon fehlschlägt Sprung nach Label Check: statt Label Exit: Deine Tasterpins sollten per internem Pullup arbeiten und nach GND gezogen werden. Falls es nicht so ist musst du die sbrs/sbrc Abfragen umdrehen. Wenn nicht beide Tasten gedrückt sind startet sofort deine Anwendung. Solange beide Tasten gedrückt sind wird auf einen gültigen Connect gewartet, ohne Timeout oder Watchdog RESET. Gruß Hagen PS: ich habe das jetzt nicht getestet sondern hier live eingetippt.
Danke! Jetzt alles funkzioniert wie ich wollte.
Nach deinem Vorschlag ich habe das so gemacht:
.org BootStart
init: cli
clr zerol
;-----------------------------
ldi r28, $00
out DDRA, r28 ;PORTA als Eingang
ldi r28, 0b11111100
out PORTA, r28 ;PullUp
ldi r28, 0
sbis PINA, PA7 ;Pruefen, ob PfeilNachUnten gedruckt ist
sbic PINA, PA3 ;Pruefen, ob PfeilNachOben gedruckt ist
rjmp NoButtons
ldi r28, 1 ;Sonst warten auf PC unendlich (r28=1)
sbi PORTD, PD6 ;Led "OK" ein
NoButtons:
;-----------------------------
...
...
; fixed baudrate, identifier scanning with timeout
ldi cmdl, byte1(Baudrate)
ldi cmdh, byte2(Baudrate)
movw baudl, cmdl
;-------------------------------------
rjmp abd
abd0: cpi r28, 1
brne exit
;-------------------------------------
abd: movw xl, zerol
ldi cmdl, byte3(BootDelay / 6)
ab1: ldi parah, (BootInfo - BootSign) * 2
ldi zl, byte1(BootSign * 2)
ldi zh, byte2(BootSign * 2)
ab2: rx_1
rjmp ab2
ab3: sbiw xl, 1
sbc cmdl, zerol
rx_0
brne ab3
;breq exit
;-------------------------------------
breq abd0
;-------------------------------------
rcall getx
xlpm r0, z+
cp r0, paral
brne abd
dec parah
brne ab2
.endif
; send info about chip/bootloader
Bedenke das mit deiner Lösung du mit beiden gedrückten Tasten in die Baudrate/Bootinfo Schleife reinkommst aber nur mit einem Connect oder eben RESET wieder raus. Bei meinem Vorschlag bleibt der Bootloader so lange in dieser Schleife wie entweder beide Tasten gedrückt sind oder ein Connect erfolgte. Dh. ist der AVR noch in dieser Schleife, also ohne gültigem Connect, und werden die Tasten losgelassen so startet die installierte Anwendung. Gruß Hagen
Du hast recht. Aber genau das war mein Ziel. In einigen Fällen beim Update passieren unerwünschte Fehler. Dann weiteres Update ist nicht möglich. Hauptprogramme existiert nicht mehr und Kunde kommt nicht in Bootloader. Jetzt, wenn so was passiert, Kunde trotzdem hat Möglichkeit Bootloader starten.
Gast
#1407446
Hallo Hagen, Dein Bootloader ist echt super. Habe ihn schon bei meheren Geräten eingesetzt. Jetzt will ich ein Konsolenprogramm für Linux schreiben. Habe in diesem Thread gelesen das jemand schon mal angefangen hat. Will das ganze in C schreiben. Vielleicht später auch mal eine einfache GTK Gui. Aber Vorrang hat erst mal das Konsolenprogramm. Könntest du mir dafür die nötigen Infos geben wenn es geht. MFG Alex
Gast
#1415516
Hi Hagen !
Genialer Loader, sehr schnell !
Ich verwende Bascom, kann dort die AVRootloader.exe als
Programmer einbinden. Übergeben wird dann :
AVRootloader.exe -PCOM1 -B115200 -SBOOTLOADER -DD:\Projekte\GPS\gps3dec\
-F{FILE} -Aepc
Für {FILE} setzt Bascom dann GPS.hex automatisch ein.
Wenn ich nun auf "Flash" klicke startet der AVRootloader und
löscht den Flash des Atmels. Danach sollte er dann ja den
Flash programmieren, aber das macht er nicht. Ich muss per
Hand auf "Program" klicken, dann flasht er artig den Chip.
Mit der Option -Aepc sollte er aber doch den kompletten Vorgang
automatisch ausführen, oder? Mache ich da was falsch ?
Matthes
Gast
#1415523
PS. - ist eine 1Wire Verbindung - per Hand funktioniert alles bestens
probiere mal -Apc, der Bootloader wird dann so flashen als wäre die Checkbox "erase during programming" angehackt. Es kommt letztendlich auf's Gleiche raus nur eben mit dem Unterschied das es mit dieser Option schneller ist. Denoch sollte er alle Kommandos auch ausführen wenn sie als Parameter angegeben wurden. Entweder mal wieder einen Bug eingebaut oder die interne Funktion .DoEraseFlash() gibt einen Fehler zurück. Sobald eine der angegebenen Parameter einen Fehler auslösst wird der komplette Vorgang der Auswertung der Parameter abgebrochen. Gruß Hagen
@alex, hier im Forum anmelden dann kannst du auf einen Link neben meinem Namen klicken und mir eine PN schicken. Ich antworte dann auf die EMail und schon können wir kommunizieren. Gruß Hagen
Grüß Hagen!
Erst Riesige "Danke Schön" für deinen Bootloader, ist einfach Klasse.
Nun mein Problem:
Ich verknupfe deine DLL V2 mit eigener Anwendung, ich möchte EEPROM
auslesen mit Function ReadEeprom aus dem AVRootIntf und dann in einem
File speichern. Aber BufOut ist immer leer. Was mache ich falsch?
Hier ist eine Stück vom Code
procedure TForm1.Button8Click(Sender: TObject);
var
EBuffer: pointer;
BufOut : array of byte;
begin
SetLength(BufOut,64);
EBuffer := Addr(BufOut);
FNameEEPROM := ExtractFilePath(ParamStr(0)) + 'temp1.eep';
if FLoader.Mode = moDisconnected then FLoader.DoConnect;
if FLoader.Command.ReadEeprom(EBuffer, 64) then
begin
Hex_File_Write;
end;
if FLoader.Mode = moConnected then FLoader.DoDisconnect;
end;
Versuche folgendes
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
1.) Codeschutzblöcke mit try finally end 2.) DoConnect(), DoDisconnet() kann rekursiv benutzt werden, wichtig ist nur für jedes erfolgreiche DoConnect() muß ein DoDisconnect() aufgerufenw werden, ergo Punkt 1.) Schutzblock einrichten 3.) try except Block, du bist der On-Top-Caller und damit der On-Top-Fehler/Ausnahmen-Behandler 4.) Niemals Addr() verwenden, obsolete. Wenn dann mußt du bei dynamischen Arrays -> das sind Zeiger auf Records die Zeiger auf Daten enthalten, das erste Datenelement mit Addr() ermitteln. Also zb. Addr(Buffer[0]) kurz geschrieben also @Buffer[0]. Das dynamische Array könnte ja auch mehrdimesional sein. 5.) Aktionen, also vorbereitender Programcode immer nur zum Zeitpunkt ausführen wenn er nötig ist Gruß Hagen
Hallo Hagen, ich möchte mich für den Bootloader und die umfangreiche Doku bedanken. Ich bin recht neu im Thema AVR unterwegs. Gestern habe ich es geschafft, den Loader erfolgreich auf einem Mega 8 zu installieren. Ich habe Anfangs etwas Probleme gehabt, da ich nicht wusste, dass bei einem MAX 232 und bei meinem USB Seriell Wandler mit Atiny 2313 (ist auf dem Board von Ulrich Radig drauf) das UART Siganl umgekehrt werden muss. Aber jetzt geht es, somit kann ich nun auch meinen 666p in Angriff nehmen. Also, vielen Dank für Deine Arbeit, und dafür, dass Du dies alles öffentlich stelltst. Gruß Christian
Danke, und
1 | |
so steht's im AVRootloader.asm ;) Was ist 666p ? Gruß Hagen
Hallo Hagen, ja, ich habe den Kommentar dann auch gesehen. Ist also wirklich sehr gut dokumentiert, nur lesen muss man(n) alles :-)) Beim 666p habe ich mich vertippt muss nachtürlich ein 644p sein. Gruß Christian
Grüß Hagen! Danke für schnelle Antwort und deine Tips, den Code habe ich Ausprobiert, genau das, was ich brauchte.
Gast
#1476440
Hallo Hagen, tolles Projekt, tausend Dank für Deine Arbeit!!! Ich würde gerne in Delphi eine kleine App zu Deiner DLL schreiben, mit der ich dass EEProm modifizieren kann (lesen/schreiben), aber leider krieg ich keinen connect. Wenn ich bei GetAppCmdResponse '' zurückgebe, geht die Anwenndung baden und meldet irgendwann zuviel Exeptions "Integer divide by zero at0x0037c8e2". Wenn ich ' ' zurückgebe geht das zwar gut aber Connect hab ich trotzdem nicht. Ich bräuchte das Verhalten der AVRootloder.exe, die ja auf Reset meines ATTiny wartet. Wäre toll, wenns einen Tip gäbe.
Gast
#1489958
Hat sich erledigt.... Ich mach halt mein eigenes Interface über RS232.
Gast
#1495437
Hallo Hagen, herzlichen Dank für dein tolles Projekt, leider habe ich nich gewisse Startschwierigkeiten... Es tut mir leid dich trotz der umfangreichen Doku damit zu behelligen. Folgender Aufbau: Ein Atmega644 mit max232 an D0 un D1 angeschlossen. .include "m644Pdef.inc" .equ UseWDR = 1 .equ UseAutobaud = 1 .equ UseVerify = 1 .equ UseE2Write = 1 .equ UseE2Read = 1 .equ UseSRAM = 0 .equ UseCrypt = 1 .equ UseCryptFLASH = 1 .equ UseCryptE2 = 1 .equ UartInvert = 1 .equ RX_PORT = PORTD .equ RX = PD0 .equ TX_PORT = PORTD .equ TX = PD1 .set XTAL = 8000000 .set BootDelay = XTAL/4 BootCodeSize habe ich gesetzt. Compilieren und flashen hat ohne Probleme geklappt. Fuses: SPIEN gesetzt BootFlash size=512 words Boot start address=$7E00 BOOTRST gesetzt sonst alles aus. Leider meldet mir AVRootloader immer "Error: no Device found". Angeschlossen ist das ganze an einen Com am Mainboard. Die Taktquelle ist der interne 8MHz Oszillator. Kann der zu ungenau sein? Ich kann übrigens mit HTerm Daten vom Controller empfangen. Hat vielleicht jemand eine Idee was das Problem verursacht? Vielen Dank, Manuel
1. BootCodeSize auf 0 setzen 2. neu kompilieren 3. BootCodeSize auf Wert aus AVRStudio setzen 4. neu kompilieren 5. schaue im Messsagewindow von AVRStudio nach welche Boot Fuses du setzen sollst 6. flashen 7. Fuses setzen Takt kann nicht das Problem aus Sicht des Bootlloaders sein da du die AutoBaud benutzt, das sollte ausreichend kurzzeit stabil sein. - neuste Version ? - AVRootloader.INI alles richtig ? Gruß Hagen
Gast
#1495620
Hallo, danke fuer die schnelle Antwort. 1-4 habe ich gemacht, 5: Please program Boot Fuse to First Boot Start ! Welche ist das? Die einzige die mir AVRStudio in diese Richtung anbietet ist BOOTRST, welche auch gesetzt ist. Version sollte passen, 6.0; habe das letztmoegliche hier aus dem thread gezogen. In der ini habe ich testweise ConnectTrials=30 Connect=100 gesetzt; Sonst unveraendert gelassen. Vor dem Compilieren habe ich noch make password ausgefuehrt und gespeichert. Gruss Manuel
Es gibt first, second, third und fourth Bootstart ;) in AVRStudio gibt es eine DropDown Auswahl mit, na rate mal, vier Einträgen. Wenn also zb. second Bootstart gemeint ist dann stellt man in dieser DropDown Liste den 2. Eintrag ein. Ansonsten sieht alles richtig aus nach deinen Beschreibungen. - COM Port in Windows Anwendung richtig ? - das BootSign richtig eingestellt ? - hast du mal die Debug Option probiert und dir dann das Protokoll angeschaut ? Gruß Hagen
> "Error: no Device found" Diese Meldung kann eigentlich nur kommen wenn der COM Port auf AUTO steht. Setze den COM Port auf den an dem der AVR dran ist und probier dann einfach den Connect Button. Die Software verbleibt dann so lange im Connect bis du es manuell abbrichst. Gruß hagen
Gast
#1498722
Ja, mit den ComPort Einstellungen habe ich schon gespielt, leider ohne Erfolg. BOOT-Sign habe ich gelassen wie es war (BOOTLOADER). Das Message Fenster bleibt stumm, auch bei Debug=1 in [System]. Kann es sein, dass es an meinem Port am PC liegt? Mir ist frueher schon aufgefallen, dass HTerm empfangene Zeichen nur blockweise anzeigt, da scheint irgendein Puffer im Spiel zu sein. Vielleicht ist das sendeseitig genauso? Waere super wenn das doch noch laufen wurde. Viele Gruesse und schoenes Wochenende, Manuel
Debug=1 ist veraltet. Probiere [Timeouts] Options=1. Du müsstest dann im Protokoll Fenster wesentlich mehr Infos sehen. Poste diese hier. Gruß Hagen
Hallo, ich habe ein Problem. Ich habe den Bootloader auf einen Atmega8 aufgespielt (ja ich habe das richtige Include ausgewählt). Nach viel Probieren bin ich nun soweit, dass ich über die Software Connecten kann. Jedoch heißt es bei Device name, es sei ein ATtiny87. Ich habe dann versucht, aus dem Tut das erste Beispiel aufzuspielen. Aber das Programm (AVRootloader 6.0) sagt, es fehlt ein RJMP to MAIN oder sowas. Gerade ist ein neues Problem aufgetaucht. Er braucht nun sehr lange um zu connecten, und wenn es klappt, dann nur sehr kurz.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
Gast
#1499093
Hier die Ausgabe: Das Teil sendet sporadisch irgendwelchen Mist zurueck.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
Hallo zusammen, hab mein Problem gelöst. Es lag an einer leeren 9V Batterie. Das Programm ist echt super, großes Lob an dich. gruß Christopher
@Manuel: der Bootloader scheint zu verbinden sendet dann aber permanent den Feler $C2 zurück was heist CRC Fehler. Es sieht so aus als ob deine Hardware Kommuniaktion unsauber ist. Auf alle Fälle empfängt der AVR permanent irgendwelche Zeichen. Antworten tut er auf alle Fälle korrekt, das kannst du an $96 09 06 04 37.. erkennen. Gruß Hagen
$9609 -> ATmega644 $06 -> Bootloader Version 6 $04 -> 4 FLASH Pages für Bootloader = BZ1 gesetzt $37 -> $30 für alles Ok, $07 -> UseCrypt = 1, UseCryptFLASH = 1, UseCryptE2 = 1, UseVersioning = 0 Gruß Hagen
Was hast du bei AVRootloader.ini [Timeouts] -> Options stehen ?
Hallo, ich habe noch ein Problem mit dem Bootloader. Ich denke ich stelle mich nur dämlich an, aber ich finde es nicht raus. Ich kann den Mega8 nur einmal über den Bootloader flashen. Danach springt er den Loader nicht an. Er müsste doch, wenn die SW sendet bei einem Reset den Bootloader anspringen, oder? Meines Fuses füge ich mal bei. Der Mega8 läuft mit Quarz 12MHz. Es lauft dort ein Programm, welches Daten ADC Daten auf der seriellen Schnittstelle ausgibt. Die kommen auch am PC an. Als Interface kommt ein FTD232 RL zum Einsatz, angeschlossen über Rxd/Txd. Der erste Flash funktioniert über diese Verbindung. Im Protokoll des AVRootloader.exe sehe ich, dass Daten gesendet werde, und das der AVR auch etwas sendet. Aber dies sind die Daten, die er auf der seriellen ausgibt. Der Reset liegt auf einem Taster mit PullUp Widerstand, und funktioniert auch. Wo ist mein Fehler? Gruß Christian
Gast
#1502148
> Wo ist mein Fehler?
BOOTRST=Häckchen
Gruß Sven
Hallo Sven, danke für die Rückmeldung. Leider geht es dann immer noch nicht. Ein Reset des AVR löst weiterhin kein Connect mit dem AVROotloader aus. Ich habe mal die Logdatei aus dem AVRootloader beigefügt. Vielleicht kann damit jemand etwas anfangen. Gruß Christian
@Christian: kannst du mir sagen was 'Channel 5 value 1023' bedeutet ? Das ist nämlich das was die PC-Bootloader Software über deinen COM Port empfängt. Also am Bootloader liegt es nicht. Gruß Hagen
Hallo Hagen, das ist die Ausgabe des laufenden Programms. Es gibt nacheinander den ADC Wert der 8 Ports aus. Aus meiner Sicht bedeutet dies, der Bootloader wird nach dem Reset nicht angesprungen. Nur beim ersten mal Flashen wird der Bootloader angesprungen. Wenn ich also jetzt mit meinem Programmiergerät über die IPS Schnittstelle das HEX File des Bootloader flashe und im Anschluß über den AVRootloader das Programm übertrage geht es. Beim zweiten Versuch jedoch schon nicht mehr. Gruß Christian
ich kenne nur zwei Probleme die solche Symptome verurschen 1.) BOOTRST nicht gesetzt 2.) nicht an die beschrieben Vorgehensweise beim Kompilieren gehalten. - BootCodeSize=0 setzen - neu kompilieren - aus AVRStudio Message Fenster cseg [used] auslesen - in BootCodeSize eintragen - neu kompilieren Ansonsten kann man keine weiteren Ausagen dazu treffen, wie im Thread hier schon mehrmals angesprochen, hast du nicht die nötigen Infos geliefert. Gruß Hagen
Hallo. ich habe jetzt nochmal ein wenige getestet, und jetzt geht es. Ich weiss aber nicht so richtig warum. Vielen Dank für Eure Unterstützung. Gruß Christian
Gast
#1507105
Hallo Hagen, habe bei [Timeouts] -> Options=1 stehen. Heute Nachmittag werde ich das Teil mal an einem anderen Rechner testen. Vielen Dank. Manuel
Gast
#1508580
Also jetzt verstehe ich die Welt nicht mehr... Nach viel rumprobieren schaffe ich es eine Verbindung herzustellen. Ich benutze einen max232n mit Standardbeschaltung nach Datenblatt (5x 1muF). Beschaltet ist pin13(max) mit pin3(com) und pin14(max) mit pin2(com). Andere Seite: pin11(max) mit pd1 und pin12(max) mit pd0. Verbinde ich die Pind der Controllerseite habe ich ein schoenes Loopback. Funktioniert tadelos. Versuche ich nun mit AVRootloader zu verbinden klappt das nicht, bis ich mindestens einen der Pumpelkos rausziehe, dann verbindet er sich sofort; es koennen sogar Programme uebertragen werden. Stecke ich die Elkos zurueck, bricht die Verbindung ab. Was soll das? Ich bin kein voelliger Neuling auf dem Gebiet, habe sowas aber noch nie gesehen?
Gast
#1508595
Hallo Manuel, ich hatte schon ein ähnliches Problem mit dem MSP430. Ich erinnere mich noch dunkel das sich bei der INIT Sequenz über den JTAG Programmer der RST Puls mit dem MAX232 gestritten haben. Der eine will runter der andere ist per Default auf high, oder umgekehrt...
Gast
#1508703
Das verstehe ich nicht, JTAG habe ich per fuse deaktiviert, ein Wechsel auf andere Controllerpins aendert nichts. Wenn ich den Controller Daten ausgeben lasse ist es uebrigens genauso, mit Pumpelkos geht nichts; ziehe ich einen raus kommen sofort die Werte. Stecke ich ihn wieder ein klappt die Uebertragung weiterhin, bis zum reset des Controllers, dann geht das Spiel von vorne los. Am Chip liegt es nicht, wurde bereits getauscht. Das kann doch nicht so schwer sein, als ich den Chip die letzten Male verbaut habe hats immer auf Anhieb geklappt. Fallen euch noch Fallstricke ein, die ich uebersehen habe?
Gast
#1510102
Einzige Erklärung meinerseits: dein Elko brückt den TX des MAX. Dh. du meinst du hast diesen richtig angeschlossen, schließt ihn aber am TX Eingang des MAX an und baust so einen schönen Tiefpass für die Datenleitung. Zumindest würde das das beschriebene Verhalten erklären. Gruß Hagen
Gast
#1510229
Das wäre schön, dann würde ich die Sache verstehen... Es ist egal welchen Pufferelko ich rausziehe (können auch beide sein). An den Vout kann ich nachvollziehen, dass die Ladungspumpen arbeiten. Wie gesagt, Loopback funktioniert mit Elkos, Übertragung zum AVR aber nur ohne Elkos. Geisterhaft...
Hallo Hagen. Hagen Re schrieb: > Ich benutz eigentlich zwei Arten um aus der Anwendung in den Bootloader > zu springen. Das ist sehr hilfreich beim Automatischen Programmieren des > AVRs. Bei den ATtinys überwache ich per PinChange ISR den RX Pin und > nutz eine ISR wie nachfolgende > >
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
> > Das hat den Vorteil das man die laufende Anwendung durch die PC-Software > automatisch in den Bootlaoder kommt. Da es ohne Watchdog per direktem > RJMP geht kann man über den SRAM Befehl der PC-Software den aktuellen > Inhalt des SRAMs und IO/PORT Bereiches auslesen und analysieren. > Leider kann ich kein Assembler, würde aber gerne grob verstehen, was du damit meinst. Wenn ich einen Attiny ohne Hardware UART habe, stehen mir doch auch keine UART Interrupts zur verfügung. Was bedeutet in diesem Fall "PinChange"? Bascom könnte ich verstehen. Da funktioniert der Befehl ISCHARWAITING() z.B. nicht beim Attiny mit Software UART. Ich kann nur mit Inkey() das momentan empfangene Zeichen lesen oder mit waitkey() solange das Programm anhalten, bis ein Zeichen empfangen wird und dieses einlesen. (Soweit ich das verstaden habe) Bei "meiner" Watchdog Lösung gibts das Problem, dass die Verbindung häufig erst nach einigen Sekunden hergestellt wird, oder auch mal gar nicht. Vermutlich weil die restlichen 4 Pins permanent damit beschäftigt sind, einen Schrittmotortreiber zu füttern und ADC Signale zu empfangen. Dann reagiert die Serielle Schnittstelle gar nicht. Vielleicht käme ich mit der Alternative zum Watchdog weiter. Viele Grüße Robertz
PinChange = Pin Change Interrupt so wie im Datenblatt beschrieben. Man wartet also auf verändeerungen an einem Pin, hier also der RX Pin des Bootloaders und ruft den Bootloader aus der Anwendung auf. Wenn du in deiner Anwendung mit IRQs arbeitest hat dies den Vorteil das deine beschtriebenen Wartezeiten wegfallen. Ich vermute mal du benutzt in deienr App eherr das Polling. Der Watchdog wird dann benutzt um einen echten RESET des AVRs zu bewerkstelligen und damit den Bootloader definiert zu starten. Das ist besser als ein direkter Sprung zum Bootloader aus der Applikation. Also: 1.) schreibe eine ISR für den Pin Change IRQ 2.) in dieser ISR prüfst du den RX Pin auf Veränderung und aktivierst den WDT mit anschließdender Endlosschleife. Somit schlägt der WDT zu und reset den AVR. 3.) in deiner Main aktiviere den Pin Change IRQ und setze die Pin-Maske für den PinChange IRQ korrekt. Also auf welchen Pin die PinChange ISR reagieren soll. 4.) in deiner Main aktiviere die Interrupts mit SEI(). Das von dir zitierte Beispiel arbeitet zwar mit dem PinChange aber nicht mit dem Watchdog sondern direktem Sprung zum Bootloader. Gruß Hagen
Falls du eher der HW-Typ bist und die SW nicht gebacken bekommst kannst du auch per HW einen RESET auslösen lassen. Die PC-Software unterstützt die Konfiguiration des DTR/DSR Pin der RS232. Diesen Pin kannst du an den RESET des AVRs legen. Jedesmal wenn nun die PC-Software einen Connect versucht pulst sie die DTR/DSR Leitung der RS232 und somit den RESET Pin des AVRs. Wie es konkret geht steht hier im Thread, Readme's und AVRootloader.ini beschrieben. Gruß Hagen
Hallo, ich arbeite mit dem AT90USB1287 auf einem AT90USBKey Board und wollte gerne Deinen Bootloader ausprobieren. Leider hat das Board aber keine RS232-Schnittstelle sondern nur USB (und JTAG). Das Kompilieren des Bootloaders und das Laden in den Flash hat auch geklappt, allerdings erkennt der PC das Device nicht (im Devicemanager). Vermutlich liegt das daran, dass eine USB-Kommunikation zwischen Bootloader und PC nicht vorgesehen ist sondern nur RS232 oder? Kann ich den Bootloader trotzdem irgendwie verwenden bzw. gibt es eine Version mit USB? Oder sollte es eigentlich funktionieren und ich hab nur was falsch gemacht? Danke für die Hilfe! Gruß, Nora
Alle auf RS232 und RS485 basierten Schnittstellen gehen, nicht USB. Das müsstest du schon selbst programmieren. Am besten dürfte es sein wenn du einen beliebigen Pin des AVRs als 1-Wire-RS232 Bootloader Pin benutzt. Du brauchst dann nur bischen zu löten, siehe 1-Wire.png im ZIP und einen USB-Seriell Wandler. Gruß Hagen
Gast
#1520835
Hi zusammen, ich setze den Rootloader seit einiger Zeit ein. Läuft soweit prima! Jedoch habe ich jetzt was ganz merkwürdiges: 2 identische Schaltungen mit Mega8L und Quarz 8Mhz, 3V3 UB und 1 Wire Mode. Der einzige Unterschied zwischen den Beiden sind die Prozessoren die aus unterschiedlichen Chargen stammen. Eine Schaltung kann ich problemlos flashen, bei der anderen kommt kein Connect zustande. Flashe ich herkömmlich, also mit normalen Programmer, läuft die Schaltung einwandfrei. Fusebits sind natürlich richtig gesetzt, das hex des Rootloaders ist natürlich immer das gleiche. Kann mir dabei jemand helfen?
Gast
#1520847
Hi matthes, ich hatte mal das Problem, dass der Quarz nicht recht anschwingen wollte und somit der Bootloader nur ab und zu funktionierte. Das Setzen der CKOPT-Fuse hat geholfen. Evtl. liegt's auch am Quarz? ;)
Gast
#1520863
CKOPT habe ich auch schon probiert. Auch alle Geschwindigkeiten der Schnittstelle. Und die Startzeit des Atmel ......
Ändere in AVRootloader.inc
1 | |
zb. auf den Wert 5 um. Vielleicht "lindert es die Symptome" ohne die Ursache zu kennen. Gruß Hagen
Gast
#1522028
Ok, danke, werde ich testen. Gibt es noch eine Möglichkeit dem "Symptom" auf die Schliche zu kommen?
Gast
#1522045
Du könntest die Prozessoren mal in den Schaltungen tauschen, dann weißt du zumindest, ob's der µC ist oder die Schaltung. ;) Bei SMD natürlich etwas aufwändiger ...
Gast
#1522464
Ich habe mal eine Frage: Das Windows Programm zeigt ja eine maximale Buffergröße des Bootloaders an. Wie finde ich heraus wie viel SRAM bei meiner Booloader-Konstellation für den Buffer übrig bleibt. Deine Software meint 472 Byte; ich haben aber keine Idee, wie Du das abfragst oder aus den Device-Parametern berechnest. Ach ja: BootloaderSize = Flash_PageSize * BootPages; Stimmt das? Vielen Dank für eine Erleuchtung! Achim
Gast
#1523347
Also, BaudTolerance auf 5 bringt auch nix. Prozessor kann ich nicht über kreuz tauschen, da die andere Schaltung wasserdicht vergossen ist. Habe jetzt praktisch jeden Parameter ausprobiert, egal was ich mache, es klappt nicht. Auch die Quarzfrequenz stimmt. Ich gehe mal davon aus, das "faststartup" bei den Fuses richtig ist. Habe da aber auch mehrere Einstellungen versucht...... Auf allen anderen Schaltungen mit einem Mega8 die ich auftreiben konnte funktioniert der Bootloader einwandfrei. Ich mache mir nur Sorgen, wenn ich bei der nächsten Bestellung nur solche "Ausreißer" bekomme ...........
Gast
#1523385
Da bleibt nur eins übrig: zukünftig eine 100% - Prüfung vor dem Vergießen. ;)
Gast
#1523487
neee, ich möchte das Problem schon lösen !
>Ach ja: BootloaderSize = Flash_PageSize * BootPages; >Stimmt das? Ja. (SRAM Size / FLASH_PageSize -1) * FLASH_PageSize ergibt maximale Buffergröße. Somit ist sichergestellt das 1. noch genügend SRAM für den Stack vorhanden ist und die 2. 8 bytes Prüfsummenblöcke auch noch reinpassen. Maximal benutzt die Software also (SRAM Size / FLASH_PageSize -1) * FLASH_PageSize +8 bytes. Gruß hagen
Hallo Hagen, erstmal vielen Dank für deinen genialen Bootloader. Ich verwende folge Zusammenstellung: Atmega8L (TQFP32) 8Mhz (extern) Kommunikation mit dem PC über ein Bluetooth-Modul BTM-222. Wird wie ein gewöhnlicher COM-Port behandelt. Dein Bootloader in der Version 6.0 Mein Ziel: Atmega über Bluetooth flashen OHNE manuellen Reset per Knopf. Mein Stand: Flashen mit externen Reset funktioniert jetzt einwandfrei nach langen Versuchen mit den Timeouts. Dann habe ich die Watchdog Methode gewählt. Diese Funktioniert auch soweit gut hatte bei mir bis jetzt aber den Nachteil, dass mein Hauptprogramm ungewollt alle 2 Sekunden resettet. Daraufhin habe ich den Watchdog im Hauptprogramm deaktiviert, dann funktionierte aber wie erwartet nicht mehr der Bootloader-Reset über die PC Software. Und ein Watchdog-Reset alle 2 Sekunden möchte ich nicht im Hauptprogramm verwenden. Jetzt würde ich gerne die PinChange Funktion nutzen um meinen Atmega8 zu resetten. Weil der BTM-222 hat zwar ein RTS/CTS Pin kann diesen aber nicht nutzen. Sprich ein Reset über ein RTSPulse kann ich leider auch nicht nutzen. Muss ich dann nur ein Codeschnipsel in mein Hauptprogramm einfügen um ein PinChange zu erreichen? Das BTM-222 verwendet mit dem Atmega8 ein 2Wire Modus ohne Pegelwandler aber mit deiner UARTInvert option. Verstehe ich es richtig, dass deine PC-Software über AppCMD z.b. den Wert 0x55 ans Hauptprogramm schickt und der Atmega dann über PinChange resettet. Sorry,... ich bin noch recht neu in der MCU-Programmierung und weiß jetzt nicht welche Lösung ich verwenden soll... P.S. Dein Test-Sourcecode im Ordner Test lässt sich bei mir im AVR-Studio 4.18 mit dem AVR-GCC Compiler nicht compilieren. Da kommt immer ein Fehler von der ld.exe Über eine Hilfe würde ich mich sehr freuen. :-) Gruß Dennis
Gast
#1531195
Hi Dennis, wie du weiter oben gelesen hast, habe ich einen Atmel der nicht so richtig will. Was verwendest du für Timeouts? Ich habe auch schon mit denen gespielt, evtl. sind diese aber noch zu eng eingestellt?
Ich habe die Timeouts in der INI nur bei BASE geändert. Auf 100ms. Das funktioniert sogar über Bluetooth 100% zuverlässig allerdings nur per RESET-Taster. Da ich aber Bluetooth verwende, nervt mich der Reset-Taster. Ich möchte demnach einen Reset per Software durchführen, bekomme das aber nicht gebacken! Reset via RTS-Signal ist leider auch ausgeschlossen, weil das BTM-222 unterstützt diese Funktion nicht. Jetzt bleibt nur noch Watchdog oder ein "Jump to Bootloader" übrig. Nur mir fehlt ein Lösungsansatz. Das Beispiel im Ordner Test verstehe ich nicht so ganz. Zumal wie ich jetzt herausgefunden habe besitzt der Atmega8 keine PinChange Funktion über "PCINT", der 8er hat nur den externen INT0 und INT1 Pin. Gruß Dennis
Du hast mehrer Möglichkeiten: 1. Polling des RX Pins des Bootloaders in deiner Anwendung. Falls der RX pin toggelt dann über Watchdog Reset den Bootloader starten 2. PinChange oder Ext. Int. am RX Pin benutzen und auf Toggeln der RX datenleitung warten. 3. schreibe UART Funktionen für deine Anwendung. In der Empfangsroutine wartest du auf eine von dir festlegbaren Command String, zb. sowas wie "bootstart". Wenn du den empfängst kannst du einen Response String zurück senden, zb. "startboot" und wiederum per Watchdog Timeout einen Reset zum Bootloader durchführen. In der AVRootloader.ini setzt du das Topic AppCmd=bootstart und AppCmdresponse=startboot. Setze [Timeouts] AppCmd=20. Der PC-Bootloader sendet nun vor jedem Connect Versuch den String "bootstart" an deine Anwendung im AVR. Dort reagierst du indem du "startboot" sendest und den WDT startest. Die PC Software wartet bis sie "startboot" also das AppCmdresponse empfangen hat, fügt ein 20 Millisekunden Delay ein und macht mit dem normalen Connect zum AVRootoader im AVR weiter. Somit hast du also den Bootloader im AVR softwaremäßig gestartet. Wenn AppCmdResponse nicht benutzt wird, also leer ist, dann wartet die PC Software nicht auf eine Bestätigung Seitens deiner UART Routinen sondern macht gleich mit dem AppCmd delay und dem Connect weiter. Letztere Methode ist mit ihrem Handshaking relativ stabil und sicher hat aber den Nachteil das die Baudrate in deinen UART Routinen meistens hardcoded ist, dh. die AutoBaud Funktion die im Bootloader drinnen ist steht dir nicht zu Verfügung. Gruß Hagen
Gast
#1535086
Hallo, ich bin gerade dabei den AVRootloader auf meinem ATmega8 in Gang zu bringen, leider funktioniert es bisher nicht: Ich habe die AVRootloader.hex laut Anleitung erstellt (AVR-Studio, mit "m8def.inc" sowie der richtigen Portbeschreibung für den ATmega8, also PD0 und PD1). Die hex-Datei habe ich mit Ponyprog auf den ATmega8 geladen. Bei der Fusebits bin ich mir 100%ig sicher: BOOTSZ1 = 1 (kein Häkchen) BOOTSZ0 = 0 (Häkchen) BOOTRST = 0 (Häkchen) Der Code hat nur 432Bytes (<256Words), also sollten die Fusebits eigentlich passen, oder? Wenn ich nun die Verbindung mit AVRootlaoder aufbauen möchte findet er leider keine Device im Protocol steht: 29.12.09-15:28:04-687 > Connecting on port COM1... 29.12.09-15:28:05-796 > Connecting on port COM41... 29.12.09-15:28:06-875 > Connecting on port COM42... 29.12.09-15:28:15-546 > Error: no Device found Die Kommunikation über die RS232 funktioniert aber sicher, hab eben grad getestet. Mache ich grundsätzlich irgendwas falsch, oder ist zumindest mein vorgehen korrekt? oder hat zufällig einer einen konfigurierten Bootloader fürn ATmega8 mit passenden Fusebits herumliegen? Vielen Dank für Eure Hilfe! Schöne Grüße CJ
Gast
#1539381
Hagen Re schrieb: > (SRAM Size / FLASH_PageSize -1) * FLASH_PageSize ergibt maximale > > Buffergröße. Somit ist sichergestellt das 1. noch genügend SRAM für den > > Stack vorhanden ist und die 2. 8 bytes Prüfsummenblöcke auch noch > > reinpassen. > > Maximal benutzt die Software also (SRAM Size / FLASH_PageSize -1) * > > FLASH_PageSize +8 bytes. Vielen Dank Hagen, aber bitte hilf mir doch nochmal: Bezogen auf meinen ATTiny84 wäre das dann: (512/64 -1)* 64 =448 Bytes Buffergröße Mit Deinem Programm bekomme ich aber folgendes: Connection : 1-Wire Device name : ATtiny84 Device signature : 1E930C SRAM size : 512 Byte EEPROM size : 512 Byte FLASH size : 8192 Byte FLASH size for application : 7232 Byte FLASH pagesize : 64 Byte Bootloader size : 960 Byte Buffersize for data : 472 Byte SRAM start address : 96 Bootloader version : 6 Use bootsection : No Versioning supported : Yes Cryptography supported : Yes FLASH data must be encrypted : Yes EEPROM data must be encrypted : No Bootloader information : Application software version : 3.2.2.0 Application version address : 0x001C3A
Die PC-Software geht von SRAM_Size - PageSize + 24 aus. Ergibt 512 -64 +24 = 472 Bytes. Ganz genau genommen geht sie immer davon aus das SRAM_Size mod PageSize = 0 ist also immer ohne Rest teilbar. Am korrektesten wäre also die Formel (SRAM_Size div PageSize -1) * PageSize + 24. Das ist der vom Protokoll her gesehen maximale Buffer der benutzt wird. Wird Verschlüsselung benutzt so muß man die 512 Bytes erstmal in x PageSize Buffer unterteilen. Damit für den Stack noch was übrig bleibt ziehen wir erstmal PageSize ab und erhalten so den minimal nutzbaren Datenbuffer = 448 Bytes. Das ist die maximal nutzbare Größe für die Daten im FLASH/EEPROM. Bei der Entschlüsselung wird im SRAM noch zusätzlich 3 XTEA-Buffer a 8 Bytes benötigt. Der erste XTEA Datenblock ist intern das Feedback Register, der 2. Datenblock a 8 Bytes ist das Ausgaberegister. Der 3. 8 Bytes Buffer liegt dann am Ende des SRAMs und enthält den zu entschlüsselnden Prüfsummenblock. Vor diesem liegen nun x Pages a PageSize Bytes an FLASH/EEPROM Daten. Somit ergibt sich das wir den SRAM erstmal in 64 bytes (Pagesize) Blöcke aufteilen. Somit kommt man auf Max. Buffersize = SRAM_Size - Page_Size + 24. Es verbleiben dann 40 Bytes für den Stack. Dieser Buffer wird aber nur so groß benötigt wenn mit der Verschlüsselung gearbeitet wird, ohne Verschlüsselung fallen die 24 Bytes weg. Bei der Verschlüsselung sieht es also so aus: Feedback | Output | Datenblock 1 | Datenblock 2 | ... | Datenblock x | Prüfsummenblock. Alle diese Blöcke sind 8 Bytes groß. Die Anzahl x dieser Datenblöcke ist immer x = (SRAM_Size - Page_Size) / 8. Wird nun entschlüsselt so "wandern" die Bedeutung dieser 8 bytes Blöcke. Am Anfang wird das Feedback Register mit den Datenblock 1 XOR verknüpft. Dann wird dieser Block mit XTEA halb entschlüsselt und dieses Zwischenresultat mit dem Feedback Register erneut xor-verküpft. Nun die zweite Hälte der XTEA Entschlüsselung durchgeführt und in den als Output markierten Datenblock gespeichert. Aus dem ehemaligen "Output" Block wird der nächste "Feedback" Datenblock und aus Datenblock 1 wird der neue "Output" Block. Nun beginnt wieder alles von vorne usw. Somit stehen die verschlüsselten Datenblöcke am Anfang der Entschlüsselung um 8 bytes nach hinten versetzt im SRAM und nach der Entschlüsselung sind diese Daten um 8 bytes nach vorne kopiert wurden. Damit wird die Entschlüsselungsfunktion so wie erforderlich in ihrer Performance gesteigert und das gesammte System arbeitet wie ein "sliding Window" während der Entschlüsselung über den kompletten Buffer. Das erklärt die zusätzlichen 24 Bytes die man benötigt. Gruß Hagen
Gast
#1542175
Hallo Hage, super vielen Dank für Deine ausführliche Antwort!!! Ich verstehe ungefähr 30% davon, den Rest werde ich mir noch erarbeiten. Ansonsten läuft Dein Bootloader bei mir einfach nur spitzenmäßigg, reibungslos, wie es sein soll. Vielen vielen Dank für Deine AArbeit!!! Gruß Achim
Gast
#1545196
Hallo zusammen,
kann mir auf die Schnelle jemand verraten wie ich aus der Applikation
direkt in den Bootloader springen kann?
Bei BootMode = 0 sollte das doch mit einem jmp gehen.
Es geht um einen Atmega644; das Datenblatt sagt, bei FirstBootStart
beginnt die BootLoader Flash Section bei 0xfe00.
Warum bringt mich
asm volatile("rjmp 0xfe00") dann ins Hauptprogramm?
Vielen Dank.
Manuel
Schaue dir mal den \Test\ Ordner im ZIP an. Dort zeige ich wie man mit WinAVR GCC in C den Bootloader startet. Entweder per direktem Jump oder viel besser mit dem WatchDog. Machst du einen Jump dann musst du sicherstellen das du alle HW und Ports usw. manuell so zurücksetzt das der AVR so wie nach einem RESET eingestellt ist. Nutzt du dagegen den WD-Timeout wird der AVR einen RESET machen und alles ist so wie es der Bootloader erwartet. Gruß Hagen
Gast
#1562749
Hallo Hagen, vielen Dank für dein AVRootloader, ich finde ihm TOP! Ich habe es geschafft eine Verbindung zwischen dem PC und einem AT90USB1287 (AT90usbkey Plattform) zu kriegen. Als Verbidung habe ich den 1-Wire verwendet ( aber nicht mit 2,7 kOhm, sondern mit 2 kOhm Widerstand, ich hoffe,dass das kein Problem ist ;) ) Das einziges Problem ist, dass die Baudrate kann nicht mehr als 28800 eingestellt werden, keine Ahnung warum. Ich habe kleine Anwednung, ein paar LEDs leuchten lassen, geschrieben und mittels dein Windows-Programm verschlüsselt und drauf geladen. Es ging ohne Probleme! Das Problem ist, wenn ich eine großere hex-Datei auf dem µC laden will. Es funktioniert irgenwie nicht. Ich habe keine Ahnung warum nicht, habe alles durchgesucht, nochmal alles gelesen, aber nichts gefunden. Ich habe auch mit den Werten für Timeouts gespielt, aber wieder ohne Erfolg! Vielleicht hättest du eine Idee woran mein Problem liegt? Ich hänge dir das Protocol an. In dem kann man sehen, dass ich zuerst eine kleine Anwendung erolfreich lade, dann versuche ich eine großere Anwendung( 60kBytes) zu laden, aber es gibt einen Fehler. Es ist egal, ob ich die Verschlüsselung benutze oder nicht, in beiden Fällen es funktioniert nicht. Vielen Dank im Voraus! Wenn du andere Infos brauchst, sag einfach bescheid. Gruß Kostadin
Hallo, ich habe jetzt auch versucht den Bootloader auf meinem Atmega8 zu verwenden. Leider bekomme ich keine Verbindung! Meine Einstellungen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
FuseBits: BOOTSZ1 = 1 BOOTSZ0 = 0 BOOTTRST = 0 Wenn ich meinen Controller resette (Taste) dann empfange ich eine 0 (Byte-WERT) mit dem Terminal. Ist das richtig? Sendet der Bootloader eine 0 beim starten?
Hat sich erledigt. Ich hatte das Invertieren nicht gesetzt. Ich bin begeistert von dem Bootloader. Mit AppCmd und Watchdog automatisch resetten. Funktioniert alles bestens. TOP Bootloader
Gast
#1580206
@Kostadin: du benutzt 1-WIRE-RS232 ? Laut Protokoll, ja, er bringt aber auch einen ICOM-Echo-Fehler was darauf schließen lässt das du eben nicht 1-Wire als Hardware benutzt. Bei 1-Wire muss das was die PC-Software an Daten sendet auch von der PC-Software wieder empfangen werden, das sogenannte Echo der Daten. Das wird durch mein RS232 1-Wire Treiber berücksichtigt. Das Echo wird wieder empfangen und mit den vorher gesendeten Daten verglichen. Sollten Unterschiede im Echo gefunden werden oder das Echo ganz ausbleiben so wird der ICOM-Echo-Error gemeldet. Ich vermute also: entweder nutzt du keine 1-Wire Hardware und die PC-Software detektiert nicht den richtigen Modus, also 1-Wire statt 2-Wire. Oder du benutzt 1-Wire Hardware und diese ist nicht stabil. Gruß Hagen
Hallo euch allen, ich bin schon seit einiger Zeit auf der Suche nach einem CAN-Bootlader für den AT90CAN. Leider konnte ich dazu aber kein fertiges Projekt finden. Genauere Informationen gibt es unter fogendem Link: Titel - Beitrag "CAN BUS Bootloader AT90CAN" Ich hoffe es finden sich einige um dieses Projekt zu realisieren oder die dabei helfen können. Grüße martin
Gast
#1608132
Hallo Hagen, ich hab mal versucht, Dich via PM zu kontaktieren, was bisher nicht gelang. Wahrscheinlich ist Deine t-offline Addy nicht mehr aktuell. Auf alle Faelle hab ich nen avrdude Patch, der Flash schreiben und verifizieren (implizit und bissl hingedreht auch explizit) kann. Jetzt steht nur noch EEPROM schreiben (lesen muesste gehen) und Encryption an. Und genau bei der Encryption brauch ich Deine Hilfe. Wie funktioniert das Verfahren? Ich werde das dann fuer avrdude implementieren, damit der bootloader vollstaendig unterstuetzt wird. Ziel ist natuerlich die Aufnahme der Unterstuetzung in Mainline, womit dann alle wichtigen Systeme abgedeckt sein duerften. Ich bin unter swarner ät mibtec punkt de zu erreichen. Gruß, Sascha
Hi Swarner, deine Idee finde ich klasse! Ich habe auch mal ein Programm für den Bootloader geschrieben. Wahlweise Kommandozeile oder GUI. Das ganze ist in Lazarus geschrieben, sodass es auf vielen Plattformen funktioniert. Verschlüsseln kann es nicht. Dafür kann es aber schon verschlüsselte Dateien programmieren. im Beitrag Beitrag "Re: AVR-Bootloader mit Verschlüsselung" ist der Quellcode. Ich hoffe er hilft dir weiter. Auf das alles bald im AVRDude erscheint, was richtig klasse wäre! Viele Grüße, piowux
@Sascha: sorry aber zZ. bin ich gebunden mit anderen Projekten. Wenn deine Mail sich nur auf ein kleines Problem bezöge hätte ich sichderlich just in time auch geantwortet. Da du aber eine ausführliche Dokumentation von mir benötigst brauche ich mehr Zeit dazu, und die habe ich eben nicht. Ich schaue zu das ich die nächste freie zeit benutzte um dir alle infos sauber zusammen zu stellen. Gruß Hagen
Gast
#1610222
@Hagen: Danke fuer die Antwort. Solange Deine Mail Adresse richtig war, bin ich beruhigt :) Die Encryption eilt nicht, wahrscheinlich ist es sogar besser, wenn ich da inkrementell vorgehe. Also mach Dir da keinen Stress deswegen - ich bin noch laenger da. @Arne: Danke fuer Deinen Code. Wenn ich wo Zweifel hab, kann ich jetzt nachsehen, wie Du es Dir gedacht hast :) Ich hab z.B. ganz vergessen den "RUN" Command zu nutzen ;) Wegen Deines ATMEGA8-only-Poblems: Du brauchst glaub ich CPU abhaengig nur die RAM Puffergroesse. Wenn Du einfach die Pagesize nimmst, die du fuer die Bootloadergroesse eh brauchst (erase pages usw.), liegst Du auf der sicheren Seite (ok, muesstest Du je CPU die Pagesizes verwalten, alternativ nimmst Du die kleinste Pagesize, die vom Bootloader unterstuetzt wird, 32 Bytes. Das Flashen wird dadurch wesentlich langer dauern, aber immerhin kannst so alles flashen.) Ich musste genau deswegen dem dude noch ein sramsize in die Chip Config pflanzen - leider. Gruesse Sascha
Hallo, Der Bootloader läuft bei mir super mit Kabel. Jetzt möchte ich über Bluetooth (BTM-222) flashen. Leider bekomme keine Verbindung über Bluetooth. Wie muss ich die Timeouts einstellen? Base habe ich schon versucht zu erhöhen. 50, 100, 200 Es kann keine Verbindung aufgebaut werden! Meine Einstellungen: Connection : 2-Wire Device name : ATmega16, ATmega16A Device signature : 1E9403 SRAM size : 1024 Byte EEPROM size : 512 Byte FLASH size : 16384 Byte FLASH size for application : 15360 Byte FLASH pagesize : 128 Byte Bootloader size : 1024 Byte Buffersize for data : 920 Byte SRAM start address : 96 Bootloader version : 6 Use bootsection : Yes Versioning supported : Yes Cryptography supported : No Application software version : not defined Application version address : 0x003BFC [Timeouts] Connect=0 Base=100 Erase=10 Flash=15 Eeprom=10 Buffer=1 AppCmd=0 KeepAlive=250 MaxPacketSize=0 RTSPulse=0 RTSInterval=0 Options=1
Hallo Hagen ! Ich hab mal zwei kurze Fragen zu UseSpecialWrite. Da mein ganzes Projekt in ASM ist, hab ich den Aufruf folgendermassen programmiert:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Ist das so richtig ? (Denn bei mir funktionierts leider nicht) Bin leider kein C-Profi, deshalb ist das Test-Project für mich nicht immer ganz so leicht zu verstehen ! UseSpecialWrite = 1 ! Muß ich sonst noch was einstellen oder ändern ? Gruß Stefan
Gast
#1632210
>>Ist das so richtig ?
Nein, benutze RCALL statt RJMP da ja die Bootloader Funktionen mit RET
zum Aufrufer zurückkehren. Es sei denn dein obiger Sourceausschnitt wird
selber per RCALL aufgerufen und du möchtest das die Bootloader
Funktionen direkt zu derem Aufrufer zurückkehren sollen.
Desweiteren sollte der Offset -2 statt -5 sein. Im C Source ist dort -5
weil die FLASH Adressen als Byteaddressen interpretiert werden in ASM
aber als Wordadressen.
Deine Parameter->Register sind korrekt.
Aktiviere mal UseSpecialRead=1 und UseSpecialMsg=1. Dann schreibe einen
Aufruf für UseSpecialMsg
RCALL FlashEnd-4
In R25 sollte nach Rückkehr der Funktion die Länge des Boot-Msg-Strings
drinnen stehen und in r24:r23:r22 der Zeiger auf die FLASH Adresse an
der die BootInfo steht. Nun kannst du damit die BootInfo aus dem FLASH
lesen ,wenn die Security-Fuses so gesetzt sind das die App auf den
Boot-FLASH zugreifen kann. Somit hats du erstmal eine reine ReadOnly
Funktion und zerschießt dir nicht gleich den FLASH wie bei falschem
Aufruf von WriteFlash().
Im nächsten Schritt benutze ReadFlash() um Daten aus dem FLASH in einen
SRAM Buffer zu lesen. Wenn das geht mit WriteFlash() weitermachen und
mit ReadFlash() verifizieren.
Gruß Hagen
Gast
#1632212
@Etumic: Die BTM-222 sind bischen schwer zu konfigurieren und kannst du sicherstellen das diese korrekt laufen ? Wenn ja wird es ein Timing Problem sein und da kann ich dir nur schlecht weiter helfen. Gruß Hagen
Gast
#1632237
@Stefan: nochwas: - alle diese Funktionen benutzen Byteadressen als FLASH-Zeiger - r25 des 4-Bytes Zeiger auf die zu schreibende FLASH Adresse ist normalerweise 0x00 (es gibt ja nicht soviel FLASH in einem AVR). Benutzt du in r25 den Wert 0xAC als Magic Code kannst du in den Boot-FLASH schreiben, falls du die Securityfuses entsprechend gesetzt hast. - in ASM ist FlashEnd = FLASH_SIZE_IN_BYTES / 2 -1, sollte also bei dir die Word Addresse sein. Gruß Hagen
Hallo Hagen ! Vielen Dank für die Hilfe ! Es lag am Rjmp Flashend -5 ! Das sind halt die feinen Unterschiede zwischen C und ASM ! Fals nochmal jemand danach sucht: Hier der Funktionierende Code für den Aufruf von UseSpecialWrite aus Assembler:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
Gruß Stefan
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.



