Datum:
Angehängte Dateien:Anbei mein AVRootloader. - unterstützt alle selbstprogramierbaren 8Bit-AVRs - 1-Wire und 2-Wire RS232 Modus, invertierbar - Baudraten je nach XTAL von 600 bis zu 256000 Baud per USB-RS232 - XTEA Verschlüsselung für FLASH/EEPROM Schreiben - 16Bit CRC für die komplette Datenübertragung, Senden & Empfangen - FLASH schreiben/löschen mit implizitem Verify - separates FLASH Verify - EEPROM schreiben/lesen, schreiben mit implizitem Verify - SRAM schreiben/lesen - Baudrate Detektion, Baudrate kann aber auch fest eingestellt werden - WatchDog Unterstützung - fertige PC-Software mit HEX-Editoren für EEPROM & SRAM/Registerfile/IO Ports - ATmega128 bei 115200 Baud in 16 sec mit Verschlüsselung 22 Sekunden - im ZIP Datei AVRootloader.txt enthält Anleitung - je nach Konfiguration zwischen 344 bis 906 Bytes Codegröße, letzters mit XTEA Entschlüsselungsfunktion Gruß Hagen
Datum:
Hallo Hagen, mal 'ne andere Frage, womit hast Due die Windows-Applikation programmiert? Nur eine EXE, das gefällt mir und die Optik ist Dir auch ganz gut gelungen. Danke. Gast
Datum:
Ah, ich denke ich habs schon gefunden. Schient Delphi zu sein!? Gast
Datum:
Ah, ich denke ich habs schon gefunden. Scheint Delphi zu sein!? Gast
Datum:
Na da hab ich ja meine korrigierte Watchdogfunktion grad noch rechtzeitig gepostet. Peter
Datum:
@Peter: Ich habe sie nach Datenblatt des ATTiny461 und ATMega88-168 programmiert. Ist sie etwa falsch ? @Gast: Ja ist Delphi 5. Der HEX-Editor ist von Mirkes.de wobei ich diesen nur empfehlen kann weil es der einzigste freie für Delphi auf dem Markt ist. COM Port Zugriff habe ich in eigenes Objekt implementiert und benutzt Overlapped-IO. Gruß Hagen
Datum:
Sieht gut aus. Noch ne Kleinigkeit, was für Z-Dioden verwendest du im Schaltplan? Steht nur die Bauteilnummerierung dran... Werner
Datum:
@Werner, BAT54C sind SMD in SOT23, keine Z-Dioden, sind Schottky Dioden. Ist eventuell beim Eagle Symbol nicht so gut erkennebar ?! Wichtig ist der 2k Widerstand, bei Peters Bootloader wurde dort ein 4k7 angegeben. Ich habe diese bei meinen Tests mit ATmega128, ATmega168 und ATtiny461 dann auf 2k reduziert. Als RS232 habe ich die RS232 meines Laptops, der Dockingstation des Laptops und ein USB-RS232.Kabel getestet. Mit dem 2k ging es besser, aber ich benutze auf AVR Seite ja auch nur den interne PullUp statt einem externen. Das hat dann alles funktioniert mit Baudrate von 600 bis 256000 Baud, vorrausgesetzt der Takt des AVRs ist hoch genug für die hohen Baudraten. Den ATtiny461 habe ich mit internem RC Oszillator + PLL laufen, sind dann 16MHz. Den ATMega128 mit externem Quarz bei 15.97MHz. @Peter, ich habe noch mal in das ATmega168 Datenblatt geschaut und ich meine das ich keinen Fehler mit dem Watchdog gemacht habe. Im Datenblatt Seite 48 ist exakt die Sequenz angegeben die ich auch benutzt habe, eben mit dem Unterschied das WDE über die ODER Verknüpfung gesetzt wird, ist auf Seiet 47 ebenfalls beschrieben. Testen konnte ich den WatchDog eben nur für die genannten 3 AVRs und da hat er funktioniert. Nur beim ATTiny461 sind par Ungereimtheiten die aber nichts direkt damit zu tuen haben. Wenn man bei dem Teil die WDTON Fuse setzt und dann wieder löscht so wird der WatchDog solange mit ständig gesetzem WDE Bit laufen bis man dem AVR den Saft abdreht. Ein RESET setzt das WDE Bit noch lange nicht zurück. Anderst ausgedrückt: löscht man die WDTON Fuse dann muß man dem AVR den Saft abdrehen damit das auch eine Wirkung erzielt. Ein einfaches RESET reicht nicht aus. Dh. nach dem Löschen von WDTON verhält sich der AVR noch solange als ob WDTON gesetzt ist bis er keinen Saft mehr hat !! Das hat mich Stunden an Fehlersuche gekostet und ich war schon der Meinung ich habe den ATTiny461 geschrottet. Gruß Hagen
Datum:
Hagen Re wrote: > @Peter, > ich habe noch mal in das ATmega168 Datenblatt geschaut und ich meine das > ich keinen Fehler mit dem Watchdog gemacht habe. Hab ich ja nicht behauptet, sondern das es die gleiche Sequenz ist, die ich als letztes gepostet hatte. Sie sollte daher funktionieren. Ich hatte vorher ne andere, die nicht funktioniert hat. Man darf beim ersten Schreiben nicht die WDP-Bits anders setzen, dann wirds ignoriert. Steht aber nirgends im Datenblatt. Hat mich auch einige Zeit gekostet. Den Rest des Codes habe ich noch nicht verdaut. Ich hab da immer Probleme mit so großen monolitischen Brocken, daher unterteile ich gerne alles in kleine Häppchen. Auch wenn dann vielleicht ein paar CALLs und RETs mehr an Code entstehen. Dein Code ist ja auch äußerst sparsam kommentiert. Die Umleitung des Bootloader-Reset bei den ATtinyxxx/ATmega48 machst Du vermutlich schon in der EXE. Ich habs deswegen im AVR gemacht, damit selbst bei Empfangsfehlern kein Aussperren möglich ist. Ist ja auch nicht viel Code. Zumindest das Löschen sollte aber von oben nach unten erfolgen. Peter
Datum:
Hi Peter, >Ich hatte vorher ne andere, die nicht funktioniert hat. >Man darf beim ersten Schreiben nicht die WDP-Bits anders setzen, dann >wirds ignoriert. Steht aber nirgends im Datenblatt. Hm das es ignoriert werden soll wusste ich auch nicht. In irgendeinem der Datenblätter steht aber das man die WDP Bits erst setzen sollte wenn man vorher das WDCE Bit einmalig gesetzt hat da ansonsten der WatchDog Prescaler beim Verkürzen der Zeitspanne schon vorzeitig auslössen könnte. >Den Rest des Codes habe ich noch nicht verdaut. >Ich hab da immer Probleme mit so großen monolitischen Brocken, daher >unterteile ich gerne alles in kleine Häppchen. Auch wenn dann vielleicht >ein paar CALLs und RETs mehr an Code entstehen. Ja verstehe ich. Der Bootloader sollte so kompakt wie möglich werden und da sind Optimierungen über die einzelnen Blöcke hinaus manchmal notwendig. Es ist schon blöde wenn wegen 2 Bytes zuviel an Code der Bootloader eine ganze FLASH Page mehr benötigt. >Dein Code ist ja auch äußerst sparsam kommentiert. >Die Umleitung des Bootloader-Reset bei den ATtinyxxx/ATmega48 machst Du >vermutlich schon in der EXE. Ja, das ist aber auch abgesichert. Bei solchen AVRs wird erstmal der letzte FLASH Block gelöscht. Dann die 1. Page Programmiert. Der Bootloader arbeitet dabei immer mit einer CRC Prüfsumme beim Übertragen der Befehle und den darauf folgenden Daten der 1. Page. Nachdem der Bootloader die 1. Page programmiert hat wird auch immer gleich ein Verify gemacht. Dh. das FLASHEN/Löschen von Pages und Schreiben in den EEPROM enthält ein implizites Verify. Benutzt man die Verschlüsselung so hat man sogar eine 64 Bit Prüfsumme inkusive über den XTEA mit Doppel-CBC Modus. Wenn dabei nur 1 Bit falsch sein sollte so propagiert sich dieser Bit Fehler durch alle nachfolgenden Datenblöcke bis zum letzten Datenblock. Der letzte Datenblock enthält eine 32 Bit Signatur (ersten 4 Bytes des Passwortes). Ich hatte noch darüber nachgedacht per DEFINES zuschaltbar eine ähnlich Vorgehensweise wie bei deinem Bootloader umzusetzen, aber so langsam verbraucht das Projekt einfach zuviel Zeit. Es fragt sich wie gering/hoch sind die Wahrscheinlichkeiten. Das mit der Souceformatierung ist so'ne Sache, jeder hat da seine Vorlieben. Ich mage es in gewisssen Projekttypen wenn ich nicht so viel zersplitterte Sourcedateien habe da man so den Überblick hat. Das Einlesen/Überblicken ist für Neulinge dann einfacher. Gruß Hagen
Datum:
Hallo Hagen, hast Du vor Deine Delphi-Sourcen auch zu posten? Ich würde mir gerne mal ansehen, wie Du die Übertragung der Dateien zu Kontroller realisiert hast. Ich bin im Augenblick dabei ein kleines Programm zu entwickeln, dass EEPROM-Inhalte an den Kontroller übertragen soll, aber irgendwie bekomme ich das nicht vernünftig hin. Gruß Frank
Datum:
Hallo Hagen, ich wollte deinen bootloader auf einen m168 ausprobieren, aber leider komme ich nicht zum Erfolg. a) Hardware: habe einen FTDI232BM zwischen dem mega168 und USB hängen der mega168 ist im 256word boot mode gefused. b) SW
; copyright HR .nolist ; supported devices ;.include "can128def.inc" ; AT90CAN128 ;.include "can32def.inc" ; AT90CAN32 ;.include "can64def.inc" ; AT90CAN64 ;.include "m1280def.inc" ; ATmega1280 ;.include "m1281def.inc" ; ATmega1281 ;.include "m128def.inc" ; ATmega128 ;.include "m161def.inc" ; ATmega161 ;.include "m162def.inc" ; ATmega162 ;.include "m163def.inc" ; ATmega163 ;.include "m164Pdef.inc" ; ATmega164P ;.include "m165def.inc" ; ATmega165 ;.include "m165Pdef.inc" ; ATmega165P .include "m168def.inc" ; ATmega168 ;.include "m168Pdef.inc" ; ATmega168P ;.include "m169def.inc" ; ATmega169 ;.include "m169Pdef.inc" ; ATmega169P ;.include "m16def.inc" ; ATmega16 ;.include "m2560def.inc" ; ATmega2560 ;.include "m2561def.inc" ; ATmega2561 ;.include "m323def.inc" ; ATmega323 ;.include "m324Pdef.inc" ; ATmega324P ;.include "m3250def.inc" ; ATmega3250 ;.include "m3250Pdef.inc" ; ATmega3250P ;.include "m325def.inc" ; ATmega325 ;.include "m325Pdef.inc" ; ATmega325P ;.include "m3290def.inc" ; ATmega3290 ;.include "m3290Pdef.inc" ; ATmega3290P ;.include "m329def.inc" ; ATmega329 ;.include "m329Pdef.inc" ; ATmega329P ;.include "m32def.inc" ; ATmega32 ;.include "m406def.inc" ; ATmega406 ;.include "m48def.inc" ; ATmega48 ;.include "m48Pdef.inc" ; ATmega48P ;.include "m640def.inc" ; ATmega640 ;.include "m644def.inc" ; ATmega644 ;.include "m644Pdef.inc" ; ATmega644P ;.include "m6450def.inc" ; ATmega6450 ;.include "m645def.inc" ; ATmega645 ;.include "m6490def.inc" ; ATmega6490 ;.include "m649def.inc" ; ATmega649 ;.include "m64def.inc" ; ATmega64 ;.include "m8515def.inc" ; ATmega8515 ;.include "m8535def.inc" ; ATmega8535 ;.include "m88def.inc" ; ATmega88 ;.include "m88Pdef.inc" ; ATmega88P ;.include "m8def.inc" ; ATmega8 ;.include "pwm2Bdef.inc" ; AT90PWM2B ;.include "pwm2def.inc" ; AT90PWM2 ;.include "pwm3Bdef.inc" ; AT90PWM3B ;.include "pwm3def.inc" ; AT90PWM3 ;.include "tn13def.inc" ; ATtiny13 ;.include "tn2313def.inc" ; ATtiny2313 ;.include "tn24def.inc" ; ATtiny24 ;.include "tn25def.inc" ; ATtiny25 ;.include "tn261def.inc" ; ATtiny261 ;.include "tn44def.inc" ; ATtiny44 ;.include "tn45def.inc" ; ATtiny45 ;.include "tn461def.inc" ; ATtiny461 ;.include "tn84def.inc" ; ATtiny84 ;.include "tn85def.inc" ; ATtiny85 ;.include "tn861def.inc" ; ATtiny861 ;.include "usb1286def.inc" ; AT90USB1286 ;.include "usb1287def.inc" ; AT90USB1287 ;.include "usb162def.inc" ; AT90USB162 ;.include "usb646def.inc" ; AT90USB646 ;.include "usb647def.inc" ; AT90USB647 ; unsupported devices, no self programming or sram to small ;.include "1200def.inc" ; AT90S1200 ;.include "2313def.inc" ; AT90S2313 ;.include "2323def.inc" ; AT90S2323 ;.include "2343def.inc" ; AT90S2343 ;.include "4414def.inc" ; AT90S4414 ;.include "4433def.inc" ; AT90S4433 ;.include "4434def.inc" ; AT90S4434 ;.include "8515def.inc" ; AT90S8515 ;.include "8535def.inc" ; AT90S8535 ;.include "AT86RF401def.inc" ; AT86RF401 ;.include "m103def.inc" ; ATmega103 ;.include "tn11def.inc" ; ATtiny11 ;.include "tn12def.inc" ; ATtiny12 ;.include "tn15def.inc" ; ATtiny15 ;.include "tn22def.inc" ; ATtiny22 ;.include "tn26def.inc" ; ATtiny26 ;.include "tn28def.inc" ; ATtiny28 #message "compile for" __PART_NAME__ .ifndef PageSize .error "Device don't support Bootloader !" .else .equ UseWDR = 0 ; set to 0/1 to de/activate WatchDog .equ UseAutobaud = 1 ; set to 0/1 to de/activate Baudrate Detection .equ UseVerify = 1 ; set to 0/1 to de/activate Verify FLASH Command, FLASH write/erase includes implicit verify, can be deactivated .equ UseE2Write = 1 ; set to 0/1 to de/activate EEPROM Write Command .equ UseE2Read = 1 ; set to 0/1 to de/activate EEPROM Read Command .equ UseSRAM = 0 ; set to 0/1 to de/activate SRAM Commands .equ UseCrypt = 0 ; set to 0/1 to de/activate cryptography .equ UseCryptFLASH = 0 ; set to 0/1 to de/activate only use cryptography for writing to FLASH .equ UseCryptE2 = 0 ; set to 0/1 to de/activate only use cryptography for writing to EEPROM .equ UartInvert = 1 ; set to 1 to invert UART levels, for RS232 drivers such as MAX232 .equ RX_PORT = PORTD ; Receive Port and Pin .equ RX = PD0 .equ TX_PORT = PORTD ; Transmit Port and Pin .equ TX = PD1 .set XTAL = 14745600 ; only important for BootDelay if Autobaud is used .set BootDelay = XTAL / 3 ; 300ms .set BootBaudrate = 115200 ; only used if no Baudrate Detection activated, XTAL is important .set BootVersion = 1 ; Version 1 .set BootCodeSize = 494 ; compile and set to value in [.cseg] Used, compile again |
c) error Meldung im flash Windowsprogramm: 30.03.08-22:24:34-875 > Connecting... 30.03.08-22:24:34-968 > Switch to 2-Wire mode 30.03.08-22:24:39-328 > Device connected 30.03.08-22:24:39-359 > programming Device... 30.03.08-22:24:39-375 > execute compiled data 30.03.08-22:24:39-375 > selected options in compiled file: 30.03.08-22:24:39-375 > - programming FLASH 30.03.08-22:24:39-375 > - erase FLASH during programming 30.03.08-22:24:39-375 > - full verify FLASH after programing 30.03.08-22:24:39-375 > - programming EEPROM 30.03.08-22:24:39-546 > ICOM: read error. 30.03.08-22:24:39-578 > Device disconnected hast du eine Idee?
Datum:
Nachtrag: folgendes kommt bei "device information": Connection : 2-Wire Device name : ATmega168 Device signature : 1E9406 SRAM size : 1024 Byte EEPROM size : 512 Byte FLASH size : 16384 Byte FLASH size for application : 15872 Byte FLASH pagesize : 128 Byte Bootloader size : 512 Byte Buffersize for data : 920 Byte SRAM start address : 256 Bootloader version : 1 Use bootsection : Yes Cryptography supported : No besten Dank :-)
Datum:
Angehängte Dateien:Gut, das heist 90% der wichtigen Arbeit geht schonmal, er hat eine 2-Wire Verbindung erkannt und alle Device-Infos sind korrekt empfangen. Ich habe die Timeouts sehr knapp bemessen. Bei den Zeiten für das Programmieren des FLASHs und EEPROMs habe ich fast alle Datenblätter duchwühlt und die maximalen Zeiten angenommen. Leider scheint es so zu sein das manche AVRs längere Zeiten benötigen als im Datenblatt angegeben. Ich habe nun mal die wichtigsten Timeouts in der INI konfigurierbar gemacht. In der Section [Timeouts] kannst du das einstellen. Erhöhe als erstes den Timeout für Flash=25. Bis auf "Buffer" und "Base" Timeout kann man eigentlich alle Timouts nach oben setzen ohne das sich was an den Gesamtprogrammierzeiten verändern sollte. Der Timeout "Base" ist speziell, normalerweise berechnet die Software den BaseTimeout nach der eingestellten Baudrate, also den Timeout für 1 Zeichen bis es komplett übertragen wurde. Mit dem Wert in "Base" kann man nun die minimale Wartezeit für diesen Timeout einstellen. Bei hohen Baudraten kann also der Timeout für 1 Zeichen unter zb. 25 Millisekunden betragen. Möchte man das auf 25 ms limitieren dann stellt man dies in "Base=25" ein. In AVRootloader.asm habe ich noch eine klitzekleine Verbesserung bei der XTEA Entschlüsselung die uns 6 Bytes FLASH einspart eingebaut. Desweiteren habe ich beim 2-Wire die Ansteuerung so verändert das der RX-PIN mit Pullup arbeitet falls man beide PINs RX und TX auf den gleichen Port gelegt hat. Gruß Hagen
Datum:
Ach übrigens, das Full Verify kannst du eigentlich immer abhacken. Die FLASH löschen und schreiben und EEPROM schreiben Funktionen haben ein implizites Verify integriert. Das zusätzliche Full Verify dient eigentlich nur dazu um überprüfen zu können ob das schon geflashte Program auf dem AVR mit dem aktuellen HEX File identisch ist. Und da du noch par Bytes Platz hast empfehle ich dir die Watchdog Unterstützung zu aktivieren. Der Watchdog wird damit nicht explizit aktiviert aber falls du per WachtDog aus deiner Applikation in den Bootloader springen möchtest oder generell den WatchDog eingeschaltet hast dann ist das sehr hilfreich. 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
// Pinchange ISR für PB6, bei LowLevel springen wir den Bootloader an __attribute__ ((naked)) ISR(PCINT_vect) { if (PINB & (1 << PB6)) { asm volatile("reti"); } else { asm volatile("rjmp __vectors"); } } int main(void) { MCUSR = 0; WDTCR = (1 << WDE) | (1 << WDCE); WDTCR = 0; // RX Pin auf Eingang mit Pullup DDRB = 0; PORTB = (1 << PB6) // PinChange on PB6, Bootloader Pin GIMSK = (1 << PCIE1); PCMSK1 = (1 << PCINT14); sei(); .. blabla while (1) { } } |
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. Ansonsten gehts auch über den WatchDog.
// Pinchange ISR für PB6, bei LowLevel springen wir den Bootloader an __attribute__ ((naked)) ISR(PCINT_vect) { if (PINB & (1 << PB6)) { asm volatile("reti"); } else { WDTCR = (1 << WDCE); WDTCR = (1 << WDE); for (;;) ; } } int main(void) { MCUSR = 0; WDTCR = (1 << WDE) | (1 << WDCE); WDTCR = 0; // RX Pin auf Eingang mit Pullup DDRB = 0; PORTB = (1 << PB6) // PinChange on PB6, Bootloader Pin GIMSK = (1 << PCIE1); PCMSK1 = (1 << PCINT14); sei(); .. blabla while (1) { } } |
Gruß Hagen
Datum:
Hallo Hagen,
super vielen Dank für dein schnelles update.
Ich habe deinen neuen Bootloader auf den mega168 mit gleichen settings
geflasht. Das flashen mit dem neuen Windows programm hat auf anhieb
geklappt. Ich brauchte keine weiteren timings anpacken. Baudrate war
256000b/s (FTDI chip).
Wollte dann rausfinden welches der minimum timeout Wert ist und bliebt
dann bei Flash=13 hängen. Alles über 13 war OK. Flash und Eeprom konnte
beides gleich gut geschrieben werden.
Mir ist allerdings aufgefallen, das ich das EEPROM nur mit max. 38400b/s
auslesen konnte ("EEPROM Content"). Hohere Baudratenwerte resultierten
zu einem "ICOM: read error". Auch ist unter "EEPROM Content" der "write
to devive" Button dekativiert, wenn ich ein externes *.eep file geladen
habe.
Bei "SRAM content" sieht es genau so aus. Leider nur bis 38400b/s ist
das auslesen möglich.
Crypted habe ich auch geflashed und hat auch geklappt. Einen minimalen
Geschwindigkeitunterschied habe ich bemerkt, aber dieser war klein 2,22s
zu 2,63sek bei 256000b/s.
...
Du hast zwar geschrieben, das der Bootloader so gut wie fertig ist, aber
ich würde trotzdem gerne paar kosmetische Wünsche äußern.
a)
Bei den folgenden settings brauche ich genau 514 bytes Bootcode size.
Kann man das vieleicht noch um 2 bytes drücken, damit es in die 256words
boot block passt? Gibt es da noch Optimierungsmöglichkeiten?
.equ UseWDR = 0
.equ UseAutobaud = 1
.equ UseVerify = 1
.equ UseE2Write = 1
.equ UseE2Read = 1
.equ UseSRAM = 1
.equ UseCrypt = 0
.equ UseCryptFLASH = 0
.equ UseCryptE2 = 0
.equ UartInvert = 1
b) eine Fortschrittsanzeige beim flashen wäre nett. Es wird zwar
"working" angezeigt und er hat 16kb in 2,2sek reingeflashed, aber wenn
ein Laufbalken keine Mühe machen würde, wäre das klasse.
vielen Dank für den tollen Loader + Windows Application. Großes
Dankeschön auch an Peter, der viel dazu beigetragen hat.
mfg.
chris
Datum:
Angehängte Dateien:@Chris, >Mir ist allerdings aufgefallen, das ich das EEPROM nur mit max. 38400b/s >auslesen konnte... Erhöhe den Wert für [Timeouts] Buffer=10 oder Base=50. Anbei mal die neuste Version. Ich habe das Fehlerhandling dahingehend geändert das man sieht in welcher internen Funktion eine Exception ausgelösst wurde. Das vereinfacht uns die Suche nach der richtigen Stelle für die wir den Timeout anpasssen müssen. Leider ist es so das Windows ganz unterschiedlich nach Treiber des Seriellen Gerätes die Timeouts benötigt. Ohne Timeouts geht es nicht und mit zu großen Timeouts verplempern die Gerätetreiber mehr Zeit als der Rest der Arbeit kostet. Teste es nochmal mit der neusten Version und sage mir was für eine Fehlermeldung kommt. Dann kann ich dir genau sagen welchen Timeoutwert wir erhöhen müssen. >Crypted habe ich auch geflashed und hat auch geklappt. Einen minimalen >Geschwindigkeitunterschied habe ich bemerkt, aber dieser war klein 2,22s >zu 2,63sek bei 256000b/s. Bei einem ATMega128 ist der Unterschied 16 sec. zu 22 sec. wobei der ATMega mit 16Mhz läuft. Leider ist eben sichere Kryptography per Software auf dem AVR immer aufwendig. Der XTEA ist da schon schnell im Vergleich zu zb. DES oder AES. Man kann ungefähr 700 Takte pro Datenbyte rechnen. >Bei den folgenden settings brauche ich genau 514 bytes Bootcode size. >Kann man das vieleicht noch um 2 bytes drücken, damit es in die 256words >boot block passt? Gibt es da noch Optimierungsmöglichkeiten? Kenn ich und mich nervt das dann auch sehr ;) Du kannst UseVerify=0 setzen. Wie schonmal gesagt ist diese Option für den Hobby-Betrieb meistens überflüssig. Alles an Datenübertragung ist per 16Bit CRC abgesichert. Zuerst überträgt man 2 Bytes Kommandocode dann darüber eine 2 Bytes CRC. Sollte also da schon ein Bitfehler aufgetreten sein merkt das die Software schon frühzeitig. Bei den Komandos du danach noch weitere Daten senden werden diese wiederum per CRC abgesichert. Nachdem man also einen FLASH/EEPROM Datenbuffer gesendet hat wird der Befehl zum Schreiben der Daten in den FLASH/EEPROM gesendet. Beide Fuktionen schreiben die Daten weg und verifizieren anschließend die geschriebenen Daten, indem diese Funktionen den FLASH/EEPROM erneut auslesen, mit den Daten im Buffer. Somit hat man schon ein implizites Verify das sehr schnell geht da keine Daten erneut zum AVR gesendet werden müssen. Die einzigste Schwachstelle an dem Konzept ist als die CRC Prüfsumme über die empfangenen Daten. UU. kann es vorkommen das mehrere Bitfehler gleichzeitg auftreten und die CRC Prüfsumme versagt. Dann schreibt man quasi fehlerhafte Daten in den FLASH und das implizite Verify merkt davon nichts. Bei meinen Test mit absichtlich schlecht gewählten Baudraten und somit ständigen Fehlern hat der AVR nicht ein einzigstes Mal den Datenübertragungsfehler nicht bemerkt. Bei meinen Test war nur eine Baudrate von 256000 kritisch (bei 16Mhz Takt mit interner PLL und RC-Oszi auf ATtiny461). Im Besonderen ist das Lesen von Daten vom AVR bei 256000 Baud kritisch. Die interne Zeitschleife ist dann sehr kurz und benötigt bei 16Mhz nur 33 Takte. Ich würde dir also raten wieder auf 128000/115200 Baud runter zu gehen. Wenn du das mal genauer analysierst (also die Programmierzeiten) so wirst du feststellen das die USB-RS232-Treiber keinen großen Geschwindigkeitsvorteile bringen. Bei mir ist es sogar so das eine normale COM-Schnitstelle bei 115200 leicht schneller ist als ein USB-RS232-Dongle bei 256000. Davon mal abgesehen, erzeugt dieser USB-RS232 Treiber auf meinem System bei dieser Baudrate sporadisch einen Bluescreen (das sind die einzigsten Bluescreens die ich seit Jahren gesehen habe auf meinem System!) Ansonsten könntest du UseAutobaud=0 setzen, du benutzt ja einen externen Quarz. Oder du verkürzt BootSign: db. "BOOT" auf zb. "BT". Dann gehst du in AVRootloader.INI und ändert in [System] Sign=BT um. Was anderes fällt mir nicht ein, es gibt aus meiner Sicht keine anderen Möglichkeiten des Code noch kürzer zu machen ohne das man was an der Funktionalität verändert. >b) eine Fortschrittsanzeige beim flashen wäre nett. Es wird zwar >"working" angezeigt und er hat 16kb in 2,2sek reingeflashed, aber wenn >ein Laufbalken keine Mühe machen würde, wäre das klasse. Nicht so einfach möglich, auf Grund des Datenkonzeptes schon. Denn wenn wir mit verschlüsselten Daten arbeiten dann wird alles in eine binäre "Scriptdatei" compiliert, passiert auch bei unverschlüsselten Daten, aber die Verschlüsselung war der Grund für diese Scriptdateien. Eine solche Scriptdatei ist quasi eine Liste aller Befehle + Daten die an den AVR gesendet werden. Vorteil ist eben das ich das als Basis für weitere Features benutzen wollte, zb. man kann extern solche Scripte erzeugen und durch meine Software ausführen lassen. Nun das verschlüsselte Format verschlüsselt nicht nur die Daten und ihre wahre Größe sondern auch die Addresen an die diese Daten geflasht werden sollen. Da meine Sofwtare beim Erzeugen solcher Dateien auch "Lücken" im FLASH die nur mit 0xFF gefüllt werden erkennt und entfernt (dh. es werden nur Pages programmiert die nicht vollständig mit 0xFF gefüllt sind, solche Pages werden per Erasekommando nur gelöscht). Es gibt also konzeptionell gesehen keine so einfache Möglichkeit einen Fortschrittsbalken zu bauen, bzw. wenn dann würde er eher nach der Anzahl der Befehle funktionieren und keinen zeitlichen Zusammenhang zur Gesamtdauer der Befehle enthalten. Ich denke mal drüber nach, aber dann kann es nur so sein das ich die Anzahl der abzuarbeitende Befehle/Kommandos dafür benutze. >Auch ist unter "EEPROM Content" der "write >to devive" Button dekativiert, wenn ich ein externes *.eep file geladen >habe. Hm geht schon nur gewusst wie ;) Ich habe diesen "Fehler" aber in obiger Version beseitigt. Normalerweise ist es nämlich so das du im HEX Editor Daten veränderst. Diese werden rot markiert dargestellt. Im EEPROM-HEX-Editor kannst du per rechten Mausklick ein Popupmenu öffen mit dem du diese Selektion auch selber setzen kannst. Markiere einfach mal im EEPROM die Addressen 0x0000 bis 0x001F. Dann Rechten Mausklick und im Popup "Select Cells" auswählen. Wenn du nun "Write to Device" oder "Save to File" anklickst so werden nur diese ausgewählten Zellen programmiert bzw. gespeichert. Alle anderen nicht markierten Zellen werden im AVR nicht verändert. Lange Rede kurzer Sinn: Man kann also von einem AVR den EEPROM auslesen. Dann markiert/editiert man nur einen ausgewählten Bereich davon und speichert das in eine EEP Datei. Nun wählt man diese EEP Datei samt HEX Datei für den FLASH auf der 1. Page der Sofwtare. Dann drückt man "Copile" und erzeugt eine ACY-Datei. Wird diese Datei ausgeführt dann werden nur die EEPROM Zellen programmiert die man vorher manuell ausgewählt hat. Sinn ist es das man selektive Konfigurationen in das EEPROM schreiben kann. In der neusten Version wird wenn nichts in den HEX-Editoren selektiert ist alles geschrieben. Beim SRAM Content aber nur der SRAM Bereich. Das violette Registerfile und der grüne IO-Bereich wird nicht geschrieben. Den IO-Bereich musst du also weiterhin explizit editieren. >vielen Dank für den tollen Loader + Windows Application. Großes >Dankeschön auch an Peter, der viel dazu beigetragen hat. Ja dem schließe ich mich an, habe viel gelernt. Gruß Hagen
Datum:
Hallo Hagen, deine ausführlichen Antworten sind wirklich bemerkenswert. Du steckst ne menge Zeit da rein, aber ich denke ich habe nun alles soweit hinbekommen und verstanden. >Erhöhe den Wert für [Timeouts] Buffer=10 oder Base=50. >Anbei mal die neuste Version. Ich habe das Fehlerhandling dahingehend >geändert das man sieht in welcher internen Funktion eine Exception >ausgelösst wurde. Deine neue Windows Applikation gibt mir folgende Meldung aus, wenn Base auf 25 steht. Connecting... 31.03.08-21:48:09-064 > Switch to 2-Wire mode 31.03.08-21:48:09-846 > Device connected 31.03.08-21:48:09-877 > read EEPROM... 31.03.08-21:48:09-908 > CmdReadEeprom.ReadByte(1) ICOM: read error. 31.03.08-21:48:09-924 > Device disconnected Durch Erhöhung des Wertes auf 50 funktioniert es gut. Es gibt keine Fehlermeldung mehr. Allerdings auch genau ab 50, Werte <50 resultieren im oben genannten Fehler. Dies habe ich bis max. Baudrate getestet. >>Bei den folgenden settings brauche ich genau 514 bytes Bootcode size. >>Kann man das vieleicht noch um 2 bytes drücken, damit es in die 256words >>boot block passt? Gibt es da noch Optimierungsmöglichkeiten? >Kenn ich und mich nervt das dann auch sehr ;) >Du kannst UseVerify=0 setzen. Ja, du hast recht. Sieht so aus, das der "normale" flashvorgang reicht um eine recht hohe Fhashwahrscheinlichkeit zu erreichen. Das verkürzen des Boot sign von "BOOT" auf "BT" würde in meinem Fall wirklich helfen, wow. :) Wenn dieses keine weiteren Auswirkungen hat, würde ich jetzt einfach mal dauerhaft bei mir so einstellen. >>b) eine Fortschrittsanzeige beim flashen wäre nett. Es wird zwar >>"working" angezeigt und er hat 16kb in 2,2sek reingeflashed, aber wenn >>ein Laufbalken keine Mühe machen würde, wäre das klasse. >Nicht so einfach möglich, auf Grund des Datenkonzeptes schon. Das ist absolut kein Thema. Sowas ist auch wirklich nur "nice to have". Es gibt ja ein feedback im Protocol was einem anzeigt ob alles geklappt hat. >>Auch ist unter "EEPROM Content" der "write >>to devive" Button dekativiert, wenn ich ein externes *.eep file geladen >>habe. >Hm geht schon nur gewusst wie ;) Ich habe diesen "Fehler" aber in obiger >Version beseitigt. Normalerweise ist es nämlich so das du im HEX Editor >Daten veränderst. Diese werden rot markiert dargestellt. ja, ich habe mittlerweile auch rausgefunden, wie man den Editor richtig bedient. :) trotzdem sehr hilfreich das man jetzt ohne Änderung des Inhaltes sofort die EEPROM Inhalt schreiebn kann. Sowas brauche ich recht regelmäßig da ich ein Parameterimage im EEPROm ablege. vielen Dank und ich hoffe das dies auch anderen Leuten geholfen hat. cu chris
Datum:
>Das verkürzen des Boot sign von "BOOT" auf "BT" würde in meinem Fall >wirklich helfen, wow. :) Kürzer geht halt nicht mehr, es sollten also mindestens 2 Zeichen sein und der komplette String sollte eine gerade Anzahl an Zeichen haben. Dieser String dient einerseits als Identifier/Passwort, andererseits auch zum "Testen" der Verbindung. Wenn es also möglich ist sollte der String schon länger sein da so Übertragungsfehler auf Grund einer leicht daneben liegenden Auto-Baudrate besser erkannt werden. >Durch Erhöhung des Wertes auf 50 funktioniert es gut. Es gibt keine >Fehlermeldung mehr. Allerdings auch genau ab 50, Werte <50 resultieren >im oben genannten Fehler. Dies habe ich bis max. Baudrate getestet. Das deutet auf schon oben genanntes Verhalten der verschiedenen RS232-USB-Treiber hin. Normalerweise benötigt der AVR maximal 10 Takte bis er anfängt die ersten Datenbytes aus dem EEPROM an den PC zu senden. Also niemals 50ms an Zeit. Der Timeout entsteht beim ersten zu empfangenden Datenbyte beim Auslesen des EEPROMs, gleich nach dem Senden der 2 Kommandobytes + 2 Bytes CRC. Sowas kann nur passieren weil der USB-RS232-Treiber oder das USB-Hardware-Protokoll Zeitverzögerungen einbaut. Du solltest also in deinem Falle den Timeout "Base" immer auf minimal 50ms stehen lassen, denn bei deiner Hardware/Treiber kommen quasi 50 + 1000000/Baudrate * Datenbytes Zeitverzögerung raus. Rechnet man das Verhältnis aus so sieht man das dise 50ms weit über der Zeit liegen die man für ganze Datenpackete ansich benötigen würde. Deshalb nutz ich die gute alte UART meines Laptops ;) Eventuell müsstest du auch "Buffer" auf 50ms setzen, aber das erhöht drastisch die Programmierzeiten ! Vielleicht findest du ja einen Dreh wie man den USB-RS232-Treiber dazu überedet mit kürzeren Zeitverzögerungen zu arbeiten. Ich arbeite zZ. mit Base=25 Erase=5 Flash=10 Eeprom=10 Buffer=1 und normaler UART bei 115200 Baud ohne Probleme. Gruß hagen
Datum:
Angehängte Dateien:Hier die neuste Version, geändert wurden: - Anleitung zur Benutzung der Verschlüsselung und der prekompilierten ACY- Dateien beigefügt - Wenn AVRootloader.exe eine Verbindung herstellen möchte so zieht er den DTR-Pin der RS232 auf High-Pegel. Damit kann man über DTR eine Stromversorgung zb. eines Treibers machen, aber bitte RS232 Spezifikationen beachten - unter Win2k/Win95 wurde das Fenster der AVRootloade.exe nicht in den Vordergund geholt. Stattdessen blinkte nur das Icon in der Tastleiste. Dieses Problem wurde behoben (ist aber auch Standardverhalten auf diesen Windowsversionen) - Darstellungsprobleme im SRAM-Content HEX-Editor beseitigt - mit rechten Mausklick in diese HEX-Editoren öffnet sich ein Popup-Menu mit dem man zb. selektierte Zellen im Editor rot markieren kann. Beim Zurückschreiben in den AVR oder beim Speichern in eine Datei werden dann nur diese selektierten Zellen berücksichtigt. Mit diesem Feature kann man zb. selektive EEPROM Dateien erzeugen die nur ausgeählte Speicheraddressen schreiben. - die AVR Device Liste in AVRootloader.asm (.includes) wurde auf den neusten Stand gebracht - die Datei AVRootloader.dev wurde ebenfalls auf den neusten Stand gebracht, möchte man diese neu erzeugen lassen so muß AVRStudio im System korrekt installiert sein. Löscht die aktuelle AVRootloader.dev Datei und startet die Anwendung. Aus den XML Part Description Files des AVR Studios wird dann eine neue AVRootloader.dev erzeugt. - Howto für selektive EEPROM Updates hinzugefügt Gruß Hagen
Datum:
Angehängte Dateien:Leider war noch ein Fehler drinnen, ich hasse das wenn man unter Zeitdruck arbeitet. Die Funktion "make Password" veränderte die Formatierung des Passwortes in der AVRootloader.asm und in der AVRootloader.ini falsch. Jetzt ist's richtig ;) Danke an Wolfgang der mich darauf aufmerksam gemacht hat. Gruß Hagen
Datum:
@Hagen Mal 'ne einfache Frage, ich überlege schon seit Tagen, wofür man einen Bootloader mit Verschlüsselung benötigt. Wer soll da wo Daten klauen und vor allem wie? Wäre froh, wenn Du mir das erklärst, damit ich wieder schlafen kann ;-)
Datum:
@ Neugieriger Z.Bsp. wenn du mehrere Geraete im Umlauf hast und bei einer Programaenderung nicht selbst von Standort zu Standort wandern und diese updaten willst. @Hagen Re Danke für Dein Programm. Werde es in meiner naechsten grösseren Serie mal einsetzen.
Datum:
Hallo Hagen! Ist es möglich mehrere Controller gleichzeitig zu programmieren, Wenn diese alle parallel an der Seriellen Schnittstelle hängen.
Datum:
Wie soll das gehen, wenn eine Point-to-Point Kommunikation stattfindet? Es geht hier um einen Bootloader und nicht etwa um ein Programmiergerät...
Datum:
Ja ich weiß. Ich habe aber eine Anwendung wo ich bis zu 10 Controller parallel betreiben will. Diese laufen alle mit der gleichen software. Ist nur blöd immer jeden einzeln zu programmieren. Vielleicht hat jemand ja eine Idee.
Datum:
Möglich ist sowas aber nicht mit dem Bootloader wie er jetzt ist, vielleicht sogar ja doch. Wenn alle AVR Bootloader als BootSign: einen anderen Wert hätten, zb. AVR1 hat "BOOT1" AVR2 hat "BOOT2" usw. Alle liegen sie per 1-Wire auf dem gleichen Bus und die 1-Wire-RS232 wäre der Master. Dann könnte eine Point-to-Point Kommunikation von mehreren Geräten quasi im Halb-Duplex funktionieren, eben so wie auf einem 1-Wire-Bus. Die PC-Software müsste dann nacheinander erst die Signatur "BOOT1" senden und warten bis sich der entsprechende AVR meldet. Dann wird dieser Programmiert, danach sendet der PC nun "BOOT2" und verbindet mit AVR2 usw. usw. Gruß Hagen
Datum:
Ich hatte an etwas ähnliches gedacht. Komfortabler wäre es doch wenn mann in der Windows Software die Anzahl der Controller angeben könnte, damit die Windows Software dann je nach Anzahl der Controller, nacheinander die Abfrage tätigt (also z.B. BOOT1,BOOT2..) Alle Controller lauschen auf der RX Leitung und aktivieren den TX Zweig zum Antworten nur wenn sie gefragt werden. Danach deaktivieren sie diesen wieder. Wenn die Windows Software alle Antworten gesammelt hat kann die Programmierung ja parallel laufen. Oder ist solches nicht möglich?
Datum:
Damit müssen doch die Bootloader wieder unterschiedlich sein. Im zweifelsfall reicht es ja vielleicht unterschiedliche Passwörter zu nehmen. Es reagiert dann jeweils nur der Controller, wo das Passwort passt.
Datum:
Hardwaremäßig ist es am einfachsten im 1-Wire-Modus zu arbeiten, das geht ohne Umprogrammierung der Software (AVR-Bootloader) jetzt schon. Das BootSign: aktuell der Wert "BOOT" ist das was du unter Passwort verstehst. Das lässt sich in der PC-Software in AVRootloader.ini jetzt schon ändern. Man müsste die PC-Software so umprogrammmieren das sie diesen Wert autom. inkrementiert. Allerdings ist es schon richtig das man bei diesem Verfahren die AVRootloader.asm individuell programmieren müsste. Vorstellbar wäre es diese Software so zu erweitern das eine Serialnummer im EEPROM abgelegt wird. Am Anfang installiert man auf den AVR diese Software und programmiert diese Serialnummer individuell, also immer nur ein AVR an der 1-Wire Hardware angeschlossen. Nach diesem Setup kann man alle AVRs parallel am 1-Wire hängen. Die PC Software fragt nun wie beim Original-1-Wire diese Serialnummer=ID ab und ermittelt auf diese Weise alle AVRs die am 1-Wire-Bus hängen. Danach kann man per PC-Software selektiv all Geräte flashen oder eben eine Auswahl oder alle in einem Rutsch sequientiell nacheinander. Gruß Hagen
Datum:
Wenn man sich die Anforderung von James ansieht und daraus ableitet, welcher Aufwand schon beim Programmieren der einzelnen Bootloader zu betreiben wäre, oder den Aufwand, der seitens Hagen notwendig wäre, dann würde ich mal ein back-to-the-roots anregen. Warum nicht einfach ein Lötpad in der Nähe eines jeden Controllers und diesen mal kurz mit einer Prüfspitze berühren. Parallel dazu einen Taster, der die Betriebsspannung aus-einschaltet und fertig, oder einfach den Pin vom Controller aus überwachen, so wie Hagen es oben dargestellt hat. Das geht doch ratz-fatz...
Datum:
Ich fände es gut, wenn die Windowssoftware noch ein "simples" Terminal Program mitbringen würde. Da ich über dieselbe serielle Schnittstelle programiere wie die, auf der ich Statusmeldungen ausgebe fände ich es gut, wenn das in einer Software wäre. Was hälst du davon? Werner
Datum:
Hatte ich auch schon dran gedacht aber es stellt sich die entscheidende Frage wie solls gehen ? Der Bootloader sollte primär vollkomman unabhängig zur eigentlichen Anwendungssofwtare sein. Die PC-Software wäre demnach eine Kombination aus Bootloader-Software für den AVR-Bootloader und Terminal-Software für die Anwendung. Soweit unproblematisch wenn dieses Terminal vollkommen separat funktioniert. Dh. also eigener Verbindungsaufbau usw. da ja nicht mit dem Bootloader connected wird sondern mit der installierten Anwendung. Die Anwendung im AVR muß also selber die UART Kommunikation machen unabhängig vom Bootloader. Dazu hatte ich angedacht eine 1-Wire Bibliothek die per Interrupts arbeitet vorzusehen die man dann in die eigene Anwendung einbinden könnte. Nur die liebe Zeit ist das Problem. Ich programmiere in meiner Freizeit nur Dinge die ich auch selber benötige, verständlich oder ? Wenn also irgendeiner eine solch fertige Library mir anbietet dann bin ich gerne bereit meine PC-Software dahingehend anzupassen. Das ist im Grunde kein großer Aufwand. Ich habe mir auch schon AVR309 (IgorPlug-USB) angeschaut und als untauglich verworfen da dort keine Kommunikationstimeouts unterstützt werden die aber für das Bootloaderprotokoll essentiell sind. >Da ich über dieselbe serielle Schnittstelle >programiere wie die, auf der ich Statusmeldungen ausgebe fände ich es >gut, wenn das in einer Software wäre. Siehst du, Du machst es so. Ich zb. habe am gleichen 1-Wire-Pin normalerweise eine LED, also Ausgang dran, im aktuellen Projekt. Wenn sich bei mir also der Bedarf nach so einer Schnittstelle andeutet würde ich das auch in die gleiche PC-Software integrieren, logisch. Gruß Hagen
Datum:
Ich arbeite mit den "normalen" Uart-Routinen aus meinem Hauptprogramm. Da ich "genügend" I/O habe benutze ich auch den 2-Draht Modus. Aber schön zu hören, dass das vielleicht noch kommt ;-) Wenn ich das richtig verstanden habe, ist der normale Ablauf doch wie folgt - PC Software starten - Connect to device - AVR einschalten bzw. resetten - PC Software connected - danach kann ich programmieren Manchmal habe ich nun, dass die PC Software zwar in den connected Modus wechselt, aber die alte Anwendung auf dem AVR trotzdem gestartet wird. Dann kann ich natürlich nicht programmieren. Würde es hierbei etwas bringen, die Wartezeit des Bootloader hochzusetzten, oder was läuft hier schief? Werner
Datum:
Ja, Wartezeit hochsetzen. Die PC-Software sendet beim Connect (egal ob manuell mit Connect-Button ausgelösst oder durch Button "Program"/"Erase" etc.pp. automatisch ausgelösst) permanent ein #0#0#0#0#13BOOT. #0#0#0#0 steht für Kommando "Restart Bootloader", #13 ist das Zeichen für die AutoBaud Funktion und "BOOT" das Passwort/die Signature. Das Interval dieses Packetes definiert sich über die Baudrate, je höher die Baudrate desto höher kann das Wiederholungsinterval werden. Der AVR-Bootloader versucht nun innerhalb von zb. 300ms (default und fix) darauf zu reagieren. Nun kann es vorkommen das das Timing so ungünstig ist das sich diese Intervalle auf eine Art überschneiden das keinerlei Connect möglich ist. Dann einfach nochmal RESET/POWER OFF drücken. Oder aber in der Applikation so wie oben schon angedeutet auf Pegelwechsel am RX-PIN reagieren. Dann würde die Applikation solange in den Bootloader springen bis die PC-Software aufhört irgendwas zu senden. In diesem Falle kann man das BootDelay im AVR-Bootloader als defakto deaktiviert ansehen und die PC-Software steuert den AVR fern. Alternativ könnte ich das BootDelay so abändern das nicht exakt x Milliskunden im Gesamten gewartet wird, also fester Timeout, sondern das wenn nach x Millisekunden rein garnichts passiert ist ein Timeout entsteht. D.h. würde das BootDelay zb. auf 300ms stehen und nach 200ms kommt irgendein Impuls auf Rx rein so verlängert sich das Delay um weitere 300ms. Somit würde der Bootloader solange im Delay bleiben bis entweder eine gültige Verbindung zustande kam (Bootloader startet) oder aber die PC-Software für mindestens 300ms Ruhe gibt (Applikation startet). Ist also keine PC-Software aktiv so startet die Applikation nach 300ms, ist eine PC-Software aktiv so läuft der Connect-Prozess so lange bis die PC-Software "aufgibt" und 300ms später startet die Applikation, oder es aber zu einer gültigen Verbindung kommt (nochmal in anderen Worten;). Solche Probleme lassen sich nur dann umgehen wenn man zusätzliche Steuerleitungen mit diesen Funktionen vorsieht. Eine Möglichkeit habe ich jetzt schon integriert. Der DTR Ausgang der RS232 wird beim Beginn eines Connects in der PC-Software auf HIGH-Peel gezogen (ist normalerweise -12 bzw. -6 oder sogar 0 Volt, je nach RS232 Hardware). Man könnte also den DTR über eine Shottky wie beim 1-Wire an einen Pin des AVRs legen. DTR wird momentan so geschaltet damit man aus diesem Pin quasi eine Spannungsversorgung eines Pegelwandlers (2x Transistor) aufbauen kann. Ich hatte auch schon vorgesehen das der RTS Pin ebenfalls kurzeitigt seinen Pegel verändert, von HIGH auf LOW und wieder HIGH. Über eine Shottky wie beim 1-Wire direkt an den RESET des AVRs. Die PC-Software pulst diesen Pin nun vor jedem Connect-Versuch. Habe ich aber wieder rausgenommen und kann wenn gewünscht wieder eingebaut werden. Aber genau der Punkt das man auch nur mit wenigen Kabeln arbeiten kann ist primäres Ziel gewesen bei diesem Bootloader ;) Gruß Hagen
Datum:
Hallo Hagen, ich wollte jetzt mal auch Deine tollen Bootloader benutzen, an einem ATMEGA162, nachdem ich n halben Tag gesucht habe und endlich gefunden hab, das ich ja n MAX232 davorgeschaltet habe und natürlich dann: .equ UartInvert = 1 setzen muß, bin ich jetzt ein Stück weiter, Aber leider funktioniert das Programmieren nicht: 18.04.08-18:02:02-958 > Switch to 2-Wire mode 18.04.08-18:02:03-083 > Device connected 18.04.08-18:02:04-833 > programming Device... 18.04.08-18:02:04-833 > execute compiled data 18.04.08-18:02:04-833 > selected options in compiled file: 18.04.08-18:02:04-833 > - programming FLASH 18.04.08-18:02:04-942 > CmdFlash.ResCheck() Error: Verify failed Ich hab schon verschiedene Baudraten und Timeouts probiert, daran schein es nicht zu liegen. Hast Du evtl. n Tip ? Die Idee mit dem Terminal ist mir auch gleich aufgefallen, ich hab hier ZOC in Verwendung, und wenn das gestartet ist kommt die AVRootloader.exe nicht mehr an die COM, also Programm beenden, AVRootloader.exe aufrufen, programmieren, usw., Ne integrierte Lösung wär schon nicht schlecht, muß ja kein ausgewachsenes Terminal sein, nur Ein- und Ausgaben. Da ich meißtens ein CommandLineInterface in meine größeren AVRs integriere wäre das echt hilfreich. Danke und Grüße, Micha
Datum:
Hm, das sieht übel aus. Es bedeutet das dein AVR kaputt geflasht ist. Mal davon abgesehen das auch ein Fehler im Bootloader voehanden sein könnte ;) Nach dem Programmieren einer FLASH Page wird der FLASH sofort wieder ausgelesen und mit den soeben programmierten Daten im SRAM Buffer verglichen. Sollte es dabei zu einer Inkonsistenz kommen wird der Fehler "Verify failed" zurückgeliefert. Also schlägt bei dir das implizite Verify zu und meint das dein FLASH nicht sauber programmiert werden kann. Gehen wir davon aus das der Bootloader keinen Fehler macht, deine Hardware ansonsten sauber ist (keine Spannungseinbrüche in der Versorgung zb.) dann heist dies das dein AVR defekt ist. Wenn du den ISP noch dran hast dann solltest du erstmal versuchen deinen AVR damit zu flashen. Es sollte dann ebenfalls ein Verify Fehler auftreten. Dann wäre dein AVR FLASH definitiv kaputt. Am besten flasht du alle Zellen einmal auf 0x00 und einmal auf 0xFF um sicher zu gehen. Wenn kein Verify Fehler per ISP auftritt dann muß ein Fehler im Bootloader vorliegen, kann aber beim besten Willen nicht sagen was dort falsch sein sollte. >Die Idee mit dem Terminal ist mir auch gleich aufgefallen, ich hab hier >ZOC in Verwendung, und wenn das gestartet ist kommt die AVRootloader.exe >nicht mehr an die COM, also Programm beenden, AVRootloader.exe aufrufen, >programmieren, usw., Ja ich weiß :) Ich hatte als ich began mit dem Bootloader schon die gleiche Idee aber immer wieder verworfen. Es ist eben eine Bootlaoder Software und keine Applikationsbezogene Software. Ich denke nochmal drüber nach verspeche aber nichts, es stehen erstmal andere Änderungen an. 1.) die Funktionalität des Bootloaders wird in ein Interface gepackt. Die Funktionalität der Kommunikationsschnittstelle (bisher COM-Port) ist schon längst in einem solchen Interface. Das Ganze kommt in eine DLL. Nun kann man mit allen Standard-Programmiersprachen für Windows die Interfaces, also COM, DCOM unterstützen auf diese Interfaces der DLL zugreifen. Somit ist die komplette Bootloader Funktionalität auch aus eigenen Programmen heraus nutzbar. Man kann so auf einfache Weise entweder das Kommunikations-Interface durch ein egenes ersetzen, zb. direkter USB Treiber, AVR309 wenn man möchte etc.pp. Oder man kann eigene Befehle die man in den AVR-Bootloader integriert hat mit dem Bootloader Interface erweitern. 2.) es wird eine PIN geben. In den ersten par EEPROM Zellen des AVRs kann in Zukunft eine PIN programmiert werden. Der Bootloader bekommt ein neues Kommando bei dem man diese PIN dem Bootloader mitteilen muß damit er alle anderen Kommandos überhaupt akzeptiert. So kann man jeden AVR individuell mit dieser PIN schützen. Kann sie nach Eingabe der PIN über das EEPROM Kommando neu schreiben oder löschen. Statt PIN könnte man sagen Serialnummer die als programmierbares Passwort benutzt wird. Damit gibt es also insgesamt drei verschiedene Schutzmaßnahmen die der Bootloader unterstützt. Das BootSign -> "BOOT" das als harcoded Passwort für alle AVRs mit gleichem Bootloader dienen kann. Die PIN die im EEPROM individuell für jeden AVR programmiert werden kann, zb. auch durch die Endkunden. Und schlußendlich die Verschlüsselung samt 128 Bit Passwort um Fernupdates gesichert durchführen zu können. Natürlich ist die Unterstützung einer solchen PIN ebenfalls konfigurierbar. 3.) das Verfahren des Boot Timeouts wird leicht geändert. 4.) Vieleicht, aber nur vieleicht ! Ein Standalone Bootloader für den PC. Mit der jetzigen PC Software würde man dann eine eigene EXE kompilieren die die verschlüsselte ACY-Datei (HEX für FLASH/EEPROM) enthält. Das GUI dieser Anwendung würde wie ein Setup-Assistent aussehen, die automatische Ermittlung der Schnittstelle enthalten und auch autom. die eingebundene ACY-Datei flashen. Gruß Hagen
Datum:
Hallo Hagen, Danke für Deine schnelle und ausführliche Antwort, da können wir ja noch einiges erwarten von Deinem Projekt, :-) die Idee mit der DLL ist sehr gut, da ich nämlich hier schon ein Sourceproject für ein Terminal-programm habe, allerdings in C, aber vielleicht kann man dann beide irgendwie verheiraten, :-)) bzgl. meinem AVR, gottseidank hatte ich noch den ISP dran, war ja noch am Bootloader-basteln, also das Programmieren/Verify über ISP funktioniert stabil und problemlos, sowohl alles FFFF (kriegt man ja durch erase schnell hin :-)), als auch alles 0000, oder die Applikation selbst, wie gesagt über ISP ist alles ok. still any ideas ?? :-)) Grüße, Michae
Datum:
Uff. Versorgt der ISP den AVR mit Spannung ? Das Problem was ich sehe ist das die Routine die den FLASH programmiert ihre Daten aus dem SRAM bekommt. Damit wird der Pagebuffer befüllt und anschließend der Program Befehl ausgeführt. Danach lädt der AVR nochmal die soeben programmierten Zellen aus dem FLASH und vergleicht sie mit den Daten im SRAM. Es gibt also nur 4 Möglichkeiten wo ein Fehler passieren kann. 1.) FLASH Programmierung, dh. dein FLASH ist wirklich defekt oder kann nicht sauber programmiert werden weil deine Spannungsversorgung schlecht ist 2.) SRAM Daten verändern sich willkürlich zwischen der FLASH-Programierphase und FLASH Verifyphase. Auch das könnte an einer Spannungsversorgung liegen 3.) meine Software im AVR hat an dieser Stelle noch einen Bug. Das halte ich aber für unwahrscheinlich, ich hatte bisher noch nie einen solchen Verify Fehler selbst mit einem Projekt bei dem die Spannungsversorgung sehr heikel ist (Solar-Panel -> 1.2V NiMH Akku -> Stepup auf 3.0 Volt). 4.) Datenübertragung, dh. alles läuft im AVR korrekt ab, am Ende wird der Returncode SUCCESS gesendet aber als ERRORVERIFY empfangen. Das ist aber enorm unwahrscheinlich da diese Fehlercodes sich im oberen Nibble komplett unterscheiden -> $3x -> $Cx. Wie gesagt bisher hatte ich bei meinen Projekten (ATtiny45, ATtiny461, ATmega168) keinerlei Probleme. Mache mal folgendes: 1.) AVRootloader.asm -> UseSRAM = 1, UseE2Read=1, UseE2Write=1 setzen, neu compilieren und installieren, WICHTIG! vergiß nicht BootCodeSize=??? anzupassen so wie es in der Readme steht. 2.) AVRootloader.exe starten und über Button "Connect to device" eine Verbindung herstellen 3.) auf Page "Device Information" überprüfen ob alle Angaben mit deinem AVR übereinstimmen 4.) auf Page "SRAM Content" gehen und Button "Read from Device" drücken 5.) in dem grünen Bereich des HEX Editor gehen und rechten Mausklick machen, im Popup "Clear Cells" drücken 6.) auf Button "Write to device" klicken 7.) auf Button "Read from device" klicken und schauen ob alle Zellen im grünen Bereich weiterhin auf 0x00 stehen (bis auf die letzten par Bytes -> Stack) 8.) nun alle Zellen im grünen Bereich auf 0xFF setzen und Steps 6.-7. wiederholen Du musst dann immer exakt das wieder aus dem SRAM auslesen was du vorher dort hineingeschrieben hast. Sollte das nicht der Fall sein so hast du ein Kommunikationsproblem, zb. mit dem MAX-Treiber. Die gleichen Tests kannst du auch mit dem EEPROM machen -> Page "EEPROM Content". Hier wird wie beim FLASH ebenfalls das implizite Verify durchgeführt. Gruß Hagen
Datum:
>die Idee mit der DLL ist sehr gut, da ich nämlich hier schon ein >Sourceproject für ein Terminal-programm habe, allerdings in C, >aber vielleicht kann man dann beide irgendwie verheiraten, :-)) Ich möchte keine falschen Erwartungen wecken. zZ. verifiziere ich erstmal ob mein angedachtes Konzept auch funktioniert. Ich werde mit Interfaces arbeiten und das in deiner DLL. Alle Programmiersprachen die Windows-COM-Interfaces unterstützen können dann darauf zugreifen (also keine IDispatch-Interfaces!) Das unterscheidet sich zu einer normalen DLL gewaltig da meine DLL quasi nur ein Objekt exportiert und keine Funktionen. Jeder der sich mit Interfaces auskennt weiß welche Vorteile das hat es bedeutet aber auch das diese DLL eher wie ein OCX/ActiveX funktioniert statt wie eine normale DLL mit exportierten Funktionen. Desweiteren könnte man diese Interfaces benutzen um auf die COM-RS232-Schitstelle zu zugreifen um damit dann deine Terminal-Geschichte zu machen. Das hat aber dann keinen Zusammenhang zum eigentlichen Bootloader sondern bietet nur die Anbindung der RS232. Ich sehe nämlich einen ziemlichen Aufwand in dem Punkt wie man Bootloader uund Terminalclient in der eigenen Applikation miteineraner verbindet. Der Bootloader arbeitet per Pollling in der Kommunikation und unterdrückt jede asynchrone Verarbeitung per ISRs. Der Terminal Client in der Applikation sollte so in keinem Falle arbeiten, dieser sollte Interrrupt-gesteeurt funktionieren. Zusätzlich noch das problem das je nach Kommunikationshardware, also 1-Wire/2-Wire/invertiert/nicht invertiert, müsste der Terminalclient in der Applikation alle diese Modis auch unterstützen. Es macht ja keinen Sinn wenn der Bootloader im 1-Wire läuft und das Terminal nur im invertierten 2-Wire Modus funktioniert. Ich bin eventl. gerne bereit einen kleinen Terminal-Srver in der PC-Software zu integrierten die aufbauend auf den aktuellen Verbindungsparametern die der Bootloader zuvor ausgehandelt hat sich mit dem AVR nach dem Start der Applikation weiterhin zu verbinden, bzw. verbunden zuz bleiben. D.h. man verbindet erstmal zum Bootloader (zwecks AutoBaud, Autodetektion 1-Wire/2-Wire). Man bleibt verbunden wechselt zu terminal Page und Startet die Applikation im AVR. Diese Applikation müsste sich die Baudrate etc.pp. aus den internen Registern des AVRs holen und ihrerseits eine Terminalkommunikationssoftware initialisieren. Bisdahin aber nicht weiter. Dh. die UART-Kommunikation in der eigenen Awnedung um den terminalclient zu implementieren wäre nicht meine Aufgabe. Gruß Hagen
Datum:
Angehängte Dateien:Hallo Hagen, der AVR wird nicht vom ISP versorgt, sondern von einem 7805 gespeist, das "self-made" Board habe ich schon Jahre im Einsatz, eigentlich nie irgendwelche Ungereimtheiten bzgl. Spannung gehabt. Allerdings hängt dort am exterenen Memoryinterface des AVRs ein Parallel-Flash für Datenspeicherung. Das sollte aber eigentlich kein Problem sein, so lange das SRE-Bit nicht gesetzt ist. Das mit dem SRAM würd ich ja gern probieren, da schein aber noch ein Problem mit dem PC-Programm zu sein, die Buttons "Read from device" usw. sind nicht im sichtbarem Bereich, auch wenn ich das Programmfenster maximiert habe, ebenfalls sind im Hauptfenster die Browserknöpfe verschwunden, egal wie groß ich die Fenster mache. (siehe angehängte Bilder) Sieht nach einem Fontgröße-/art-Problem aus, ich schätze mal das PC-Programm setzt keine Fonts selber sodaß die "default" Systemfonts genommen werden, und die sind von PC zu PC verschieden. Bei meinem PC auf Arbeit waren alle Buttons zu sehen, wie gewünscht, beim PC hier zuhause, wie gesagt, komm ich an einige Buttons nicht ran. bzgl. Terminal, der letzte Abschnitt von Deiner vorherigen Mail bringt mich auf einen Gedanken: Wie wäre es wenn dein PC Programm eine virtuelle COM anbietet, damit kann dann JEDES Terminalprogramm benutzt werden. die COM-Parameter werden vom PC Programm einfach übernommen, und es werden die Zeichen, die nichts mit der Bootloader-Kommunikation zu tun haben, einfach durchgereicht. Allerdings weiß ich nicht wie es programm-technisch schwierig ist eine virtuelle COM zu implementieren.
Datum:
Angehängte Dateien:ich weiß nicht wie man hier zwei Dateien anhängt, hier also noch das andere Bild
Datum:
Angehängte Dateien:Also du hast ja Probleme ;) Erstmal müssen wir die PC-Software bei dir richtig zum laufen bringen. Welches Betriebsystem hast du ? Welche Einstellungen hast du bei der Darstellung, Fonts, Scalierung etc.pp. ? Du bist der Erste der solche Probleme hat. Ich habe das Program mit Delphi 5 programmiert und verlasse mich darauf das Delphis VCL da alles richtig macht, sprich Ausrichtung der Controls usw. Das es damit Probleme geben soll ist mir neu, immerhin arbeite ich damit professionell seit dem es Delphi auf dem Markt gibt. Schick mir doch mal ne PN so das du mir per EMail noch mehr Screenshots schicken kannst. Du must da auch nicht auf die Bildgröße achten, mein Postfach ist ziemlich groß. Also ich habe das bei mir mal versucht zu reproduzieren, Systemfonts, Scrollbars, Bildschirmscalierung etc.pp. verändert, bekomme es aber nie hin das so ein Fehler auftritt wie der bei dir. Probiere doch mal die EXE aus dem Attachment. Ich habe den Font, den BIDI-Mode und die Autoscalierung und einige andere Werte geändert. Denke zwar nicht das das hilft aber probieren können wir es ja mal. Ich bräuchte also als erstes von dir noch mehr Infos über dein System. >Das mit dem SRAM würd ich ja gern probieren, da schein aber noch ein >Problem mit dem PC-Programm zu sein, die Buttons "Read from device" usw. Falls es mit der geänderten Version geht dann probiere das mit dem SRAM und EEPROM aus, damit wir wissen ob es an der Kommunikation liegt. >bzgl. Terminal, der letzte Abschnitt von Deiner vorherigen Mail bringt >mich auf einen Gedanken: >Wie wäre es wenn dein PC Programm eine virtuelle COM anbietet, damit >kann dann JEDES Terminalprogramm benutzt werden. >die COM-Parameter werden vom PC Programm einfach übernommen, und es >werden die Zeichen, die nichts mit der Bootloader-Kommunikation zu tun >haben, einfach durchgereicht. Allerdings weiß ich nicht wie es >programm-technisch schwierig ist eine virtuelle COM zu implementieren. Ich soll einen Windows Kernelmode Treiber mal eben programmieren ? Vergiß es ganz schnell, den Streß will ich nicht nochmal haben. Es ist ja kein Problem für mich, aufsetztend auf die schon bestehende COM-Verbindung ein Terminal laufen zu lassen, das ist das geringste Problem. Das was die Sache so zeitaufwendig macht ist die nötige Bibliothek die wir auf AVR Seite benötigen um sie in die eigene AVR-Applikation einbinden zu können. Und exakt diese Bibliothek werde ich in nächster Zeit nicht programmieren. In der PC-Software wäre das ein Kinderspiel, einfach Verbindung zum Bootloader, Run-Kommando senden das die Applikation durch den Bootloader im AVR gesteartet wird und dann übernimmt die Terminalbibliothek die Kontrolle über die RS232. Nur, damit ich die PC-Software dann ordentlich testen kann müsste ich für den AVR eben auch diese Bibliothek programmieren und das mache ich jetzt nicht. Und sowas blind, ohne reale Tests zu programmieren, um dann einen erhöhten Support zu haben, weil Nichts ohne Test sofort in der Praxis laufen kann, mache ich ebenfalls nicht. Es ist Hobby und ich muß mir ganz genau überlegen welches meiner Projekte, von den vielen, ich mal endlich fertig bekommen will. Dazu gehört dieses Terminal eben nicht, weil ich es nicht brauche. Denke das das wohl nachvollziehbar ist, oder ? Schick mir ne PN, und wir können dann eine Zusammenarbeit anstreben. Wenn du die Tests und die Terminalbibliothek für den AVR übernimmst, baue ich die entsprechende Funktionalität in die PC-Software sofort ein. Gruß Hagen
Datum:
Hallo Hagen, nur ganz schnell bevor ich ins Bett gehe, das angehängte PC Programm funktioniert, alle Buttons sind sichtbar, so wie auch auf meinem Arbeits-PC, ich hab hier das normale Windows XP mit Sp2 zum Laufen, also nichts exotisches, alles weitere per PN Grüße, Micha
Datum:
Guten Morgen Hagen, melde Dich bitte mal bei grooves_AT_gmx_DOT_de ich kann hier als Gast Deine E-Mail nicht lesen, Grüße, Micha
Datum:
SMTP error from remote mailer after RCPT TO:.....:
host mx0.gmx.net [213.165.64.100]: 550 5.1.1 ... User is unknown
{mx094}
Du musst mir schon deine richtige EMail Addresse geben. Oder melde dich
hier im Forum als registrierter Benutzer an, dann geht das auch per PN
indem du meinen Namen anklickst (ist dann blau)
>ich hab hier das normale Windows XP mit Sp2 zum Laufen, also nichts...
ich entwickle die PC-Software auch auf diesem System, und läuft. Du
musst also irgendwas anders eingestellt haben.
Gruß Hagen
Datum:
Für alle die es interessiert. Das Problem vom Micha konnte eingegrenzt werden. Der ATmega162 kann im Kompatibilitätsmodus als ATmega161 laufen. Meine PC-Software ermittelt alle nötigen Parameter wie FLASH/EEPROM/SRAM Position/Größe aus den ATMEL Part Decsrption XMLs die beim AVR Studio enthalten sind. In diesen XMLs ist der ATmega161comp unvollständig bzw. fehlerhaft beschrieben, es fehlen die Infos für die BootPages. Desweiteren benutzt mein Bootloader aus Effizienzgründen eine spezielle Berechnung der Signatur der AVRs. Diese Berechnung reduziert die 3 Bytes Signatur auf eine 1 Bytes Signatur. Das funktioniert auch wunderbar bis eben auf den Punkt ATmega161. Dessen Signatur überschneidet sich dann mit der Signatur des neueren ATtiny88. 31=1E9311, ATtiny88 , 8192, 64, 512, 256, 64, 0, 0, 0, 0 31=1E9401, ATmega161 , 16384, 512, 1024, 96, 128, 8, 0, 0, 0 31=1E9401, ATmega161comp, 16384, 512, 1024, 96, 128, 0, 0, 0, 0 34=1E9404, ATmega162 , 16384, 512, 1024, 256, 128, 2, 4, 8, 16 Losung dieser Probleme mit der aktuellen Version sieht so aus: 1.) .DEV Datei so abändern 31=1E9311, ATtiny88 , 8192, 64, 512, 256, 64, 0, 0, 0, 0 3E=1E9401, ATmega161 , 16384, 512, 1024, 96, 128, 8, 0, 0, 0 3F=1E9401, ATmega161comp, 16384, 512, 1024, 96, 128, 2, 4, 8, 16 34=1E9404, ATmega162 , 16384, 512, 1024, 256, 128, 2, 4, 8, 16 also aus 31 wird 3E/3F beim ATmega161/comp, beim ATmega161comp müssen die letzten 4 Zahlen synchron wie beim ATMega162 geändert werden 2.) in AVRootloader.inc .set SIGNATURE_CRC = (SIGNATURE_000 << 3) + (SIGNATURE_001 << 4) + SIGNATURE_002 ersetzen mit .set SIGNATURE_CRC = 0x3E oder 0x3F je nachdem ob man ATmega161 oder ATmega161comp benutzt wird 3.) in AVRootloader.asm muß beim ATmega162 im Kompatibilitätsmodus .include "m161def.inc" ; ATmega161 Inkludiert werden, nicht m162def.inc !! Da dieses Problem nur mit dem ATMega162/161comp. auftritt wird es erstmal keinen HotFix geben, das Teil ist eh abgekündigt. Gruß Hagen
Datum:
Angehängte Dateien:Version 2.0 Die SIGNATURE_CRC wurde entfernt. Der neue ATtiny88 überschneidet sich mit dem ATmega161 beim Verfahren der Version 1.0. Nötige Änderung dafür ist in AVRootloader.asm -> BootSign: die 4 Bytes. Die PC-Software kann aber weiterhin mit der Version 1.0 benutzt werden, ist also abwärtskompatibel. AVRootloader.dev aktualisert auf die neusten AVRs und beim ATMega161/ ATmega161comp. (ATmega162 im 161 Kompatibilitätsmodus) Fehler aus den AVR Studio XML Dateien beseitigt. ATMEL hat dort falsche Angaben gemacht. Die PC-Software ist intern komplett neu geschrieben worden. Wer Interesse hat kann die AVRootloader.DLL benutzen um die komplette Funktionalität der PC-Software (ohne GUI) in seine eigene Anwendung zu integrieren. Diese DLL implementiert die Funktionalität über Interfaces, sollte also auch über andere Programmiersprachen nutzbar sein. Delphi Header in AVRootIntf.pas. Über diese Schnittstelle kann man auch eigene Communications-Interfaces vorgeben über die dann die AVRootloader Schnittstelle kommuniziert, zb. AVR309 USB oä. Über AVRootloader.ini in Section [Timeouts] RTSPulse=? kann man das Verhalten beim Verbindungsaufbau der PC-Software von der RTS-Leitung der RS232 einstellen. Man kann über diese Option also den RTS PIN der RS232 zb. für x Millisekunden von HIGH auf LOW und wieder HIGH ziehen. Damit könnte man, über Serienwiderstand und Shottky Diode den RTS Pin auf den RESET Pin des AVRs klemmen. Bei jedem Verbindungsaufbau der PC-Software zum Bootloader wird somit autom. der AVR in den Reset versetzt. Wer möchte kann ein Copyright String oä. in AVRootloader.asm einbauen. Dieser String wird dann in der PC-Software in der Device Information angezeigt. Das geht so: BootSign: .db "BOOT" BootInfo: .db SIGNATURE_001, SIGNATURE_002, BootVersion, BootPages BootMsg: .db SUCCESS, "Hello World" BootEnd: Wichtig ist das das erste Byte immer SUCCESS ist. Das Timeout-Handling in der Baudratedetektion wurde geändert. Sollte innerhalb des Timeouts, zb. 250ms, eine gültige Baudrate detektiert worden sein so verlängert sich der Timeout ab diesem Moment um weitere 250ms. Entweder der Bootloader empfängt das korrekte BootSign: (zb. BOOT) und springt in den Kommandomodus oder aber die Baudrate-Detektion startet erneut mit weiteren 250ms. Wenn also Ruhe auf der RX-Leitung ist, so startet die Applikation wie gewohnt nach dem Timeout. Wenn aber eine PC-Software versucht eine Verbindung aufzubauen so bleibt der Bootloader solange in der Baudrate-Detektion bis die PC-Software aufhört eine Verbindung aufzubauen. Diese Vorgehensweise macht das Verfahren wesentlich robuster. In Version 1.0 war der Timeout ein Gesamt-Timeout des Verbindungsversuches. Nach den zb. 250ms wurde immer die Applikation gestartet, egal ob eine PC-Software einen Verbindungsaufbau versuchte oder nicht. Gruß Hagen
Datum:
Nochmal zurück zu Michaels Problem mit dem ATMega162 im ATMega161 Kompatibiliätsmodus. Zuerst zur Lösung des Problemes: 1.) in AVRootloader.asm .include "m161def.inc" ; ATmega161 .equ RWWSRE = 4 ; activate for ATmega162 in ATmega161 compatibility mode einfügen. Wichtig ist das das RWWSRE Bit manuell nachträglich deklariert werden muß. 2.) in AVR-Studio Fuses M161C=Häckchen BOOTSZ=Boot Flash size=512 words start address=$1E00 BOOTRST=Häckchen 3.) AVR-Studio Lockbits BLB0 und BLB1 nicht setzen. Erklärung: Der ATMega161 kennt das "Read While Write" Feature des SPM Befehles nicht. Der ATMega162 kennt diese Feature aber. Lässt man den ATMega162 im Kompatibilitätsmodus arbeiten als 161'er dann muß man nach dem Programmieren einer FLASH Page denoch diese Page wieder für den Lesezugriff freischalten. Da aber in m161def.inc das nötige RWWSRE Bit nicht deklariert ist wurde also die geschriebene FLASH Page nicht zum Lesen freigeschaltet. Das anschließende Verify musste somit scheitern. Zum Glück betrifft die nur das Sorgenkind ATMega161 bzw. den Kompatibilitäsmodus des ATMega162. Die PC-Software erkennt nun korrekt einen ATmega161. Die Problematik entstand weil der ATMega162 im m161 Modus das Extended IO ausblendet und somit die SRAM Startaddresse von 0x0100 auf 0x0060 vorverlagert und einiges der Peripherie deaktiviert. Man kann also nicht den Bootloader so compilieren das er als ATmega162 läuft und die Fuse des M161C Modus setzen. Man muß den Bootloaer auf dem M162 wirklich als M161 compilieren, aber dann unterscheiden sich die Programmierbefehle (SPM) trotzdem. Kurz gesagt: der ATMega162 im M161C Modus ist nicht vollständig kompatibel zum ATMega161, der SPM Befehl funktioniert dann weiterhin wie bei einem ATmega162. Gruß Hagen
Datum:
Angehängte Dateien:Es tut mir ja leid, aber ein neues Update. Mit bestimmten HEX Files, bei denen die Speicherblöcke nicht linear aufsteigend in ihrer Addresse vorlagen, kam es zu Fehlern. Die PC-Software hat also HEX Files falsch interpretiert. Unter normalen Umständen dürfte das aber kein Problem sein da die meisten Tools wie WinAVR GCC oder AVR Studio solche HEX Files immer mit linear nachfolgenden Addressen erzeugen. Mit der neuen Version ist das natürlich gefixt. Gruß Hagen
Datum:
Hallo, hast Du zufällig irgendwo eine Anleitung wie man den Loader in seine eigene Delphi-app einbauen kann? Ich komme da nicht recht weiter, würde gerne einen "One-Button" upload von meiner Software aus einbauen, Comport ist da schon bekannt. Ich müsste also nur dem Loader den Comport übergeben und eine Datei zum flashen. Irgendwelche Tipps? Louis
Datum:
Angehängte Dateien:Ja, das geht. Der Bootloader relevante Teil befindet sich auch in der AVRootloader.dll. Du kannst diese DLL in deine Delphi Anwendung einbinden, das sähe so aus wie im Attachment gezeigt. Als erstes entpackst du diese ZIP zb. nach c:\programme\atmel\ mit Ordnern. Dann startest du Delphi und öffnest das Project1.dpr im Pfad ..\AVRootlaoder\Test DLL\. Darin zeige ich wie man die AVRootloader.dll über die Unit AVRootIntf.pas benutzen könnte. Ist alles auf ein Minimum reduziert damit man die Funktionweise besser sehen kann. Im Grunde für ein bischen erfahrenen Laien echt einfach. Du benötigst später deine EXE, die AVRootloader.dll, AVRootloader.dev und die von dir compilierte *.ACY Datei zu deiner *.HEX und *.EEP Datei. Eine ACY Datei enthält das HEX für den FLASH (Programm) wie auch die EEPROM Daten aus der *.EEP Datei wenn man das möchte. Die Daten im ACY sind natürlich mit dem Paswort und XTEA verschlüselt. Im DEMO prjekt kannst du solch eine ACY Datei ezeugen lassen und sie dann Programmieren. Die AVRootloade.asm habe ich so angepasst das sie für einen ATmega162 im 1-Wire-RS232 mit sicherer Verschlüsselung arbeitet. Das musst du an deine Bedürfnisse anpassen, steht aber in der Readme drinnen wie und was. Das Test.hex das ich mitliefere ist für einen ATmega162. Ich würde das DEMO an deiner Stelle also soweit reduzieren das man nur noch den "Program" Button hat. Eventuell sogar ganz ranehmen und die Aktion gleich nach dem Start der Anwendung ausführen. Mit der normale PC-Bootloader-Software im Ordner \AVRootloader\Windows\ kannst du nun deine *.ACY Dateien verschlüsselt erzeugen und sie dann mit deinem Program in den AVRladen lassen. Also alles wie die Buttons "Connect", "Erase", "Compile" raus. Die Methoden .GetACYFileName und .GetEEPROMFileName liefern immer '' zurück. Nur die Methode .GetFLASHFileName gibt den Namen deiner *.ACY Datei zurück. Minimalistisch sähe es so aus:
uses AVRootIntf;
type
TMyObj = class(IApplication)
procedure ProcessMessages; stdcall;
procedure Changed; stdcall;
procedure Output(const Msg: WideString; Code: Integer); stdcall;
function GetFLASHFileName: WideString; stdcall;
function GetEEPROMFileName: WideString; stdcall;
function GetACYFileName: WideString; stdcall;
function GetPassword: WideString; stdcall;
function GetBootSign: WideString; stdcall;
function GetTimeouts: TTimeouts; stdcall;
function OpenCommunication: ICOM; stdcall;
constructor Create;
end;
procedure TMyObj.ProcessMessages;
begin
end;
procedure TMyObj.Changed;
begin
end;
procedure TMyObj.Output(const Msg: WideString; Code: Integer);
begin
end;
function TMyObj.GetFLASHFileName: WideString;
begin
Result := ExtractFilePath(ParamStr(0)) + 'test.acy';
end;
function TMyObj.GetEEPROMFileName: WideString;
begin
Result := '';
end;
function TMyObj.GetACYFileName: WideString;
begin
Result := '';
end;
function TMyObj.GetPassword: WideString;
begin
Result := '';
end;
function TMyObj.GetBootSign: WideString;
begin
Result := 'BOOT';
end;
function TMyObj.GetTimeouts: TTimeouts;
begin
Result.Base := 50;
Result.Erase := 20;
Result.Flash := 25;
Result.Eeprom := 20;
Result.Buffer := 1;
Result.RTSPulse := 0;
Result.RTSInterval := 0;
end;
function TMyObj.OpenCommunication: ICOM;
begin
Result := OpenCOM('\\.\COM2', Self);
Result.SetParams(115200);
end;
constructor TMyObj.Create;
begin
OpenAVRootloader(Self).DoProgram(False, False);
end;
|
Gruß Hagen
Datum:
Angehängte Dateien:Im Attachment mal das Test project für den ATmega162 das ich benutze. 8Mhz interner Takt, an PD0 der 1-Wire-RS232 RX, wenn man 2-Wire testen möchte dann an PD1 der TX Pin und an PD3 eine LED mit Vorwiderstand nach VCC. Vergiß niemals die Lockbits entsprechend zu setzen. Also nach dem Upload der Bootloader Software die Lockbits so setzen das ein Auslesen des AVRs nicht mehr möglich ist. Ansonsten hat das alles ja keinen Nutzen ;) Gruß Hagen
Datum:
Naja andererseits kannst du dir auch die Arbeit sparen und meine fertige PC-Software benutzen, rufe sie in deinem Falle mit folgenden Parametern auf AVRootloader.exe -PCOM2 -B112500 -Dc:\pfad_zu_deinen_ACY_files\ -Ftest.acy -Apc Damit startest du meine PC-Software, diese versucht eine Verbindung über COM2 mit 112500 Baud und flasht Test.ACY das im Pfad c:\pfad_zu_deinen_ACY_files\ liegt und schließt die PC-Software nach erfolgereicher Aktion wieder automatisch -> Parameter -Apc. Die Erklärung dieser Kommandozeilenparameter findest du in AVRootloader.txt. Möchtest du eine unverschlüsselte HEX/EEP Datei auf diese Weise in einen AVR uploaden der nur mit verschlüsselten Daten arbeitet dann füge den Parameter -K5441C8CA4DDF8EEA19AAAFD877AEB488 noch hinzu. Natürlich den Key den du in deinem Bootlaoder auch benutzt. Sollte einer dieser Parameter nicht übergeben worden sein so lädt die PC-Software die nötigen Einstellugen aus der INI-Datei AVRootloader.ini. Man könnte also auch einfach "AVRootloader.exe -Apc" aufrufen und sollte dann vorherig einmalig alle Parameter im GUI der Software voreingestellt haben. Vergiß auch nicht ein neues Passwort zu erzeugen, damit du nicht das im Source vordefinierte benutzt, macht ja keinen Sinn wenn jeder dein Passwort kennt ;) Dazu startest du meine PC-Software und drückst den "Make Password" Button auf der ersten Seite. Daraufhin wird per Zufall ein Passwort erzeugt und auch gleich in AVRootloader.asm geschrieben. Alternativ kannst du auch noch dieses neue Passwort in die AVRootlaoder.ini schreiben lassen. Und es wird auch noch in die Zwischenablage kopiert, also einfach STRG+EINFG drücken wenn du es woanderst sichern möchtest. Gruß Hagen
Datum:
Vielen vielen Dank für die ausführliche Info! Echt super, dann kann ich ja gleich loslegen :) Ich habe nur ein kleines Problemchen: Meine Hardware meldet sich nicht, ich flashe den Bootloader nach dem Compilergang, das klappt wunderbar. Aber leider bekomme ich keine Verbindung. Ich habe einen Mega644p mit 16 MHz, habe BOOTRST gesetzt, BOOTSZ0 und BOOTSZ1 nicht. Mit dem Fastboot von Peter Danegger klappt es an der Hardware prima, Deiner läuft offenbar nicht. Was könnte ich da falsch machen? Habe den normalen Uart0 an, also PD0 und PD1 als Pins. Uartinvert habe ich beide ausprobiert. Irgendwelche Tipps? Louis
Datum:
1.) in AVRootloader.asm .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 = 16000000 .set BootDelay = XTAL/4 .set BootBaudrate = 115200 .set BootVersion = 2 .set BootCodeSize = 852 nun neu kompilieren, und HEX file auf AVR uploaden. Fuse auf "First Boot Start" und BOOTRST setzen. Boot Flash size=512 words Boot start address=$7E00 ($FC00) Danach AVR über RS232, du benutzt doch einen Pegelwandler ? falls nicht und du benutzt direkt die RS232 Leitungen dann UartInvert=0 setzen. PC-Software starten, und richtigen COM Port auswählen und Baudrate einstellen 112500 ist ein guter Wert. Nun Button "Connect to Device" drücken und eventuell den AVR reset'en. Im "Protocol" Window sollte dann stehen das er auf 2-Wire Modus gewechselt ist. Wenn er dann eine Verbindung hat kannst du in "Device Information" alle wichtigen Einstellungen zum AVR sehen. Als nächsten Test "EEPROM Content" und "Read from Device" ausprobieren. Und dann mal einige Änderungen von Hand im HEX Editor machen und "Write to Device" drücken. >> Deiner läuft offenbar nicht. bei dir nicht ;) Hast du sonst igrendwas in AVRootloader.asm verändert ? zb. BootSign: "BOOT" oder sowas ? Gruß Hagen
Datum:
Arg...es war der Programmer, der Hat Mist geschrieben, am Ende fehlte etwas, anscheinend ist der defekt. Ich habe es jetzt aber am Laufen, wunderbar! Encryption läuft auch, genau das habe ich gesucht. Super, vielen vielen Dank! Louis
Datum:
Hi Louis, beachte bitte folgendes damit es auch kryptographisch sicher ist: 1.) erzeuge mit der PC-Software einen neuen Schlüssel - steht dann in AVRootloader.asm bei BootKey: drinnen, 16 Bytes - steht wenn du möchtest in AVRootloader.ini in Password=?? drinnen 2.) stelle sicher das die Option UseSRAM=0 ist. Ansonsten kann nämlich ein cleverer Angreifer den Bootloader ausnutzen um ihn zu knacken indem er gezielt den SRAM und damit IO/Register Bereiche manipuliert. 3.) stelle sicher das UseCryptFLASH=1 ist, ansonten bei UseCryptFLASH=0 kann man verschlüsselte wie auch unverschlüsselte Daten schreiben, und somit auch ein eigenes Program das den Bootlaoder FLASH ausliest und somit auch den BootKey:, es sei denn das LPM/SPM in der Application Section verboten wird über die Fuses. 4.) wenn du deine/meine Bootloader-PC-Software deinen Kunden gibts stelle sicher das dort in der AVRoiotloader.ini bzw. nirgends der Schlüssel gespeichert ist 5.) liefere ausschließlich nur verschlüsselte ACY Dateien aus Falls du mit Delphi meine AVRootloader.dll benutzt wäre ich für ein Feedback sehr dankbar, ich würde gerne sehen was daraus wird ;) Gruß Hagen
Datum:
Hallo Hagen, danke für die Tipps, ich habe sie jetzt bei einem Exemplar mal angewandt, das Teil ist jetzt sozusagen dicht und nur noch durch meine Software beschreibbar. Das ist genau das, was ich gesucht habe, jeder kann ein Update flashen, aber nur eins dass von mir kommt und geprüft ist. So kann auch keiner den Code knacken und sehen wie die Software arbeitet. perfekt. Mein Mega64 wird nach Abschluss mit beiden Lockbits gelockt, das sollte so bombensicher sein. Ich gebe bescheid wenn ich die Software soweit habe, noch ist sie nicht 100% fertig. Louis
Datum:
>Mein Mega64 wird nach Abschluss mit beiden Lockbits gelockt, das sollte >so bombensicher sein. Aber nicht den Fehler machen, wie ich aus Überschwenglichkeit, alle Lockbits zu setzen, auch diejenigen die dem Bootloader den LPM/SPM Befehl sperren ;) Gruß Hagen
Datum:
Hehe, nene, so doof bin ich nun auch wieder nicht.. Btw, was genau bedeutet eigentlich SPM und LPM? Steht überall im datasheet, nur die Erklärung fehlt... Louis
Datum:
SPM - Store Program Memory LPM - Load Program Memory Weist auf die beiden gleichnamigen Assembler Mnemonics, mit denen sich der Mikrocontroller selbst den Flash schreiben bzw. aus seinem eigenen Flash (innerhalb des Programms) lesen kann.
Datum:
Ich habe die sehr nette AVRootloader fuer ein ATmega32 implimentiert. Es funksioniert auch schon, aber nicht alles wie es beschreibt ist. "Make Password" ohne in AVRootloader.ini zu spechern tut nichts. Was heist "in die Zwischenablage kopiert und kann so anderenorts gespeichert werden"? Bei mir wird nichts weiter abgefragt un nichts gespeichert. Muss in AVRootloader "Password = " stehen mit blank?
Datum:
Doch, tut es: Das Kennwort wird in die .asm-Datei des Loaders gespeichert, (ganz unten...) Beim Assembler-Lauf wird es dann in den Code eingefügt, der Loader muss es ja irgendwo her wissen wenn er einsam und alleine in seinem Megaxxx seitzt und auf Programme wartet. Das Passwort selbst wird in die Zwischenablage kopiert, öffne Notepad und drücke STRG+V, dann siehst Du es. Das Kennwort solltest Du GUT aufbewahren, ist es weg kannst Du keine Software mehr laden! Louis
Datum:
> Muss in AVRootloader "Password = " stehen mit blank?
Jain ;) Entweder
[System]
Password=
mit oder ohne Leerzeichen ist egal da diese intern entfernt werden, oder
[System]
Password=0A5ED11C8B0FA36F7C4F1EE20526904B
oder
Password=$0A,$5E,$D1,$1C,$8B,$0F,$A3,$6F,$7C,$4F,$1E,$E2,$05,$26,$90,$4B
Alle Sonderzeichen, auch Spaces werden entfernt und das was übrig bleibt
sind die HEX-Chars und das wird als Passwort benutzt. Ob man A..F groß
oder klein schreibt ist egal.
Wenn kein Passwort in der INI Datei gespeichert wurde fragt die
PC-Software per Dialogbox das Passwort ab wenn es benötigt wird. Das
Passwort in die INI Datei zu speichern erleichtert dem Programmierer
also die Arbeit. Bei der Installation der Software bei deinen Kunden
sollte das Password nicht gespeichert werden, logisch.
Beantwortet man die Frage "Do you want to save Password in INI-File ?"
mit NEIN/NO dann wird das Password in der INI Datei gelöscht.
Danach wird die AVRootloader.asm Datei mit dem neuen Passwort
modifiziert und zusätzlich ins Clipboard kopiert. Du kannst es also per
Paste irgendwo selber abspeichern.
Um das Passwort nicht zu verlieren bietet es sich an die geänderte
AVRootloader.asm zu sichern, im Projektbackup das ja jeder Programmierer
auch macht ?!
Nach "Make Password" muß also AVRootloader.asm neu kompiliert werden.
Gruß Hagen
Datum:
Vielen Dank fuer die erklaerung. Jetz habe Ich wieder etwas neues von Deutsch gelernt: Zwischenablage = Clipboard ! Ich werd es mal wieder probieren.
Datum:
Angehängte Dateien:Hallo, also der Bootloader ist eine tolle Sache. Hab diesen erfolgreich auf einen ATmega8 im Einsatz. Jetzt wollte ich diesen auf einen ATtiny85 auch benutzen. Leider kommt beim Flashen folgender Fehler: Cmd.WriteFlash.ResCheck() Error: Verify failed Folgendes habe ich bereits probiert: 1. Informationen lesen, funktioniert Software erkennt den ATtiny85 2. EEPROM lesen, schreiben, schauen ob sich was zufällig ändert. Funktioniert auch. 3. Wie 2. nur mit SRAM. 4. Flashen via ISP funktioniert. 5. Anderer ATtiny85 gleiches Problem 6. Verschiedene Baudraten, keine Erfolg Im Anhang die ASM die ich benutze. Vieleicht hat jemand eine Lösung.
Datum:
letzte Version der PC-Bootloader Software downloaden. Mit welchem Entwicklungswerkzeug hast du dein HEX erzeugt ? Also das was du über den Bootloader flashen möchtest. In den älteren Versionen der PC-Software war bei der Interpretation der Daten im HEX File ein Fehler. Sobald im HEX File die Addressen nicht linear sortiert gespeichert wurden gabs mit der alten Version Probleme. Wenn man mit AVR Studio oder WinAVR GCC arbeitet entstand dieses Problem nicht. Alternativ in der AVRootloader.INI die Section [Timeouts] modifizieren, sprich größere Timeouts wählen. Ich tippe aber auf ersteres Problem. Kannst ja mal das HEX File posten. Übrigens kannst du das UseVeritfy = 0 sezten und so par Bytes Code sparen was dazu führt das die 518 Bytes in deinem Falle unter 512 Bytes sinken und du somit eine Flashpage (64 Bytes) weniger für den Bootloader verbrauchst. Beim Schreiben vom FLASH/EEPROM ist schon eine Prüfsumme enthalten und auch ein integrierter Lesetest der soeben programmierten Daten, ergo: ein implizites Verify. Das zusätzliche externe Verify das mit UseVerify=1 aktiviert wird dient nur als zusätzliche Absicherung bzw. um testen zu können ob der FLASH eines schon programmierten AVRs mit einem HEX File übereinstimmt. Wenn man also nur sichergehen möchte das die aktuelle Programmierung korrekt verlief dann recith das impliziete Verify aus und man kann mit UseVerify=0 einiges an Code sparen (der natürlich dann deiner Anwednung zugute kommt). Gruß Hagen
Datum:
Angehängte Dateien:Hallo, Danke für die Antwort. Also die AVRootloader.exe ist vom 06.05.08 und ist ca. 940KB groß. Die HEX erzeuge ich mit avr-gcc 4.2.2. Das mit der UseVerify ist z.Z. noch aktiv weil eben dieser Fehler auftritt. Das mit den Timeout's werde ich noch probieren. Gibt es denn einen offiziellen (ich nen das mal so) Downloadplatz? Gruß Daniel
Datum:
Ok, aktuellste Version hast du und HEX sieht auch sauber aus. Bleiben noch zwei Möglichkeiten a) erhöhe die Timeouts, denke aber nicht das das was ändert b) dein AVR könnte defekt sein, bzw. dessen Spanungsversorgun instabil. Versuche den AVR mal über ISP zu flashen. Connecte mal mit dem Bootloader und poste hier alle was im Info Fenster angezeigt wird, vielleicht kann ich ja daraus was erkennen. Downloadplace ist hier dieser Thread ;) Gruß Hagen
Datum:
Daniel wrote: > Leider kommt beim Flashen folgender Fehler: > Cmd.WriteFlash.ResCheck() Error: Verify failed Ich tippe mal auf Selbstprogrammierfuse nicht gesetzt. Peter
Datum:
Hallo, also der letzte Tipp war goldwert. Ich hatte das Extended-Fuse-Byte nicht gesetzt. Danke für die Hilfe. Gruß Daniel
Datum:
Hallo Hagen, ich bin von dein Bootloader voll begeistert. Mit meinem ATmega8535 habe ich gleich probiert. Funktioniert soweit, bis auf die Lockbits. Setze ich keine Lockbits kann ich mein FLASH-Programm problemlos immer wieder neu beschreiben. Möchte ich mein Programm vor dem Auslesen schützen, so setze ich dann im Programmer BOOTLOCK02. Damit kann ich das Auslesen mit einem ext. Programmer verhindern. Leider geht dein EXE-Prog. dann nicht. Fehlermeldung kommt: Cmd.SetAddr. readByte() ICOM: read error Besteht die Möglichkeit, mit deinem EXE-Prog. nur den FLASH zu schreiben ohne das das Programm immer erst auf EEPROM oder FLASH lesen will? Was ja nicht geht, weil ich den Ausleseschutz aktiviert habe. Grüße
Datum:
Hallo Hagen, zwischenzeitlich habe ich mal dein Delphi-Programm ausprobiert. Bei der Function "Button2Click..." habe ich "FLoader.DoProgram(False, False)" probiert und bekommen die gleichen Rückmeldungen wie unter Einstellungen von "True": Connection : 2-Wire Device name : ATmega8535 Device signature : 1E9308 SRAM size : 512 Byte EEPROM size : 512 Byte FLASH size : 8192 Byte FLASH size for application : 7680 Byte FLASH pagesize : 64 Byte Bootloader size : 512 Byte Buffersize for data : 472 Byte SRAM start address : 96 Bootloader version : 2 Use bootsection : Yes Cryptography supported : No Device connected Program... execute compiled data selected options in compiled file: - programming FLASH - erase FLASH during programming - full verify FLASH after programing Cmd.WriteFlash.ResCheck() Error: Verify failed Grüße
Datum:
@Elektroniker Ich habe das Datenblatt des ATMega8535 nicht zur Hand aber die Fuses müssen so programmiert werden das - das Auslesen per ISP etc.pp. nicht mehr möglich ist - das die korrekte Bootsection eingestellt wird, also >= 512 Bytes = 256 Words - evntl. den SPM Befehl aus der Application Section verboten wird - evntl. der LPM Befehl aus der Application Section verboten wird - der Code in der Boot Section, eg. der Bootloader, per SPM und LPM Zugriff auf die Application Section und mindestens per LPM Zugriff auf die Boot Section hat Der Bootloader muß also per SPM + LPM in die Application Section Zugriff haben. Du kannst den SPM ZUgriff des Bootloaders in die eigene Boot Section verhindern damit sich der Bootloader nicht selber löschen kann. Aber in jedem Fall muß der Bootloader per LPM den kompletten FLASH auslesen können. Einerseits weil der Bootloader nach dem Programmieren des FLASH/EEPROM per LPM diesen wieder ausliest und mit den soeben programmierten Daten im SRAM-Buffer vergleicht, ergo implizites Verify beim Programmieren. Und andererseits weil der Bootloader am Ende im FLASH eine Tabelle mit wichtigen Daten enthält die er auslesen können muß, also solche Daten wie Signatur und Identifier. Lange Rede kurzer Sinn: ich schätze du hast zu viele Lockbits gesetzt und damit den Bootloader ausgesperrt. Gruß Hagen
Datum:
>Bei der Function "Button2Click..." habe ich "FLoader.DoProgram(False, >False)" probiert und bekommen die gleichen Rückmeldungen wie unter >Einstellungen von "True": Der Parameter "VerifyFlash" = TRUE kann nur dann von Relevanz sein wenn die Datei die du flashen möchtest eine reine HEX Datei ist. Ist es aber eine "precompilierte" ACY-Datei dann entscheiden die Optionen die bei ihrer Kompilierung gesetzt waren. Erkennen kannst du das ganz einfach am letzten Punkt im Protokoll >selected options in compiled file: >- programming FLASH >- erase FLASH during programming >- full verify FLASH after programing full verify FLASH after programming ist VerifyFLASH=TRUE bei einer HEX-Datei oder die vergleichbare Checkbox in der PC-Bootloader-Applikation bei der Erstellung einer ACY-Datei. Ändert aber nichts an der Sache, da der Bootloader schon während des impliziten Verifys gleich nach der Programmierung aussteigt. Dieses Verify kann nicht deaktiviert werden per PC-Software, höchstens indem man die AVRootloader.ASM Datei umschreibt. Es gibt also im AVRootloader gleich zwei Arten des Verify. Das implizite Verify wie vorher ausgiebig beschrieben. Und das separate und zu jeder Zeit nachträglich durchführbare Verify, wie bei den vielen anderen Bootloadern üblich. Letzeres benötigt man eigentlich nur um verifizieren zu können ob der Inhalt einer gegebenen HEX Datei mit dem Kontext im AVR übereinstimmt. Gruß Hagen
Datum:
Hallo Hagen, danke für die schnellen und ausführlichen Anworten. Mit dem Mega8535 kann man nicht so viele Fuses setzen. Meine gesetzten Fuses: BOOTRST, BOOTSZ1 und BOOTLOCK02 Wird BOOTLOCK02 nicht gesetzt, dann funktionioert alles. Leider auch das Auslesen des Programms über den externen Programmer. Aber das möchte ich verhindern. Ich bin nochmal alle Postings in diesem Thread durchgegangen. Du hattest am 06.05.2008 geschrieben: >Vergiß niemals die Lockbits entsprechend zu setzen. Also nach dem Upload >der Bootloader Software die Lockbits so setzen das ein Auslesen des AVRs >nicht mehr möglich ist. Ansonsten hat das alles ja keinen Nutzen ;) Wie kann man dein Bootloader einstellen, dass der die Lockbits setzt? Und wenn die gesetzt werden, dann kann ich mit dein EXE-Prog. nicht mehr auf den µC zugreifen, weil dann doch die gleiche Fehlermeldung kommen müsste, als wenn das BOOTLOCK02 gesetz würde? Soviel ich verstanden habe, werden die Lockbits immer gelöscht (egal vom Bootloader oder über ext. Programmer), wenn das FLASH gelöscht oder neu beschrieben wird. Leider geht es nicht mit EXE-Progr. weil er gleich den Inhalt lesen möchte und nicht vorher löscht oder neu beschreibt. Könnte das nicht abgeändert werden, wenn ich den µC FLASH neu beschreiben möchte? Oder? Zum Delphi-Programm: Ich finde es super, dass Du es in Delphi geschrieben hast und ich programmiere selber nur in Pascal/Delphi und Assembler. Leider wissen nicht soviele Leute von der tollen Programmiersprache Delphi/Pascal gegenüber den Anderen. Ich brauche eigentlich nichts weiter ausführen. Auf jedenfall hast Du mir schon mit deinem Delphi-Tipp erstmal geholfen und werde es später noch vertiefen. Wenn Fragen diesbzgl. auftreten, stell ich diese hier im Forum gerne rein. Grüße
Datum:
>Soviel ich verstanden habe, werden die Lockbits immer gelöscht (egal vom >Bootloader oder über ext. Programmer), wenn das FLASH gelöscht oder neu >beschrieben wird. >Leider geht es nicht mit EXE-Progr. weil er gleich den Inhalt lesen >möchte und nicht vorher löscht oder neu beschreibt. Könnte das nicht >abgeändert werden, wenn ich den µC FLASH neu beschreiben möchte? >Oder? Nee da hast du was falsch verstanden. Der Bootloader selber setzt die Fuses nicht, das kann er garnicht. Man könnte für neuere AVRs die verschiedene Fuses per Program setzen können, diese Funktionalität in den Bootloader implementieren, aber dabei sehe ich keinen wirklichen Nutzen. Du programmierst über ISP/JTAG/DW die AVRootloader.HEX in den AVR, natürlich vorher kompiliert für deinen AVR mit deinen gewünschten Optionen. BOOTSZ Fuse setzen damit der AVR beim RESET den Bootloader startet. Danach mit PC verbinden und PC-Bootloader starten und als Test mal EEPROM/SRAM auslesen und schreiben. Wenn das geht kannst du die Lockfuses setzen. Das dürfte schon reichen denn nun kann man den ISP/JTAG nur noch aktivieren wenn man den AVR vollständig löscht. Also mit AVRStudio so: BOOTSZ=Boot Flash size=256 words Boot address=$0F00 Lockbits: LB=Further programming and verification disabled BLB0=SPM prohibited in Application Section BLB1=No lock on SPM and LPM in Boot Section Ergibt Lockbits=0x38 Man kann also den ATMega8535 schon so konfigurieren das es ziemlich sicher ist. Die Frage ist also mit welchem Programmiertool du den AVR flash'st. Gruß Hagen
Datum:
Hallo Allerseits, bei Verwendung von 'BootMsg' unbedingt darauf achten, dass der Text eine UNGERADE Anzahl von Zeichen enthält. Ansonsten hängt der Assembler ein NullByte an. Dieses Byte wird auch ausgegeben und verwirrt das PC-Programm. Das PC-Prog erkennt den connect nur zum Teil. Das Senden der 'BootSign' wird eingestellt, das Programm selbst geht aber nicht in den Zustand "connected". Grüße JoJo
Datum:
>bei Verwendung von 'BootMsg' unbedingt darauf achten, dass der Text eine >UNGERADE Anzahl von Zeichen enthält. >Ansonsten hängt der Assembler ein NullByte an. >Dieses Byte wird auch ausgegeben und verwirrt das PC-Programm. Das lässt sich im PC-Program sehr einfach abstellen, werde das demnächst mal bereinigen. BootMsg kann man auch nur verwenden wenn der Bootloader ohne Verschlüsselung arbeitet. >Das PC-Prog erkennt den connect nur zum Teil. Das Senden der 'BootSign' >wird eingestellt, das Programm selbst geht aber nicht in den Zustand >"connected". Könntest du mir genauer erklären was du damit meinst ? Ich interpretiere deine Aussage so das die PC-Software den Connection-Aufbau einstellt, sprich in den Connect-Status wechselt, obwohl der Bootloader im AVR immer noch im Connectaufbau verbleibt. Eigentlich ist das aber sehr unwahrscheinlich. Die PC-Software sendet permanent das BootSign. Solange bis der AVR die richtige Baudrate detektiert hat und das empfangene BootSign mit dem im AVR im FLASH gespeicherten verglichen hat und Übereinstimmung existiert. Danach sendet der AVR seine BootInfo an die PC-Software. Diese geht erst in den Connect Status wenn sie diese BootInfo sauber empfangen hat und die darin enthaltenen Angaben auch stimmig sind. Dh. normalerweise geht der AVR als erster in den Connect-Status und erst danach die PC-Software. Von daher ist es also unwahrscheinlich das die PC-Software schon im Connectstatus ist der AVR aber noch nicht. Sollte es zu dem Fall kommen das der AVR nach Senden der BootInfo im Connectstatus ist die PC-Software aber die empfangene BootInfo nicht erkennt dann beginnt der Connectionaufbau von vorne. Die PC-Software sendet also weiterhin #0#0#13 + BootSign. Der AVR der schon in der Kommandoschleife ist, also connected, erkennt aber die beiden #0#0 Zeichen als Restart-Kommando. Bei diesem Kommando springt also der AVR wieder an den Anfang des Bootloaders und befindet sich dann wieder im Connection Aufbau Status. Dh. selbst wenn der AVR schon im Connectstatus ist die PC-Software aber noch nicht so synchronisiert sich der AVR spätestens beim nächsten Connectionaufbau der PC-Software neu. Je länger also BootSign gewählt wird desto wahrscheinlicher kann die PC-Software und der AVR einen Fehler in der autom. Baudrate-Erkennung oder Datenübertragung erkennen. Es ist also von Vorteil für die Stabilität wenn BootSign länger gewählt wird. Gruß Hagen
Datum:
Hallo Hagen, mit BootMsg: .db SUCCESS, "Hello World" PC-Prog sendet permanent 'BootSign' AVR antwortet mit: [94][06][02][08][30] = 4 Byte 'BootInfo' + Success [48][65][6C][6C][6F][20][57][6F][72][6C][64][30] = 11 Byte 'BootMsg' + Success [C2][94][06][02][08][30] = 1 Byte ??? + 4 Byte 'BootInfo' + Success [48][65][6C][6C][6F][20][57][6F][72][6C][64][30] = 11 Byte 'BootMsg' + Success PC-Prog stellt das Senden ein = connect PC-Prog zeigt das auch an = Windows Sanduhr verschwindet, Titelzeile, Buttonbeschriftung. Protokollfenster: 19.09.08-14:36:10-875 > Connecting... 19.09.08-14:36:10-937 > Switch to 2-Wire mode 19.09.08-14:36:11-031 > Device connected DeviceInformation nur letzte Zeile: Info : Hello World mit BootMsg: .db SUCCESS, "Hallo Welt" PC-Prog sendet permanent 'BootSign' AVR antwortet mit: [94][06][02][08][30] = 4 Byte 'BootInfo' + Success [48][61][6C][6C][6F][20][57][65][6C][74][00][30] = 10 Byte 'BootMsg' + Nullbyte + Success [C2][94][06][02][08][30] = 1 Byte ??? + 4 Byte 'BootInfo' + Success [48][61][6C][6C][6F][20][57][65][6C][74][00][30] = 10 Byte 'BootMsg' + Nullbyte + Success PC-Prog stellt das Senden ein = connect PC-Prog zeigt das nicht an = Windows Sanduhr bleibt, Titelzeile bleibt auf [connecting..., please press RESET on Device] Buttonbeschriftung bleibt auf Abort connecting... Protokollfenster: 19.09.08-14:47:36-609 > Connecting... 19.09.08-14:47:36-687 > Switch to 2-Wire mode DeviceInformation nur letzte Zeile: Info : Hallo Welt Es scheint so, dass nur ein Teil der PC-Software in den Zustand 'Connected' wechselt. Gruß JoJo p.s. Meine Einstellungen Mega168: UseWDR = 1; UseAutobaud = 1; UseVerify = 1; UseE2Write = 1; UseE2Read = 1; UseSRAM = 0; UseCrypt = 0; UseCryptFLASH = 0; UseCryptE2 = 0; UartInvert = 1; RX_PORT = PORTD; RX = PD0; TX_PORT = PORTD; TX = PD1; XTAL = 8000000; BootDelay = XTAL/4; BootBaudrate = 115200; BootVersion = 2; BootCodeSize = 528;
Datum:
Angehängte Dateien:>AVR antwortet mit: >[94][06][02][08][30] = 4 Byte 'BootInfo' + Success >[48][65][6C][6C][6F][20][57][6F][72][6C][64][30] = 11 Byte 'BootMsg' + >Success >[C2][94][06][02][08][30] = 1 Byte ??? + 4 Byte 'BootInfo' + Success >[48][65][6C][6C][6F][20][57][6F][72][6C][64][30] = 11 Byte 'BootMsg' + >Success Was mich wundert ist das der AVR zweimal die BootInfo sendet. Das unbekannte Byte 0xC2 ist ein Fehlercode. Im Attachment mal eine geänderte Version der AVRootloader.exe. In dieser behandle ich die evntl. auftretenden Nullterminatoren der BootMsg. Gruß Hagen
Datum:
Dank Dir, ich kann das aber erst am Montag testen. Gruß JoJo
Datum:
Hallo Hagen, mit der neuen Version von 'AVRootloader.exe' läuft es einwandfrei. Das BootMsg nur ohne Verschlüsselung verwendbar ist war mir vorher nicht klar. Besten Dank für die schnelle Hilfe. Gruß JoJo
Datum:
BootMsg liegt zwischen BootInfo und BootKey. Bei der Aushandlung der Verschlüsselung zwischen Bootloader und PC Software wird ein verschl. Prüfcode benutzt. Dieser besteht aus BootInfo und ersten 4 Zeichen von BootKey. Bevor die verschl. Daten an den AVR gesendet werden, muß dieser Prüfsummen-Block an den AVR gesendet werden. Nur wenn die entl. Prüfsumme identisch zu BootInfo + 4 Zeichen BootKey ist, kann der AVR programmiert werden, bzw. akzeptiert der Bootloader die Programmierungskommandos. Liegt nun eine BootMsg zwischen BootInfo und BootKey so verändert dies die Signatur. Gruß Hagen
Datum:
Hallo Hagen, endlich bin ich wieder dazugekommen weiter zu machen. Das Problem wurde mit LOCKBIT1 und LOCKBIT2 gelöst, d.h. diese Bits werden gesetzt. Die BOOTLOCK01/02/11/12 dürfen nicht gesetzt werden, ist nur ein Bit gesetzt, dann kann der Bootloader nicht richtig mit dem Zielsystem verbinden. Auf jedenfall arbeitet es sehr gut. Danke nochmal für die ausführlichen Antworten. Als Programmer nehme ich den ISP2-USB von E-LAB. Ein sehr gutes Teil mit vielen Möglichkeiten. Grüße
Datum:
Hallo Hagen, ich muß gestehen daß ich Deinen Code noch nicht so ganz verstehe. Den anfänglichen Verbindungsaufbau durch Vergleich von [BootSign] und anschließender Übertragung der [BootInfo]+ SUCCESS, sowie optionaler [BootMsg] + SUCCESS zum PC habe ich soweit begriffen. Doch wie geht's weiter? Ich glaube erkannt zu haben daß zuerst eine komplette Page ins SRAM abgelegt wird, die im AVR berechnete CRC16 mit der vom PC verchickten CRC16 verifiziert wird und anschließend der eigentliche ,Erase-Flash'-Vorgang gestartet wird. OK,ich weiß - eigentlich läßt sich Dein Bootloader ohne nennenswerte Modifikationen verwenden. Das ist bei meinem Projekt (Funkvernetztes Multicontrollersystem) so nicht möglich. Ich würde mich deshalb sehr freuen wenn Du mir das Protokoll im Detail beschreiben könntest. Viele Grüße Marcus
Datum:
@ Hagen Re Wie ich dem Quelltext entnehme, wird der ciphertext nach den ersten 16 Runden mit dem Initialisierungvektor (bzw. danach mit dem jeweiligen vorherigen Ciphertext) xored um nach den zweiten 16 Runden nocheinmal xored zu werden. Ich würde gerne mal wissen wie Du darauf gekommen bist und ob Du bitte einen Link mit einer Kryptoanalyse oder irgendeine andere Referenz dazu nennen könntest?
Datum:
@ Hagen Re Also ich habe im Moment zwei Verständnisprobleme: 1. In Deine Datei AVRootloader.txt lese ich " Das zweifache XOR'ing des Feedback vor den ersten 16 Runden und vor den zweiten 16 Runden verändert den XTEA auf eine Weise das eine Alles oder Nichts Entschlüsselung entsteht. Ändert sich also nur 1 Bit in den Daten so wird der komplette Datenblock und alle auf ihn nachfolgenden Datenblöcke falsch entschlüsselt." Wenn ich CBC mode richtig verstanden habe, wäre das aber auch mit einem einmaligen XOR vor jedem 32 Runden Zyklus gegeben. (Gemäß der unten angegebenen Beschreibung von CBC in wikipedia). 2. Die Terminologie weicht von der mir bekannten ab. Was ist mit Feedback gemeint? Wo bleibt der Initialization Vector? Als Referenz bitte ich Dich, wenn möglich die beiden Seiten aus Wikipedia zu verwenden: CBC: http://de.wikipedia.org/wiki/Cipher_Block_Chaining_Mode bzw. http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation XTEA: http://de.wikipedia.org/wiki/Extended_Tiny_Encrypt... bzw. http://en.wikipedia.org/wiki/XTEA
Datum:
@Klugscheisser: 1.) XTEA ist eine Stromverschlüsselung. Normalerweise benutzt man bei diesen Ciphern keine Feedbackoperationen sondern wendet sie direkt auf den Datenstrom an. Dabei wird mit XTEA aus einem Key ein Schlüsselstrom erzeugt, quasi wie bei einem Pseudozufallsgenerator der Seed und der Zufallsbitstrom, und dieser wird einfach per XOR mit den Daten verknüpft. 2.) CBC ist ein Feedbackmodus der für die Blockverschlüsselungen sinnvoll ist. CBC ist dabei ein sogenannter selbstsynchronisierender Feedbackmodus, es gibt auch noch andere. Eine Blockverschlüsselung zerlegt die Nachricht in Datenblöcke a zb. 8 Bytes und verschlüsselt dann mit dem Cipher diese Blöcke, jeweils immer komplett separat ohen Abhängigkeiten zwischen den einzelnen Blöcken. Das wäre der ECB Modus -> Electronic Code Book Cipher Mode. CBC verknüpft nun diese Datenblöcke untereinander. Angenommen wie haben eine Nachricht aus 4 Datenblöcken a 8 Bytes. Der zu entschlüsselnde Ciphertext wurde aber mit einem Bitfehler empfangen der sich im 2. Datenblock befindet. Wird nun entschlüsselt so passiert beim CBC folgendes: 1. Datenblock wird korrekt entschlüsselt. 2. Datenblock wird auf Grund des Bitfehlers komplett falsch entschlüsselt. 3. Datenblock kann unter Umständen ebenfalls noch falsch entschlüselt werden, aber der 4. Datenblock wird wieder korekt entschlüsselt. Dh. Selbstsynchronisation bei einem Feedback Modus heist das sich ein Bitfehler in einem Datenblock maximal diesen Datenblock + dem nachfolgenden Datenblock falsch entschlüsselt. Alle nachfolgenden Datenblöcke, wenn ohne Fehler empfangen, werden auch wieder korrekt entschlüsselt. 3.) angenommen unser Ciphertext umfasst 10 Datenblöcke. Der 10. Datenblock enthält eine Prüfsumme oder einen bekannten Identifier oä. Wir möchten nun das wenn in einem der 10 Datenblöcke ein Bitfehler entstanden ist das der letzte 10. Prüfsummendatenblock mit 100% Sicherheit auch komplet zerstört wird. Dh. wir möchten das ein Bitfehler im Ciphertext sich bis zum letzten Datenblock propagiert. Dies zerstört die Selbstsynchronisation des CBC-Modus, dh. die Selbstsynchronisation des CBCs ist für unserer Zwecke unerwünscht. Denn 4.) wie wollen mit XTEA nicht nur Daten schützen sondern deren Integrität sicherstellen. Und dazu kann man sogennate CMACs benutzen, also Message Authentification Codes basierend auf Ciphern/Verschlüsselungen. 5.) Da XTEA eine Stromverschlüsselung ist habe aber die Plaintextdaten keinen Einfluß auf den internen Zustand des Ciphers. Dh. der Copher produziert nur vom Passwort abhängige Schlüsselströme. Bei einem Blockcipher stellt der äußere Feedbackmodus, hier CBC, aber sicher das der Ciphertext sowohl vom Passwort wie aber auch Datenstrom abhängig ist. Und exakt das benötigen wir auch um überhaupt einen CMAC aufbauen zu können, also die Abhängigkeit alle nachfolgenden verschlüsselten Datenbytes vom Schlüsselstrom wie auch von den vorherig verschlüsselten Datenbytes. 6.) also benutzt meine XTEA implementierung einen Feedbackmodus der im Grunde genommen für XTEA als Stromverschlüsselung normalerweise garnicht benutzt wird. Würde man diesen äußeren CBC Feedback nur anwenden nachdem ein Datenblock durch XTEA verschlüsselt wurde dann würden sich die Datenbytes der Nachricht aber nicht auf die internen Zustandsregister des XYTEAs nicht auswirken. Es fehlt also eine grundlegende Bedingung um mit XTEA+CBC einen CMAC errechnen zu können. Deshalb arbeitet mein XTEA so das er die 32 Runden in 2x 16 Runden XTEA splittet. Der CBC Modus wird nun zweimal angewendet, einmal vor der Entschlüsselung des Datenblockes, für die ersten 16 Runden. Dann wird das CBC-Feedback-Register erneut mit dem internen XTEA Registern xor-verknüpft und nochmals die zweiten 16 Runden XTEA angewendet. Nun ist sichergestellt das auf kryptographisch sichere Weise der Datenstrom der Nachrichtenbytes in den internen Status des XTEAs eingearbrieitet wurde. Wir können nun mit diesem XTEA Daten verschlüsseln wie auch die Integrität der Daten durch einen CMAC überprüfen. Denn ein empfangener Bitfehler führt mit 100% sicherheit immer dazu das alle nachfolgenden Datenbits bishin zum letzen Datenblock fehlerhaft entschlüsselt werden müssen. Nun der Bootloader verschlüsselt mehrere FLASH Pages in folgender Weise: 1.) ein 8 Bytes Datenblock aus ZUfall wird erzeugt + 8 Bytes BootInfo Signatur + ersten 4 Bytes des Schlüssel. Dieser Datenblock wird als allerrster zum AVR gesendet und initialsiert die Entschlüsselung. Durch die Zufallsbytes und der Eigenschaft der vollständigen Propagation meiner XTEA+2xCBC Implementierung heist dies das unsere kompletter Ciphertext randomisiert wurde. Also selbst wenn man die exakt gleiche HEX Datei mit dem exakt gleichen Key merhmals verschlüsseln würde so wäre der Ciphertext immer komplett anderst. Dies verhindert solche Angriffe wie Known Plain-/Ciphertext/Reply/Exchange Attacks. Zusätzlich serialisiert man das HEX auf den spezifischen AVR da die nächsten 4 Bytes identisch zur BootInfo sein müssen. Dh. ein verschl. HEX kann nur entschlüsselt werden wenn die im ersten Block enthaltene BootInfo (Signatur des Bootloaders + AVR) identisch ist. Die letzen 4 Bytes im Datenblock sind die ersten 4 Bytes des Passwortes, also 32Bit. Der AVR entschlüsselt also diesen ersten Datenblock und nur wenn diese 4 Schlüsselbytes identisch zum Key sind kann korrekt entschlüsselt werden. Man detektiert somit also entweder einen Datenübertragungsfehler mit 1/2^32 Wahrscheinlichkeit oder aber man erkennt das mit einem falschen Passwort gearbeitet wurde. Wichtig dabei ist es das dem Angreifer keinerlei Möglichkeiten in die Hand gegeben werden einen Ciphertext schneller als bei einer Brute Force Attacke brechen zu können und auch das der Angreifer unsere "Prüfsummenlogik" mißbrauchen kann um seine Brute Force Attacke zu beschleunigen. Das stellt der Zufallsseed und das unbekannte Passwort als Verifier sicher. 2.) Nun sendet der AVR Blockweise die zu programmierenden FLASH Daten. Dabei sind diese Daten in Blöcke a max. nutzbarere SRAM für Buffer aufgesplittet. Bei einem SRAM mit 256 Bytes und einer FLASH Pagesize von 64 Bytes wird dieser Buffer also 192 Bytes groß sein und man kann 3 FLASH Pages am Stück übertragen. Der XTEA Cipher wird dabei nicht mehr neu initialisiert sondern arbeitet mit der Initialisierung im Step 1.) immer weiter. Somit hängt der Erfolg der korrekten Entschlüseelung dieser Datenblöcke von allen vorherigen Datenblöcken ab. Der PC sendet nun 192 Bytes an Daten die ge-flasht werden sollen und hängt als letzten 8 Bytes Datenblock wiederum einen Spezialdatenblock an. In diesem wird auf die Addresse des FLASHs in dem die Daten geflasht werden sollen verschlüsselt. Also auch die Addresse wohin man die Daten schreiben soll sind verschlüselt gespeichert. Neben dieser Addresse (3 Bytes) sind in diesem Datenblock wiederum die ersten 4 Bytes des Keys verschlüsselt, quasi als Prüfsumme. Da mein XTEA+2xCBC, wenn er mit einem Bitfehler dekodiert, alle nachfolgenden Datenbytes ebenfalls falsch dekodiert, wird somit diese 4 Bytes Prüfsumme ebenfalls falsch dekodiert. Man kann also mit einer Entschlüsselung nicht nur die Daten schützen sondern sparrt sich einen extra Prüfsummen Algorithmus zu implementieren der auch kryptographsich sicher sein muß ! Eine CRC ist ja kryptographsich nicht sicher man müsste schon mit einem HMAC-> Hash Message Authenfication Code arbeiten und somit würden wie einen Hashalgo. wie SHA1 oä. implementieren müssen. Das sparen wir uns mit meiner abgewandelten Form des XTEAs. Einen kryptographischen Beweis der Sicherheit meiner Abwandlung kann und werde ich dir nicht liefern können. Aber wenn du mal genau drüber anchdenkst ist das auch nötig da ich nur die bekiannten Verfahren entsprechend kombiniert habe. Ich gehe also davon aus das meine Abwandlung nicht die Eigenschaften des XTEAs noch CBCs kryptrographisch negativ beeinflusst. Immerhin wende ich wie gehabt CBC vor der Entschlüsselung an, das ist Standard. Dann nach der Hälfte der Entschlüsselung wende ich CBC erneut an und beeinflusse nur indirekt über die XOR Operation den internen Status des XTEAs, das hat keinen Einfluß auf die Sicherheit vom XTEA da wir nur die zu entschl. Daten modifizieren. Sogesehen basiert mein 2x CBC zwar auf CBC hat aber längst nicht mehr die Eigenschaften eines normalen CBC Modus. Gruß Hagen PS: ich habe jetzt nicht nochmal alles quergelesen, Tip- und Rechtschreibfehler kannste behalten ;)
Datum:
@ Hagen Re Vielen Dank für Deine sehr ausführliche Antwort. Das lese ich jetzt erstmal.
Datum:
Ich musste bei der Konstruktion verschiedene Aspekte berücksichtigen 1.) Algo. muß auf AVR performant und Resourcenschonend sein 2.) alle mir bekannten Angriffe müssen ausgeschlossen sein. Also zb. das der Angreifer mal eben zwei Datenblöcke austauschen kann ohne das der Bootloader dies detektieren kann. Denn sonst wäre es möglich "gezielt" eine/mehrere verschl. Nachrichten neu zu rekombinieren, ohne das der Angreifer überhaupt Ahnung davon haben muß was er da an Daten vor sich hat. 3.) der Bootloader muß sicherstellen können das das verschl. HEX für seinen Prozessor/Bootloadertypus erzeugt wurde. 4.) der Bootloader soll erkennen ob die Daten mit dem korrekten Passwort verschlüsselt wurden 5.) oberste Priorität hat die Integrität der zu flashenden Daten. Dh. es muß ausgeschlossen sein das der Bootloader falsche Daten flasht. Also aus meiner Sicht, und ich habe mittlerweile über 5 Jahre intensivste praktische Erfahrungen mit der Kryptographie, sehe ich zZ. keinen erfolgversprechenden Angriff auf die durch meinen AVRootloader geschützen Daten. An der Dokumentation des kompletten Kommando-/Daten-/Verschl- Protokolles muß ich noch arbeiten. Bitte habt Verständnis das das noch ein bischen Zeit benötigt. Es ist für mich ein Aufwand von 6 Stunden sowas zu programmieren aber ein Aufwand von weit mehr Stunden sowas zu dokumentieren und nachfollziehbar zu erklären warum es so und nicht anders konstruiert wurde. Gruß Hagen
Datum:
@ Hagen Re Vielleicht erlaubst Du mir doch die Bitte, doch den Quellcode der Windows-Software zu posten. Das wäre nett. (oder habe ich was übersehen?)
Datum:
>Vielleicht erlaubst Du mir doch die Bitte, doch den Quellcode der >Windows-Software zu posten. Das wäre nett. (oder habe ich was >übersehen?) Hm, logisch betrachtet hat das Eine nichts mit dem Anderen zu tuen. Meine Intention die Windows-Software nicht frei verfügbar zu machen ist nicht in der Kryptograhie begründet, also zb. einer Hintertür die ich hätte einprogramieren können. Es ist eine Frage des Supportaufwandes und eben auch der Kontrolle der Verbreitung des AVRootloaders. Ich würde also vorschlagen das du mir eine PN sendest und wir dann per EMail aushandeln ob und wie du meine Sourcen benutzen/bekommen kannst. Die PC Software wurde mit Delphi5 also PASCAL programmiert. >Wir können nun mit diesem XTEA Daten verschlüsseln wie auch die >Integrität der Daten durch einen CMAC überprüfen. Denn ein empfangener >Bitfehler führt mit 100% sicherheit immer dazu das alle nachfolgenden >Datenbits bishin zum letzen Datenblock fehlerhaft entschlüsselt werden >müssen. Diese Aussage von mir ist nicht ganz korrekt. Denn eine 100%'tige Propagation von Fehlern kann es garnicht bei dem Verfahren geben. Wenn der letzte 8 Bytes Datenblock falsch entschlüsselt wurde dann haben wir mit 1/2^64 Wahrscheinlichkeit eine falsche Fehlerantwort vom System bekommen. Logisch da das interne Feedbackregister für den 2x CBC nur 8 Bytes und der interene Status des XTEAs ebenfalls nur 8 Bytes groß ist. Somit ist dies identisch zu einer 64 Bit breiten Prüfsumme. Der letze 8 Bytes Datenblock der nach den zu flashenden Daten gesendet wird besteht aus folgenden Daten: 3 Bytes Addresse an die diese Daten geflasht/geeepromt werden sollen 1 Byte Datenblock-Längen-Korregier-Byte. Angenommen wir möchten nur 5 Bytes im FLASH speichern dann haben wir das Problem das XTA+2x CBC aber immer mit volständigen 8 Bytes großen Datenblöcken arbeiten muß. Wir müssen also diese 5 Bytes mit 3 Bytes Zufall auffüllen. Bei der ENtschlüsselung benötigen wir dann die Information das von den soeben entschl. 8 Bytes nur 5 Bytes von relevanz sind. Nun dieses Datenbblöck-Längen-Korrekturbyte macht dies, es würde dann den Wertt 3 enthalten der dann am Ende der XTEA Prozedur von der Datenlängenvariablen subtrahiert wird. Dies hat den Vorteil das wir nur 1 Byte an Datenmenge verbrauchen denn ansonsten müsste man eine Längenangabe der zu flashenden Daten benutzen und das wären mehr als 1 Byte an Information die jedesmal pro Packet gespeichert werden müssen. Davon abgesehen kann der Korrekturfaktor nur den Wert 0 bis 7 annehmen und somit verbleiben 5 Bits ind diesem Byte die man noch anders benutzen könnte, als Flags zb. 4 Bytes Verifier, das sind die ersten 4 Bytes des BootKey. Dieser wird nach der ENtschlüsselung mit dem Bootkey verglichen und nur wenn identisch arbeitet das System weiter. Beim allerersten empfangen Datenblock (16 Bytes) besteht der letzte Datenblock mit fast identischen Aufbau wie vorher beschrieben. Nur mit dem Unterschied das in den ersten 4 Bytes nun die BootInfo gespeichert wurde, statt Addresse + Korrektufaktor. Somit ist die Überprüfungsfunktion dieser "Prüfsumme" bei der Initialsierung wie auch Datenentschlüsselung fast identisch. Dh. alle Datenblöcke im verschl. HEX File sind vom allerersten Initialiserungsdatenblock abhängig und somit auch von den allerersten 8 Bytes des verschlüsselten Zufallsseeds. Gruß Hagen
Datum:
>1. In Deine Datei AVRootloader.txt lese ich " Das zweifache XOR'ing des >Feedback vor den ersten 16 Runden und vor den zweiten 16 Runden >verändert den XTEA auf eine Weise das eine Alles oder Nichts >Entschlüsselung entsteht. Ändert sich also nur 1 Bit in den Daten so >wird der komplette Datenblock und alle auf ihn nachfolgenden Datenblöcke >falsch entschlüsselt." Alles oder Nichts aus Sicht der aktuellen Position eines Bitfehlers oder Bitmanipulation. Würde also das allererste Datenbit gekippt im Ciphertext dann soll der AVR die komplette Nachricht bis hin zum "Prüfsummen"block komplett fehlerhaft entschlüsseln. Sogesehen: man kann nur Alles oder Nichts korrekt entschlüsseln. Wir benötigen dieses Feature für den CMAC. >2. Die Terminologie weicht von der mir bekannten ab. >Was ist mit Feedback gemeint? Wo bleibt der Initialization Vector? Feedback, das ist das zusätzlich mötige 8 Bytes Register das bei fast jedem Cipher-Feedbackmodus nötig ist. Feedback heist dann das über dieses Register und meistens per XOR Operation eine Verknüpfung der Datenblöcke untereinadner erfolgt. Würde man dies nicht machen, also im ECB Modus arbeiten dann kann man verschiedene Angriffe durchführen ohne den Cipher real brechen zu müssen. Zb. wir haben eine verschl. Banküberweisund die aus 2 Datenblöcken bestünde. Im ersten Datenblöck steht Absender + Betrag drinnen. Im 2. Datenblock steht der Empfänger. Wir veranlassen als Angreifer die Zielperson uns eine Banküberweisung zu machen, auf unser Konto. Wir fangen aber jede der verschl. Banküberweisungen der Zielperson ab. Diese tätigt nun eine Überweisung der Miete. Wir fangen diese Nachricht ab und ersetzen den letzen Datenblock mit dem Datenblock unserer Banküberweisung die an uns gehen. Schon geht die Miete auf unser Konto. Das ist möglich weil die Datenblöcke eben vollständig separat voneinander durch ECB verschlüsselt wurden. Der InitVector ist hardcoded alles Nullen. Denn real betrachtet senden wir ja als ersten 16 Bytes Datenblock einen verschl. Block bei dem die ersten 8 bytes verschlüselster Zufall ist. Damit ist das real der InitVector aber eben verschlüsselt. Denn es ist ja egal ob wir den IV am Anfang mit lesbaren/ungeschützen Zufall benutzen oder aber einfach den ersten zu entschlüsselenden Datenblock per Zufall erzeugen und diesen dann als quasi "nachfolgenden" IV benutzen. Vorteil ist dabei das wir das System kryptogaphisch damit stärken, ich vertrete also die Auffassung das es besser ist mit einem fixen IV also Nullen o.ä. zu benutzen und dafür den ersten oder sogar noicht den 2. Datenblock einfach mit Zufall zu füllen und verschlüsselt zu speichern. In beiden Fällen haben wir technsich betrachtet den gleichen Aufwand nur ist bei meiner Methode der IV auch noch durch den Cipher geschützt. Gruß Hagen.
Datum:
Hm, jetzt rede ich die ganze Zeit davon das XTEA ein Streamcipher ist, das ist natürlich falsch denn es ist ein Blockcipher, sorry. Gruß Hagen
Datum:
Die zweistufige CBC Verknüpfung hat den Vorteil das man nur ein 8 Bytes großes Feedback Register benötigt. Wollte man die gleichen Features mit anderen Ciphermodis, die auch dafür konstrueirt wurden (also für CMAC) implementieren, dann benötigt man größere Register, also mehr an Variablen. Das wird für die Optimierung auf dem AVR den Registerdruck auf die CPU erhöhen und somit mehr Resourcen verbrauchen und damit die Performance reduzieren. Es ist dann einfacher XTEA als Funktion jeweils mit auf 16 reduzierten Rundenanzahl auf zwei Aufrufe zu implementieren. Und dann eben im Zwischenschritt das CBC-Feedbackregister erneut zu manipulieren. Mein XTEA benutzt also ein Feedbackmodus der auf CBC als Operation basiert aber im Grunde ganz andere Eigenschaften des Gesamtsystemes erzeugt. Damit ist es kein CBC mehr basiert aber analytisch auf dem Kryptobeweis des CBCs. Gruß Hagen
Datum:
@ Hagen Re Ich möchte Dir nochmals für die Mühe danken, die Du Dir mit der Beantwortung der Fragen machst. Mein eigener Bootloader wird sicherlich um einiges anders aussehen. Dennoch lese ich Deinen Code und Deine Antworten mit grossem Interesse. XTEA wird es halt auf jeden Fall, da der Code dafür wirklich extrem klein sein kann. Das Du die Verbreitung der Windows-SW kontrollieren möchtest akzeptiere ich selbstverständlich. Wäre halt nett gewesen, ist aber nicht notwendig.
Datum:
Melde dich hier an und sende mir eine PN und dann kannst du die Sourcen haben. Ich bin immer daran interessiert wenn sich dritte Personen die Zeit nehmen und meine Sourcen analysieren und somit eventuelle Fehler finden und beseitigt werden. Dasa erhöht ja die Anwendungssicherheit und verifiziert meine Arbeit. Davon abgesehen könnten wir so per EMail noch mehr Erfahrungen und Wissen austauschen und eventuell kann auch ich dir gerade bei den Kryptosachen noch par Tipps geben. >XTEA wird es halt auf jeden Fall, da der Code dafür wirklich extrem >klein sein kann. Falls du ihn kürzer als meine Implementierung bekommst dann wäre ich dir sehr dankbar wenn du mich daran partizipieren ließest. Gruß Hagen
Datum:
Hi Hagen, habe heute mittag deine Soft runtergeladen, a bissel gelesen (bin lesefaul) parameter geaender (auf 2te rs232 des 128 mit max232) Bootloder programmiert und funktioniert !, !!! VIELEN DANK FUER DIE TOLLE SOFT !!!! vlg Charly
Datum:
@ Hagen Re So. Habe mich jetzt mal angemeldet. Kriegst noch ne PN.
Datum:
Ich habe da noch eine kleine Frage: Man kann ja einen Bootstring angeben, der z.B die Hardwareversion enthalten kann. Wenn ich jetzt mit der DLL eine neue Software in den Controller laden möchte, und der Bootstring nicht korrekt ist (z.B. falsches Gerät für die Software), kommt bei mir keine Fehlermeldung, sondern es passiert nichts. Kann ich irgendwie abfragen, welcher Bootstring in der Hardware steckt bevor ich mit dem Upload beginne? So könnte ich dann je nach Bootstring eine andere Software auf den Controller laden. Louis
Datum:
Hi Louis, du beziehst dich auf obigen Post mit der BootMsg: ? Du benutzt die AVRootIntf.DLL und allozierst mit OpenAVRootloader(...) ein IAVRootloader Interface. Dieses Interface hat mehere Sub-Interfaces wie .CommandSet: ICommandSet oder eben .Device: IDevice. Über dieses .Device Member des AVRootloader Interfaces kommst du an die .Info: WideString ran. Nach dem also über .DoConnect() eine Verbindung aufgebaut ist, kann man auf diese Info = BootMsg zugreifen. Oder aber in deinem IApplication Interface die "Callback-.Methode" .Changed. Diese Methode .Changed wird immer dann aufgerufen wenn sich zb. im Verbindungsstatus verändert hat.
var
Loader: IAVRootloader;
begin
Loader := OpenAVRootloader(Self, ...);
if Loader.DoConnect() then
try
ShowMessage(Loader.Device.Info); // BootMsg anzeigen
finally
Loader.DoDisconnect();
end;
end;
|
Alle Daten in .Device stehen auch nach einen .Disconnect() weiter zur Verfügung. Erst beim nächsten .DoConnect() werden diese Daten aktualisiert. Du kannst also ohne Probleme auf .Info zugreifen um damit deine AVRs noch mehr zu serialisieren usw. Du hast über .Device Zugriff auf alle Daten die auch meine PC-Software anzeigen kann. Gruß Hagen
// connected Device Information, part of IAVRootloader
IDevice = interface
['{9EC8A92B-F6BB-47F3-A9C9-DF8F4F481F49}']
function Signature: Integer; stdcall;
function Name: WideString; stdcall;
function Info: WideString; stdcall;
function FlashSize: Integer; stdcall;
function AppFlashSize: Integer; stdcall;
function EepromSize: Integer; stdcall;
function RamSize: Integer; stdcall;
function RamStartAddress: Integer; stdcall;
function PageSize: Integer; stdcall;
function BufferSize: Integer; stdcall;
function Version: Integer; stdcall;
function UseBootSection: Bool; stdcall;
function RetCode: Byte; stdcall;
function Support: Integer; stdcall;
function XMLFileName: WideString; stdcall;
end;
|
Datum:
Aber beachte dabei das mit der Nutzung von BootMsg: keine XTEA Verschlüsselung mehr nutzbar ist. Man könnte aber mit wenigen Änderungen im Source BootMsg auch mit Verschlüsselung benutzen. Das habe ich aber nicht weiter ausgebaut da der Trick mit BootMsg: quasi nur ein Abfallprodukt war. Warum mit BootMsg: die Verschl. nicht mehr richtig funktioniert habe ich in einem der verherigen Postings erklärt. Gruß Hagen
Datum:
Hallo hagen, kann man den bootloader auch in externen anwendungen verwenden??? Habe ein VB 2008 Programm indem würde ich gerne eine update funktion einbauen und dann die firmware flashen. Kannst mir bitte mal n code exampel schicken oder so??? danke
Datum:
Uff ich denke VB2008 sollte DLLs laden können und mit statischen Interfaces umgehen können. Ich habe nur ein Beispiel für Delphi beigepackt und mit VB2008 kenne ich mich im Grunde nicht aus. Meine Zeit als ich mit Basic zu tun hatte war ja vor 20 Jahren, oder länger. Du müsstest dann nur noch die Interfaces in AVRootIntf.pas nach VB portieren. Ich habe dabei sehr darauf geachtet möglichst mit den Standard Datentypen zu hantieren und alles stdcall deklariert wie es bei COM/DCOM/ActiveX Controls nach MS Standard üblich ist. Allerdings sind es eben statisch importierbare Interfaces und keine von IDispatch ableiteten Interfaces wie bei leicht zu importierenden COM/ActiveX Controls. Dazu hätte ich eine TypeLib bauen müssen und das war mir einfach zuviel Overhead. Ich meine du solltest es einfach mal probieren und wenn du möchtest können wir bei EMail dann gemeinsam über deine Sourcen schauen. Also verstehen würde ich ein VB Script schon nur dir jetzt ein funktionierendes Beispiel liefern nicht. Dazu müsste ich mich erst einarbeiten und das kostet zuviel Zeit. Aber gehen solltes es wenn VB2008 DLLs importieren kann und Interfaces unterstützt, was ich denke auch so ist. Gruß Hagen
Datum:
Hallöle! Ich habe hier folgendes Problem: Habe alle Einstellungen wie in AVRootloader.txt beschrieben gemacht, kompiliert und mangels eines "AVRStudio-kompatiblen Brenners" mit einem STK200-Parallelport-Brenner unter Bascom in den Controller (Mega32) geschubst. Ging auch gut und hat auch gefunzt. Allerdings nur EINMAL! Scheinbar hat die zu brennende hex-Datei die Bootloader-Datei wieder überschrieben. Ich kann mich erinnern, dass man beim Microsyl-Bootloader erst einige Einstellungen (Fusebits setzen) durchführen musste um den Bootloader in einem geschützten Bereich zu verschieben/installieren zu können, so dass er nach dem brennen immer noch da ist. Könnte mir bitte jemand die Anleitung posten, wie ich das anstelle (ihn im "Bootsector" zu installieren). Ich würde den Bootloader gern als Ersatz für den Parallelportbrenner benutzen, da auch teurere Notebooks nicht mehr zwingend nen Parallelport haben. Mit nem USB-RS232-Kabel funktioniert der nämlich Bootloader tadellos. Danke
Datum:
Du musst bei allem Megas die BOOTSZ Fuses entsprechend setzen. Wenn du mit AVRStudio das ASM kompilierst dann wird im Message-Window auch angezeigt welche BOOTSZ Fuses du setzen musst. Das hängt ja von der Größe des compilierten Bootloaders ab. Zusätzlich kannst du dann noch die Lock-Fuses setzen um den Mega dicht zu machen. Leider kann ich dir aber nicht exakt sagern welche Einstellungen du bei deinem Programmer treffen musst. Machst du diese Einstellung nicht, so kannst du einmal die AVRootloader.HEX programmieren und dann darüber nur einmal ein eigenes Progranm über den Bootloader laden. Danach springt der AVR immer sofort das eigen Program an und nicht zuerst den Bootloader. Gruß Hagen
Datum:
Hallo Hagen, können wir Deine AVRootIntf.DLL etwas ausbauen ? Es wäre schön wenn man zum Beispiel die Com Port Geschichte auch umgehen kann um direkt über USB zu Flaschen (Stichwort: FTDI o. LPC...). Aktuell wollte ich nämlich gerade einen Intel HEX Loader nachbauen hab aber Deinen Thread gesehen und glaube das ich mir das sparen könnte. Und ich hab gesehen wir nutzen beide Pascal könnte Dich also unterstützen. Gruß Gerry
Datum:
@Gerry: >Es wäre schön wenn man zum Beispiel die Com Port Geschichte auch umgehen >kann um direkt über USB zu Flaschen (Stichwort: FTDI o. LPC...). Garnicht nötig, wird schon unterstützt ;) Konzeptionell sind in AVRRootloader.DLL drei Interface implementiert. 1.) IAVRRootloader dieses Interface wurde durch mich entwickelt und setzt die abstrakte highlevel Schnittstelle der Bootloader Funktionen um. Es enthält also das Kommunikationsprotokoll des Bootlaoders usw. 2.) ICOM dieses Interface erledigt die serielle Kommunikation. Es ist die Verbindungsschnittstelle zwischen IAVRRootloader und dem seriellen COM-Port. Auch dieses Interface habe ich komplett durchimplementiert. 3.) IApplication Diese abstrakte Schnittstelle muß der Programmierer der die beiden vorherigen Schnittstellen anwenden möchte implementieren. Es übernimt die Aufgabe der Abfrage alle Parameter. Einer der Parameter die das IAVRootloader Interface vom IApplication Interface abfragt ist das Kommunikations-Interface, also die ICOM Implementierung. Wenn man nun per USB kommunizieren möchte so braucht man nur ein eigenes ICOM Interface zu bauen das nicht auf dem COM Port aufsetzt sondern auch USB. Das eigene IApplication Interface wird in der Methode function OpenCommunication: ICOM; stdcall; also ein eigenes ICOM Objekt zurückgeben das dann auf die USB Schnittstelle aufsetzt. Normalerweise wird jetzt die Funktion OpenCOM(), importiert aus der DLL, aufrufen, und damit meine standardmäßige Implementierung auf dem seriellen COM Port. Du musst also in deinem IApplication Interface (Callbacks) nur die OpenCommunication() abändern und dort eine eigene Implementierung eines ICOM Interfaces das auf USB aufsetzt. Gruß Hagen
Datum:
@Gerry: soweit erstmal so gut. Man muß aber nun noch überprüfen ob das eigentliche Kommunikationsprotokoll des Bootloaders für USB auch konzeptionell tauglich ist. Im zb. ICOM Interface sind zb. die Timeouts der Kommunikation einstellbar. Davon macht das IAVRootloader Interfcae intern regen Gebrauch, da nur so sicherzustellen war das alle performant und denoch stabil läuft. Auch die einzelnen Protokollschritte des Bootloaders sind auf ein serielles Protokoll, wie die RS232, aufsetzend. Ich denke aber das es relativ einfach sein müsste auch auf USB aufsetzen zu können, Hauptsache es ist ein serielles USB Protokoll, und das ist imer der Fall. Denoch muß die überprüft werden und das geht im Grunde nur wenn man erstens Ahanung vom USB hat und zweitens es praktisch auch versucht. Gruß Hagen
Datum:
Hallo Hagen, hab gerade gesehen das der Bootloader in ASM ist. Tja und ASM ist für mich nur kryptisch. Da ja die Komunikation nicht über uart läuft müste also der Bootloader umgeschrieben werden und das kann ich definitiv nicht in ASM. Gerry
Datum:
Ja der AVR Teil ist in Assembler, das ist eine zwingende Voraussetzung wenn man sowas effizient haben möchte, bzw. das letzte Quentchen an Optimierung haben möchte. Die obige Vorgehensweise macht dann Sinn wenn man zb. per USB direkt einen USB-Serial-Wandler ansprechen möchte. Auf AVR Seite hat man ja sowieso alles auf RS232. Möchte man dies aber abändern dann muß man natürlich auch den Assembler Source des Bootloaders anpassen. Das werde ich aber mit Sicherheit nicht machen wollen ;) Allerdings dürfte auch das garnicht mal so schwierig zu ändern sein, es gibt defakto nur 3 Stellen im Source die angepasst werden müssten. 1.) Baudrate-Detektion gleich am Anfang im Source 2.) die Sub-Funktion getc() um ein Zeichen vom der RS232 zu lesen 3.) und putc() um ein Zeichen in die RS232 zu schreiben Man könnte durch die Änderung der letzten beiden Punkte zb. auch die HW-UART der AVRs benutzen, oder eben auf USB Hardware zugreifen, falls sie im AVR vorhanden ist. Gruß Hagen
Datum:
Hagen Re wrote: > Die obige Vorgehensweise macht dann Sinn wenn man zb. per USB direkt > einen USB-Serial-Wandler ansprechen möchte. Auf AVR Seite hat man ja > sowieso alles auf RS232. Möchte man dies aber abändern dann muß man > natürlich auch den Assembler Source des Bootloaders anpassen. Das werde > ich aber mit Sicherheit nicht machen wollen ;) Nun bei mir läuft nichts über Uart :) Alles schön Parallel > > Allerdings dürfte auch das garnicht mal so schwierig zu ändern sein, es > gibt defakto nur 3 Stellen im Source die angepasst werden müssten. > 1.) Baudrate-Detektion gleich am Anfang im Source > 2.) die Sub-Funktion getc() um ein Zeichen vom der RS232 zu lesen > 3.) und putc() um ein Zeichen in die RS232 zu schreiben > Ja, ABER in ASM ;) Kein Problem, werd wohl Ende der Woche meinen BL fertig haben. Schade so erfindet man das Rad jedesmal neu.
Datum:
>Kein Problem, werd wohl Ende der Woche meinen BL fertig haben. >Schade so erfindet man das Rad jedesmal neu. Naja, es hängt halt von den Prioritäten ab die man sich setzt. Man hat dann zwar zwei Räder aber für jeweils unterschiedliche Konzepte. Eine wichtige Priorität in meinem Bootloader war es eben ihn sehr kompakt zu bekommen und das geht mit zb. C eben längst nicht so kompakt wie in Assembler. Ich habe bewusst den Punkt der Portierbarkeit, der Lesbarkeit für viele Anwender, zurückgestellt. Das ist eben dann der Nachteil den ich in Kauf nehmen musste. Ansich kein Nachteil für mich und dem Wunsch im Hobby einen eigenen Bootloader zu haben. Aber eben für diejenigen Nutzer denen ich im Nachinein frei den Bootloader zur Verfügung gestellt habe und kein Assembler verstehen. Gruß Hagen
Datum:
tolle Arbeit!!!!!!!!!!!! richtig genial!!!!!!!!!!! Nun zu meinem Problem. Habe einen ATMEGA162. Wenn ich die Verschlüsselung deaktiviere also UseCrypt=0 dann kann ich den hex über den Bootloader auf den ATMEGA162 flashen, wenn ich aber UseCrypt=1 setzt und dann versuche die acy-Datei drauf zu flshen bringt er mir die Meldung cmd.SetBuffer.ResCheck(2) Error: Decryption failed. Kann jemand damit etwas anfangen?
Datum:
Jo ich ;) Wie hast du die ACY Datei erzeugt ? Normalerweise geht das so: 1.) AVR mit RS232 verbinden 2.) PC-Bootloader starten 2.1.) dort dein HEX als FLASH-File eintragen/Auswählen 2.2.) nun Compile Button drücken 2.3.) PC Software verbindet mit AVR und fragt somit alle Informationen ab 2.4.) nun wird aus der HEX Datei eine ACY Datei erzeugt 2.5.) PC Software trennt sich vom AVR So ist sichergestellt das das ACY File auch zum Bootloader im AVR passt. Nur auf AVRs die den gleichen Bootloader installiert haben kann dieses ACY installiert werden. Wichtig dabei ist das das Passwort das die PC Software benutzt, steht wenn man es möchte in AVRootloader.INI unter Password, identisch mit dem Passwort in AVRootloader.ASM ist und diese ASM erneut auch compiliert wurde. Ich schätze das gerade letzeres bei dir nicht der Fall ist. Also starte PC Software und drücke Button "Make Pasword". Danach erzeugt die Software per Zufall ein 16 Bytes Schlüssel. Dieser wird in die Zwischenablage kopiert, in die AVRootloader.INI gespeichert wenn du es wünscht und auch sofort in die AVRootloader.ASM Datei geschrieben. Danach mit AVRStudio diese AVRootloader.ASM erneut kompilieren und das daraus entstehende HEX File auf den AVR installieren. Sollte das Passwort der ACY Datei nicht identisch zum Passwort im AVR sein, oder die verschlüsselten AVR-Device-Informationen im ACY File nicht identisch zum Bootloader im AVR sein, dann tritt dieser Fehler den du beschrieben hast auf. Gruß Hagen
Datum:
Wobei, mit dem ATMega162 hatten wir schon ganz andere Probleme, siehe par Postings weiter oben.
Datum:
Ach und nochwas: du hast die AVRootloader.ASM mit Verschlüsselung konfiguriert, also UseCrypt=1 UseCryptFLASH=1 UseCryptEEPROM=1 UseSRAM=0 und ein neues Passwort erzeugt hast, per PC Software, und alles im AVRStudio neu kompiliert hast. Flashe nun AVRootloader.HEX in den AVR und setze die Fuses. Dann startest du die PC Software und verbindest m it dem AVR -> Button "Connect". Nun wählst du als FLASH File deine HEX Datei aus und drückst den Button "Program". Die PC Software wird nun im Hintergrund erkennen das der AVR nur mit Verschlüsselung programmierbar ist und somit dein HEX File live im Hintergrund erstmal in eine im Speicher liegende ACY Datei compilieren und diese dann flashen. Wenn das bei dir geht dann hast du vorher mit falschen Passwörtern gearbeitet ;) Gruß Hagen
Datum:
ja die Postings habe ich gesehen, wie gesagt ohne Crypt geht alles nur mit Encrypt geht nix. Habe es genauso noch ein paar mal gemacht, er bringt immer den gleichen Fehler. Psswort ist das gleiche, habe ich schon überprüft. Ich habe die include m162def.inc ausgewählt.
Datum:
HAbe so gemacht und das hex ausgesucht, er hat nicht erkannt das es ein hex ist und wieder die gleiche FEhlermeldung gebracht.
Datum:
Angehängte Dateien:Habe ich eventuell falsche Fuse bits gesetzt? siehe Anhang
Datum:
Uff mal im Ernst, warum muß ich immer die Probleme Anderer lösen, geht nicht gegen Dich oder Andere. Ist eher ne Frage das ich ein bischen jammern möchte ;) Also zeige mal den Anfang der Konfiguration der AVRootloader.ASM und dann alles an Daten am Ende, also ab BootInfo: dieser Datei. Könte es sein das du eine BootMsg, wie obem im Thread beschrieben, benutzt ? Achso, die Fuses sehen gut aus. Gruß Hagen
Datum:
>HAbe so gemacht und das hex ausgesucht, er hat nicht erkannt das es ein >hex ist und wieder die gleiche FEhlermeldung gebracht. Doch hat er erkannt sonst würde im Log nicht dieser Fehler auftauchen. Poste auch mal bitte den kompletten Inhalt des Log-Memos. Gruß Hagen
Datum:
@Luis: >Man kann ja einen Bootstring angeben, der z.B die Hardwareversion >enthalten kann. >Wenn ich jetzt mit der DLL eine neue Software in den Controller laden >möchte, und der Bootstring nicht korrekt ist (z.B. falsches Gerät für >die Software), kommt bei mir keine Fehlermeldung, sondern es passiert >nichts. Du könntest das aber jetzt schon ohne Änderungen an der Software machen. Dafür gibt es zwei Wege: 1.) ohne Verschlüsselung: Du benutzt für dein Gerät eine eigene BootVersion. Also in AVRootloader.ASM die BootVersion verändern, auf größer 2. Nun startest du die PC-Software, wählst dort dein HEX+EEP File für das Gerät aus und kompilierst eine ACY-Datei. Wenn man eine ACY-Datei kompiliert dann verbindet die PC-Software erstmal mit dem Bootloader im AVR und fragt dort die BootInfo ab, also auch die BootVersion. Diese Daten stehen dann im ACY-File und diese wird verteilt. Später programmiert man den AVR mit dieser ACY-Datei und nur wenn die BootInfo im AVR identisch zu den Daten im ACY-File sind kann diese den AVR programmieren. 2.) mit Verschlüsselung: Du erzeugst für dein Gerät eine neue AVRootloader.ASM Datei mit einem nur für diese Geräte gültigen Passwort, und Verschlüsselung ist eingestellt. Dazu in der PC-Software den Button "Make Password" drücken und das .ASM im AVRStudio erneut kompilieren. Danach mit der PC-Software aus deinem HEX+EEP File eine ACY-Datei erzeugen. Auch in diesem Moment steht im ACY die Kopie der BootInfo aus dem AVR aber zusätzlich werden alle Daten mit dem Passwort verschlüsselt. Diese ACY Datei kann dann später nur auf den Geräten installiert werden die das gleiche Passwort benutzen. Zusätzlich können deine Kunden nun über die PC-Software und voreingestellte Parameter (zb. per Windows-Verknüpfung) in einem Rutsch diese verschl. ACY-Datei programmieren. Aber nur du kannst, weil du als Einziger das Passwort kennst, solche ACY-Dateien für deine Geräte erzeugen. ABER! beachte das du in diesem Fall keine BootMsg: benutzen darfst, sonst geht das mit der Verschl. nicht. Gruß Hagen
Datum:
Danke Hagen, es lag an der BootMsg! Habe ich jetzt raus gemacht und es geht! Es soll nicht nur bei danke bleiben. Möchte dich für deine Bemühungen entschädigen. Ich schreib dir gleich ne PN
Datum:
Danke Ali, dein Vorsatz ist schon eine Belohnung und ein netter Geburtstagsgruß für mich ;)
Datum:
Hallo Hagen, hab heute Deinen Bootloader mal ausprobiert und habe keine Problem damit gehabt. Compiliert, gelinkt, geflasht und dann gebootloaded ... Einfach klasse! Vielen vielen Dank für Deine Arbeit! Beste Grüße, Michael
Datum:
Hallo Hagen, ich versuche deine AVRootloader.dll mit einem VB Express Programm anzusprechen. Die DLL kann ich wie folgt einbinden.
Public Declare Function OpenAVRootloader Lib "AVRootLoader.dll" Alias "OpenAVRootloader" () As String |
Das Programm meldet mir aber sobald ich die Funktion verwende einen Fehler. Ich weiß nicht genau was oder ob die Funktion von dir was zurück gibt. und was ich ihr übergeben muss. Hast du vielleicht eine Schnittstellenbeschreibung zu der DLL? Ich glaube das würde auch anderen helfen, die versuchen mit VB, C/C++ oder C# usw. die DLL anzusprechen. Ich kann leider überhaupt kein Delphi. Vielleicht kannst du auch kurz erläutern wie die prinzipielle Vorgehensweise bei der Initialisierung der Verbindung ist. MfG Andy :) PS: Der Bootloader ist echt klasse. Auch die Anleitung wie man ihn benutzt und einrichtet.
Datum:
So wie du das versucht hast kann das nicht funktionieren. Diese Funktion erwartet ein Interface und gibt auch ein Interface zurück. Das sind ähnliche "Datenstrukturen" wie Objekte, genauer gesagt sind es Schnittstellen von Objekten. Dafür gibt es einen Standard von MS damit eben verschiedene Programmiersprachen über diesen Weg kompatibel sein können. Leider kenne ich mich in diesem Fall nur mit Delphi/PASCAL sehr gut aus, vielleicht noch ein bischen C. Aber wie es heutzutage in VB, ergo BASIC geht weiß ich leider auch nicht. Ein erfahrener Programmierer in VB und Delphi sollte in der Lage sein an Hand der AVRootIntf.pas Source diese zu portieren. Die einzigen beiden normal exportierten Funktionen in der DLL sind also Funktionen die solche Interface-Objekte erzeugen und zurückgeben. Die eigentliche Schnittstelle steckt dann als Methoden in diesen Interfaces. Deren Deklaration, also Namen, Typen, Parameter, Rückgabewerte und Aufrufkonventionen (stdcall, cdecl usw.) kann man in der AVRootIntf.pas Source nachlesen. Dieser Source ist damit auch die Dokumentation der DLL. Gruß Hagen
Datum:
Ok danke. Ich hab in der VB Hilfe auch schon was zu diesen Interface Typen gefunden. Ich werds einfach weiter versuchen. Wenn ich was zustande bekomme werde ich berichten. Grüße
Datum:
Melde dich per PN bei mir, einfach auf den blauen Namen klicken bei meinen Postings. Ein bischen kenne ich mich ja schon mit VB aus und somit könnte ich dir helfen bei der Translation nach VB. Ich habe es halt nicht installiert und normalerweise rücke ich auch nur Sourcen raus die ich auf Korrektheit verifiziert habe. Per EMail könnten wir quasi gemeinsam am Problem arbeiten, bis es läuft. So hätte auch ich einen Vorteil dabei. Gruß Hagen
Datum:
Hallo Hagen, Ich habe eben Deinen Bootloader in der Version vom 19.9.08 (soviel ich gesehen habe die aktuellste) auf einem Crumb256 Modul von chip45 getestet. Ich muss sagen, das ist der erste Bootloader der auf Anhieb bei mir gelaufen ist, alle Achtung! Der Crumb256 hat ja bereits einen FTDI-Chip mit drauf der auf USART0 verdrahtet ist. Ich habe also Deinen Code einfach auf die dem USART0 zugeordneten Pins auf Port E, Pins 0 und 1 geändert und siehe da, funktioniert. Aber ein kleines Poblem ist noch aufgetaucht: Vorsichtshalber hatte ich zunächst in AVRootloader.exe nur 38400 Baud ausgewählt. Das Programmieren des Flash-Speichers klappte auch problemlos, nur das Auslesen des EEPROMs oder SRAMs endete immer mit der Fehlermeldung "Cmd.ReadEeprom.ReadByte(1) ICOM: read error" bzw. "Cmd.ReadRam.ReadByte(1) ICOM: read error". Versuche mit dem Parameter Base in "AVRootloader.ini" und verschiedenen Baudrates ergaben, dass die Defaulteinstellung "Base = 50" nur für 115200 Baud passt, dann funktioniert alles fehlerfrei. Wenn ich aber z.B. nur mit 38200 Baud arbeiten will, muss ich Base deutlich erhöhen. Mit 100 funktioniert's sicher, die genaue Grenze habe ich nicht ermittelt. Gruß Gerd
Datum:
Je geringer die Baudrate desto höher sollte der Wert in Base sein. Dies ist das Basistimeout zum Warten auf 1 ASCII Zeichen beim Empfang über die Schnittstelle. Intern werden die Timeouts aus der Baudrate errechnet, allerdings ohne die Berücksichtigung der eventl. zusätzlichen Timeouts die durch den USB und dessen Treiber entstehen. Deren Berechnungsmethoden sind nicht öffentlich und höchstwarscheinlich von Hersteller zu Hersteller auch noch unterschiedlich. Letzendlich wird man über die Parameter in der INI einen Kompromiß für die eigene Hardware/Treiber Kombination finden müssen der einerseits die Gesamtperformance des Bootloaders nicht so sehr negativ beeinflusst und andererseits die Stabilität des Bootloaders (Anzahl Timoutfehler) negativ beeinträchtigt. Ich bevorzuge natürlich die Stabilität und Zuverlässigkeit statt die um par Bruchteile einer Sekunde schnellere Programmierzeiten. >Fehlermeldung "Cmd.ReadEeprom.ReadByte(1) ICOM: read error" bzw. >"Cmd.ReadRam.ReadByte(1) ICOM: read error". Exakt diese Fehlermeldungen beeinflußt man über den Wert Base in der INI Datei. Sie entstehen weil die PC-Software voeher ein Kommando an den AVR gesendet hat und nun auf eine Antoert vom AVR warten muß. Minimal wartet die PC-Software den Wert in Base in Millisekunden oder die Zeitspanne die sich aus der Baudrate und der Übertragung von 1 ASCII Zeichen ergäbe. Gruß Hagen
Datum:
Hallo Hagen ! Erstmal dickes lob für den AVRootloader ! Ist echt spitze ! Ich hab ein kleines Problem bei der Implementierung eines anderen Icom Interfaces ! Und zwar will ich auf einen ftdi232 per D2xx-Treiber zugreifen. Ich komme aber mit der einbindung als ICom nicht ganz klar ! Wie genau muß ich denn die funktion Opencommunication in der AVRootinf anpassen bzw. wie kann ich die neue funktion richtig einbinden. Delphi meldet mir immer: Error: Application.OpenCommunication provides no communication interface Die Funktion zum öffnen der Kommunikation über D2xx hab ich übrigens aus den Delphi-Quellen auf der Homepage von FTDI (D2xxappl.pas)! Wäre klasse wenn du oder jemand anderes eine Antwort hätte ! Gruß Stefan
Datum:
1.) du baust dir ein neues Object, abgeleitet von TInterfacedObject mit der Schnittstelle ICOM, inetwa so
TCOM = class(TInterfacedObject, ICOM)
private
FApplication: IApplication;
FHandle: THandle;
FDCB: TDCB;
FTimeouts: TCommTimeouts;
FDCBSet: Boolean;
FTimeoutsSet: Boolean;
FTimeout: Cardinal;
FEcho: Bool;
FWCRC: TCRCDef;
FRCRC: TCRCDef;
FOverlapped: TOverlapped;
public
constructor Create(const APort: WideString; const AApplication: IApplication);
destructor Destroy; override;
procedure SetTimeout(Value: Cardinal; const ProcName: WideString = ''); stdcall;
procedure SetParams(Baudrate: Cardinal; Parity: Byte = NOPARITY; Databits: Byte = 8; Stopbits: Byte = ONESTOPBIT; const ProcName: WideString = ''); stdcall;
procedure SetEchoMode(Value: Bool); stdcall;
function EchoMode: Bool; stdcall;
procedure Flush; stdcall;
procedure Purge; stdcall;
procedure SetDTR(Value: Bool); stdcall;
procedure SetRTS(Value: Bool); stdcall;
procedure InternalWriteData(Buffer: Pointer; Size: Integer; Flags: TCRCFlags = []; const ProcName: WideString = '');
procedure WriteData(Buffer: Pointer; Size: Integer; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
procedure WriteByte(Value: Byte; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
procedure WriteChar(Value: Char; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
procedure WriteWord(Value: Word; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
procedure WriteLong(Value: Cardinal; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
procedure WriteCRC(const ProcName: WideString = ''); stdcall;
procedure ResetCRC; stdcall;
procedure ReadData(Buffer: Pointer; Size: Integer; Flags: TCRCFlags = []; const ProcName: WideString = ''); stdcall;
function ReadByte(Flags: TCRCFlags = []; const ProcName: WideString = ''): Byte; stdcall;
function ReadChar(Flags: TCRCFlags = []; const ProcName: WideString = ''): Char; stdcall;
function ReadWord(Flags: TCRCFlags = []; const ProcName: WideString = ''): Word; stdcall;
function ReadLong(Flags: TCRCFlags = []; const ProcName: WideString = ''): Cardinal; stdcall;
function ReadCRC(const ProcName: WideString = ''): Bool; stdcall;
end;
|
Natürlich implementierst du alle Methoden durch. 2.) du stellst ja eine IApplication Schnittstelle zur Verfügung, als ebenfalls ein Object wie zb. ein TForm das die IApplication implementiert. Deren Methode function OpenCommunication: ICOM; stdcall; sähe dann so aus:
function TForm1.OpenCommunication: ICOM;
begin
Result := TCOM.Create('COM1', Self);
end;
|
Obiges TCOM Objekt ist ein Copy aus meinen internen Sourcen zum Zugriff auf die RS232. 3.) falls du Fragen bzgl. den Methoden, Parameter und Arbeitsweise der ICOM Methoden hast, dann frag. Gruß Hagen
Datum:
Angehängte Dateien:Hallo Hagen ! Danke für die schnelle und ausführliche Antwort ! Leider hab ich tatsächlich ein paar Verständigungsprobleme bezüglich der ICom-Schnittstelle ! Wenn ich das richtig interpretiert habe setzt deine TCom Methode auf der Icom Methode auf und führt den Verbindungsaufbau zum AVR anschließend über deine Dll aus, oder ?! Vielleicht habe ich mich auch nicht richtig ausgedrückt: Für den FTDI gibt es zwei Arten von Treiber. Einen der die Com-Schnittstelle emuliert (benutze ich bisher und funktioniert soweit gut) und einen proprietären USB-Treiber der eine Eigene dll für den Verbindungsaufbau mitbringt. Dieser enthält bereits Methoden um eine Verbindung zum FTDI aufzubauen (allerdings nicht über eine Com-Schnittstelle, sondern über zb. die ID des FTDI). Ich habe mir das so vorgestellt das ich die Verbindung zum FTDI über die Dll von FTDI herstelle und die Datenübertragung dann von deiner dll ausführen lasse. Oder habe ich da einen Denkfehler drin ? Ich hab als anhang mal den Delphi-Source von FTDI angehängt aus dem ich die Datenverbindung übernommen habe. Ich kann mir gut vorstellen das du genug zu tun hast, aber vielleicht findest du ja mal die Zeit einen Blick darein zu werfen und mir vielleicht einen anhaltspunkt zu geben wie ich das implementieren kann. Ich werde es auf jedenfall weiter versuchen und wenn ich eine Lösung gefunden habe diese auch weitergeben da es bestimmt genügend Leute gibt die Ihren AVR per USB(FTDI) ansteuern möchten. Ich bin natürlich trotzdem über jeden Hinweis dankbar ! Gruß Stefan
Datum:
Hi Stefan, als erstes vorweg: möchtest du mit geringsten Aufwand arbeiten dann benutze den Virtuellen COM Port Treiber den der FTDI liefert. Dann musst du diesen nur im System installieren und kannst sofort mit dem bestehenden AVRootloader damit arbeiten, also ohne irgendwelche Programmierung. Die Frage ist eben was für Vorteile du dir durch die direkte Ansteuerung des FTDIs auf Windows Seite erhoffst. Schneller als der viruelle COM über RS232 wirds wohl nicht gehen (denke ich zumindest) und der Aufwand den virtuellen COM Port Treiber im System zu instalieren (ohne brauchst du ja nur die FTDI-DLL) ist auch nicht so enorm. Die Schnittstellen des AVRootloaders bestehen aus vier Interfaces: IApplication, muß durch den Benutzer (also dir) implementiert werden. Par Postings weiter oben findest du einen Delphi Source der das demonstiert. ICOM, das ist die native Schnittstelle zum eigentlichen Kommunikationstreiber unter WIndows. Für den Zugriff auf RS232 = COM Schnittstellen habe ich schon alles implementiert. Für den direkten Zugriff auf zb. deine FTDI-DLL musst du diese ICOM Schnittstelle durch ein eigenes Objekt implementieren. Eine beispielhafte Deklaration eines solchen Objektes habe ich im vorherigen Post schon aufgezeigt (meine Implementierung für die RS232). IAVRootloader, ist der eigentliche Bootloader Code. Dieser greift auf das übergebene IApplication Interface zu um zb. Parameter, Einstellungen und Ausgaben im eigenen GUI zu machen. Desweiteren fragt er das Kommunikations-Interface = ICOM Objekt bei IApplication ab und benutzt dieses um mit der eigentlichen Kommunikationshardware zu reden. IDevice, ist ein Sub-Interface von IAVRootloader und nur eine Strukturierung der vielen Methoden des Bootloader Interfaces. IDevice stellt quasi gruppiert alle Informationen zum verbundenen AVR dar. Schau dir also mal meine Beispiel-Anwednung par Postings weiter oben an. Dann beginnst du deine eigenes ICOM Objekt zu bauen und gibts es statt dem Aufruf OpenCOM() als Resultat in deiner IApplication Schnittstelle bei der Methode .OpenCommunication() zurück. Gruß Hagen
Datum:
Hallo Hagen ! Der Hauptvorteil soll eigentlich darin liegen das ich keine virtuellen Com-Ports mehr benutzen muß, sondern die angeschlossenen AVR's über ihre ID identifizieren und direkt ansteuern kann. Bei den virtuellen Com-Ports ist oftmals das Problem, das sich die Portnummer ändern und du nacher 10 reservierte Com-Ports im System hast und außerdem nicht mehr weißt unter welchem Comport der AVR jetzt zu erreichen ist ! Ich werde mich jetzt mal nen bißchen mit der ICom auseinandersetzen ! Danke und Gruß Stefan
Datum:
Hallo Hagen ! Ich bin grad bei der Implementierung der TCom-Schnittstelle. jetzt hab ich zum Beispiel
procedure TCom.SetTimeout(Value: Cardinal; const ProcName: WideString = ''); begin Set_USB_Device_TimeOuts(Value,Value); end; |
implementiert.
Ist das so richtig ?
Was bedeutet 'const ProcName: WideString ' ? bzw was muß ich hier
übergeben ?
Außerdem bekomme ich bei
FWCRC: TCRCDef;
FRCRC: TCRCDef;
eine Fehlermeldung über nicht definierte Variablen !
Gruß Stefan
Datum:
> ist das so richtig ? Ja. > Was bedeutet 'const ProcName: WideString ' ? > bzw was muß ich hier übergeben ? Musst du nicht benutzen, ist nur für eine gezieltere Fehlerbehandlung nötig. Zb. hat die ICOM Schnittstelle die Methode: ReadByte(CRCFlags, ProcName); und wird in verschiedenen higher-Level Funktionen des IAVRootloader Interfaces benutzt. Zb. so
FCOM.Purge;
FCOM.SetTimeout(FTimeout.Base, 'Cmd.ReadEeprom.SetTimeout(1) ');
FCOM.WriteWord($0400 + Bytes mod 256, [crcReset, crcSend], 'Cmd.ReadEeprom.WriteWord() ');
CRCOk := False;
Buf[0] := FCOM.ReadByte([crcReset], 'Cmd.ReadEeprom.ReadByte(1) ');
try
if Bytes > 1 then
begin
Buf[1] := FCOM.ReadByte([], 'Cmd.ReadEeprom.ReadByte(2) ');
if Bytes > 2 then
begin
FCOM.SetTimeout(Bytes * FTimeout.Base, 'Cmd.ReadEeprom.SetTimeout(2) ');
FCOM.ReadData(@Buf[2], Bytes -2, [], 'Cmd.ReadEeprom.ReadData() ');
FCOM.SetTimeout(FTimeout.Base, 'Cmd.ReadEeprom.SetTimeout(3) ');
end;
end;
CRCOk := FCOM.ReadCRC('Cmd.ReadEeprom.ReadCRC() ');
Res := FCOM.ReadByte([], 'Cmd.ReadEeprom.ReadByte(3) ');
except
on E: ECOMReadError do Res := Buf[0]
else raise;
end;
|
Falls also TCOM.ReadByte() einen Fehler meldet, Timeout oder so wird .ReadByte() eine Exception auslösen und in dieser wird der Wert in ProcName als Message mit eingebaut. Sowas geht mit anderen Sprachen wie .NET und C# schon automatisch, allerdings erzeugen die auch einen trace-baren Aufrufstack und mit Delphi erzeugt man optimierten Nativcode der durch die Registeroptimierung der Parameter oft ohne Stack auskommt. Ergo denke ich pragmatisch und baue so einen Paramater ein, im Hobby kann man ja so vorgehen. > Außerdem bekomme ich bei FWCRC: TCRCDef; FRCRC: TCRCDef; > eine Fehlermeldung über nicht definierte Variablen ! Ähm, du hast ja nicht meinen vollständigen Source und damit auch nicht meine Unit CRC.pas. Das Beste wird es sein du schickst mir einen PN oder lädst dir von hier http://www.michael-puff.de/Developer/Delphi/Import... mein Delphi Encryption Compendium. In diesem enthalten ist meine CRC.pas Unit, kannste sowieso immer gebrauchen da sie alle Cyclic Redundance Checksum unterstützt. Gruß Hagen
Datum:
Nochwas, wir betrachten mal FCOM.WriteWord($0500 + Pages, [crcReset, crcSend], ''); Das sendet das Kommando zum EEPROM schreiben. Die CRCFlags bedeuten nun folgendes: 1.) crcReset, setzt die FWCRC: TCRCDef Struktur zurück, also resetet die Schreib CRC auf $0000. Und das bevor die CRC über die Bytes $05 $00 gesendet werden. 2.) nun wird das Byte $05 und ($00 + Pages) gesendet über COM und auch darüber die FWCRC updated. 3.) crcSwend bedeutet das WriteWord() als letztes die berechnete CRC über COM sendet In Summasumarum werden also 4 Bytes gesendet $05 = Kommando Write Eeprom Pages = Anzahl zu schreibender Pages CRC = CRC16 CRC Die zu programmierenden Daten wurden schon vor diesem Kommando in den SRAM Buffer im AVR geschrieben und ebenso die Anzahl der Bytes die in diesem Buffer gültig sind. Ebenso die Addresse an die diese Daten geschriben werden sollen. Angenommen man hat vorher mit dem SetBuffer() Kommando also die Datenbytes $FF $FF $FF $FF gesendet und möchte nun aber mit dem WriteEeprom Kommando ($05) aber 512 Bytes im Eeprom schreiben dann würde man einfach das Kommando $05 $80 crc crc absetzen. Die Sequenz um ab Addresse $012345 512 Bytes mit $FF im Eeprom zu befüllen sähe also so aus 1.) SetAddr() -> $FF $01 $23 $45 crc crc 2.) SetBuffer() -> $FE $00 $00 $04 crc crc $FF $FF $FF $FF crc crc 3.) WriteEeprom() -> $05 $80 crc crc Jedesmal wenn die CRC gesendet wurde wird sie neu initialisiert. SetAddr() benutzt 24 Bit lineare Addressen, egal ob SRAM/EEPROM/FLASH gelesen/geschrieben wird. Das erste Byte ist immer das Kommando. Verschiedene Kommandos bestehen aus 2 oder 4 Bytes + 2 Bytes CRC danach. Also auch die Kommandos sind mit CRC separat abgesichert. Je nach Kommando werden danach entweder weitere Daten gesenedet oder empfangen oder das Kommando ist schon fertig, arbeitet also ohne Daten. Falls Daten gesendet oder empfangen werden so sind diese ebenfalls mit der 16 Bit CRC abgesichert. Tjo, soweit zum grundsätzlichen Aufbau der Kommando/Daten des Protokolles. Übrigens alles ist Big-Endian !! WriteWord($FF00) sendet also $FF $00 WriteLong($01020304) sendet $01 $02 $03 $04 Gruß Hagen
Datum:
Es wird schnell ersichtlich das man mit der obigen Methode den Kommunikationsaufwand reduzieren kann. Ich hatte mal eine Testversion meiner PC-Bootloader-Software geschrieben die die zu programmierenden Daten für den FLASH und EEPROM nach sich wiederholenden Sequenzen analysierte und dann mit der obigen Methode quasi eine Komprimierung durchführte. Solange man viele solcher Sequenzen hat konnte man 25-50% an Kommunikation damit einsparen. Leider zeigte aber die Realität, also normale Programme für AVRs, das man dieses Ratio eben nicht erreichen kann. Also habe ich in der aktuellen Version der PC-Software darauf verzichtet und benutze diese Feature nur mein zb. Löschen des EEPROMs. Die ansosten einzige Optimierung in dieser Richtung ist beim Schreiben des FLASHs. Sollten dort komplette Pages im HEX auftauchen die alle mit $FF gefüllt sind so werden diese nur durch ein EraseFlash() Kommando programmiert. Auch dieses Kommando -> $02 Pages crc crc, kann mehrere Pages am Stück löschen. Gruß Hagen
Datum:
Hallo Hagen, habe ein Problem mit dem AVRootloader, ruft man das Prg. per Komandozeile auf funktioniert es nicht wenn im Pfad ein Leerzeichen ist (oder bin ich zu dumm ? ) z.B. -Dc:\programme\avr tools\ -Ftest.hex ergibt c:\programme\avr\test.hex koenntest du das bitte pruefen & event. beheben ? vielen Dank !!! vlg Charly
Datum:
@Charly: Uff, das ist so ein Feature von Delphis RTL das ich schon seit langem hasse. Es kann solche Parameter nicht korrekt auswerten, Leerzeichen stellen einen Separator zwischen mehreren Parametern dar. Das müsste ich definitiv im Source ändern, wird aber dann heissen das ich die Kommandozeile aufwendig von Hand parsen müsste, statt eben auf fertige Funktionen der RTL zurück zu greifen. Vorerst musst du den Ordner umbenennen zb. in avr_tools, also mit Unterstrich statt Leerzeichen. Mal sehen, es könnte demnächst sowieso eine Version 3.0 kommen. Gruß Hagen
Datum:
Mal ne kleine Umfrage meinerseits. Was für Erweiterungen und Verbesserungen schweben euch noch vor ? - Versionsverwaltung der geflashten Software - Updates überprüfen diese Versionsnummer - diese Versionsnummer wird nur bei Verschlüsselung überprüft, also durch den AVR selber mit verschlüsselten Daten. Manipulationen sind ausgeschlossen. Dieses Feature würde nur vorhanden sein bei aktvierter Verschlüsselung. Nur dort macht es auch kryptographisch einen Sinn, alles andere wäre nur informativ. Das bedeutet das im vorgefertigten und verschlüsselten ACY File die Versionsnummer der verschlüsselten HEX Datei gespeichert wird. Im ACY File steht das alles geschützt drinnen. Diese Daten werden beim Kunden zum AVR gesendet und dieser überprüft die aktuell installierte Version mit der gerade empfangen Versionsnummer. Nur wenn es eine neuere Version ist wird eine Programmierung des FLASHs zugelassen. Die Versionsnummer könnte in den letzten Zellen im Anwendungs-FLASH gespeichert werden, quasi so wie der Einsprungsvektor bei den kleinen AVRs. Es würden also zb. 4 Bytes vom Anwendungs-FLASH weniger zur Verfügung stehen. - Bug beseitigen mit der BootMsg: im Zusammenhang mit der Verschlüsselung - Bug beseitigen mit der Kommandozeile - Autodetektion des COM Ports bzw. Serielle Schnittstellen - separate Bootloader-EXE die nur vorgefertigte ACY Dateien programmieren kann, quasi die jetzige Bootloader Software in abgespeckter Version. Dafür enthält diese EXE, quasi wie ein selbstextrahierendes ZIP, schon die ACY Datei. - Auswahlbox für das BootSign: in die PC-Software integrieren. Welchen Sinn hat das ? Nun, wenn man den Bootloader auf 1-Wire benutzt dann kann man jetzt schon mehrere AVRs am gleichen 1-Wire-Bus auf einer Platine verdrahten. Werden diese mit dem Bootloader programmiert, benutzen aber alle eine andere BootSign: dann kann man mit der PC-Software über einen Draht alle AVRs programmieren. Man könnte also zb. 10 baugleiche AVRs auf einer Platine per 1-Wire-Bus verbinden. Alle benötigen im Grunde die gleiche Anwendungssoftware. Man muß also nur 10 Versionen von AVRootloader.ASM komplieren mit jeweils anderen BootSign: zB. BOOT00 bis BOOT09. Dann programmiert man diese 10 unterschiedlichen Bootloader in diese AVRs. Danach kann man sie alle über die PC-Software programmieren. Entweder indem man diese 10 BootSign in einer Auswahlbox von Hand auswählt und dann jeden AVR einzeln programmiert oder aber die PC-Software geht automatisch alle Einträge in dieser Auswahlbox durch und versucht alle mit der gleichen Software zu programmieren. - bitte keinen Vorschlag wie "Terminal" integrieren ;) Gruß Hagen
Datum:
@Henry: >"" ? >-D"c:\programme\avr tools\" Nee geht nicht, habs sicherheisthalber probiert. Um eine Änderung im Source, wie oben beschrieben käme ich also nicht rum. Nur kann ich dann ja gleich alles richtig machen, statt mit Tricks zu arbeiten. Ist halt schade das das es die Delphi RTL nicht gleich richtig macht. Gruß Hagen
Datum:
Hallo Hagen ! Hab mir deine CRC.pas runtergeladen und integriert. Implementieren muß ich hier aber nichts weiter, da die Funktionen bereits in der ICom implementiert sind, oder ?!? Außerdem hab ich noch ein paar Fragen: Die d2xx.dll besitzt keine Flush funktion, dafür aber Purge_Buffer_In und Purge_Buffer_Out. Welche muß ich hier verwenden und wie kann ich die Flush Funktion Implementieren. Außerdem ist keine Echo Funktionalität vorgesehen. Wird diese zwingend benötigt ? Und zu guter Letzt noch die drei Proceduren ReadCrc,WriteCRC und ResetCRC. Hier stehe ich momentan leider komplett auf dem schlauch was die Implementierung angeht. Zur Version 3.0: Die Idee mit der Versionsnummer finde ich super ! - Autodetektion des COM Ports bzw. Serielle Schnittstellen Wie stellst du dir das vor ? Einfach das alle Ports die im System vorhanden sind und genutzt werden im Programm aufgelistet werden(hab ich bei mir schon implementiert), oder willst du ne erkennung einbauen an welchem ComPort der AVR hängt ? Ansonsten weiterso und nochmal Danke für deine wirklich ausführliche Hilfe! Gruß Stefan
Datum:
Die .Flush() Funktion sollte beide Buffer vollständig senden oder empfangen, nicht Purgen.
procedure TCOM.Flush;
begin
if FHandle <> 0 then
FlushFileBuffers(FHandle);
end;
|
versuche es mal mit einer Leermethode also ohne Implementierung. > Außerdem ist keine Echo Funktionalität vorgesehen. Wird diese zwingend > benötigt ? Würde ich einbauen, da nicht sooo schwierig. Alle Methoden die mit .Read??? und .Write??? beginnen landen intern immer bei .ReadData() und .WriteData() Also nur in diesen beiden Methoden findet die komplexere Komunikation, CRC Berechnung und auch der EchoMode statt. Bei .EchoMode=TRUE musst du also in .WriteData() nur exakt die Bytes wieder sofort einlesen die du gesendet hast und verwerfen, überprüfen mit den gesendeten Bytes. > ... ReadCrc,WriteCRC und ResetCRC. Ganz einfach:
procedure TCOM.WriteCRC; var CRC: Word; begin CRC := CRCDone(FWCRC); InternalWriteData(@CRC, SizeOf(CRC)); // WriteData() ohne CRC berechnung CRCDone(FWCRC); end; procedure TCOM.ResetCRC; begin CRCDone(FWCRC); CRCDone(FRCRC); end; function TCOM.ReadCRC(const ProcName: WideString): Bool; begin ReadWord([], ProcName); Result := CRCDone(FRCRC) = 0; end; |
>..Autodetektion des COM Ports bzw. Serielle Schnittstellen >Wie stellst du dir das vor ? 1.) alle COM Ports im System ermitteln, samt FriendlyName, also sowas "COM4: Bluetooth serieller Kommunikationsanschluß" 2.) COM Port ComboBox wird umgebaut zu einer reinen DropDown Liste. Also keine manuelle Eingabe eines COM Ports merh möglich. Zusätzlich wird es in dieser Liste einen Eintrag wie "AUTO" geben. Ist dieser ausgewählt so versucht die Software bei einem Connect() alle in der Liste vorkommenden Ports anzusprechen und mit einem evntl. angeschlossen AVR zu kommunizieren. Das geht natürlich nur dann wenn der AVR aus der Anwendungssoftware in den Bootloader gesprungen ist. Dazu gibt es mehrere Möglichkeiten: a) man überwacht per PinChange den Bootloader-RX/1-Wire-Pin und springt dann aus der PinChange-ISR direkt in den RESET Vektor zum Bootloader oder benutzt den WatchDog um einen RESET auszulösen. Oder man benutzt den RTS Pin der RS232, konfiguriert in der .INI Datei das Verhalten der RTS Leitung entsprechend und verbindet die RTS Leitung mit RESET am Board oder legt sie an einen extra Pin am AVR der wiederum mit PinChange-ISR überwacht wird. Wichtig bei dieser Auto-Detektion des Ports ist es also das der AVR in den Bootloader springt auf Verlangen der PC-Software. Ansonsten muß man permanter den RESET-Taster. Gruß Hagen
Datum:
Bitte noch die Möglichkeit vorsehen den AVR mit einem beliebigen Text aus der .ini-Datei (z.B. "*RST<CR><LF>") in den Bootloader zu schicken.
Datum:
@JoJo: Warum dann aber nicht auf den Wert in BootSign: in der Applikation reagieren ? Die PC-Software sendet bei einem Connect() wiederholt den Wert 0x00,0x00,0x00,0x00, "BOOT" bzw. das was in BootSign: drinnen steht, bis a) der Bootloader reagert mit einer Rückmeldung b) der Connect() Versuch in der PC-Software manuell beendet wird c) eine gewisse Anzahl von Connect() Versuchen abgelaufen ist (* neue Version wird das so machen müssen wenn sie ein AUTO Connect() durchführt) Desweiteren muß klar sein das die Baudrate stimmen muß. Die eigene Anwendung hängt also am UART und erwartet eine Kommunikation mit der richtigen Baudrate, ganz im Gegensatz mit dem Bootloader der eine Baudrate-Detektion besitzt. Ich denke also das dein angedachtes Feature schon jetzt mit dem Bootloader geht, du musst nur richtig konfigurieren ;) Der Connect() ist ein zeimlich Timining kritischer Prozess, sowohl im AVR wie auch auf PC Seite. gruß Hagen
Datum:
Angehängte Dateien:Hallo Hagen, das habe ich auch gedacht und schon probiert. Gescheitert bin ich aber daran dem AVRootloader im Sign=BOOT den Code für <LF> einzufügen. In meinem Fall ist der Befehl zum Einsprung in den Bootloader auch etwas länger als 4 Zeichen z.B.: ":System:Firmware:Update". Dadurch würde dann der Bootloader unnötig aufgebläht. Ich habe mir bisher mit einer Batchdatei geholfen. Das klappt aber je nach Rechner und Auslastung mehr schlecht als recht. Zuverlässiger ist dann zuerst den AVRootloader zu starten, aber nicht "Connecten" und dann den Batch zu starten. Das ganze ist auch als Wunsch für die neue Version zu verstehen. Ich bin mit dem Loader bisher auch prima klargekommen. Danke für Deine Arbeit. JoJo
Datum:
@Jojo, Du möchtest also in der PC-Software das sie bei einem Connect folgendes macht 1.) einen konfigurierbaren String über RS232 senden 2.) eine kurze Zeit warten 3.) mit der bisherigen Vorgehensweise weitermacht Hm, könnte ich so ändern wenn du dich bereit erklärst diese neue Version speziell auf dieses Feature hin zeitnah zu testen ;-) Gruß Hagen
Datum:
Genau. Ob die Wartezeit zwischen 1) und 3) notwendig ist kann ich zur Zeit nicht beurteilen. Da dieses Feature nicht jeder braucht sehe ich auch kein Problem darin, das in der "Ini"- Datei zu "verstecken". Ist ein Eintrag vorhanden dann wird dieser String einmalig gesendet. Wenn nicht dann nicht. Ob und wie man in diesen String Steuerzeichen (Escape-Sequenzen, CR, LF etc.) mit einbauen kann ist mir noch nicht ganz klar. Zum Testen: Kein Problem wenn mich nicht gerade der Grippevirus erwischt. Gruß JoJo
Datum:
>Ob und wie man in diesen String Steuerzeichen (Escape-Sequenzen, CR, LF >etc.) mit einbauen kann ist mir noch nicht ganz klar. Kommt eh, auch für die BootSigns als ESCaped Sequence. Etwa so Test/0a/0dString// eräbe dann test <lf><cr> String / > das in der "Ini"- Datei zu "verstecken" nur so geplant. Gruß hagen
Datum:
Auf die einfachsten Sachverhalte muss einen leider immer wieder jemand anderes hinweisen. Die Sache mit dem Wald und den Bäumen.
Datum:
Angehängte Dateien:@JoJo: hier zum Testen ;) @Andere: neuste Version 3.0, was hat sich geändert ? - Versionsverwaltung für eure eigene Software in AVRootloader.ASM eingebaut. Die Versionsnummer ist 4 Bytes groß und wird in den letzten 4 Bytes im Anwendungsflash gespeichert. Bei AVRs mit Bootsektion exakt die 4 Bytes vor BootStart, also letzten 4 Bytes des nutzbaren FLASHs für eure Anwendung. Bei AVRs ohne Bootsektion steht in den letzten 2 Bytes der JMP zu Main. Deshalb steht die Version in den 4 Bytes davor. Ihr könnt also in eurer Software per LPM auf diese Versionsnummer zugreifen. Der Bootloader sendet diese Versionsnumer beim Connect zur PC-Software. Diese stellt die Versionsnummer im "Device Information" Fenster dar. In AVRootloader.ASM könnt ihr per UseVersioning=1 die Versionsverwaltung aktivieren. Wird die Verschlüsselung als Updatemöglichkeit benutzt kann bei einem Update eurer AVRs mit einem kompiliertem ACY File eine Versionsnummernprüfung erfolgen. Dabei vergleicht der Bootloader im AVR die im ACY verschlüsselt gespeicherte neue Versionsnummer mit der aktuell installierten Versionsnummer. Ist die neue kleiner als die alte wird ein Fehler zurückgemeldet und der AVR kann nicht programmiert werden. In der PC-Software sind 4 Eingabefelder in denen ihr eure Versionsnummer eingeben könnt die bei der Kompilation einer ACY Datei benutzt werden soll. Über die "Verify Mask" könnt ihr bestimmen welche Teile der Versionsnummer im AVR überprüft werden sollen. Somit könnt ihr ein "Back-Update" des AVRs durchführen indem ihr einfach eine ACY Datei kompiliert und alle 4 Checkboxen abhackt. Diese Versionsverwaltung ist kryptographisch sicher, also nur ihr als Besitzer des Paßwortes bestimmt das Verhalten der Versionsverwaltung. Alle Daten sind verschlüsselt, sowohl in der erzeugten ACY Datei wie auch bei der Datenübertragung zum AVR. Nur der Bootloader im AVR entschlüsselt und vergleicht diese Versionsnummern. Diese geschützte Versionsverwaltung funktioniert beim Schreiben des FLASHs wie auch EEPROMs. Dafür muß aber die zwingende Verschlüsselung des FLASHs und EEPROMs in AVRootloader.ASM aktiviert sein. - Autodetektion der COM Ports auf dem PC. Dabei werden die installierten und verfügbaren COM Ports im System ermittelt und mit ihren FriendlyName angezeigt. - Autodetektion des COM Ports an dem der Bootloader angeschlossen ist. In der COM Port Auswahlliste einfach "AUTO" auswählen. Diese könnt ihr auch in der Kommandozeile nutzen. Ist AUTO gewählt und es wird eine Verbindung aufgebaut dann versucht die PC-Software jeden COM Port in der Auswahlliste. Die Anzahl der Trials bei diesem Versuch pro COM Port kann in der AVRootloader.INI -> [System] -> ConnectTrials=? eingestellt werden. Damit dies aber funktioniert muß euer Gerät autom. in den Bootloader wechseln können. Es gibt mehrere Wege, zb. PinChange ISR am RX Pin des Bootloader, oder RTS-Leitung der RS232 am RESET des AVRs und RTSPulse/RTSInterval in AVRBootloader.ini entsprechend konfiguriert. - Neu ist die Möglichkeit das die PC-Software bei der Verbindung einen definierbaren String sendet. Eure Anwendung im AVR, die selber die UART benutzt, kann diesen Befehl dann benutzen um in den Bootloader zu springen. Dazu konfiguriert ihr in AVRootloader.INI -> [System] -> AppCmd= . Der Wert in AppCmd kann Sonderzeichen enthalten zb. so AppCmd=RunBoot/0ATest// Ein Backslash mit anschließend einem HEXadecimalen Wert, immer zwei Zeichen lang. Ein Doppelslash hebt den ESCapecode auf. VORSICHT! ihr könnt nicht das Zeichen #13 -> /0D benutzen, leider. Das liegt daran das die Baudrate Detection im Bootloader dieses Sonderzeichen auswertet. Wollt ihr es denoch benutzen so müsst ihr den Bootloader ohne "Baudrate Detection" konfigurieren, also mit fest eingestellter Baudrate (was meistens dann auch Sinn macht). - Auswahlbox für das BootSign in PC-Software eingebaut. Man kann, wenn man 1-Wire Kommunikation benutzt, alle AVRs eines Gerätes am gleichen 1-Wire-Pin verdrahten. Alle AVRs, können unterschiedliche Typen sein, benutzen den AVRootloader. Nun kann man mit der PC-Software all diese AVRs updaten. - Fehler beim Auswerten der Kommandozeile beseitigt, Leerzeichen im Pfad wurde als Separator erkannt. - Fehler bei der BootMsg beseitigt. Die BootMsg wurde in AVRotloader.asm verschoben und kann nun auch mit der Verschlüsselung benutzt werden. - Der Wert im Eingabefeld "ACY Info" in der PC-Software wird beim Kompilieren einer ACY Datei in diese lesbar gespeichert. Neben diesem Wert auch die lesbare Versionsnummer. Mit einem einfachen Texteditor kann man diese Infos aus einer ACY Datei auslesen. - Kompatibilität zum Bootloader Version 1 und 2 sollte gewährleistet sein. - einige kleinere Darstellungsfehler beseitigt - alle Dateien wie AVRootloader.dev und AVRootloader.ASM wurden auf die neusten AVRs aktualisiert (AVR Studio 4.15 Build 623) - neuer Parameter -SBOOT für die Kommandozeile eingebaut, damit kann man das BootSign für den Bootloader-Connect vorgeben - für diejenigen die die AVRootloader.DLL benutzen. Diese ist nicht kompatibel zur alten Version ! Testen konnte ich das Ganze zZ. nur auf einem ATmega162, also mit einem AVR mit Bootsektion. Es wäre lieb wenn einer, der zZ. mit einem ATTiny den Bootloader benutzt, die neuste Version testet. Speziell BootMsg, UseVersioning mit/ohne Verschlüsselung, danke. Gruß Hagen
Datum:
Angehängte Dateien:Hallo Hagen, das ging ja fix. Hier mein vorläufiges Ergebnis: ES KLAPPT, aber... - Anzeige der verfügbaren Schnittstellen: Com2 erscheint 4mal (siehe Bild) - Beschreibung für AppCmd in Bootloader.txt: Backslash soll Slash heißen - AppCmd wird jetzt immer vor Bootsign gesendet. Ich bin von einmalig AppCmd und anschließend "unendlich oft" BootSign ausgeganngen. So stört es aber auch nicht. (Evtl. währe ein Parameter wie bei RTSInterval möglich - muss nicht) Mein Wunsch ist damit zur vollsten Zufriedenheit erfüllt. Besten Dank für Deine Arbeit. JoJo
Datum:
@JoJo: > Anzeige der verfügbaren Schnittstellen: Com2 erscheint 4mal Echt blödes Betriebssystem. Tja was kann ich tun, ich weiß es nicht ! Denn es scheint keine Methode zu geben die gerade im System aktiven Schnittstellen mit ihrem FriendlyName abfragen zu können. Ich habe nun mittlerweile 4 verschiebene Vorgehensweisen zur Ermittlung der aktiven COM Ports implementiert und getestet (alle aus dem WEB, zb. MSDN) Keine hat davon richtig funktioniert, also habe ich mir selber eine zusammengestrickt. Ich gehe nur über die Registry. Das Problem ist nun, ich kann zwar ermitteln welche COM Ports im System aktiv sind, aber ich kann deren eindeutigen FriendlyName nicht ermitteln. So wie bei dir, kann es vorkommen das über einen längeren Zeitraum verschiedene Installationen erfolgten. Oder das zb. ein USB-Seriell-Wandler an verschienden USB-Hubs angeschlossen wurde. Jedesmal kann dann der gleiche COM Port für ein anderes Gerät benutzt werden. Diese Infos stecken in der Registry und ich lese sie aus. Dummerweise weiß ich zwar das es einen aktiven COM2 im System gibt (auch aus der Regustry) kann aber die möglichen installierten Treiber/Geräte aber nur über den Portnamen zuordnen. Installierte Treiber können es aber eben mehrere zu einem Port sein, welcher davon aktiv ist kann man nicht aus der Registry auslesen, bzw. ich habe keinen Trick im WEB dafür gefunden. Ich bin kurz davor alles wieder umzubauen auf mein altes GUI, dh. FriendlyName wieder aus der Anzeige raus zu nehmen. Denn was nützt es wenn man den COM2 zb. dreimal sieht, mit drei unterschiedlichen FriendlyNames, und damit dann doch wieder keinerlei sinnvolle Information mehr hat welches Gerät nun real angeschlossen ist. > AppCmd wird jetzt immer vor Bootsign gesendet. Ja, ich dachte mir das dies der beste Kompromiß ist. Denn es könnte ja sein das die Applikation selber nicht beim ersten Senden von AppCmd richtig reagiert. Für meinen Bootloader im AVR ist dieses AppCmd egal, solange AppCmd kein #13 enthält und nichts mit BootSign überreinstimt !! Ich habe diese Änderung ja nur für dich, als bisher einzigen Nutzer, eingebaut. Gruß Hagen
Datum:
Mir würde es schon reichen wenn nur die vorhandenen Schnittstellen in der Liste auftauchen. In meinem Fall also Com1 bis Com4, egal wie die sonst noch genannt werden. Hauptsache in der Liste sind keine ComPorts vorhanden, die nicht im System vorhanden sind. Viele Programme zählen einfach Com1..Com255 in der Liste auf. Ist ja auch am einfachsten. Ich habe übrigens mit einem Mega168 getestet. JoJo
Datum:
Angehängte Dateien:Ich habe den Friendlyname der COM Ports wieder rausgenommen. Es gibt keine Methode die Liste der aktiven COM Ports (aus der Registry) mit der Liste der möglichen COM Ports + FriendlyName zu synchronisieren. Auf meinen Rechnern ist die Registry und Installationen sauber, deshalb tratt dieses Problem so nicht auf. Zusätzlich habe ich einen weiteren Parameter für die Kommandozeile eingebaut, Parameter -V. Dieser setzt die Daten für die Versionsverwaltung. Das könnte so aussehen -V0102F01A0F Daraus wird Version 1.2.240.26 und alle Verify Checkboxen angehackt. Der letzte 2 Zeichen HEXadezimal Wert im Parameter gibt die Bitkodierung dieser Checkboxen vor. Gruß Hagen
Datum:
Hallo Hagen ! Für die Comports hab ich dir ne Routine, funktioniert bei mir einwandfrei ! Nur die Friendlynames sind nicht eingebaut, aber das ist für dich sicher nen klax !
function StrX(const Trenner:Char; s:string; x:integer):string; //Sucht X-ten String in s
var sl:TStringList;
begin sl:=TStringList.Create;// Die Liste nimmt die einzelnen Strings auf
// siehe Online.Hilfe ExtractStrings (so kommen die Strings in sl
// -1 weil jede sl mit 0 beginnt
if ExtractStrings([Trenner],[' '],PChar(s),sl)>= x-1 then
// z.B. Leerzeichen am Anf.ignorieren Quelle Liste
result:= Trim(AnsiDequotedStr(sl[x-1],'"')) else result:='';
// im Ergebnis steht so das X-te Wort der Zeile s
sl.Free;
end;
function ComDa(ComNr:String): boolean; stdcall;
var
TestHandle : integer;
begin
TestHandle :=
CreateFile(PChar('\\.\'+ComNr),GENERIC_READ or GENERIC_WRITE,0,
nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,LongInt(0));
if (TestHandle <= 0) then
Result := false
else
begin
Result := true;
CloseHandle(TestHandle);
end;
end;
procedure TForm1.ComPorts;
var
BytesNeeded, Returned, I: DWORD;
Success: Boolean;
PortsPtr: Pointer;
InfoPtr: PPortInfo1;
TempStr: string;
begin
ComboBox1.Items.Clear;
Success := EnumPorts(
nil,
1,
nil,
0,
BytesNeeded,
Returned);
if (not Success) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
begin
GetMem(PortsPtr, BytesNeeded);
try
Success := EnumPorts(
nil,
1,
PortsPtr,
BytesNeeded,
BytesNeeded,
Returned);
for I := 0 to Returned - 1 do
begin
InfoPtr := PPortInfo1(DWORD(PortsPtr) + I * SizeOf(TPortInfo1));
TempStr := InfoPtr^.pName;
if Copy(TempStr, 1, 3) = 'COM' then //begin //Hier ist der Filter angegeben, der nur ComPorts ausgibt
if ComDa((StrX(#58,TempStr,1))) = true then
ComboBox1.Items.Add(StrX(#58,TempStr,1)); //Strings in einer TComboBox hinzufügen
// end;
end;
finally
FreeMem(PortsPtr);
end;
end;
if not Success then MessageBox(Handle, 'Die COM-Port-Liste konnte nicht erstellt werden.', PChar(Application.Title), MB_OK or MB_ICONWARNING);
end;
|
Vielleicht klappt es ja damit ! Hab ich auch irgendwo aus dem internet ! Ansonst mal wieder respekt wie schnell du sowas umsetzt ! Coole Sache ! Gruß Stefan
Datum:
@Stefan: hier mein Code, geht einfach über die Registry.
procedure GetComPorts(Items: TStrings);
function DoSort(List: TStringList; Index1, Index2: Integer): Integer; register;
begin
Result := Integer(List.Objects[Index1]) - Integer(List.Objects[Index2]);
end;
var
N,R: TStringList;
S: String;
I,J,M: Integer;
begin
N := TStringList.Create;
R := TStringList.Create;
try
with TRegistry.Create do
try
RootKey := HKEY_LOCAL_MACHINE;
if OpenKeyReadOnly('\HARDWARE\DEVICEMAP\SERIALCOMM\') then
begin
GetValueNames(N);
for I := 0 to N.Count -1 do
begin
S := AnsiUpperCase(ReadString(N[I]));
if Pos('COM', S) = 1 then
begin
M := 0;
for J := 4 to Length(S) do
begin
M := M * 10;
if S[J] in ['0'..'9'] then
M := M + Ord(S[J]) - Ord('0');
end;
R.AddObject(S, Pointer(M));
end;
end;
end;
finally
Free;
end;
R.CustomSort(@DoSort);
Items.Assign(R);
finally
N.Free;
R.Free;
end;
end;
|
Die Devicemap in der Registry zeigt alle zZ. aktiven COM Ports an. Gruß Hagen
Datum:
Hello Hagen, I am sorry but I do not speak German language. For a few days (weeks) I am looking for suitable AVR bootloader with TEA (XTEA) encryption. Your bootloader is realy the best I have seen till now. I have tried it for a few hours on ATMEGA128. Transfers to flash with or without encryption worked well on uprocessor in STK500 behaind HW COM. In my application I use Lantronix XPORT, on PC I have installed virtual COM. Where is my problem: When I transfer file without encryption, LAN connectivity switches on and file is transfered well. Everything is all right. But when I try to transfer encrypted file, bootloader is connected, LAN is connected too, but LAN activity is not blinking and bootloader is "working". Have you ever tried this kind of transfer? What can be wrong? Thank you for your shareing of code, it had to take much time and much work. Best regards Petr
Datum:
Hi Petr, i know less about you special hardware setup, it is very uncommon to me. To get more information i need some error protocol output from my bootloader software. Normaly the connection process is always the same, even if cryptography is used. I do not see any point why it should differently work with and without cryptography. The only suggestion, or even my opinion, where that the XPORT LAN-protocol, to transfer the virtual COM port data, must be wrong or probable the timing is quit different. Try to increment the values in AVRootloader.ini in section [Timeouts], especialy value for Base. But iff you get no correspondending error messages, eg. timout errors in my bootloader software this suggestion would by pretty useless. Best regards, Hagen
Datum:
Hi Hagen, if AVRootloader is in state "working" it is impossible close the window of loader. I was waiting for long time and after it I obtained protocol I enlose: 20.01.09-07:19:38-441 > Connecting on port COM4... 20.01.09-07:19:38-551 > Switch to 2-Wire mode 20.01.09-07:19:38-671 > Device connected 20.01.09-07:19:41-976 > Program... 20.01.09-07:19:41-976 > execute compiled data 20.01.09-07:19:41-976 > $70,$06,$C8,$F7,$06,$AD,$AE,$04,$EE,$83,$3D,$81,$50,$3F,$31,$DC 1.0.0.1 20.01.09-07:19:41-976 > selected options in compiled file: 20.01.09-07:19:41-976 > - programming FLASH 20.01.09-07:19:41-976 > - FLASH data are encrypted 20.01.09-07:26:07-020 > Cmd.SetBuffer.ReadByte() ICOM: read error. During state "working" I can not see any activity on the line. I will try to catch start of the communication to the terminal and after it I will be back here. Increasing of timeout has no influence to the result. Regards Petr
Datum:
Hallo Hagen ! Hab auch nochmal nen bißchen gesucht und hab diese Seite gefunden: http://www.delphipraxis.net/topic140097,0.html (COM Ports im System auslesen) Die benutzt zwar die Jedi winApi.dll, dafür scheint aber alles zu funktionieren ! zeigt bei mir nur verbundene, vorhandene Com-Ports incl. FriendlyName an ! Gruß Stefan
Datum:
@Stefan, danke dir, kannte ich aber schon und habe alle Methoden probiert. Der Weg übers SetupAPI funktioniert leider nicht richtig. Also das was es anzeigt ist zwar richtig (aktive Ports und FriendlyName) aber es zeigt nicht alle aktiven Ports im System an. Zb. mit Bluetooth und USB Wandler soll es ein Problem haben. Kann man irgendwo bei MSDN nachlesen. Meine obige gepostete Methode funktioniert sehr gut, solange man keine Friendlynames benötigt. Und mit der letzten Version benötige ich sie auch nicht mehr, da dieses Feature raus ist. Der Trick mit dem testweisen Öffenen des COM Ports ist absolut nicht das was ich möchte. Es kann durchaus sein das ein COM Ports durch eine andere Anwendung geöffnet ist und diesen Port möchte ich denoch in der Liste anzeigen. Grundsätzlich sehe ich es im Hobby nicht ein den "Mist" den andere Entwickler verzapft haben ausbessern zu wollen. Dazu ist mir, und vielen anderen Benutzern des Bootloaders, dieses Feature einfach zu unwichtig. Wenn man sich mal den Aufwand, nur par COM Ports im System zu ermitteln, anschaut dann ist dieser nicht gerecht fertigt. Ein vorausschauender Systementwickler berücksichtig im Besonderen die Useablity dessen was er erschafft für die darauf aufsetzenden Entwickler. So entsteht ein gutes OS und kein MS-Windows. Es ist Aufgabe vom OS solche Daten sauber und möglichst einfach abfragbar zur Verfügung zu stellen. Wenn aber für diese Abfrage ein 250-Zeiler benötigt wird dann stimmt da was am Konzept und Umsetzung des OS nicht. Nun, und ich werde mich nicht hinsetzen, viel Zeit verschwenden, um diese Schwachstelle auszubügeln. Ergo: AVRootloader zeigt keine Friendlynames an, fertig, Thema abgegessen ;) Sorry musste aber mal Luft raus lassen. Gruß Hagen
Datum:
@Hagen Vielen Dank für dieses Update. Super! Ich hätte aber noch eine Anregung an das Optische. Ist zwar nicht so wichtig aber durchaus nützlich. Und zwar eine Fortschrittsanzeige. Natürlich wenn der Aufwand dafür nich zu groß ist.
Datum:
Hallo Hagen ! Ist doch kein Problem, wenn man die FriendlyNames nicht gescheit einlesen kann ist das ja nun wirklich nicht dein Problem. Da hast du absolut recht ! Für mich ist das Feature sowieso eher nebensächlich ! Ich kämpfe ja immernoch mit der TCom Implementation ! :-) Du hast geschrieben das die neue AVRootloader.dll nicht mehr zur alten kompatibel ist ! Betrifft das auch meine TCom Function oder hat das ausschließlich mit der Versionsabfrage zu tun ? Übrigens: Tolles Update !! Die Version 3.0 gefällt mir sehr gut ! Gruß Stefan
Datum:
Sorry! Ist schon lange her das ich den Tread von Anfang an durchgelesen hab. Ja ich weiß!! Es gibt ja auch die [STRG]+[F] Kombi. schäm
Datum:
Hallo Hagen, super Projekt! Ich würde Deinen Bootloader auch gerne einsetzen, aber da muss ich wohl eine Änderung vornehmen und möchte im Vorfeld fragen, ob Du das für machbar hältst: Ich möchte den Bootloader per DMX-Schnittstelle nutzen, d.h. vor dem UART des Controllers sitzt ein RS485 Pegelwandler (Standardteil). Rx und Tx sind seperat angeschlossen, allerdings muss ich nun den Pegelwandler von Empfangen auf Senden umstellen können. Reicht das in deinem Code an ein/zwei Stellen die entsprechenden Ports zu setzen, oder wird das Deiner Meinung nach ein größeres Unterfangen??? MfG, roeben
Datum:
@Stefan: >Du hast geschrieben das die neue AVRootloader.dll nicht mehr zur alten >kompatibel ist ! Betrifft das auch meine TCom Function oder hat das >ausschließlich mit der Versionsabfrage zu tun ? Ja und Nein ;) Einfach die AVRootIntf.pas bei dir neu einbinden als Header. Es betrifft das IApplication Interface (muß weitere Parameter zurückliefern) und den TTimeout Record, enthält ebenfalls neue Felder. Allerdings, schäm mich :( habe ich schon wieder par kleinere Veränderungen am Bootloader gemacht. Diesen werde ich nach einer gewissen Wartezeit hier ebenfalls veröffentlichen. Es nutzt ja nichts das Forum wegen par unwichtigen Änderungen ständig voll zu müllen. Ich warte also noch ab ob irgendwelche Fehler oder Verbesserungswünsche eintrudeln und veröffentlich dann die neuste Version. Essentiell gehts um das XPORT Problem vom Petr. Ich denke das der XPORT mit großen Datenpacketen ein Problem hat. Also wurde mein AVRootloader dahingehend geändert das man die maximale Packetgröße der Datenübertragung konfigurieren kann. @roeben: >Ich möchte den Bootloader per DMX-Schnittstelle nutzen, d.h. vor dem >UART des Controllers sitzt ein RS485 Pegelwandler (Standardteil). Rx und >Tx sind seperat angeschlossen, allerdings muss ich nun den Pegelwandler >von Empfangen auf Senden umstellen können. Reicht das in deinem Code an >ein/zwei Stellen die entsprechenden Ports zu setzen, oder wird das >Deiner Meinung nach ein größeres Unterfangen??? Sollte sehr einfach gehen: 1.) vor der Baudrate Detektion, also gleich am Anfang auf Empfang stellen 2.) bei putc: nach den rcall waitf auf Senden stellen 3.) bei getc: die erste schleife leicht abändern und auf Empfang stellen. Hier sollte der rjmp getc auf eine neue Addresse nach deinem Umstellen auf Empfang zeigen etwa so:
putc: rcall waitf rcall waitf sbi RS485_PORT, PinRX_TX ldi cnt, 10 com paral |
getc: cbi RS485_PORT, PinRX_TX get0: rx_1 rjmp get0 |
und am Anfang des Booloaders vor
cbi RS485_PORT, PinRX_TX
sbi RS485_DDR, PinRX_TX
.if UseAutobaud
; baudrate detection
abd: ldi cmdl, byte3(BootDelay / 6)
|
Das dürfte es gewesen sein. Ich bitte dich um zwei Dinge 1.) baue deine Änderungen, wenn sie so funktionieren sollten, per DEFINES und bedingter Comilierung in den AVRootloader.ASM ein. Also wie bei RX_PORT/TX_PORT/RX/TX zwei neue Defines. Die obigen Änderungen, falls sie funktionieren dann per bedingte Compilerswitches einbauen. Und finally UseRS485 als Compilerswitch. 2.) veröffentliche deine Änderungen, wenn sie denn funktionieren, bitte hier im Forum oder maile sie mir, das ich sie übernehmen kann. So haben alle was davon. Gruß Hagen
Datum:
@Hagen: Hab gerade die Test-Dll vom AVRootloder 3.0 getestet ! Leider bekomme ich mehrere Fehler: [Fehler] Unit1.pas(43): E2003 Undefinierter Bezeichner: 'GetAppCmd' [Fehler] Unit1.pas(43): E2003 Undefinierter Bezeichner: 'GetAppVersion' [Fehler] Unit1.pas(43): E2003 Undefinierter Bezeichner: 'GetACYInfo' [Fehler] Unit1.pas(43): E2211 Deklaration von 'OpenCommunication' unterscheidet sich von der Deklaration in Interface 'IApplication' Gruß Stefan
Datum:
Datei AVRootIntf.pas mal anschauen, das sind die besagten Änderungen. Das was ich dir per Mail geschickt habe ist alles auf diese neue Version compiliert. Du musst also nur deine Sourcen updaten. Gruß Hagen
Datum:
@Stefan: jetzt hab ichs kapiert ;) Du musst in deiner Application natürlich diese neuen Methoden des Interfaces auch deklarieren und implementieren. Dh. in deinem TForm hast du als Schnittstelle IApplication angegeben, hast aber diese neuen Methoden nicht im TForm deklariert. Der Compiler meckert es also an. Die function OpenCommunication(Index: Integer): ICOM; stdcall; hats einen neuen Parameter Index um die Autodetektion des COM Ports zu realisieren. Index beginnt dabei immer bei 1 und zählt hoch, so lange bis der IAVRootloader eine Verbindung herstellen konnnte oder aber die Methode .OpenCommunication() den Rückgabewert auf nil setzt, eg. Result := nil; Meine .OpenCommunication sieht also so aus:
function TMainForm.OpenCommunication(Index: Integer): ICOM;
var
PortName: String;
begin
Result := nil;
if AnsiCompareText(Port, 'AUTO') = 0 then
begin // Auto Detection
if Index >= CBPort.Items.Count then
begin
Output('Error: no Device found', ocError);
Exit;
end;
PortName := CBPort.Items[Index];
try
Result := OpenCOM('\\.\' + PortName, Self);
except
Output(Format('Info: can not open port %s', [PortName]), ocInfo);
raise EAbort.Create('');
end;
end else
begin // one COM Port is selected
if Index > 1 then Exit;
PortName := Port;
try
Result := OpenCOM('\\.\' + PortName, Self);
except
raise Exception.CreateFmt('Error: can not open port %s', [PortName]);
end;
end;
try
Result.SetParams(Baudrate);
except
raise Exception.CreateFmt('Error: can not setup baudrate to %d', [Baudrate]);
end;
Output('Connecting on port ' + PortName + '...', ocInfo);
end;
|
Gruß Hagen
Datum:
Hallo Hagen ! Danke für die erklärung der OpenComunication Function ! jetzt bin ich schon wieder nen bißchen weiter ! :-) Aber was ich eigentlich gemeint habe waren nicht die Sourcen die du mir gemailt hast, sondern die Test-Dll aus dem AVRootloader.Zip ! Da hast du zwar die Anpassungen bezüglich der Ausgabe der Versionsnummer usw. gemacht, aber die Implementierung der GetAppVersion usw. wohl nicht vervollständigt ?! Ich kann Sie bei mir auf jedenfall nicht kompilieren ohne besagte Fehlermeldungen ! Gruß Stefan
Datum:
Hallo in die große Runde, erstmal ein großes Lob für diesen super Bootloader! Respekt! Nun zu einem kleinen Problem was ich habe. Ich habe hier einen Attiny45 mit der neusten AVRootloader Version den ich per 1-Wire (PB3) flashen möchte. Das funktioniert auch ohne Probleme mit der in der pdf gezeigten Schaltung. Nun möchte ich aber einen FTDI benutzen. Ich habe dafür entsprechend im Bootloader folgende Zeile angepasst und neu geflashed. .equ UartInvert = 1 Bei der Schaltung habe ich einfach die Dioden entfernt. RX hängt also direkt an PB3 und TX über den 2k Widerstand auch an PB3. Nun leider funktioniert die Kommunikation gar nicht. Auf dem Oszi konnte ich nach erstem Test keine Antwort des Tiny sehen. Irgendwann ist der Pin dann einfach ein Ausgang und HIGH. Meine zweite Frage wäre noch, wie die Verschaltung aussehen müssten, wenn man mehrere Controller programmieren möchte. Das Vorgehen mit dem BootSign hab ich verstanden. Ich würde mal vermuten, dass vor jeden uC mit einem Widerstand am 1-Wire-Bus hängt oder? Sonst könnten sich die Controller ja gegenseitig kurzschließen. Vielen Dank! PS: Danke nochmal für die tolle Software! Grüße
Datum:
Nachtrag: Also ich hab folgendes probiert: UartInvert = 0 und mit der FTDI Software eingestellt, dass die TX/RX Leitungen invertiert werden sollen. Es klappt sofort! Kann es sein, dass es dann ein Softwarefehler ist, wenn UartInvert = 1 und 1-Wire-Mode gleichzeitig an sind?
Datum:
>Kann es sein, dass es dann ein Softwarefehler ist, wenn UartInvert = 1 >und 1-Wire-Mode gleichzeitig an sind? Denke ich nicht, es müsste funktionieren. Definieren wir erstmal: - RX_out ist Output des FTDI für die empfangenen Daten - TX_in in Input des FTDI für die zu sendenden Daten Serienwiderstand 2k zwischen RX_out und TX_In. TX_In an AVR Pin. Nun liegt bei 1-Wire, bei keiner Aktvität immer der Pullup nach VCC am Pin an. Durch die Verschaltung am FTDI zieht aber RX_out über den 2K den TX_In auf LOW Pegel. Schaue also mal ob dein 2k Serienwiderstand in der richtgen Leitung ist. Ich habe aber selber noch nicht diese Kombination getestet und es könnte also durchaus sein das es damit noch Softwareprobleme gibt. Wenn du mehrere AVRs über 1-Wire programmieren möchtest dann sollte UartInvert=0 sein. Jeder AVR könnte aus Sicherheitsgründen einen Serienwiderstand von zb. 220-470 Ohm am Pin haben, je nach VCC. Normalerweise sollten die sich aber nicht in die Query kommen wenn alle Bootloader der AVRs im definierten Zustand sind, dh. sie warten alle erstmal das Connect Commando ab. Wenn nun die AVRs alle unterschiedliche BootSign: haben dann reagiert immer nur derjenige AVR der mit der jeweiligen BootSign: angesprochen wurde, alle anderen AVRs lauschen nur auf der Leitung. Es gibt aber denoch das Problem das durch dummen Zufall, während gerade ein AVR programmiert wird, die Connect Sequenz im Datenstrom auftauchen könnte. Somit würde ein zweiter AVR in die bestehende Verbindung zwischen funken. Man sollte also die BootSign: der AVRs möglichst lang wählen und so das die Wahrscheilichkeit das diese als Daten im normalen Datenstrom vorkommen sehr gering ist. Angenommen die BootSign's benutzen nur Großbuchstaben, sind 8 Zeichen lang dann beträgt die Wahrscheinlichkeit für eine Fehldetektion 1 zu 229607785695641627262976 = 256^5 * 26^8. 256^5 für die ersten 5 Bytes -> 0x00,0x00,0x00,0x00,0x0D gefolgt von den 8 Buchstaben der Bootsign. Alles bezogen auf die Übertragung von 13 normalen Datenbytes im Datenstrom = 20282409603651670423947251286016 mögliche Kombinationen. Die Bootsign der AVRs selber sollten sich stark voneinander unterscheiden. Die Bootloader Software ist im Grunde nicht dafür konstruiert worden, ich weiß aber das es real funktioniert und wie man sieht ist es auch bischen Wahrscheinlichkeitsrechnung ;) Gruß Hagen
Datum:
Hallo Hagen, danke für deine ausführliche Antwort. >- RX_out ist Output des FTDI für die empfangenen Daten >- TX_in in Input des FTDI für die zu sendenden Daten Finde ich persönlich verwirrend, da RX für receive und TX für transmit steht. D.h. RX ist der Empfangspin des FTDI und der TX der Sendepin des FTDI. Bezogen auf den zweiten Kommunikationspartner genau umgekehrt, aber das ist ja erstmal Konventionssache. Der Widerstand ist in der Sendeleitung des FTDI, er verhindern ja z.B. dass ein Kurzschluss entsteht, wenn der Tiny grad Sender ist. Tiny z.B. High und FTDI Low. Passt soweit auch von der Schaltung. Einen Pullupwiderstand gibt es ja gar nicht (abgesehen vom internen Pullup der ja bestimmt aktiviert ist, wenn der Tiny Empfänger ist). Habe den Nachmittag ein bisschen getestet und der Tiny meldet sich einfach nicht im 1-Wire Modus mit aktivierter Invertierung. Aber mit der Invertierung der Signale im FTDI klappt ja alles wunderbar. >Normalerweise sollten die sich aber nicht in die Query kommen wenn alle >Bootloader der AVRs im definierten Zustand sind, dh. sie warten alle >erstmal das Connect Commando ab. Das müsste aber voraussetzen, dass der Tiny Pin im Hauptprogramm nur als Eingang genutzt wird oder? Weil wenn das BootSign keine Übereinstimmung findet, laden die Tinys ja das Hauptprogramm und wenn dort eben der Pin ein Ausgang ist, funken alle anderen uC dem einen der geflasht werden soll in die quere. Oder wird der Bootvorgang angehalten, wenn ein Connect Commando erkannt wurde, das BootSign aber nicht stimmt? Die Sache mit den langen BootSigns ist ein guter Tip! Vielleicht mache ich mal einen Testaufbau. Gibt es eigentlich eine Beschränkung in der Zeichenanzahl des BootSign? Nette Grüße Mark
Datum:
>Gibt es eigentlich eine Beschränkung in der Zeichenanzahl des BootSign? ja, 256 Zeichen. 256 deshalb weil der Zähler beim Senden/Empfangen ein 8Bit Register ist. Würde man dies auf 0 setzen == 256 mod 256, dann kann man 256 Zeichen als Maximalanzahl betrachten. > Finde ich persönlich verwirrend, da RX für receive und TX für transmit Ich habe in der Benamung nur die Sendrichtung mit angegeben, ergor stimmen unsere Sichtweise ansonsten überein. Da ich aber weiß das hier desöfteren Interpreatationsfehler gemacht werden, wollte ich nur sicher gehen. probiere mal folgende Modifikation:
; send char putc: rcall waitf rcall waitf ldi cnt, 10 com paral sbi TX_DDR, TX put3: tx_out rcall waitf lsr paral brcs put4 tx_0 put4: rcall put5 dec cnt brne put3 cbi TX_DDR, TX put5: ret |
in AVRootloader.inc änderst du das Makro:
.macro tx_out xout TX_PORT, cnth .endmacro |
Gruß Hagen
Datum:
Hallo Hagen ! Hab jetzt erstmal die Anbindung des FTDI per D2xx.dll auf Eis gelegt. Ich bekomme trotz identischer Implementierung der vorhandenen FT_W32 functionen immernoch, für mich unerklärliche, Fehlermeldungen. Außerdem funktioniert die Einbindung über VCP-Treiber ja zufriedenstellend. Einziger Wehrmutstropfen war die fehlende automatische Erkennung des richtigen Devices, die ich ja jetzt durch den Anmeldestring ersetzten kann. Damit wären wir dann bei meinem nächsten Problem. Da die Test-Dll veraltet ist fehlt mir die Implementierung der neuen Funktionen. Könntest du die wohl hier posten oder mir als PN zukommen lassen ?! Ich habe übrigens noch einen Verbesserungsvorschlag für die AVRootloader.asm ! Kannst du die so verändern, das bei aktivierter Versionsverwaltung automatisch die Verschlüsselung aktiviert wird ? Damit bin ich nämlich erstmal ganz schön auf die Schnautze gefallen ! :-) (Ja ja, wer nicht lesen kann und so...) Gruß Stefan
Datum:
Hab gerade ein riesen Problem mit der Versionsüberprüfung !! Immer wenn ich die Option im AVR aktiviere bekomme ich keinen Connect mehr !! Hab schon alle möglichen Konfigurtionen ausprobiert, auch unterschiedliche BootSize und BootReset. Alles andere funktioniert einwandfrei, nur wenn ich die Versionsprüfung aktiviere geht nichts mehr !! Irgendwelche Vorschläge ??? Gruß Stefan
Datum:
@Hagen Danke für die Modifikation! Kann ich aber erst in ca. einer Woche testen, da ich jetzt erstmal eine Woche nicht mehr zu Hause bin. Melde dann aber wies aussieht. Grüße Mark
Datum:
Angehängte Dateien:@Stefan: >Hab gerade ein riesen Problem mit der Versionsüberprüfung !! >Irgendwelche Vorschläge ??? Welcher AVR, welche Konfiguration ? Das Versioning funktioniert mit und ohne Verschlüsselung. Aber nur mit aktivierter Verschlüsselung wird ein Update an Hand seiner verschlüsselten neuen Versionnummer in der ACY Datei auch überprüft. Ohne Verschlüsselung ist das Versioning ein informativer Wert, muß also manuell verifiziert werden und kann jederzeit auch downgraded werden. >Ich habe übrigens noch einen Verbesserungsvorschlag für die >AVRootloader.asm ! Kannst du die so verändern, das bei aktivierter >Versionsverwaltung automatisch die Verschlüsselung aktiviert wird ? Also nein ;) da je nach Konfiguration so mehrere Möglichkeiten entstehen. Gruß Hagen
Datum:
> Welcher AVR, welche Konfiguration ? Atmega8, und an der Konfiguration hat sich nichts geändert zum AVRootloader2 ! Habs mit und ohne Autobaud, mit und ohne Verschlüßelung, usw. probiert ! Der AVR hängt übrigens an nem FT232R ! > Das Versioning funktioniert mit und ohne Verschlüsselung. Dann hab ich das wohl falsch verstanden ! :-) > Also nein ;) da je nach Konfiguration so mehrere Möglichkeiten > entstehen. Hat sich ja dann auch erledigt, da es ja auch ohne Verschlüßelung funktioniert ! Hatte halt die Verschlüßelung in Verdacht weshalb das bei mir nicht funktioniert! Muß aber wohl woanders dran liegen ! Ich werde nacher nochmal nen paar Tests machen ! Gruß Stefan
Datum:
Hallo Hagen ! Also hab mal noch nen paar Tests gemacht ! Ergebnis beim Versioning bleibt das gleiche ! Sobald es aktiviert ist kein Connect. Dann hab ich mal unter AppCMD einen Wert =Test eingegeben. Ergebnis: Kein Connect !!! Also schließe ich daraus das die Probleme irgendwo in der kommunikation mit dem FTDI liegen müßen, da du und auch andere Benutzer anscheinend keine Probleme haben ! Gibt es jemanden hier der den neuen AVRootloader zusammen mit einem FTDI erfolgreich betreibt ? Hab schon nen bißchen mit den Timeouts gespielt, leider ohne Ergebnis !! Werde jetzt mal ne alte schaltung mit RS232 raussuchen und da mal testen. Gruß Stefan
Datum:
@all Also erstmal entwarnung was den FTDI angeht ! Der hat damit nichts zu tun ! @Hagen Das problem liegt beim irgendwo beim Reset des AVR ! Wenn ich per Hand einen Reset ausübe(was in meiner Schaltung leider nicht verbaut ist) bekomme ich problemlos einen Connect. Ohne den Reset bekomme ich keine Verbindung ! Konfig: - ATMega8 mit 10 MHZ-Kristall - Nur der Rootloader installiert ! - Bootsize und Bootreset sind programmiert - mit und ohne Autobaud getestet Ohne Versioning und AppCmd klappt der Connect immer, mit einem der beiden aktiviert geht nichts mehr ! Woran kann das liegen ? Gruß Stefan
Datum:
Angehängte Dateien:@Stefan: benutze mal die Version im Attachment. Setze in AVRootloader.INI den Wert in [System] -> Debug=1. Mache einen Connect und schaue im Protokol nach was beim Wert "Received: " angezeigt wird. Je nach Konfiguration den AVRootloader.ASM sollte folgendes angezeigt werden (in HEX) 1.) ohne Versioning, ohne BootMsg 4 Bytes BootInfo, 1 Byte SUCCESS Code $3x wobei X die Features anzeigen 2.) mit Versioning, ohne BootMsg 4 Bytes BootInfo, 4 Bytes Version ($FF,$FF,$FF,$FF bei ungeflashten AVR), 1 Byte SUCCESS Code 3.) ohne Versioning, mit BootMsg x Bytes BootMsg immer gerade Anzahl Bytes, 4 Bytes BootInfo, 1 Byte SUCCESS Code 4.) mit Versioning, mit BootMsg x Bytes BootMsg, 4 Bytes BootInfo, 4 Bytes Version, 1 Byte SUCCESS - wenn die BootMsg definiert wurde dann wird sie immer als erstes gesendet - wenn es eine Version gibt dann wird sie als letztes gesendet und er SUCCESS Code muß >= $38 sein, Version ist immer 4 Bytes, und bei AVRs ohne geflashte Anwednung immer $FF,$FF,$FF,$FF - BootInfo wird immer dazwischen gesendet und ist 4 Bytes Der SUCCESS Code ist immer $30 + $08 wenn UseVersioning = 1 + $04 wenn UseCryptE2 = 1 + $02 wenn UseCryptFASH = 1 + $01 wenn UseCrypt = 1 Das System in der PC-Software geht nun so vor: Warte auf Zeichen von RS232 bis Timeout von [Timeouts].Base eintritt. Solange kein Timeout Fehler baue einen String aus allen empfangenen Zeichen auf. Nach einem Timeout zeige bei [System].Debug=1 in INI Datei den empfangenen Sring HEX-formatiert im Protocol Fenster an. Analysere nun diesen String: - steht am Ende ein gültiger SUCCESS Code ? - ist der SUCCESS Code mit UseVersiong konfiguriert ? wenn ja vorhergenenden 4 Bytes als Verson interpretieren und wegschneiden, wenn neun nur SUCCESS Code wegschneiden. - nun stehen am Ende 4 Bytes an BootInfo, auswerten und auf Plausibilität prüfen und wegschneiden. - nun ist dieser String entweder leer oder enthält die BootMsg. Gruß Hagen
Datum:
Hallo Hagen hab das mal alles der Reihe nach durchprobiert ! > 1.) ohne Versioning, ohne BootMsg > > 4 Bytes BootInfo, 1 Byte SUCCESS Code $3x wobei X die Features anzeigen $93 $07 $03 $10 $37 > 2.) mit Versioning, ohne BootMsg > > 4 Bytes BootInfo, 4 Bytes Version ($FF,$FF,$FF,$FF bei ungeflashten > AVR), 1 Byte SUCCESS Code nur recieved: !! hier findet auch vorher kein switch to 2-wire mode.. statt > 3.) ohne Versioning, mit BootMsg > > x Bytes BootMsg immer gerade Anzahl Bytes, 4 Bytes BootInfo, 1 Byte > SUCCESS Code abwechselnd: recived: $C2 $C2 $C2 recived: $C2 $C2 egal was ich bei AppCmd eingebe ! > 4.) mit Versioning, mit BootMsg > > x Bytes BootMsg, 4 Bytes BootInfo, 4 Bytes Version, 1 Byte SUCCESS wieder abwechselnd: recived: $C2 $C2 $C2 recived: $C2 $C2 habs mit und ohne AutoBaud versucht ! Und hab auch mal den Timeout enorm erhöht (500 !), gleiches Ergebnis ! Kannst du damit was anfangen ? Gruß Stefan
Datum:
$C2 = ERRORCRC, der AVR Bootloader scheint also zu antworten was bedeuten würde das er schon längst in der Command FSM läuft, also connected ist. Probiere mal als AppCmd 1.) AppCmd=/00/00/00/00 2.) AppCmd=test/00/00/00/00 wir senden also par Nullen mehr, also Kommando "Restart Bootloader". Du kannst auch längere Sequenzen aus Nullen ausprobieren. Woher dein Problem nun rührt kann ich dir auch nicht sagen. Du meinst also das mit der alten Version 2.0 keinerlei Probleme mit deiner HW entsteht, aber mit der neuen wie oben beschrieben. Wenn du AVRootloader.asm in AVRStudio kompilierst dann gibts keine Fehler oder Warnungen ? Ausgewählte BootSign stimt mir der im ASM überein ? Gruß Hagen PS: ich sleber habe nun schon mit ATMega162 und ATiny461 alle Optionen getestet, Laptop-RS232 mit 1-Wire, geht wunderbar.
Datum:
Hagen du bist der Beste !! Sobald ich in der AppCmd ein /00 einsetze geht es !!! Und zwar beide Funktionen !!! Und wenn du nicht weißt woran das liegt, dann weiß ich das schon lange nicht ! Ist mir persönlich aber egal, ich kann mit der Lösung leben !! Vielen Dank !!! Gruß Stefan PS: Wenn du mir jetzt noch die Implementation der 3 neuen Funktionen für die Test-Dll zukommen lassen könntest, wäre das Spitze !! :-)
Datum:
>PS: Wenn du mir jetzt noch die Implementation der 3 neuen Funktionen für >die Test-Dll zukommen lassen könntest, wäre das Spitze !! :-) Ist doch im letzten ZIP drinnen ? oder was meinst du ? Gruß Hagen
Datum:
Das Problem mit dem FTDI scheint ein Timing Problem zu sein. Hast du mal mehre Nullen zusätzlich getestet ? Gruß Hagen
Datum:
> Ist doch im letzten ZIP drinnen ? oder was meinst du ?
Sorry ! Hab mich vielleicht falsch ausgedrückt ! Meinte den Aufruf der
Funktionen in der Test-Unit !
Also sowas in der Richtung:function TForm1.GetACYFileName: WideString; begin Result := ExtractFilePath(ParamStr(0)) + 'test.acy'; end; |
Ich will die Functionen ja auch gerne in mein eigenes programm übernehmen ! >Das Problem mit dem FTDI scheint ein Timing Problem zu sein. > >Hast du mal mehre Nullen zusätzlich getestet ? Ja hab ich ! Bis zu 12x /00 hintereinander ! Macht aber keinen Unterschied ! 1x /00 reicht aus ! Ist schon komisch, oder ?!? Gruß Stefan
Datum:
eigentlich nicht ;) Wenn der Bootloader sich schon in seiner FSM befindet so benötigt er exakt 0x00,0x00,0x00,0x00 um quasi einen Restart von sich selber zu machen um erneut in die Baudraten Detektion zu springen. Gleich nach diesen Nullen muß also 0x0D folgen, an Hand dessen die Baudrate Detektion die Baudrate ermittelt. Wenn aber die FSM schon aktiv ist und hat schon 1 Kommando Byte verarbeitet dann reichen die 4 Null-Bytes nicht aus um ein gültiges Restart Kommando zu dekodieren. Der Bootloader antwortet mit ERRORCRC oder ERRORCOMMAND, hauptsache er macht nicht irgendwas unanständiges (eben der Grund warum alle Kommandos separat mit CRC abgesichert sind). Am besten ist es 7-8 solcher Nullen zu senden, und das ist in meiner inoffiziellen Version auch schon gefixt. Der Bootloader war bei dir aber schon in seiner FSM, weil du entweder nach dem vorherigen Test den AVR nicht reset hast oder das "RunApplication" Kommando der PC-Software nicht ordentlich ausgeführt wurde. Es kann durchaus sein das der FTDI Treiber/FTDI selber sofort alle Daten im Buffer löscht wenn die PC-Software nach dem Senden dieses Kommandos sofort die VCom schließt. Ich rufe zwar FlushFileBuffers auf, aber solche Probleme habe ich schon bei einigen Treibern gesehen. Also wenn du mal testest dann prüfe auch mal ob deine Anwendung nach einem Disconnect der PC-Software auch automatisch gestartet wird. Die Aufrufe der neuen Methoden in IApplication sind trivial. Habe nur wenig Zeit das Beispiel zu korregieren (weswegen es in den letzen ZIPs auch nicht mehr drinnen ist). Beim nächsten offiziellen Update packe ichs mit bei. Gruß Hagen
Datum:
Hallo. ich habe das jetzt auch mal bei mir getestet. Aber ich bekomme leider keine Verbindung zum AVR. Folgende Einstellungen habe ich in der asm gemacht:
.include "m644def.inc" #message "compile for" __PART_NAME__ .ifndef PageSize .error "Device don't support Bootloader !" .else .equ UseWDR = 1 ; set to 0/1 to de/activate WatchDog Support .equ UseAutobaud = 1 ; set to 0/1 to de/activate Baudrate Detection .equ UseVerify = 0 ; set to 0/1 to de/activate Verify FLASH Command, FLASH write/erase includes implicit verify, can be deactivated .equ UseE2Write = 0 ; set to 0/1 to de/activate EEPROM Write Command .equ UseE2Read = 0 ; set to 0/1 to de/activate EEPROM Read Command .equ UseSRAM = 0 ; set to 0/1 to de/activate SRAM Commands .equ UseCrypt = 0 ; set to 0/1 to de/activate cryptography .equ UseCryptFLASH = 0 ; set to 0/1 to de/activate only use of cryptography for writing to FLASH .equ UseCryptE2 = 0 ; set to 0/1 to de/activate only use of cryptography for writing to EEPROM .equ UseVersioning = 0 ; set to 0/1 to de/activate Versioning for Application Software .equ UartInvert = 0 ; set to 1 to invert UART levels, for RS232 drivers such as MAX232 .equ RX_PORT = PORTD ; Receive Port and Pin .equ RX = PD0 .equ TX_PORT = PORTD ; Transmit Port and Pin .equ TX = PD1 .set XTAL = 16000000 ; only important for BootDelay if Autobaud is used .set BootDelay = XTAL/4 ; 250ms .set BootBaudrate = 115200 ; only used if no Baudrate Detection activated, XTAL is important .set BootVersion = 3 ; Version 3, must be not changed .set BootCodeSize = 406 ; compile and set to value in [.cseg] Used, compile again |
Fuses gesetzt auf: BOOTSZ: Boot Flash size = 1024 words Boot address =$7C00 SUT_CKSEL: Ext. Crystal Osc. 8.0 - Mhz Start-up time: 16k CK+65ms Quarz: 16Mhz. Als Port ist bei mir Com10 und Baud habe ich mal auf 2400 gestellt. Habe habe ich falsch gemacht ? Danke, Markus
Datum:
UartInvert=1, du benutzt doch einen Pegelwandler sagt mir meine Glaskugel ;) Gruß Hagen
Datum:
Hallo. Hab den Fehler gefunden. .equ UartInvert = 0 muss 1 sein. Ich nutzte den FTDI 232RL. Jetzt geht es wunderbar und schön schnell. Danke für dieses gute Programm. lg, markus
Datum:
@Markus: > BOOTSZ: Boot Flash size = 1024 words Boot address =$7C00 > .set BootCodeSize = 406 Die BootCodeSize hast du nach der 1. Kompilation aus AVRStudio so aktualisert ? Wenn ja dann benötigt dein Bootloader 1024 Word = 2048 Bytes an FLASH. Real verbraucht der Bootloader davon aber nur 406 Bytes. Somit stehen 1642 Bytes an FLASH ungenutzt zur Verfügung. Ich empfehle dir also diesen verschwendeten Platz mit dem Bootloader in anderer Konfiguration auszunutzen, setze .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 UseVersioning = 1 .equ UartInvert = 1 UseCryptFLASH/UseCryptE2 kannst du auch auf 0 setzen wenn du möchtest das man den AVR mit oder ohne Verschlüsselung benutzen kann. Wenn dann würde ich aber nur UseCryptE2=0 setzen, man kann also mit oder ohne Verschlüsselung den EEPROM schreiben. Bei UsCryptFLASH=1 kann der FLASH nur mit Verschlüsselung geschrieben werden. Das erhöht die Sicherheit enorm. Besonders eben auch die Datenintegrität und ihre Überprüfung wird mit der Verschlüsselung weitaus besser sein, da diese quasi eine 64Bit secure Prüfsumme benutzt, neben der 16Bit CRC die sowieso immer über die Daten berechnet wird. Erzeuge vor der Kompilation mit der PC-Software ein neues Passwort mit der PC-Software -> Button "Make Password". Setze BootSign: auf einen längeren Wert, zb. BOOTLOADER, um die Wahrscheinlichkeit einer Fehlanmeldung stark zu reduzieren. Setze in BootMsg: einen für dich aussagekräftigen Titel/Copyright. Selbst wenn du alle diese Features aktivierst wirst du maximal 950 Bytes von den 2048 zur Verfügung stehenden Bytes des FLASHs verbrauchen. Dh. der Bootloader ist für die großen ATMegas so klein das er mehrmals in die minimale FLASH Size für eine Bootpage reinpasst. Du könntest noch eine 1Kb Lookup Tabelle für deine Anwendung in diesem FLASH unterbringen. Gruß Hagen
Datum:
> Am besten ist es 7-8 solcher Nullen zu senden, und das ist in meiner > inoffiziellen Version auch schon gefixt. Also dazu kann ich nur sagen, das der Connect jetzt mit jeder Version funktioniert ! sobald ich in AppCMD 1x /00 setze !! > Der Bootloader war bei dir aber schon in seiner FSM, weil du entweder > nach dem vorherigen Test den AVR nicht reset hast oder das > "RunApplication" Kommando der PC-Software nicht ordentlich ausgeführt > wurde. Es kann durchaus sein das der FTDI Treiber/FTDI selber sofort > alle Daten im Buffer löscht wenn die PC-Software nach dem Senden dieses > Kommandos sofort die VCom schließt. Ich rufe zwar FlushFileBuffers auf, > aber solche Probleme habe ich schon bei einigen Treibern gesehen. Bei der Theorie muß ich dich leider enttäuschen ! Hab die letzten Tests sowohl mit FTDI als auch mit Max232 getestet, bei beiden das exakt gleiche verhalten !! > Also wenn du mal testest dann prüfe auch mal ob deine Anwendung nach > einem Disconnect der PC-Software auch automatisch gestartet wird. Das funktioniert einwandfrei ! > Die Aufrufe der neuen Methoden in IApplication sind trivial. Für dich vielleicht ! :-) > Habe nur wenig Zeit das Beispiel zu korregieren (weswegen es in den > letzen ZIPs > auch nicht mehr drinnen ist). Beim nächsten offiziellen Update packe > ichs mit bei. Kein Problem ! Muß meine App. halt noch nen bißchen warten ! Ich werds überleben ! Gruß Stefan
Datum:
@Stefan: >Bei der Theorie muß ich dich leider enttäuschen ! Hab die letzten Tests >sowohl mit FTDI als auch mit Max232 getestet, bei beiden das exakt >gleiche verhalten !! Was benutzt du als BootSign: ? Bzw. poste mal alles was in der ASM nach BootInfo: steht und die Section [BootSign] aus der INI Datei. Gruß Hagen
Datum:
> Bzw. poste mal alles was in der ASM nach BootInfo: steht und die Section > [BootSign] aus der INI Datei. > ASM:
BootSign: .db "BOOT" ; iff you change it then change Sign in AVRootloader.ini BootInfo: .db SIGNATURE_001, SIGNATURE_002, BootVersion, BootPages BootEnd: .if UseCrypt ; follow bytes should be keept secret and choosen randomly, 128 Bit Password, first 32 bit used as Signature BootKey: .db $14,$70,$A1,$B3,$05,$73,$D7,$DC,$E9,$2F,$50,$6A,$64,$CD,$6B,$BA .endif .endif |
INI-Datei:
[System] Sign=BOOT Port=COM4 Baudrate=256000 ConnectTrials=3 FLASH= EEPROM= ASMFile=AVRootloader.asm Erase=1 Verify=0 Protocol=0 Password=7006C8F706ADAE04EE833D81503F31DC AppCmd=/00 AppVersion=$01010107 AppVersionFlag=$0E ACYInfo= |
Sollte der Aufruf der AppCmd nicht ungefähr so funktionieren : Result:= 'App-Code/00/00'; Gruß Stefan
Datum:
Das Einzige was mir auffällt ist die Baudrate von 256000. Takt im AVR sollte mindestens 7.68MHz sein ist dann aber schon Fehleranfällig bei der Baudratedetektion. Hast du mal mit geringerer Baudrate probiert ?
Datum:
>Hast du mal mit geringerer Baudrate probiert ?
Ja klar ! 256000 war nur mal zum Testen ob es damit auch geht !:-)
Aber durch die BaudRate-Detection sollte es ja eigentlich auch egal sein
was da drin steht !?
Datum:
>Aber durch die BaudRate-Detection sollte es ja eigentlich auch egal sein >was da drin steht !? Jain ;) ganz egal ist es nicht, bei der Rechnung XTAL / Baudrate - 29 darf kein Wert kleiner 1 rauskommen. Aber selbst wenn 1 rauskäme so wäre das schon sehr kritisch (Abtasttheorem). Dh. je geringer die Taktfrequenz des AVRs und je ungenauer/kurzzeit-instabiler desto geringer sollte die Baudrate eingestellt werden. Je geringer der Wert bei XTAL/Baudrate-29 ist desto exakter sollte die Taktfrequenz durch die Baudrate teilbar sein, also ohne Rest. Je geringer aber die Baudrate ist desto längere Timeouts muß die PC-Software benutzen. Je größer diese Timeouts sind desto langammer ist der Verbindungsaufbau. Die Wahrscheinlichkeit für ein ungünstiges Connect-Timing steigt. Gruß Hagen
Datum:
OK ! Neue Erkenntnisse ! Feste BaudRate-BootSign(10Zeichen)-AppCmd(leer): Connect funktioniert ! Aber nur das letzte Zeichen vom BootSign wird angezeigt ! BaudRate-Detection-BootSign(10Zeichen)-AppCmd(leer): Connect funktioniert ! Aber es wird abwechselnd das komplette BootSign oder das letzte Zeichen ausgegeben !!! Gruß Stefan
Datum:
Und gleich noch was merkwürdiges hinterher ! Mit deiner Debug-AVRootloader Datei kommen abwechselnd das komplette BootSign oder die letzten 2 Zeichen !!! Mit deiner AVRootloader 3.1(bzw. 3.0 mit neuestem update) Datei kommen abwechselnd das komplette BootSign oder das letzte Zeichen !!! Übrigens sowohl mit FTDI als auch Max232 ! Gruß Stefan
Datum:
> Mit deiner Debug-AVRootloader Datei kommen abwechselnd das komplette > BootSign oder die letzten 2 Zeichen !!! > > Mit deiner AVRootloader 3.1(bzw. 3.0 mit neuestem update) Datei kommen > abwechselnd das komplette BootSign oder das letzte Zeichen !!! Sorry, da war ich ein bißchen voreilig !! Hatte bei der AVRootloader 3.1 noch ein /00 im AppCMD stehen, dadurch fehlte hier ein Zeichen !! Also die beiden Versionen reagieren identisch !! Gruß Stefan
Datum:
Wo wird was angezeigt ? Beim Wert "Ident:" oder "Received:" ? Beim Ident muß immer stehen: AppCmd + $00 $00 $00 $00 $0D + BootSign Bei Received darf niemals das BootSign drinnen stehen. Wenn das der Fall sein sollte dann empfängt die PC-Software teilweise Daten die sie selber abgesendet hat, und das darf überhaupt nicht sein, egal ob 1-Wire oder nicht. Lade dir mal aus dem WEB bei sysinternals.com den PortMon und sniff mal real alles das mit was über die COM geht. Deine Angaben sind teilweise sehr verwirrend für mich, kosten mir Zeit und bringen im Endeffekt nichts. Es wäre auch gut wenn du bei solchen Sachen die Ausgabe im Protkollfenster mit postest, dann kann ich mir wesentlich besser ein Bild machen. Gruß Hagen
Datum:
> Wo wird was angezeigt ? Beim Wert "Ident:" oder "Received:" ? Steht bei recived ! eine Kennzeichnung Ident hab ich noch nirgens gesehen !! > Beim Ident muß immer stehen: > AppCmd + $00 $00 $00 $00 $0D + BootSign So eine meldung hab ich noch nie gesehen ! > Bei Received darf niemals das BootSign drinnen stehen. Wenn das der Fall > sein sollte dann empfängt die PC-Software teilweise Daten die sie selber > abgesendet hat, und das darf überhaupt nicht sein, egal ob 1-Wire oder > nicht. Dann hab ich wohl nen riesen Problem !! Weil genau da steht das nämlich drin. 29.01.09-18:22:25-812 > Device disconnected 29.01.09-18:22:26-640 > Connecting on port COM1... 29.01.09-18:22:26-703 > Switch to 2-Wire mode 29.01.09-18:22:26-765 > received: $48,$61,$6C,$6C,$6F,$21,$21,$21,$21,$61,$61,$00,$93,$07,$03,$10,$FF,$FF,$FF,$FF,$39 29.01.09-18:22:26-765 > Device connected > Lade dir mal aus dem WEB bei sysinternals.com den PortMon und sniff mal > real alles das mit was über die COM geht. Werd ich gleich mal versuchen ! > Deine Angaben sind teilweise sehr verwirrend für mich, kosten mir Zeit > und bringen im Endeffekt nichts. Es wäre auch gut wenn du bei solchen > Sachen die Ausgabe im Protkollfenster mit postest, dann kann ich mir > wesentlich besser ein Bild machen. OK ! Ich gelobe Besserung ! Will es dir ja nicht noch schwerer machen als du es mit mir eh schon hast ! :-) Danke Stefan
Datum:
Angehängte Dateien:Hab mal 2 Scans mit Portmon gemacht. Test2: AppCmd(leer)-> Connect Test3: AppCmd(AppCMD)-> kein Connect Sag mal, arbeiter der AVRootloader eigentlich mit einem WDR wenn er keinen Connect bekommt, oder versucht er es immer weiter ? Gruß Stefan
Datum:
$48,$61,$6C,$6C,$6F,$21,$21,$21,$21,$61,$61,$00, $93,$07,$03,$10, $FF,$FF,$FF,$FF, $39 $48,$61,$6C,$6C,$6F,$21,$21,$21,$21,$61,$61,$00, -> in ASCII "Hallo!!!!aa" ist deine BootMsg: Danach kommen 4 Bytes BootInfo: wobei $93,$07 -> ATmega8, $03 = BootVersion 3 und $10 = Anzahl der FLASH Pages die der Bootlaoder benötigt $10 * 64 = 1024 Bytes. Nun kommen 4 Bytes Versionsnummer, $FFFFFFFF heist noch keine Anwendung drinen. Als letztes Byte $39 = SUCCESSCODE, du hast UseVersiong=1 und UseCrypt=1 aber UseCryptFLASH = 0 und UseCryptE2 = 0. Somit kannst du unverschlüsselt wie auch verschlüsselt mit dem Bootloader kommunizieren. Allerdings benuzt die PC-Software in diesem Fall immer keine Verschlüsselung. Sooo, mal abgesehen das du das Zeichen ! zu lieben scheinst, ich sehe in diesen Daten nichts vom BootSign: Das BootSign: steht per Standard auf "BOOT". Zitat: >> Bei Received darf niemals das BootSign drinnen stehen. Wenn das der Fall >> sein sollte dann empfängt die PC-Software teilweise Daten die sie selber >> abgesendet hat, und das darf überhaupt nicht sein, egal ob 1-Wire oder >> nicht. >Dann hab ich wohl nen riesen Problem !! Weil genau da steht das nämlich >drin. Das was ich sehe ist eine perfekte Antwort des Bootloaders im AVR. >Sag mal, arbeiter der AVRootloader eigentlich mit einem WDR wenn er >keinen Connect bekommt, oder versucht er es immer weiter ? Nein nicht mit dem WDT. Ein WDR würde ja bedeuten das er sich immer wieder selber aufruft. Solange der Bootloader in der Wartephase auf einen Connect ist und er am RX Pin irgendwas empfängt (toggelt) wartet er solange bis er ein gültiges Connect empfangen hat. Dh. er versucht die Baudrate zu berechnen und wartet auf den Wert in BootSign. Sobald sich am RX Pin nichts mehr tut wird nach einem Timeout die Anwendung gestartet. Deshalb ist das #define XTAL und BootDelay wichtig. Wenn also im Normalfalle der Bootloader per RESET/Poweron angesprungen wurde und sich in BootDelay Millisekunden nichts am RX Pin getan hat dann wird die Anwendung gestartet. Wenn sich aber in dieser Zeitspanne was am RX Pin tut so wird quasi diese Zeitspanne erneut gewartet, eben ein Timeout. Solange also irgend eine PC-Software was in dieser Phase was sendet gibt es nur zwei Möglichkeiten aus dieser Schleife rauszukommen: a) für BootDelay Millisekunden hört die Software auf was zu senden oder b) sie sendet den korrekte BootSign Sequenz und der Bootloader antwortet zB. mit den Daten wie du sie oben gepostet hast. Der Watchdog wird mit UseWDT unterstützt. Aber auch nur um die WDT Zeiten zu verlängern damit der Bootloader nicht durch den WDT gestört wird. Man kann ja den WDT per WDTON Fuse permanent aktivieren und würde der Bootoader nicht das berücksichtigen so stört der WDT den Bootloader. Finally: ich sehe in deinen geposteten Daten keinerlei Fehler. Die Daten in den .LOG Files vom PortMon mal bitte auf HEX stellen, bei Sonderzeichen macht PortMon ein '.' und somit wie0 man nicht was das bedeutet. -> Menu -> Options -> Show HEX. Gruß Hagen
Datum:
Angehängte Dateien:Hallo Hagen ! OK, das mit dem BootSign hab ich wohl gründlich falsch verstanden gehabt, Sorry ! Inwieweit beeinflußt eigentlich die Einstellung der Baudrate im Program den Verbindungsaufbau ? Hab nämlich festgestellt das bei AppCmd(leer) der Verbindungsaufbau mit 115200 Baud tadellos funktioniert, aber bei zunemender Zeichenanzahl in der AppCmd ich mit der Baudrate runtermuß um sporadisch noch einen Connect zu bekommen. Sprich Connect funktioniert dann nur noch zu 30-40% ! Hab im Anhang nochmal 2 Test, diesmal mit Hex ! Gruß Stefan
Datum:
In Test4_PortMon.LOG hast du zweimal einen Connect aufgezeichnet. Der 1. davon hat super funktioniert, ab Zeile 22. Beim 2. Connect, ab Zeile 76 reagiert der AVR erst auf den zweiten Connect versuch. Er ist beim ersten noch in er FSM und antwortet deshalb mit C2 C2 -> ErrorCRC. Ein Command kann minimal 4 Bytes lang sein, bei 2x Fehler C2 (ERRORCRC) hat er also 8 Bytes empfangen. Das stimmt insoweit mit der Anzahl der voeher gesendeten Bytes über ein, sind 9 Bytes im Connect String. Danach, beim zweiten Senden des Connect Strings, verbindet er sauber. Das heist der AVR ist schon in der Command-FSM, denn das ist er einzige Punkt an dem ein ERRORCRC gesendet wird. Test5_PortMon.log ist da schon erheblich interessanter. Nach senden des Connect Strings, Zeile 22 zb., wird vom AVR die Bytes 80 00 empfangen. Nur woher kommen die ? Vom AVR garantiert nicht. Es scheint so auszusehen das irgendwas auf deinem Board nicht stimmig ist. Es gibt kein Kommando das mit den gesendeten Bytes für "AppCmd" übereinstimmen würde und der AVR würde mit C2 oder C3 darauf reagieren müssen, wenn er in seiner FSM wäre. Einzige Erklärung die ich noch habe, wenn es tatsächlich am Bootloader läge, ist das irgendeines der Bytes, bzw. sogar mehrere, innerhalb der Baudrate Detektion, als 0D Sequenz erkannt wird. Er arbeitet dann mit falscher Baudrate und sendet wiederum ein C2, aber wir sehen es als 80 00 mit anderer Baudrate. Wenn man den AVRootloader.ASM nun mit fester Baudrate programmieren würde, zb. 112500, dann müsste beim gleichen Test wie in Test5_PortMon.log was anderes rauskommen. Die Gefahr das die Baudrate Detektion andere Bytessequenzen fälschlicherweise als 0D Sequenz interpretiert ist gegeben und führt zwangsläufig dazu das der AVR eine andere Baudrate detektiert. Ich weiß es nicht warum es bei dir nicht sauber funktioniert. Es ist ja nun nicht so das es mit dem FTDI nicht funktionieren würde, das bestetigten ja die positiven Rückmeldungen hier im Forum. Gruß Hagen
Datum:
Sag mal, wenn du AVRootloader.ASM kompiliert hast, dann hast du doch aus dem Message Window vom AVRStudio den Wert aus CSeg Used in das ASM bei BootCodeSize eingetragen und mit AVRStudio erneut kompiliert. Dann hast du dir den Output im Message Window nochmal genauer angeschaut und dort den Hinweis gesehen auf welche Bootfuses du den AVR setzen solltest. Nach dem Flashen des HEX über ISP hast du auch die Boot Fuses entsprechend eingestellt, richtig. Denn ich denke auch da könntest du einen Fehler gemacht haben. Dieser Fehler könnte sein das der Bootloaderr Code im FLASH an einer falschen Addresse gespeichert wurde im Vergleich zu den eingestellten Bootfuses. Das würde dann nämlich bedeuten das nach einem RESET der AVR mitten in den Bootloader springen könnte und es so zu erklären ist warum der AVR ständig in der Command FSM drinnen ist statt in der Baudrate Detektion + BootSign Überprüfung zu warten. Gruß Hagen
Datum:
Hagen Re wrote: > Sag mal, wenn du AVRootloader.ASM kompiliert hast, dann hast du doch aus > dem Message Window vom AVRStudio den Wert aus CSeg Used in das ASM bei > BootCodeSize eingetragen und mit AVRStudio erneut kompiliert. Dann hast > du dir den Output im Message Window nochmal genauer angeschaut und dort > den Hinweis gesehen auf welche Bootfuses du den AVR setzen solltest. > Nach dem Flashen des HEX über ISP hast du auch die Boot Fuses > entsprechend eingestellt, richtig. AVRASM: AVR macro assembler 2.1.30 (build 592 Nov 7 2008 12:38:17) Copyright (C) 1995-2008 ATMEL Corporation C:\Dokumente und Einstellungen\Stefan\Desktop\AVRootloader_3_0\AVRootloader\AVR\AVRootloader.asm(68): Including file 'C:\Programme\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8def.inc' C:\Dokumente und Einstellungen\Stefan\Desktop\AVRootloader_3_0\AVRootloader\AVR\AVRootloader.asm(126): compile for ATmega8 C:\Dokumente und Einstellungen\Stefan\Desktop\AVRootloader_3_0\AVRootloader\AVR\AVRootloader.asm(164): Including file 'C:\Dokumente und Einstellungen\Stefan\Desktop\AVRootloader_3_0\AVRootloader\AVR\AVRootloader.inc' C:\Dokumente und Einstellungen\Stefan\Desktop\AVRootloader_3_0\AVRootloader\AVR\AVRootloader.asm(161): WARNING: actual settings compromise security ! C:\Dokumente und Einstellungen\Stefan\Desktop\AVRootloader_3_0\AVRootloader\AVR\AVRootloader.inc(114): Please program Boot Fuse to Third Boot Start ! C:\Dokumente und Einstellungen\Stefan\Desktop\AVRootloader_3_0\AVRootloader\AVR\AVRootloader.asm(955): No EEPROM data, deleting C:\Dokumente und Einstellungen\Stefan\Desktop\AVRootloader_3_0\AVRootloader\AVR\AVRootloader.eep ATmega8 memory use summary [bytes]: Segment Begin End Code Data Used Size Use% --------------------------------------------------------------- [.cseg] 0x001c00 0x001f3a 792 34 826 8192 10.1% [.dseg] 0x000060 0x000060 0 0 0 1024 0.0% [.eseg] 0x000000 0x000000 0 0 0 512 0.0% Assembly complete, 0 errors. 0 warnings -> BootSZ1 = 0 BooTSZ0 = 1 BootRST = 0 Hab mal die Baudrate-Detection raus genommen und mit 115200 und 19200 getestet! gleiches Ergebnis ! sobald was in der AppCmd drin steht kein Connect ! Aber ... mache ich zwischen den Connect-Versuchen einen Reset, dann bekommt er beim nächsten versuch 1x einen Connect ! Es sieht also so aus als ob ich irgendein problem mit dem 'Internen Reset' bzw. des Ablaufs der ConnectRoutine im AVR habe. Und was mich wirklich irritiert ist halt die Tatsache das es ohne AppCmd funktioniert und mit eben nicht ! Bzw. wenn er connectet dann mal mit vollem BootSign oder nur mit dem letztn Buchstaben. Siehe Test4 ab Zeile 23 und ab Zeile 81 ! So geht das dann immer im Wechsel ! Gruß Stefan
Datum:
Angehängte Dateien:Hallo Hagen ! kannst du dir mal die angehängte LogDatei anschauen. Beim ersten Connectversuch war AppCMD leer. Beim zweiten Versuch ab Zeile 123 war AppCMD = /00 ! Die empfangenen Zeichen sind in beiden Fällen identisch außer das Sie im ersten Fall hintereinander stehen und im zweiten Fall untereinander. Kannst du mir sagen woran das liegen könnte ? bzw. kann ich diese /00 nicht einfach auf AVR-Seite Hardcoden ?? GRuß Stefan
Datum:
Angehängte Dateien:Hi Stefan, probiere mal die neuste Version im Attachment aus. Ich habe den Verbindungsaufbau verändert. Bisher würde bei einem Connect Versuch erstmal auf 1-Wire eingestellt. Dann wurde der Connect-String gesendet und versucht exakt diesen Wert sofort wieder vom COM Port zu lesen. Schlug dies fehl so wurde auf 2-Wire Mode umgeschaltet. DIese Vorgehensweise birgt aber ein Problem. Wenn nämlich der AVR den 2-Wire Modus benutzt so empfängt der PC ja sofort den Signature-String des AVRs statt dem soeben gesendeten Connect-String. Der AVR ist also schon in seiner FSM drinnen, aber die PC-Software schaltet erst jetzt in den 2-Wire Modus. Darauf hin versucht sie erneut einen Connect im 2-Wire Modus und sendet erneut den Connect-String. Das ist der Grund warum bei dir diese Probleme auftraten. Nun ist das geändert. Die PC-Software geht erstmal von 2-Wire Modus aus. Sendet den Connect-String und empfängt die komplette Antwort. Dieser String kann nun am Anfang den Connect-String selber enthalten, ergo 1-Wire Modus muß benutzt werden. Aus den empfangen Daten wird der vorher gesendete Connect-String entfernt und der Rest dieser Daten ist die Signature des AVRs die er gesendet hat. Der Verbindngsaufbau und die Unterscheidung zwischen 1/2-Wire ist nun wesentlich stabiler und schneller. Gruß Hagen
Datum:
Achso, dein modifiziertes AppCmd kannste raus nehmen (die Nullen entfernen).
Datum:
Super ! Das neue Update hat auf anhieb funktioniert ! Echt klasse ! Ich danke dir für deine Mühe, war ja nun echt keine leichte Geburt :-) Gruß Stefan
Datum:
Angehängte Dateien:Hier die neuste Version 4 Neuerungen: - RS485/Profibus Unterstützung, dh. im Halbduplex Verfahren kann man RS485 Treiber benutzen die einen Data Enable (DE) Eingang besitzen. Im AVRootloader.asm einfach UseRS485=1, DE_PORT und DE setzen. Möchte man invertierte Pegel nutzen dann noch UseRS485invert=1 setzen. Diese Funktionalität konnte ich aber leider noch nicht testen ;( - verändertes Verhalten des Watchdog Timers. Wird UseWDT=1 gesetzt so wird der WDT im Bootloader explizit aktiviert und auf 2 Sekunden Timeout gesetzt. Tritt nach 2 Sekunden ein WDT auf so wird ein RESET durchgeführt. Somit ist die Stabilität des Bootloaders verbessert worden wenn zb. ein ungeplanter Verbindungsabbruch auftreten sollte. Bitte beachten das in der eigenen Anwendung auf den WDT reagiert werden muß, oder er deaktiviert wird. Wie das geht zeigt das Testprojekt im Ordner \test\. - Mit UseSaveMCUCSR=1 wird der Wert aus dem Reset-Register MCUCSR in den Stack gespeichert (RAMEND) bevor er in den WDT Routinen gelöscht wird. Somit stehen diese Informationen für die Anwendung zur Verfügung. Wie man das zb. in WinAVR GCC benutzen kann sieht man im Beispiel Projekt im Ordner \test\ - Mit UseBootMode=0/1/2/3/4 kann man das Startverhalten des Bootloaders beeinflussen. Über diese Konfiguration wird eingestellt das der Bootloader zb. nur bei einem Power Up, externen Reset, Watchdog Reset oder per Jump aus der Anwendung gestartet wird. Mit diesen Bootmodis kann man die Startup Zeit der Anwendung beeinflussen. eg. verkürzen und nur auf ausgewählte Ereignisse fixieren. - Mit UseBootVector=1 wird am Ende des FLASHs ein Sprungvektor zum Einsprungspunkt des Bootloaders erzeugt. Über diesen Vektor kann man aus der eigenen Anwednung universell für alle AVR Typen die diesen Bootloader benutzen den Bootloader aufrufen. Man muß also nicht explizit die Startadresse des Bootloaders mehr berechnen. - Mit UseSpecialFuncs=1 werden am Ende des Bootloaders verschiedene zusätzliche Funktionen und eine Sprungtabelle eingebunden. Diese Spezialfunktionen können aus der eigenen Anwendung heraus aufgerufen werden. Sie können auch durch eigenen Code/Lookup Tabelle erweitert werden. Der normale Anteil an Code des Bootloaders ist so kompakt das er auf größeren ATMegas mehrmals in die kleinste Bootsektion reinpasst. Man verschwendet also in diesem Fall ungenutzen FLASH den man nun für diese Spezialfunktionen aus der Anwendung heraus benutzen kann. Zur Demonstration wurden die Funktionen zur Abfrage der AppVersion und BootMsg/BootInfo eingebaut. Wie man diese benutzt kann man im Test Projekt im Ordner \test\ für WinAVR GCC anschauen und austesten. - im Ordner \test\ ein Test-Projekt in WinAVR GCC zur Demonstration der Bootloader Funktionalität. Im Headerfile AVRootloader.h eine universelle Schnitstelle zum Bootloader. - durch einige Optimierungen im Code konnte der benötigte FLASH reduziert werden - mehr Kommentierungen Bugfixes/Veränderungen: - die AVR Typen ATMega161/ATMega163/ATMega323 benötigen bei der Ausführung des SPM Befehles ein spezielles programmtechnisches Vorgehen. Diese wurde gefixt und eingebaut. - der Connect Prozess wurde verändert. Die Abfrage/das Warten auf das BootSign von der PC-Software benutzt nun einen Timeout innerhalb BootDelays. Bei der alten Version mit UseAutobaud=1 konnte es an dieser Stelle zu einer Endlosschleife kommen, der Bootloader verblieb also bei einem Kommunikationsabbruch endlos in dieser Schleife. - im neuen Connect Prozess erwartet der Bootloader nach dem Empfang des BootSign eine 16 CRC über diese BootSign. Dies inkrementiert die Stabilität des Connect Prozess und beseitigt gleichzeitig ein Problem beim Connect. Bei der alten Version konnte man beim BootSign "BOOT" zb. auch mit einem Wert wie "BOOT1234" einen Connect bekommen. Die zusätzlichen Zeichen "1234" störten die Command-FSM des Bootloaders und es stellt auch ein Sicherheitsrisiko dar wenn man das BootSign als Passwort betrachtet. - wenn UseVersioning=1, UseCrypt=1 und UseCryptFLASH=1 war so wird ja die AppVersion Nummer auf cryptographisch sichere Weise bei einem Update per ACY Datei überprüft. Diese Überprüfung war nicht ganz korrekt. Ist gefixt. PC-Software: - die Kommunikationsgeschwindigkeit wurde durch Optimierungen beschleunigt. - einige Fehler in der Bedienung etc.pp. beseitigt - neue Einstellungen in der AVRootloader.ini * [System]-AppCmd, [System]-AppCmdResponse, [Timeouts]-AppCmd. über diese Einstellung kann man der Software mitteilen das sie bei einem Connect erstmal das AppCmd an die eigene Anwednung zu senden hat. Wenn nun in AppCmdResponse ein Wert steht so wartet die Software auf den Empfang dieses Wertes. Eure Anwendung muß also dann dieses Response senden und startet dann den Bootloader per Watchdog oder direktem Sprung. Nach Empfang des Response wartet die Software [Timeuts]-AppCmd Millisekunden bevor sie mit dem Connect weiter macht. Startet man den Bootloader in der eigenen Anwendung zb. per Watchdog und Endlosschleife dann entsteht ein minimaler Timout von 17ms. Damit die PC-Software ebenfalls diese Zeitspanne wartet kann man zB. Timeouts.AppCmd=20 setzen. * [Timeouts]-KeepAlive ist ein Interval in Millisekunden in dem die PC-Software beim Bootloader nachfragt ob er noch aktiv ist. Hat man mit UseWDT=1 den Watchdog aktiviert so muß dieser spätestens nach 2 Sekunden periodisch zurückgesetzt werden. Exakt das macht die PC-Software im Interval von KeepAlive. Das hat mehrere Vorteile. Die PC-Software bekommt mit wenn eine Verbindung zum Bootloader unterbrochen wurde und trennt die Verbindung automatisch. Der Bootloader seinerseits erkennt das die Verbindung zur PC-Software getrennt wurde und wird spätestens nach 2 Sekunden durch einen Watchdog Timeout terminiert. Zudem inkementiert es auch die Stabilität des Bootloaders auf unvorhergesehene Ereignisse. Ich empfehle also mit UseWDT=1 zu arbeiten. * [Timeouts].Options. Dies ist ein Bitkodierter Wert. Bit 0 = 1 ist der Debugmode der PC-Software. Bit 1=2 bestimmt das Verhalten im Connect Prozess beim Senden der BootSign. Ist dieses Bit gesetzt so benutzt die Software die alte Methode beim Senden des BootSign, also ohne CRC Prüfsumme. Damit wird die Kompatibilität zum alten AVRootloader.asm gewährleistet. Für die neuste Version darf dieses Bit nicht gesetzt sein. - der neue Connect Prozess geht von einer 2-Wire Verbindung aus und schaltet erst während des Connects dynamsich auf 1-Wire um wenn dieser benutzt wird. In der alten Version war es umgekehrt. Diese Veränderung verbessert die Connect Performance und Stabilität. - XPORT (TCP/IP zu RS232-Wandler) wird sauber unterstützt. Der Grund einiger Änderungen in der Kommunikation. Bei Interesse gibt noch Tipps wie man den XPORT ordentlich konfiguriert von mir. Tipps: Wird so wie im Testprojekt im Ordner \test\ der PinChange am RX Pin benutzt um 1.) aus dem Power Down Sleep Mode aufzuwachen und 2.) den Bootloader zu starten dann sollte man in AVRootloader.ini folgende Einstellungen treffen [system] AppCmd=/AA AppCmdResponse= [timeouts] AppCmd=20 Somit sendet die PC-Software erstmal das Zeichen 0xAA um den PinChange in der ISR zu bedienen. Innerhalb dieser ISR wird der Bootlaoder per Watchdog Reset gestartet mit minimalem Timeout von 17ms. Die PC-Software wartet nun ihrerseits 20 ms und somit wird der gesammte Connect Prozess verbessert da das Timing ideal aufeinander abgestimmt ist. Lese Readme.txt im Ordner \test\ ;) Wenn ich die Spezialfunktionen in Special.inc erweitert vergesst nicht am Ende des Sources euren Sprungvektor einzubauen. Desweiteren muß die .org Direktive aktualisiert werden. In AVRootloader.h könnt ihr sehen wir ihr dann eure Funktionen aufrufen könnt. Mit der Spezialfunktion "GetBootMsg" kann man nicht nur die BootMsg aus dem FLASH auslesen sondern auch alles was danach kommt. Also auch BootKey: das Passwort der Verschlüsselung. Das ist kein Sicherheitsrisiko wenn ihr alle korrekt konfiguriert habt. Also UseSRAM=0, UseCryptFFLASH=1, UseCrypt=1. Desweiteren liefert nur ihr vorkompilierte ACY Dateien an eure Kunden aus. Somit ist jeder Anwendungscode der programmiert wird durch euch authorisiert. Gruß Hagen
Datum:
@Hagen: Ein fettes Dankeschön für den riesigen Ehrgeiz, den du hier in das Projekt investierst! Absolut fettes Tool! Vielleicht kann ich die Tage ja einige Funktionen testen. Eine Sache ist mir noch aufgefallen. Ich benutze ja den 1-Wire Betrieb auf einem ATtiny45 mit einem FTDI. Wenn ich in meiner Software den 1-Wire Pin als Ausgang nutze, dann erkennt die PC-Flash-Software in einem Großteil der Fälle immer den 2-Wire Betrieb. In den Bootloader komme ich durch das Trennen der Betriebsspannung. Den Resetpin benutze ich als 1-Wire-Pin. Die Verbindung kommt zu Stande aber eben im 2-Wire Betrieb, wodurch dann das Flashen fehlschlägt. Vielleicht hast du ja eine Idee, woran es liegen könnte. Grüße
Datum:
Hm, der Reset Pin hat der einen internen Pullup ? Der FTDI ist ein Pegelwandler und ich habe mit Use1Wire und UseUartInvert=1 einige Probleme hardwaretechnischer Art gehabt. Zu Testzwecken benutzte ich den Spare-RS232 vom STK500. Wenn man den RX-TX per Brücke verschaltet dann empfängt die PC-Software korrekterweise das was sie vorher gesendet hat. Überbrückt man RX-TX aber mit zb. einem 2k7 Widerstand so empfängt die Software nichts mehr. Warum dies so ist weiß ich bisher auch noch nicht, es sollte ja kein Problem damit geben. Aber exakt diese Minimalbeschaltung benötigt man wenn man 1-Wire mit TTL-RS232 benutzen möchte. Du kannst bei der neuen Version mal in der AVRootloader.INI [Timeouts]-Options=1 setzen, bzw. auf 3 wenn du mit der alten AVRootloader.asm testen möchtest (diese empfehle ich dir aber nicht da gerade im Connect Prozess einige Änderungen erfolgten) Mit diesen Änderungen siehst du dann im Protocol-Window der PC-Software was sie sendet und was sie empfängt. Bei 1-Wire müsste bei "received data:" erstmal das stehen was bei "send ident:" gesendet wurde. Plus am Ende die Antwort des Bootloaders die mit 0x3? enden muß. Hast du den 1-Wire in deiner Konfiguration überhaupt schonmal zum laufen gebracht ? Du könntest mir per PN, eg. Mail mal den Output des Protocolwindows mailen. Vieleicht sehe ich ja mehr. Gruß Hagen
Datum:
Angehängte Dateien:@Hagen Pullup am Resetpin ist auch drin. Überprüfe es aber morgen nochmal. Ja die 1-Wire Konfiguration mit dem FTDI habe ich in den Griff bekommen. Jedoch nur indem ich UseUartInvert=0 gesetzt habe und mit dem Konfigurationsprogramm (MProg) von FTDI den FT232R so programmiert habe, dass die RX/TX Leitungen invertiert werden. (Siehe Anlage) Mit UseUartInvert=1 und 1-Wire tut sich gar nichts. Am Oszi sieht man, dass der uC kein einziges Bit sendet. Also die PC Software empfängt immer nur ihr eigenes Signal, wenn der Pin ein hochohmiger Eingang ist. Ist er ein Ausgang, so liegt das entsprechende Signal des uC am RX des Pegelwandlers. Der Widerstand ist ja zwangsläufig nötig, da der TX des Pegelwanlders ja ein Ausgang ist. Im 1-Wire Betrieb ist der uC Pin ja zumindest zeitweise auch ein Ausgang und damit es dann keinen Kurzschluss gibt muss der Widerstand her. Da die Verbindung ja korrekt Aufgebaut wird, nur eben der falsche Wire-Modus erkannt wird, muss der uC Pin am Anfang nach dem Wiederanlegen der Spannung ein Ausgang sein. Somit merkt deine Software, dass die eigenen gesendeten Daten nicht ankommen. Der uC empfängt alles korrekt und meldet sich dann zurück. Sehr strange. Also wenn man es einfach mehrmals probiert, dann erkennt er irgendwann mit Glück den 1-Wire und man kann flashen^^ Ich schaue mir mal morgen die Sache mit deinen weiter angeführten Ideen an LG Mark
Datum:
Angehängte Dateien:Liegt nicht an dir, es lag am Source. Es tut mir ja immer leid wenn mir sowas passiert, sieht immer nach Schnellschuß aus, aber irgendwann einmal muß ich an den Sourcen was kaputt repariert haben. Im Attachment die gefixte Version. Ich habe sie nun in allen Modis getestet. 1/2 -Wire, invertiert und nicht invertiert, direkt an RS232, an USB-RS232 Wandler und am XPORT über TCP/IP. So langsam überblicke ich die ganzen RS232 Kabel auf meinem Schreibtisch nicht mehr ;) Du nimmst einen zb. 2k7 Widerstand und schließt diesen zwischen RX und TX am FTDI. Am RX Pin den RX des AVRs. In deinem Falle ist es so das 1-Wire identisch zum zb. Dallas 1-Wire oder I2C arbeitet. Der AVR zieht den RX/TX Pin aktiv nach Masse als Ausgang. Ansonsten setzt er den Pin als Eingang. Der 2k7 Widerstand am TX-FTDI zieht die Leitung auf VCC und ist also sowas ähnliches wie ein externer Pullup und Stromegrenzung. Bei dieser Verschaltung benötigt man keine Serienwiderstand falls man zb. mehrere AVRs an einer Leitung legen möchte. Der AVR kann auch mit geringerer VCC betrieben werden als der TX-FTDI Ausgang liefert. Bei 1-Wire an nativer RS232, also ohne Pegelwandler, liegt ebenfalls ein 2k7 Widerstand zwischen RX und TX an der DB9. Auch dieser dient zur Strombegrenzung und die internen Bodydioden des AVRs begrenzen negative Spannung gegen Masse. Desweiteren zieht die TX Leitung ebenfalls den RX-Pin gegen -15V. Der Bootloader benutzt hier Strong/Weak-High-Pegel statt eben Strong-Low-Pegel wie bei dir. 1-Wire-native-RS232 läuft bei mir bis auf 1.8 Volt VCC runter. Gruß Hagen
Datum:
Hallo Hagen, mir ist gerade folgendes bei der aktuellen Version aufgefallen: unter Win98se folgt dem 'Connect' sofort darauf wieder ein 'Disconnect'. Auch im Debug-Modus ist kein Grund erkennbar. Ausprobiert auf zwei Win98-PC und drei WinXP-PC mit identischem AVR-Chip (M168). Mit den Parametern UseBootMode=0, UseWDR=1 und UseSaveMCUCSR=0 überlebt das MCUCSR beim M168 ohne besondere Tricks, beim M128 ist es immer gelöscht (wie beschrieben). Wäre es nicht einfacher bei UseWDR=1 immer das gerettete MCUCSR zu restaurieren? - Dann könnte die Applikation immer gleich sein, unabhängig davon ob ein Bootloader vorhanden ist oder nicht. Gruß JoJo
Datum:
Angehängte Dateien:>Wäre es nicht einfacher bei UseWDR=1 immer das gerettete MCUCSR zu >restaurieren? - Dann könnte die Applikation immer gleich sein, >unabhängig davon ob ein Bootloader vorhanden ist oder nicht. Geht nicht, habe ich probiert. Man kann es nur löschen aber nicht wieder neu setzen (M162). Wenn ich nur das WDRF lösche dann würde es für die Anwendung nicht möglich sein darauf zu reagieren. >Mit den Parametern UseBootMode=0, UseWDR=1 und UseSaveMCUCSR=0 überlebt >das MCUCSR beim M168 ohne besondere Tricks, beim M128 ist es immer >gelöscht (wie beschrieben). Hm, das sollte eigentlich nicht der Fall sein. Bei UseWDR=1 lösche ich es ja immer mit xout MCUCSR, zerol. Ok, Fehler gefunden in der AVRootloader.inc auf folgendes abändern ; some redefinition of register names or bits .ifndef MCUCSR .equ MCUCSR = MCUSR .endif ; .ifndef MCUCSR Dämliche ständige Umbenammung der Registernamen durch Atmel. Wenn man mal eine Librariy universell programmieren möchte muß man ständig seine Registernamen per umdefinieren. >unter Win98se folgt dem 'Connect' sofort darauf wieder ein 'Disconnect'. >Auch im Debug-Modus ist kein Grund erkennbar. >Ausprobiert auf zwei Win98-PC und drei WinXP-PC mit identischem AVR-Chip >(M168). Das deutet darauf hin das die Windows Timer nicht sauber funktionieren. Im Attachment die Version habe ich mal gefixt und im Debug Modus zeige ich an ob die Timer sauber arbeiten. In der INI in der Sektion [Timeouts] KeepAlive=500 setzen. Es sollte jetzt periodisch "send keepalive" zu sehen sein. Wird die Verbindung abnormal unterbrochen steht dann "keepalive failed". Hm, könnte auch am MCUSR-Fehler liegen. Denn wenn im MCUSR/MCUCSR Register das WDRF gesetzt ist und nicht vor dem Zugriff auf WDTCR gelsöcht wird vereigert die MCU die neuen Einstellungen. Da durch den Fehler in der AVRootloader.inc nicht MCUSR sondern MCUCR manipuliert wurde, wurde auch der WDT nicht korrekt programmiert. Sicherlich stand er noch auf 17ms Timeout und hat somit den Bootloader terminiert. Ich denke das es daran liegen wird. Gruß Hagen
Datum:
Deine Erklärung(en) leuchten wie immer ein. Austesten kann ich das erst Morgen. Ergebnis folgt... Gruß JoJo
Datum:
Hi Hagen, ich bins wieder ;) Habe deine Version 4 getestet und das UartInvert-Problem ist behoben :) Dafür habe ich aber ein neues Problem. (Benutze die Version vom 09.02.2009) Ob es mit dem Bootloader zusammenhängt weiß ich nicht. Benutze den ATtiny45 mit der Konfig: 1-Wire auf dem deaktivierten Resetpin. Vcc = 3,3V, Intern 8Mhz. Der Pin ist nur auf ein Lötauge ausgeführt (Keine weiteren Bauteile dran). Flashen geht ohne Probleme, dass Programm läuft dann auch sofort an. Wenn ich jetzt aber die Versorgungsspannung aus- und wieder anschalte, passiert nischt mehr. Das Programm läuft nicht mehr an. Das kann ich daran sehen, dass ich im Programm einen Pin als Ausgang setze und HIGH ausgebe. So nun habe ich aber eine Lösung gefunden, den uC zu laden des Programms zu bewegen. Pullup-Widerstand am 1-Wire-Pin nach Vcc. Kannst du mir sagen, warum das so ist? Die RESET-Funktion des Pins ist doch mit dem FUSE-Bit ausgeschaltet. PS: In der Software schalte ich den Watchdog sofort ab. Wie gesagt, sobald das Programm einal läuft geht es. Schalte ich den uC einmal aus, fährt er aber nicht mehr hoch. Hier die Konfig aus der asm UseWDR = 1 UseSaveMCUCSR = 0 UseE2Write = 1 UseE2Read = 1 UseCrypt = 1 UseCryptFLASH = 1 UseCryptE2 = 1 UseVerify = 0 UseVersioning = 1 UseBootVector = 0 UseSpecialFuncs = 0 UseSRAM = 0 UseAutobaud = 0 UseUartInvert = 1 UseRS485 = 0 RX/TX = PB5 (Deaktivierter Resetpin) Hat es irgendwas mit dem Fix für das MCUCSR Register zu tun? Nette Grüße Mark
Datum:
Um sicher zu gehen immer die neuste Version benutzen. Du benutzt 1-Wire-TTL-Pegel und da ist es wichtig das extern ein Pullup angeschlossen ist. Normalerweise ist das der Fall über den 2k7 Widerstand zwischen deinem RX-TX Pin am Pegelwandler. Der Pegelwandler zieht den TX-Pin ja auf High wenn nichts gesendet wird. Exakt das könnte das Problem bei dir sein. Der interne Pullup am Pin ist deaktivert damit der 1-Wire-Source so funktionieren kann das beim Schalten auf Ausgang der Pin Low-Pegel hat. Problematisch wird es wenn man diesen vom AVR abtrennt, dann floated der Eingang. Es ist also in jedem Falle empfehlenswert einen ext. Pullup am Pin anzuschließen, da der interne nicht benutzt werden kann. Gruß Hagen
Datum:
Ah ok, dann ist klar was los ist. Ist intern der Pullup auch bei UartInvert=0 abgeschaltet? Könnte man nicht den Pullup eingeschaltet haben und bevor du den Pin als Ausgang benutzt ihn eben abschalten? Oder soll das Aufgrund des kleinen Codes so sein? Wären ja aber auch nur eine Hand voll ASM Befehle. Dann könnte man sich den ext. Widerstand sparen. Ich Frage deshalb, weil ich sieben PCB Boards mit je 16 tinys schon fertig habe. Aufgrund von Zeitdruck ist da ein neufräsen nicht möglich, wohingegen die Platinen (bis auf die eine zum Testen) noch nicht bestückt sind. PS: Ich kann den neusten Bootloader nicht aufspielen, da auf der Testplatine schon alles bestückt ist.. ISP ist da bei den 16 vernetzten Tinys nicht drinne ;) Besten Dank für die Erklärung! Achja, kannst du den Schaltplan für 1-Wire dann bitte updaten? Da ist kein Pullup drinne. Führt dann wie bei mir heute dazu, dass es mal geht und mal nicht ;) Beste Grüße Mark
Datum:
Hab grad mal in deinen Quellcode geguckt. ; initialize ports cbi RX_DDR, RX .if UseUartInvert && Use1Wire cbi RX_PORT, RX .else sbi RX_PORT, RX <<--- Pullup an für Uartinvert=0//1-Wire :) .endif ; .if UseUartInvert && Use1Wire Sehe ich das richtig, dass für UartInvert=0 der Pullup tatsächlich aktiviert ist? Das wäre für mich ja perfekt :) Dann stelle ich den FTDI wieder auf invertierenden Modus um, und die Sache läuft :) Grüße
Datum:
Ja, bei 1-Wire und UseUartInvert=0 ist der interne Pullp aktiv. Bei 1-Wire mit UseUartInvert=1 ist er nicht drinne. Das hat tatsächlich Gründe in der Codegröße und dem Timing. Du kannst versuchen ihn am Anfang des Bootloaders zu aktivieren und in putc: dann ein/ausschalten:
; send char putc: de_0 cbi TX_PORT, TX rcall waitf rcall waitf ldi cnt, 10 com paral put3: tx_out rcall waitf lsr paral brcs put4 tx_0 put4: rcall put5 dec cnt brne put3 de_1 sbi TX_PORT, TX put5: ret |
Sind 4 Bytes mehr Code und ob das wirklch geht weiß ich nicht. Denn man müsste eigentlich ständig zwischen Eingang+Pullup und Ausgang+Lowpegel umschalten. Dazu müsste aber die komplette putc und waitf Routine umgeschrieben werden und deren Timing würde sich um 1 Takt verändern. Diese Veränderung in der Zyklenanzahl hat es aber insich und muß im komplettten Timing der UART Routinen bis hin zur Baudrate Detektion berücksichtigt werden. Gehen tut grundsätzlich ja alles, aber die Zeit und der Aufwand ist das Problem. >Achja, kannst du den Schaltplan für 1-Wire dann bitte updaten? Nö. der ist ja für 1-Wire mit UseUartInvert=0, also direkt an der RS232. Man kann sogar noch die beiden Dioden rausnehmen, geht auch. Mit dieser abgespeckten Schaltung habe ich 1-Wire mit UseUartInvert=0 und 1 erfolgreich getestet. Allerdings mit einem echten RS232-Pegelwandler von Maxim. Kann schon sein das der FTDI sich da anders verhält. Ist ebenso beim Spare-RS232 auf dem STK500 so, die haben da eine Schutzbeschaltung eingebaut. >PS: Ich kann den neusten Bootloader nicht aufspielen, da auf der >Testplatine schon alles bestückt ist.. ISP ist da bei den 16 vernetzten >Tinys nicht drinne ;) Du hast also schon fest eine alte Version des Bootloaders drauf ? Bedenke das je nach Version du in der AVRootloader.ini dann [Timeouts] Options=2 setzen musst. Damit der Connect mit der alten BootSign Methode arbeitet. Gruß Hagen
Datum:
>Das hat tatsächlich Gründe in der Codegröße und dem Timing. Oki >Diese Veränderung in der Zyklenanzahl hat es aber insich und >muß im komplettten Timing der UART Routinen bis hin zur Baudrate >Detektion berücksichtigt werden. Reicht ja, dass ich es jetzt weis^^ >Nö. der ist ja für 1-Wire mit UseUartInvert=0, also direkt an der RS232. Ein Vermerk, dass die Beschaltung eben nur für den Mode gilt, kann nicht schaden. >Du hast also schon fest eine alte Version des Bootloaders drauf ? Es ist schon die Version 4 nur eben nicht der letzte Fix mit dem MCUCSR Register.
Datum:
>>Du hast also schon fest eine alte Version des Bootloaders drauf ? >Es ist schon die Version 4 nur eben nicht der letzte Fix mit dem MCUCSR >Register. Du nutzt ATMega8, kein Problem bei diesem da dessen Register MCUCSR heist. ATTiny45 ist wiederum ein Problem dessen Register heist MCUSR. Das sind so die miesen Stolperfallen durch Atmel die einem Programmiererleben die Munition für Herzinfarkte liefern ;) By the Way: großen Respekt für die Entwickler vom WinAVR GCC die solche Probleme der Standardisierung mit Sicherheit auch kennen werden. >>Nö. der ist ja für 1-Wire mit UseUartInvert=0, also direkt an der RS232. >Ein Vermerk, dass die Beschaltung eben nur für den Mode gilt, kann nicht >schaden. Ich werde das Schematik anpassen wenn ich die Zeit dafür finde. Grundsätzlich geht es eben auch ohne "Pullup" wenn man den Serienwiderstand zwischen RX/TX am Pegelwandler mit betrachtet. Sauber ist es nicht, das stimmmt. Gruß Hagen
Datum:
Hallo Hagen, sorry das ich mich erst jetzt melde. Das Problem mit Win98 besteht weiterhin (keepalive failed, terminate connection). Falls Du noch eine Idee bezüglich der Timer hast dann gut, ansonsten werde ich wohl über eine Verschrottung der Werkstattrechner nachdenken müssen. Vielleicht gibt es ja dafür auch noch eine "Abwrackprämie". Gruß JoJo
Datum:
> keepalive failed, terminate connection das bedeutet "create timer" und "release timer" und "send keepalive" sisht du in dem Protokoll. Das heist die Timer funktionieren, nur der Bootloader im AVR antwortet nicht auf das Keepalive Kommando. Falsch Version ? falsch konfiguriert ? Was seht bei [timeouts] ? Mal Wert Base auf 50 oder 100 hochgesetzt ? Neuste Version mit dem BugFix für das MCUCSR benutzt ? Gruß Hagen
Datum:
Angehängte Dateien:Ja, das Problem tritt ja auch nur bei den Win98-Rechnern auf. Bei den WinXP-Rechnern läuft alles einwandfrei. Bootloader ist auch neu compiliert. Win98-Protokoll als Anlage. Gruß JoJo
Datum:
>12.02.09-17:00:51-090 > send appcmd $0A 0A 2A 52 53 54 0A >12.02.09-17:00:51-090 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 >12.02.09-17:00:51-200 > send appcmd $0A 0A 2A 52 53 54 0A >12.02.09-17:00:51-200 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 >12.02.09-17:00:51-260 > received data $C2 94 06 04 08 30 1.) nimm mal bitte die $0A aus deinem AppCmd raus, mindestens das 0A Zechen am Ende des AppCmd. Die Zeichen 0A,0B,0D,0F,85,87,C3,E1 werden von der Baudrate Detektion erkannt und an Hand dieser die Baudrate berechnet. Grundsätzlich betrachtet dürfte das kein Problem darstellen da die neuste Version nur eine Verbindung akzeptiert wenn sie das exakte BootSign empfängt und anschließend eine gültige 2 Bytes CRC über diese BootSign. 2.) der AVR antwortet mit C2 -> Error CRC 94 06 04 08 -> BootInfo 30 -> SUCCESS Code Das er überhaupt C2 absendet deutet darauf hin das du garnicht die neuste Version auf deinen AVRs installiert hast. Denn nur mit der alten Version kann es zu solchen Synchronisationsproblemen der internen FSM beim Verbindungsaufbau kommen, in Verbindung mit dem Connect Aufbau der neusten Version. Das er rausfliegt ist dann nämlich logisch. Der alte Source empfängt nach dem BootSign noch 2 Bytes der CRC über dieses BootSign für die neue Version. Diese landen erstmal als Kommandos in der FSM des Bootloaders. Er erwartet noch 2 weitere Bytes die die CRC darstellen. Das erste mal nach einem Connect bei dem die PC-Software ein Befehl absendet ist beim Keepalive wenn du nur verbindst. Der AVR empfängt die ersten 2 Bytes dieses Befehles als 2 Bytes CRC des vorherigen Befehles und sendet ErrorCRC als Antwort, meine PC-Software disconnected dann. 3.) du benutzt "BOOT" als BootSign was der Standard der alten Version ist. Die neuste benuzt "BOOTLOADER". (und ich benutze dabei nur meine Glaskugel und mein Hirn) Ergo wie oben in einigen Postings zu lesen war: 1.) Setze [Timeouts] Options=3 oder =2 um den alten Verbindungsaufbau zur alten Version des Bootloaders zu aktivieren. Dann dürfte es sauber laufen. 2.) du hast auf deinen AVRs mit Sicherheit die alte Version installiert. Wenn du updatest dann [Timeouts] Options=1 oder =0 setzen. 3.) man erkennt an Hand solcher Fehler das die interne FSM sehr stabil gegen Protokollfehler ist. Schlimmer wäre es nämlich wenn sie in einem solchen Fall zb. den FLASH löscht oder falsch programmiert. Gruß Hagen
Datum:
Hallo Hagen, beim mir funktionieren die Versionen 2,3 und 4 deines Bootloaders bestens und waren bisher auch sehr wertvoll für mich. Die PC-Seite ist ein Acer-Notebook und die AVT-Seite ein Mega32 mit FTDI FT232R. Jedoch mit einem Asus Netbook bekomme ich leider keinen Connect mit der selben AVR Hardware. Habe alle Versionen durchprobiert. Mit deiner am 26.01.2009 geposteten Version (V3.0), mit Debug=1 zeigt das Protocol für den Acer folgendes: 22.02.09-15:55:34-393 > Connecting on port COM3... 22.02.09-15:55:34-453 > Switch to 2-Wire mode 22.02.09-15:55:34-513 > received: $95,$02,$03,$08,$37 22.02.09-15:55:34-533 > Device connected Beim Asus Netbook bekomme ich die gleiche Sequenz ad infinitum aber kein Connect, bis ich Abort Connect drücke. 22.02.09-11:55:16-187 > Connecting on port COM3... 22.02.09-11:55:16-265 > Switch to 2-Wire mode 22.02.09-11:55:16-328 > received: $95,$02,$03,$08,$37 22.02.09-11:55:16-390 > received: $95,$02,$03,$08,$37 22.02.09-11:55:16-468 > received: $95,$02,$03,$08,$37 Meine Einstellungen sind: .equ UseWDR = 1 .equ UseAutobaud = 0 .equ UseVerify = 1 .equ UseE2Write = 1 .equ UseE2Read = 1 .equ UseSRAM = 0 .equ UseCrypt = 1 .equ UseCryptFLASH = 1 .equ UseCryptE2 = 1 .equ UseVersioning = 0 .equ UartInvert = 1 . . .set XTAL = 16000000 .set BootDelay = XTAL/4 .set BootBaudrate = 115200 .set BootVersion = 3 .set BootCodeSize = 824
Datum:
Hi Heinrich, lade dir mal die neuste Version Beitrag "Re: AVR-Bootloader mit Verschlüsselung" Entpacke sie in einen separaten Ordner, wir sind nur an der neuen PC-Software interessiert. Im Ordner \Windows\ ist die neuste PC-Software. Setze alle Parameter deren AVRootloader.ini auf die in deiner aktuellen AVRootloader.ini. Zusätzlich [Timeouts] Options=3. Der Parameter Debug= der alten Version ist entfernt worden und befindet sich als Bit in Options. Nun starte diese neue Version und versuch eine Verbindung zum AVR mit alten Bootloader. Wenn das nicht funktioniert versuche sukzessive in [Timeouts] die Werte für Base und Connect zu erhöhen. Zb. Base=100 und Connect=50 oä. Bei solchen virtuellen Treiber wie dem FTDI eg. USB-Serialwandler sollte Base auf minimal 50ms stehen. Ein weiteres Problemfeld könnte der virtuelle Treiber des FTDIs auf diesem Notebook sein. Mal reinstallieren. Achso, und schau mal in die Datei AVRootloader.dev rein und suche nach 9502=, dort muß bei dir dann folgendes stehen 9502=1E9502, ATmega32 , 32768, 1024, 2048, 96, 128, 4, 8, 16, 32 Nur die AVRs in dieser Datei werden erkannt. Man kann also durch die Editierung dieser Datei bestimmte AVRs ausschließen oder neue AVRs nachträglich dem Bootloader mitteilen. Gruß Hagen
Datum:
Ich sehe gerade du hast UseAutoBaud=0 gesetzt. Es könnte sein das das Timing des AVR-RS232 und FTDI-RS232 nicht exakt übereinstimmt. Deshalb normalerweise immer UseAutobaud=1 setzen. Ich weiß nicht wie der FTDI sein Timing erzeugt, es ist eigentlich unlogisch das das vom USB Host abhängen sollte, aber vorstellbar ist heutzutage alles. Andererseits empfängt ja die PC-Software eine gültige Rückmeldung vom AVR. Ich denke also das mit der neuen PC-Sofwtare und höheren Timeouts.Base das problem beseitigt sein sollte. Gruß Hagen
Datum:
Hallo Hagen, der Connect geht jetzt mit deiner neuen PC-Version auf beiden Notebooks. In der INI musste ich nix ändern. Ich werde jetzt noch Testen ob die neue PC-Version auch mit allen anderen Bootloader Versionenen auf beiden PC's funktioniert. Deine Unterstützung ich echt super und das auch noch am Sonntag. Gruß Heinrich
Datum:
Alle PC-Bootloader sollten vollständig abwärtskompatibel sein. Nur bei der neusten Version muß man in der .INI bei [Timeouts] Options=0 oder 2 setzen wenn man mit der alten oder neuen AVRootoader.ASM arbeitet. Dh. das Bit #1 = 2 muß in Options bei der neusten PC-Software gesetzt sein wenn man mit dieser eine ältere AVRootloader.ASM verbinden möchte. Options=0 muß gesetzt sein wenn mit der neuen PC-Software auch mit der neusten AVRootloader.ASM verbunden werden soll. Der Hintergrund ist eine Änderung beim Verbinden mit dem Bootloader. In der neusten Version erwartet der Bootloader nach dem Empfang des BootSigns noch eine 16 Bit CRC über das zuvor empfangene BootSign. Dies beseitigt ein kleineres Problem der älteren Versionen und macht den Verbindungsaufbau stabiler und sicherer (wenn man das BootSign als Passwort betrachtet). Ansonsten ist jede Version zu 100% abwärtskompatibel, was ich auch als wichtig erachte wenn man zb. schon fertige Geräte mit älteren AVRootloader Versionen updaten möchte. Allerdings, wie du siehst, habe ich einiges an den PC-Softwares verbessert um den Gesamtprozess der Kommunikation stabiler und auch performanter zu machen. Am Kommunikationsprotokoll selber hat sich, bis auf zwei Punkte, rein garnichts geändert. Die zwei Punkte sind: 1.) neues Kommando 0xFD hinzugekommen. Dies ist nun das offizielle "KeepAlive" Kommando und im Grunde nur ein Platzhalter. Dh. im AVRootloader.ASM musste dafür garnichts geändert werden, es wird auf PC Seite erwartet das der AVR mit 0xC3 = unbekanntes Kommando, antwortet. Es dient nur dazu den Watchdog Timer im AVR zurückzusetzen. Dieser wird bei jedem Kommmando zurückgesetzt falls UseWDT=1 gesetzt ist. 2.) bei UseVersioning=1 hat sich der Aufbau des ersten verschlüsselten Initialisierungs-Blockes verändert. Statt 16 Bytes hat dieser Datenblock dann 24 Bytes Größe. In den zusätzlichen 8 bytes ist die Versionsnummernüberprüfung verschlüsselt kodiert. Da die alten Bootloader Versionen das Versioning nicht unterstützen ist auch hier die Abwärtskompatibilität sicher gestellt. Ansonsten ist es eh immer so das nur verschlüsselte ACY Dateien geupdated werden können die 1 zu 1 zur jeweiligen Bootloaderversion erzeugt wurden. Dh. PC-Software-Version 3 kann nur ACY erzeugen für Bootloader Version 3. Eine ACY erstellt mit Version 3 kann nicht auf AVRs mit Bootloader Version 4 oder 2 installiert werden. Das mag im ersten Moment eine starke Restriktion darstellen aber hier gilt aus meiner Sicht die kryptographsiche Sicherheit als Priorität. Wenn gewünscht kann das aber durchaus verändert werden, so daß die PC-Software für den Bootloader der aktuell verbunden ist eine versionerichtige ACY Datei kompiliert. Das aalles gilt aber nur bei aktivierter Verschlüsselung. Gruß Hagen
Datum:
Hallo zusammen, ich habe den Bootloader erfolgreich auf einem ATTiny25 installiert und er funktioniert soweit sehr gut. Ich benutze den 1-wire Mode an PB0. Wenn ich aber PB5 zuschalte (RSTDISBL) dann kann ich keine Verbindung mehr zum Bootloader herstellen. Ich wollte aber gern PB0 freimachen und PB5 benutzen. Hat einer eine Ahnung woran das liegen kann? Desweiteren bekomme ich auch keinen Zugang wenn die Taktfrequenz des Tiny nur 1 MHz beträgt. Ist das einfach zu wenig für die Baudrate Detektion? Gruß Rene
Datum:
Es ist zum Verrücktwerden... ich kriege es einfach nicht hin. Habe den atmega128 und probiere es gerade mit dem JTAGmkII es zum laufen zu bewegen. aber es klappt einfach nicht. Habe einen ftr232 und da die RX/TX auf den µP gelegt RX->TX TX->RX in den Dateien die entsprechenden änderungen gemacht, aber es klappt alles nicht. UART zwischen PC und µP klappt, aber sobald ich einen Bootloader reinmachen will, funktioniert es nichtmehr. Wie muß ich denn die Fusebits im AVR Stuio setzen? Ich hoffe das mir einer helfen kann... Gruß Horst
Datum:
@Rene Hast du vor dem Setzen des RSTDISBL Flags, Hagens ASM Datei geändert, dass PB5 der 1-Wire-Pin ist und vorher auch geflashed? Habe den Bootloader auf einem ATtiny45 laufen. Benutze aber eine feste Baudrate von 115200 mit internen 8Mhz.
Datum:
Hast du vor dem Setzen des RSTDISBL Flags, Hagens ASM Datei geändert, dass PB5 der 1-Wire-Pin ist und vorher auch geflashed? |
Ja habe ich, aber auch wenn ich den 1 Wire an PB0 lasse und nur RSTDISBL setze geht es schon nicht mehr. Das finde ich sehr komisch. Benutzt du PB5 (Reset) für 1-Wire? Kannst du das mal für mich überprüfen? Gruß Rene
Datum:
Ja ich benutze den Resetpin. Um in den Bootloader zu kommen, musst du erst auf "Connect" gehen, dann die Spannung kurzzeitig unterbrechen. So gehts bei mir. Wenn das geht, kannst du auch nen Pin-Change-Interrupt nehmen um aus der Applikation in den Bootloader z.B. per Watchdogreset zu kommen.
Datum:
Hmm, genauso mache ich es. Hast du das 1-Wire Interface aus dem Archiv? Benutzt du einen externen Pullup mit welchem Wert? Fragen über Fragen. ;-) Gruß Rene
Datum:
@Rene und allen anderen: Wenn ihr solche Probleme habt dann postet hier doch bitte - eure Konfiguration aus AVRootloader.asm, also alle UseXYZ=?, BootSign usw. Einstellungen - macht einen Verbindungsversuch mit der PC-Software (Button Connect...) mit in der AVRootloader.INI eingestellten Option "Debug=1" bzw. bei neuster Version Optionen=1. Im Protokoll Fenster (Memo) die ganzen Meldungen hier per Copy&Paste einfügen - beschreibt eure Hardware, also 1/2-Wire, direkt an RS232 oder an MAX/FTDI Pegelwandler - beschreibt welche Fuses ihr gesetzt habt, am Besten so wie sie AVRStudio benennt, nicht AVRDude oder andere Programme die das wieder anders handeln Habe ich diese Infos dann kann ich auch konkreter helfen. So Rene, wenn du UseUartInvert=1 hast dann musst du einen PullUp nach VCC vom PB0 legen. Gruß hagen
Datum:
Hallo Hagen, danke für deine ausführlichen infos zu den Versionen und deren Kompatibilität. Ich bin jetzt aber etwas verwirrt und zwar aus folgendem Grund: Ich kann mich mit deinem PC-Bootloader V4.0 vom 10.2.09 trotz Option=0 mit einem AVRootloader welcher mit V2.0 erzeugt wurde verbinden und eine mit V.2 erzeugte ACY erfolgreich flashen.
Datum:
>Ich kann mich mit deinem PC-Bootloader V4.0 vom 10.2.09 trotz Option=0 >mit einem AVRootloader welcher mit V2.0 erzeugt wurde verbinden und eine >mit V.2 erzeugte ACY erfolgreich flashen. Ja geht auch beides ;) Aber man sollte bei der V4.0 Version den Connect Prozess eben auf V3 und drunter einstellen, ist besser. Ohne diese Änderung gehts auch, aber die FSM im Bootloader kommt durcheinander und meldet einmalig ErrorCRC für das nächste Kommando das die PC-Software sendet. Da alle Kommandos der PC-Software beim Fehler ErrorCRC bis zu 6 mal versuchen ihren Befehl auszuführen, gehts auch ohne diese Einstellung. Dh. bei jeder Aktion der PC-Software gibt es ma. sechs Versuche wenn ein CRC Fehler aufgetreten ist. Das macht die Sache so stabil. Und natürlich kannst du ein ACY, erzeugt mit einer älteren Version, defakto mit jeder anderen Version auf einen AVR mit der gleichen Version flashen lassen. Auch das ist so beabsichtigt und habe ich oben auch so gemeint. Man kann nicht ein ACY mit zb. Version 3 auf einen AVR mit Version 2 flashen. Man kann nicht mit PC-Software Verson 4 ein ACY für AVR mit Version zb. 3 erzeugen. Aber ausführen kann jede PC-Software-Version jede ACY Version. Man muß da differenzieren zwischen ein ACY erzeugen, quasi kompilieren, und als Script später auszuführen (Program Button). ACY Dateien sind also sowas wie binäre Scripte deren Datenblöcke verchlüsselt sein können und nur von AVRs akzeptiert werden die die gleiche Version wie die des ACY haben, mit dem gleichen Passwort verschlüsselt wurden und wenn UseVersioning=1 gesetzt ist muß deren Versionsnummer gleich oder höher als die des AVRs sein. Gruß Hagen
Datum:
Korrektur: Ich habe nochmal in meine ToDo-Liste nachgeschaut und es ist bei den ACY Files so: Ab Version 3 kann man für jede beliebige AVR-Bootloader Version ein ACY kompilieren/erzeugen. Die PC-Software benötgt ja erstmal eine Verbindung zum Bootloader wenn sie eine ACY Datei erzeugen soll. Sie benutzt also immer die Optionen und Versionsnummer die auf dem AVR installiert ist. Man kann also, entgegen meinem vorherigen Statement, ohne Versionskonflikte/Einschränkungen ACY Dateien erzuegen und ausführen lassen. Das war aber bis zur Version 2 der PC-Software anders. Sorry für diese Mißverständnisse aber so langsam bei der gewachsenen Komplexität kann man auch mal durcheinander kommen ;) Gruß Hagen
Datum:
Hey Hagen, ich habe jetzt nochmal einen Test mit InvertUart=0 und den Tinys durchgeführt. Ausgangssituation war wieder, keine externe Beschaltung am 1-Wire Pin. Der FTDI wird bei bedarf mit einer Prüfspitze verbunden. Mit InvertUart=1 ist der Pullup ja deaktiviert und der Tiny kam nicht ins Hauptprogramm. Mit einem nachträglich Pullup war alles i.O. Ich habe gedacht, dass bei InvertUart=0 der Widerstand entfallen kann. Nach dem letzten Test weis ich es nun aber besser ^^ Statt eines Pullups braucht man dringend einen Pulldown. Lässt man ihn weg, startet der uC wieder nicht. Was ich irgendwie nicht ganz verstehe ist, dass du in deinem Schaltplan den 1-Wire Pin auch nur bei Bedarf über den Steckverbinder C1/C2 anschließt. Startet denn dein uC bei unbeschalteten 1-Wire-Pin? Es wäre natürlich cool, dass der uC auch hochfährt, wenn keine Flankenänderung am Pin bei vorliegt. Mir fällt noch ein Feature für die Programmiersoftware ein. Es wäre ganz nützlich, wenn man eine andere Baudrate für das Senden des AppCmd benutzen könnte als für das Flashen. Arbeite mit fester Bootloaderbaud von 115200, in der Software aber mit 1,25Mbaud. Muss mir momentan mit nem PinChangeInterrupt arbeiten, was nicht so praktisch ist. Würde absolut reichen, wenn die AppBaud in der ini einstellbar wäre. Ist aber nur ne Idee. Grüße Mark
Datum:
Hallo So da bin ich wieder. Habe die benötigten Infos zusammengetragen. Hier die Konfiguration aus AVRootloader.asm:
.include "tn25def.inc" ; ATtiny25 ; set follow equ to 0/1 to de/activate.... .equ UseBootMode = 0 ; 0 = start bootloader always ; 1 = start on power up reset or by call from application ; 2 = start on external reset or by call from application ; 3 = start on watchdog reset or by call from application ; 4 = start only by call from application (not recommended) ; with these bootmodes you can shorten startup time for application .equ UseWDR = 0 ; Watchdog support (2 sec timeout, remember to deactivate WDT in your application if not needed) .equ UseSaveMCUCSR = 0 ; save MCUCSR on stack (RAMEND) for access by application (on UseWDR=1 MCUCSR must be cleared) .equ UseE2Write = 1 ; EEPROM write command (have implicit verify) .equ UseE2Read = 1 ; EEPROM read command .equ UseCrypt = 0 ; cryptography (crypt.inc) .equ UseCryptFLASH = 0 ; explicit use of cryptography for writing to FLASH .equ UseCryptE2 = 0 ; explicit use of cryptography for writing to EEPROM .equ UseVerify = 0 ; Verify FLASH command (FLASH write/erase have implicit verify, can be deactivated) .equ UseVersioning = 1 ; Versioning for application software (stored 4/6 bytes before BootStart) .equ UseBootVector = 1 ; use a rjmp BootStart at end of FLASH to start bootloader from application code .equ UseSpecialFuncs = 0 ; some special functions for your applications (special.inc) .equ UseSRAM = 0 ; SRAM read/write commands (attention! can be a security risk) .equ UseAutobaud = 1 ; Baudrate detection .equ UseUartInvert = 0 ; invert UART levels (for RS232 drivers such as MAX232) .equ UseRS485 = 0 ; activate RS-485 Data Enable pin .equ UseRS485Invert = 0 ; inverted logic of RS-485 DE pin (HIHGH for receive, LOW for transmit) .equ RX_PORT = PORTB ; Receive port and pin .equ RX = PB0 .equ TX_PORT = PORTB ; Transmit port and pin .equ TX = PB0 .if UseRS485 .equ DE_PORT = PORTB ; DE enable pin of RS-485 .equ DE = PB2 ; must be only set if RS485 DE is used .endif .set XTAL = 8000000 ; only important for BootDelay if autobaud is used .set BootDelay = XTAL/4 ; 250ms (don't set to fast to avoid connection problems) .set BootBaudrate = 115200 ; only used if no Baudrate detection activated, XTAL is than important .set BootVersion = 4 ; Version 4 (must be not changed) .set BootCodeSize = 508 ; set to 0, compile and set to value in [.cseg] Used, compile again ;.equ RWWSRE = 4 ; activate for ATmega162 in ATmega161 compatibility mode |
Damit läuft alles super:
25.02.09-19:17:06-078 > Connecting on port COM1... 25.02.09-19:17:06-078 > Timeout.Connect = 50 ms 25.02.09-19:17:06-078 > Timeout.Base = 50 ms 25.02.09-19:17:06-078 > Timeout.Erase = 10 ms 25.02.09-19:17:06-078 > Timeout.Flash = 15 ms 25.02.09-19:17:06-078 > Timeout.Eeprom = 10 ms 25.02.09-19:17:06-078 > Timeout.Buffer = 1 ms 25.02.09-19:17:06-078 > Timeout.AppCmd = 0 ms 25.02.09-19:17:06-078 > Timeout.KeepAlive = 500 ms 25.02.09-19:17:06-078 > Timeout.RTSPulse = 0 25.02.09-19:17:06-078 > Timeout.RTSInterval = 0 25.02.09-19:17:06-078 > Timeout.ConnectTrials = -1 25.02.09-19:17:06-078 > Timeout.MaxPacketSize = 0 25.02.09-19:17:06-078 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:17:06-453 > received data $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 3E 1E 4B 6F 6D 66 6F 72 74 62 6C 69 6E 6B 65 72 91 08 04 10 FF FF FF FF 38 25.02.09-19:17:06-453 > Switch to 1-Wire mode 25.02.09-19:17:06-453 > Timer created 25.02.09-19:17:06-453 > Device connected 25.02.09-19:17:06-953 > send keepalive |
wenn ich nun nicht PB0 sondern PB5 benutzen will:
.include "tn25def.inc" ; ATtiny25 ; set follow equ to 0/1 to de/activate.... .equ UseBootMode = 0 ; 0 = start bootloader always ; 1 = start on power up reset or by call from application ; 2 = start on external reset or by call from application ; 3 = start on watchdog reset or by call from application ; 4 = start only by call from application (not recommended) ; with these bootmodes you can shorten startup time for application .equ UseWDR = 0 ; Watchdog support (2 sec timeout, remember to deactivate WDT in your application if not needed) .equ UseSaveMCUCSR = 0 ; save MCUCSR on stack (RAMEND) for access by application (on UseWDR=1 MCUCSR must be cleared) .equ UseE2Write = 1 ; EEPROM write command (have implicit verify) .equ UseE2Read = 1 ; EEPROM read command .equ UseCrypt = 0 ; cryptography (crypt.inc) .equ UseCryptFLASH = 0 ; explicit use of cryptography for writing to FLASH .equ UseCryptE2 = 0 ; explicit use of cryptography for writing to EEPROM .equ UseVerify = 0 ; Verify FLASH command (FLASH write/erase have implicit verify, can be deactivated) .equ UseVersioning = 1 ; Versioning for application software (stored 4/6 bytes before BootStart) .equ UseBootVector = 1 ; use a rjmp BootStart at end of FLASH to start bootloader from application code .equ UseSpecialFuncs = 0 ; some special functions for your applications (special.inc) .equ UseSRAM = 0 ; SRAM read/write commands (attention! can be a security risk) .equ UseAutobaud = 1 ; Baudrate detection .equ UseUartInvert = 0 ; invert UART levels (for RS232 drivers such as MAX232) .equ UseRS485 = 0 ; activate RS-485 Data Enable pin .equ UseRS485Invert = 0 ; inverted logic of RS-485 DE pin (HIHGH for receive, LOW for transmit) .equ RX_PORT = PORTB ; Receive port and pin .equ RX = PB5 .equ TX_PORT = PORTB ; Transmit port and pin .equ TX = PB5 .if UseRS485 .equ DE_PORT = PORTB ; DE enable pin of RS-485 .equ DE = PB2 ; must be only set if RS485 DE is used .endif .set XTAL = 8000000 ; only important for BootDelay if autobaud is used .set BootDelay = XTAL/4 ; 250ms (don't set to fast to avoid connection problems) .set BootBaudrate = 115200 ; only used if no Baudrate detection activated, XTAL is than important .set BootVersion = 4 ; Version 4 (must be not changed) .set BootCodeSize = 508 ; set to 0, compile and set to value in [.cseg] Used, compile again ;.equ RWWSRE = 4 ; activate for ATmega162 in ATmega161 compatibility mode |
dann passiert das:
25.02.09-19:30:36-468 > Connecting on port COM1... 25.02.09-19:30:36-468 > Timeout.Connect = 50 ms 25.02.09-19:30:36-468 > Timeout.Base = 50 ms 25.02.09-19:30:36-468 > Timeout.Erase = 10 ms 25.02.09-19:30:36-468 > Timeout.Flash = 15 ms 25.02.09-19:30:36-468 > Timeout.Eeprom = 10 ms 25.02.09-19:30:36-468 > Timeout.Buffer = 1 ms 25.02.09-19:30:36-468 > Timeout.AppCmd = 0 ms 25.02.09-19:30:36-468 > Timeout.KeepAlive = 500 ms 25.02.09-19:30:36-468 > Timeout.RTSPulse = 0 25.02.09-19:30:36-468 > Timeout.RTSInterval = 0 25.02.09-19:30:36-468 > Timeout.ConnectTrials = -1 25.02.09-19:30:36-468 > Timeout.MaxPacketSize = 0 25.02.09-19:30:36-468 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:36-843 > received data $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 3E 1E 25.02.09-19:30:36-843 > Switch to 1-Wire mode 25.02.09-19:30:36-843 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:37-234 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:37-625 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:38-015 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:38-406 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:38-796 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:39-187 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:39-562 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:39-953 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:40-328 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:40-718 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:41-109 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:41-500 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:41-890 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:42-281 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:42-671 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:43-062 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:43-453 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:43-843 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:44-234 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:44-609 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:45-000 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:45-390 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:45-765 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:46-140 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:46-531 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 25.02.09-19:30:46-562 > aborted by User |
Ich benutze 1-wire direkt ohne Pegelwandler (max232 o.ä.) nur einen
Widerstand zwischen RXD und TXD. Wie gesagt benutze ich PB0 - 4 gehts
ohne Probleme. Sowie PB5 (RESET) ins Spiel kommt gehts nicht mehr.
Natürlich habe ich dann mit den neuen Einstellungen geflasht.
Die Fuse stehen so:
http://www.bogenschuetzen-moenchengladbach.de/share/Fuse.gif
Gruß Rene
Datum:
Hier noch mal 2 Bilder vom Steckbrett:
PB0:
http://www.bogenschuetzen-moenchengladbach.de/share/PB0.gif
PB5:
http://www.bogenschuetzen-moenchengladbach.de/share/PB5.gif
Gruß Rene
Datum:
@Mark: Du benutzt aber immer den FTDI egal ob UseUartInvert=0 oder 1 ist. Neben dem PullUp/Down wie du ihn benutzt könnte vielleicht noch die Erhöhung des 2k7 Widerstandes zwischen RX-TX helfen. Auf alle Fälle benötigt man bei UseUartInvert=1 einen externen PullUp der natürlich auch entsprechend den Pegeln des FTDI + 2k7 Widerstandes dimensioniert ist. Bei UseUartInvert=0 ist das im Grunde auch so, meine Empfehlung basiert halt eben auf realen RS232 Pegeln von +-15 Volt bzw. +-10V bei USB-RS232 Wandlern. In diesem Modus wird der Pin auf Weeak/Strong Pullup gewechselt beim Empfangen und Senden. Ich schätze mal das es am FDTI und seinen Pegeln liegen wird. An der Software selber kann man nur noch wenig daran verändern, bzw. ganz allgmein gesprochen kann man daran wenig was ändern. Das ist bei einer I2C/1-Wire Software ebenfalls so. Das mit der unterschiedlichen Baudrate: Programmierbar ist im Grunde alles, nichts ist unmöglich solange es der Physik unterliegt ;) Aber konzeptionell wäre es eine größere Veränderungen in der PC-Software. Sobald das IApplication Objekt ein IAVRootloader Protokollobjekt erzeugt, hat die Applikation schon ein ICOM = Kommunikationsobjekt mit entsprechend eingestellter Baudrate erzeugt. Das IAVRootloader-Protokollobjekt hat dann im späteren Verlauf keine Zugriffe auf diese Funktionalität, es kann nur die Senden/Empfangen Funktionen benutzen. Das nennt sich Kapselung in der OOP und soll eine striktere Hierarchisierung im Source des Programmierers bewirken und somit logischen Fehlern vorbeugen. Lange Rede kurzer Sinn: konzeptionell ist dein Wunsch nicht vorgesehen worden und das bedeutet einen höheren zeitlichen Aufwand für mich. Wenn es dir nichts ausmacht lege ichs erstmal in die ToDo Liste für die nächste Version ab ;) Gruß Hagen
Datum:
@Rene: das sieht erstmal gut soweit aus, also da wo es korrekt läuft ;) Beim 2. Protokoll kann man sehr gut erkennen das der AVR nicht antwortet. Es gibt nun einige Vorschläge um das Problem systematisch anzugehen: 1.) setze UseVersioning=0 2.) setze BootMsg auf leer -> BootMsg: ;.db "deine Nachticht", bloß das Semikolon rein Ich denke aber das dies nicht das Problem beseitigt. 3.) baue einen PullUp vom Pin nach VCC rein, 10-100K. Es könnte sein das der Resetpin keinen Pullup verbaut hat oder dieser anders dimenstioniert ist. Wobei bei meinem ATTiny461,44 und 85 benutze ichz auch immer den Resetpin für den Bootloader, und das hat bisher immer funktioniert. Ich meine das könnte am ehesten helfen. Es muß ja einen Unterschied zwischen PB5 und den anderen Pins geben und da fällt mir momentan nur der interne Pullup ein. Wie programierst du eigentlich dann deinen Tiny45 im Nachinhein, per Highvoltage-Parallel-Programming ? Bedenke das solange das Debugwire am RESET noch aktiv ist das Verhalten des internen Pullups an PB5 sich unterscheidet, irgendsowas läutet mir im Hirn gerade rum. Wenn du aber den RESET als gleichwertigen Pin gefust hast dann sollte Debugwire und ISP deaktiviert sein. Das bedeutet nur noch Highvoltage Programming kann den AVR zurücksetzen. Gruß Hagen
Datum:
@Hagen >Du benutzt aber immer den FTDI egal ob UseUartInvert=0 oder 1 ist. Korrekt :) >könnte vielleicht noch die Erhöhung des 2k7 Widerstandes zwischen RX-TX >helfe ehm... also vielleicht haben wir uns irgendwie missverstanden. Solange der FTDI am Pin angeschlossen ist, funktioniert alles einwandfrei in allen Modi auch ohne externen Widerstand sei es Pullup oder Pulldown. Der Punkt ist, dass es nicht funktioniert wenn der FTDI ABGEKLEMMT ist. Der uC springt dann nach einem Restart nicht vom Bootloader ins Hauptprogramm (Vgl. in deinem Schaltplan C1/C2 NICHT verbunden). Hintergrund ist einfach, dass ich einen Pin nicht dauerhaft für das Programmieren "verschwenden" will. Grüße
Datum:
>Der Punkt ist, dass es nicht funktioniert wenn der FTDI ABGEKLEMMT ist. >Der uC springt dann nach einem Restart nicht vom Bootloader ins >Hauptprogramm (Vgl. in deinem Schaltplan C1/C2 NICHT verbunden). Hm, dann floated der Pin. Aber das sollte nur bei UseUartInvert=1 der Fall sein und deswegen auch der ext. Pullup. Wenn die Pegel am Pin stabil sind dann sollte der Bootloader nach BootDelay Millisekunden, standardmäßig 250ms die Anwendung aufrufen. Nun kommt es darauf an ob du UseWDT=1 gesetzt hast. Wenn ja muß deine Anwendung den Watchdog frühzeitig deaktivieren oder ihn selber periodisch zurück setzen. Er steht auf 2 Sekunden Timeout. Das heist auch das BootDelay in diesem Fall niemals größer 2 Sekunden gesetzt sein darf. Falls du eine LED am AVR hast dann schalte sie doch mal im Bootloader ein und in deiner Anwednung wieder aus. Gruß Hagen
Datum:
Moin Moin, ja UseWDT ist eingeschaltet und InvertUart=0 und im Hauptprogramm deaktiviere ich den Watchdog sofort, daran liegts nicht. Auf dem Osi kann ich sehen, dass der uC nach den 2s neustartet (kurzer Low-Pulse auf dem 1-Wire-Pin alle 2s). Also bei den Test fährt der Controller nur hoch, wenn ein Low-Pegel am 1-Wire Pin anliegt, sonst tut sich gar nichts. Kannst du mal gucken, ob du es nicht tatsächlich so programmiert hast?
Datum:
Hallo Hagen, vielen Dank für deine Arbeit mit dem Bootloader. Ich verwende ihn um einen ATTiny85 im 1-Wire-Modus(ohne Verschlüsselung) zu flashen. In meiner Applikation werden sofort nach dem Anlegen der Versorgung Taktsignale mit 22ms Periode auf den INT0 Eingang gegeben. Ursprünglich sollte dieser Eingang auch als 1-Wire-Eingang genutzt werden. Das hat aber nicht funktioniert - die Applikation wurde nie ausgeführt. Ich vermute das durch die Taktsignale der Bootloader ständig getriggert wurde und nie in die Applikation gesprungen ist. Habe dann einen - in der Applikation - als Ausgang beschalteten Port als 1-Wire-Port benutzt und so funktioniert es auch. Gruß und schönes Wochenende bandgap
Datum:
Solange am Bootloader Pin sich irgendwas tut so lange verbleibt der Bootloader in der Connect/Autobaud Schleife. Erst wenn für BootDelay Millisekunden am Pin Ruhe ist springt er die Anwendung an. Das war in älteren Versionen anders. Dort musste innerhalb von BootDelay Millisekunden ein gültiger Connect String empfangen werden, ansonsten sprang er die Applikation an. Nun, je nach Sichtweise verbessert oder verschlechtert die eine oder andere Lösung das Gesamtverhalten und das auch noch abhängig von Eurem eigenen HW-Aufbau. Ich denke nochmal darüber nach und werde wahrscheinlich dieses Verhalten konfigurierbar im ASM machen. Ansich kein großer Aufwand. Aber zuerst mal versuche ich das Problem vom Mark C. nachzuvollziehen und zu lösen. Danach werde ich erstmal dieses Projekt ruhen lassen, mitlerweile hat es doch einiges an Zeit gekostet. Gruß Hagen
Datum:
Angehängte Dateien:Version 5.0 Ich hoffe das dies erstmal die letzte Version ist ;) - das von Mark C. beschriebene Problem ist erstmal beseitigt - mit UseResetDelay=0 oder 1 stellt man das Timeout Verhalten des Bootloaders ein. Ist UseResetDelay=1 gesetzt so muß am RX Pin für BootDelay Millisekunden Ruhe herrschen. Sobald sich am RX Pin was tut wird der Timeout immer auf BootDelay Millisekunden verlängert. Ist UseResetDelay=0 so handelt es sich bei BootDelay um ein Gesamttimeout. Dh. nach spätestens BootDelay Millisekunden ohne korrekten Verbindungsaufbau wird die programmierte Anwendung gestartet. - UseSpecialWrite, UseSpecialWriteBoot, UseSpecialRead, UseSpecialMsg sind neu. Mit ihnen steuert man welche der Spezialfunktionen für den Zugriff durch die Anwendung eingebunden werden sollen. UseSpecialWrite=1 bindet die Funkton write_flash(address, size, buffer) ein. Mit dieser kann man den FLASH aus der Anwendung heraus programmieren. Dabei muß man aber nich auf irgendwelche Addressausrichtungen etc.pp. achten. Dh. man kann mit dieser Funktion zb. 5 Bytes aus dem SRAM an eine FLASH Adresse schreiben ohne das Pagealigment/boundary der FLASH-Pages beachten zu müssen. UseSpecialWriteBoot=1 aktiviert die Möglichkeit in den Bootloader FLASH Bereich schreiben zu können. Abgesichert wird das durch einen Magic Code und die Lockbits müssen entsprechend gesetzt sein. Ob man das aktiviert muß jeder selber wissen. Das M162 Test Projekt im Ordner \test\ macht davon Gebrauch um das Passwort BootKey der Verschlüsselung aus der Anwendung heraus zu ändern. UseSpecialRead=1 aktiviert die Funktion read_flash(address, size, buffer) mit der man einen Speicherbreich des FLASHs in den SRAM lesen kann. Hilfreich ist dies wenn man per Lockbits der Applikation verbietet den FLASH auslesen zu können, zb. Bootloader Section. UseSpecialMsg=1 aktiviert die Funktion um auf die BootMsg: zugreifen zu können. Also um zb. den Wert in BootMsg = Copyright oder BootInfo in der eigenen Anwendung anzeigen zu lassen. Das WinAVR GCC Test projekt für den M162 demonstriert den Zugriff auf diese Anwendungsbezogenen Funktionen. Gruß Hagen
Datum:
Hallo, ich habe den Bootloader in der Verion3 schon zum Laufen bekommen. Nun probiere ich gerade an der neusten Verion 5 herum und habe Probleme, die ich mir nicht erklären kann. Ich bekomme eine Verbindung zum Bootloader - die wird aber nach ca. 250 ms sofort wieder beendet - warum ist das so? Inhalt des Protokollfensters: 03.03.09-12:07:40-390 > Connecting on port COM28... 03.03.09-12:07:42-765 > Device connected 03.03.09-12:07:43-000 > Device disconnected Device Information: Connection : 2-Wire Device name : ATtiny45 Device signature : 1E9206 SRAM size : 256 Byte EEPROM size : 256 Byte FLASH size : 4096 Byte FLASH size for application : 3584 Byte FLASH pagesize : 64 Byte Bootloader size : 512 Byte Buffersize for data : 216 Byte SRAM start address : 96 Bootloader version : 5 Use bootsection : No Versioning supported : Yes Cryptography supported : No Application software version : not defined Application version address : 0x000DFA Ich habe bereits versucht dem Problem durch Anpassen der Timeouts entgegen zu wirken - bisher leider erfolglos. Bisher gelang nur das Auslesen der Device Information. Den ATtiny takte ich intern mit 128 kHz - deshalb nutzte ich für den Bootloader auch nur 1200 Baud. Hat jemand vielleicht einen Hinweis für mich? Gruß Peter
Datum:
Hallo.. beim m1280 kann UART3 und 4 nicht genutzt werden. lg, markus
Datum:
@Peter: Hallo, -hast du sowohl auf dem AVR als auch auf dem PC die neue Version ? -Aktiviere mal den Debug-Modus des Verbindungsaufbaus (über Timeouts, Options=1) und poste mal den Connectaufbau. - welche Option hast du bei UseResetDelay eingestellt ? - hat der Verbindungsaufbau bei der Version 3 problemlos funktioniert ? Gruß Stefan
Datum:
@Stefan R. Danke für deine Bemühungen. Ich habe in der Zwischenzeit schon weiter geforscht und meine Befürchtung bestätigt -> es liegt am Watchdog. Ich poste hier trotzdem nochmal die genauen Protocol-Ausgaben.
03.03.09-14:50:45-046 > Connecting on port COM28... 03.03.09-14:50:45-046 > Timeout.Connect = 50 ms 03.03.09-14:50:45-046 > Timeout.Base = 50 ms 03.03.09-14:50:45-046 > Timeout.Erase = 10 ms 03.03.09-14:50:45-046 > Timeout.Flash = 25 ms 03.03.09-14:50:45-046 > Timeout.Eeprom = 10 ms 03.03.09-14:50:45-046 > Timeout.Buffer = 1 ms 03.03.09-14:50:45-046 > Timeout.AppCmd = 0 ms 03.03.09-14:50:45-046 > Timeout.KeepAlive = 100 ms 03.03.09-14:50:45-046 > Timeout.RTSPulse = 0 03.03.09-14:50:45-046 > Timeout.RTSInterval = 0 03.03.09-14:50:45-046 > Timeout.ConnectTrials = -1 03.03.09-14:50:45-046 > Timeout.MaxPacketSize = 0 03.03.09-14:50:45-046 > send ident $00 00 00 00 00 00 00 00 00 0D 42 54 03.03.09-14:50:48-343 > received data $92 06 05 08 00 00 02 01 38 03.03.09-14:50:48-343 > Timer created 03.03.09-14:50:48-343 > Device connected 03.03.09-14:50:48-453 > send keepalive 03.03.09-14:50:49-453 > Timer released 03.03.09-14:50:49-453 > keepalive failed, terminate connection 03.03.09-14:50:50-453 > Device disconnected |
Die Timeouts habe ich hier aus Verzweiflung abartig hoch gesetzt. Aber wie gesagt - nun funktioniert es mit abgeschaltetem Watchdog-Support (UseWDR=0). Ich hatte bei Version3 keine Probleme mit dem Watchdog-Support - drum hatte ich diesen als Problemquelle ausgeschlossen. Ich werde jetzt weiter beforschen, warum hier der Watchdog-Reset aufschlägt während der Bootloader läuft. Übrigens; ich hatte UseResetDelay=1 da ich das für meine Anwendung auch für sinnvoll gehalten hatte - und wie gesagt; das scheint ja auch nicht mein Problem gewesen zu sein.
Datum:
> > Die Timeouts habe ich hier aus Verzweiflung abartig hoch gesetzt. Aber > wie gesagt - nun funktioniert es mit abgeschaltetem Watchdog-Support > (UseWDR=0). Na immerhin schon mal ein anfang ! > Ich werde jetzt weiter beforschen, warum hier der Watchdog-Reset > aufschlägt während der Bootloader läuft. Autobaud, Bootdelay, XTal richtig gesetzt ?? > Übrigens; ich hatte UseResetDelay=1 da ich das für meine Anwendung auch > für sinnvoll gehalten hatte - und wie gesagt; das scheint ja auch nicht > mein Problem gewesen zu sein. Versuch es trotzdem mal mit UseResetDelay=0, man weis ja nie ! :-) Gruß Stefan
Datum:
@Peter: >ich habe den Bootloader in der Verion3 schon zum Laufen bekommen. Nun >probiere ich gerade an der neusten Verion 5 herum und habe Probleme, die >ich mir nicht erklären kann. >Ich bekomme eine Verbindung zum Bootloader - die wird aber nach ca. 250 >ms sofort wieder beendet - warum ist das so? 1.) die PC-Software sendet alle Timeouts.KeepAlive Millisekunden ein KeepAlive Kommand zum AVR Bootloader. Bei dir also alle 250ms. Das KeepAlive Kommando ist nur ein Platzhalter und der AVR reagiert darauf mit a) dem Rücksetzen des WDT, b) mit Antwort ERRORCOMMAND, also kein gültiges Kommando. Wie ich oben schonmal beschrieben habe hat dieses System zwei Vorteile. Erstens erkennt die PC-Software ob die Verbindung zum AVR noch lebt und setzt dabei auch noch den interen WDT zurück und zweites erkennt der AVR beim Ausbleiben dieses Kommandos das die Verbindung getrennt wurde und lässt den WDT einen RESET durchführen. 2.) alle Anzeichen deuten darauf hin das ein sauberer Connect zum AVR möglich ist. Probiere nun mal statt einem "manuellen Connnect" gleich den AVR mit einer Software zu programmieren. Also sofort den "Program" Button zu klicken statt erst den "Connect" Button. Damit testen wir ob der AVR, wenn er beschäftigt ist, auch sofort per WDT einen RESET macht. 3.) der Auszug: 03.03.09-14:50:48-453 > send keepalive 03.03.09-14:50:49-453 > Timer released 03.03.09-14:50:49-453 > keepalive failed, terminate connection zeigt deutlich das der AVR nicht auf das KeepAlive Kommando antwortet, deine Annahme das der WDT zugeschlagen hat ist also sehr wahrscheinlich. In Timeouts.KeepAlive hast du 100ms drinnen stehen, ändere das auf 250 oder 500. 100ms düften gehen sollten aber unnötig sein da der WDT auf 2 Sekunden eingestellt sein sollte. Falls nicht so wissen wir schonmal das er schon früher als 100ms einen Timeout erzeugt. 4.) nun sollten wir mal nachrechnen welche Konsequenzen deine sehr langsamme Baudrate für das System hat. Ich schätze mal das es damit zusammenhängt. Dh. der Timeout des WDT ist schneller als die eigentlichen Kommunikation längerer Kommando-/Datensequenzen bei 1200 Baud. Der WDT wird intern nur beim Warten auf ein Kommando zurückgesetzt nicht während des Empfanges längerer Datensequenzen. Wir könnten nun dieses Verhalten verändern indem wir im ASM folgends abändern: bei putc: [avr] ; send char putc: xwdr de_0 rcall waitf [/avr] bei getc: [avr] getc: xwdr get9: rx_1 rjmp getc [/avr] und bei main: nun [avr] main: ldi paral, SUCCESS mai1: rcall putc movw crcl, zerol ; xwdr rcall getw [/avr] das xwdr auskommentieren. Mit diesen Änderungen setzen wir den WDT nicht bei nur bei jedem Kommando zurück sondern vor jedem Senden und Empfangen eines Zeichens über die UART. Somit gilt der WDT Timeout relativ gesehen zur Baudrate immer für 1 Zeichen über die UART. Beim originalem Source gilt der WDT für eine komplette Kommandosequenz inklusive allen übertragenen Datenblöcken. Und das könnte bei 1200 Baud länger als 2 Sekunden dauern. Ich denke das obige Änderungen dein Problem beseitigen sollten. Deine Baudrate ist halt sehr langsam eingstellt ;) Bis zur Version 3 wurde der WDT ganz anders genutzt als ab Version 4. Ab dieser Version spielt der WDT eine aktiviere Rolle und soll Verbindungsabrüche erkennen und den AVR zurück setzen und in der PC-Software die Verbindung automatisch trennen. Gruß Hagen
Datum:
@Makrus: >hat schon mal jemand den RS485 getestet ? Nein leider noch nicht, du bist also Erster ;) Das ich es bisher noch nicht slebrr testen könnte hatte ich aber schon oben geschrieben und darauf hingewiesen. >Habe bei mir am AVR den SN75176 und am PC den Devantec USB-RS485. >Ich sehe das Daten gesendet werden und auch welche zurück kommen (LED's) >nur leider verbindet sie sich nicht. Du hast ~RE und DE mit dem DE_PIN am AVR verbunden. Laut Datenblatt benötigen wir LOW-Pegel wenn wir was empfangen wollen und HIGH Pegel wenn wir senden wollen. UseRS485Invert=0 setzen. Das Makro "de_1" setzt dann ~RE und DE auf LOW. Hast du die Aus/Eingänge A/B richtig herum angeschlossen ? Nun können wir noch was am Timing des DE Pins verändern. In putc: [avr] ; send char putc: xwdr de_0 rcall waitf rcall waitf ldi cnt, 10 ...blabla brne put3 de_1 put5: ret [/avr] können wir das "de_0" Makro sukzessive zwischen/hinter "rcall waitf" verschieben. Vor dem Makro "de_1" können wir ein "rcall waitf" einbauen. Somit verschieben wir sukzessive die Enablezeiten des RS485 Treibers. Vieleicht hilft dies ja da zwar das SN75176 sehr kurze Propagationdelay von par Nanosekunden hat aber der USB-RS485 eventuell ein länderes Timing benötigt. Gruß Hagen
Datum:
Hallo Hagen, folgende Settings: UseUartInvert = 0 UseRS485 = 1 wenn ich USERS485Invert = 1 habe dann blinken meine TX und RX leds am USB-RS485 wandler. Bei 0 blinkt nur die TX led. RX = PD2 TX = PD3 DE = PD4 ~RE und DE sind zusammen am PD4 angeschlossen. (Nutze damit auch das DMX Protokoll) habe deine Vorschläge mal ausprobiert, bringt aber keine Änderung. lg, markus
Datum:
Hier mal der Link zum Schaltplan des USB-485. http://www.hoelscher-hi.de/hendrik/light/openrdm/o... lg, markus
Datum:
@Markus: Als erstes mal in AVRoorloader.ini [Timeouts] Options=1 setzen. Dann schauen was bei "received data:" drinnen steht und eventl. hier posten. Mit den USB Dingern stehe ich so langsam auf Kriegsfuß da deren Treiber immer so blöde Timingprobleme haben. Ergo: mal [Timeouts] Base=50 bis 100 setzen. Gruß Hagen
Datum:
@Markus: Auf PC-Seite sitzt meine Bootloader Software und greift über einen VCOM auf den FTDI zu. Der FTDI ist wie konfiguriert ? Müssen irgendwelche Timings bei dem berücksichtigt werden ? Ich frage weil die RS485 im AVRootloader nichts anderes wie Halbduplex RS232 ist mit der Erweiterung das beim Senden einens Zeichens einfach ein Pin seinen Pegel wechselt. Mehr nicht. Es werden keinen extra Timeouts oder Wartezeiten zwischen dem Umschalten berücksichtigt noch Irgendwas auf höherer Protokolebene wie Addressen oder so. Ich frage mich nämlich ob der FTDI Treiber/HW vollständig transparent für die PC-Software ihren DE/~RE Pin einstellt. Gruß Hagen
Datum:
@Hagen 03.03.09-18:57:23-609 > Connecting on port COM4... 03.03.09-18:57:23-609 > Timeout.Connect = 100 ms 03.03.09-18:57:23-609 > Timeout.Base = 100 ms 03.03.09-18:57:23-609 > Timeout.Erase = 10 ms 03.03.09-18:57:23-609 > Timeout.Flash = 15 ms 03.03.09-18:57:23-609 > Timeout.Eeprom = 10 ms 03.03.09-18:57:23-609 > Timeout.Buffer = 1 ms 03.03.09-18:57:23-609 > Timeout.AppCmd = 0 ms 03.03.09-18:57:23-609 > Timeout.KeepAlive = 250 ms 03.03.09-18:57:23-609 > Timeout.RTSPulse = 0 03.03.09-18:57:23-609 > Timeout.RTSInterval = 0 03.03.09-18:57:23-609 > Timeout.ConnectTrials = -1 03.03.09-18:57:23-609 > Timeout.MaxPacketSize = 0 03.03.09-18:57:23-609 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 03.03.09-18:57:24-906 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 03.03.09-18:57:26-187 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 03.03.09-18:57:27-468 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 03.03.09-18:57:28-750 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 03.03.09-18:57:30-031 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 03.03.09-18:57:31-312 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 Also der USB-RS485 funktioniert fürs senden und empfangen. Ich habe bei Geräten hier die mit DMX arbeiten auch das RDM protokoll drinnen und da ist auch senden / lesen ohne Probleme möglich. So sieht zb. der Init des FTDI für das DMX / RDM aus. FT_ResetDevice(ftHandle); FT_SetBaudRate(ftHandle, 250000); //250kBaud FT_SetDataCharacteristics(ftHandle, FT_BITS_8, FT_STOP_BITS_2, FT_PARITY_NONE); FT_SetFlowControl(ftHandle, FT_FLOW_NONE, 0, 0); FT_Purge(ftHandle, FT_PURGE_RX); FT_Purge(ftHandle, FT_PURGE_TX); FT_SetTimeouts(ftHandle, 50, 50); lg, markus
Datum:
@Hagen Also am RX Pin des AVR sehe das Daten kommen (Oszi). Nur am TX und DE Pin tut sich nix. Mit einem USB 232TTL wandler geht es wenn ich direkt auf die RX/TX lege. lg, markus
Datum:
@Hagen mit diesen Einstellungen sehe ich Daten auf RX und TX und auf DE. nur leider kommt kein Connect zustande. Am USB Wandler blinkt auch nur die TX Led .equ UseUartInvert = 1 .equ UseRS485 = 1 .equ UseRS485Invert = 0 lg, markus
Datum:
@Hagen Hier noch ne Beschreibung. Automatic Bus Turnaround The RS485 bus features automatic direction turnaround. Under idle conditions, where no data is being transmitted or received, the bus will be in the high impedance listening mode. Any data that arrives on the RS485 bus will be transmitted via the USB port to the PC. When the PC transmits data the bus direction immediately turns around to transmit the data out on the RS485 bus. When the PC stops transmitting data, there is a 3uS delay to ensure that the final data high gets a firm drive before setting the bus to idle (listening mode) again. http://www.robot-electronics.co.uk/htm/usb_rs485_tech.htm lg, markus
Datum:
>FT_SetDataCharacteristics(ftHandle, FT_BITS_8, FT_STOP_BITS_2, FT_PARITY_NONE); Der Bootloader benutzt 1 Stopbit, nicht 2. >there is a 3uS delay to ensure Das könnte das Problem sein. Der Bootloader benötigt keine 3µs um vom Empfangen auf Senden zu schalten. Somit würde der FTDI nach dem Senden die 3µs warten ohne Empfang und einige Daten verpassen. Man müsste also im Bootloader ein 3µs Delay einbauen wenn der Bootloader anfängt zu senden. Wobei bei einer Baudrate von 115200 sind das in putc am Anfang schon 8.68µs. Baue mal in getc: folgendes ein [a] getc: xwdr rcall waitf get5: rx_1 rjmp get5 [/a] >mit diesen Einstellungen sehe ich Daten auf RX und TX und auf DE. nur >leider kommt kein Connect zustande. Am USB Wandler blinkt auch nur die >TX Led >.equ UseUartInvert = 1 >.equ UseRS485 = 1 >.equ UseRS485Invert = 0 Protokoll hier posten ;) Ich muß sehen was die PC-Software empfängt für diese Einstellung. Grundsätzlich sind diese Einstellungen die ich als korrekt erwartet hätte. Ach und mit welchem XTAL arbeitet dein AVR ? Gruß Hagen
Datum:
Hallo Hagen, danke für den Hinweis bei putc und getc noch ein xwdr einzufügen. Das allein hat allerdings noch nich viel geholfen. Ich bekam zwar eine stabile Verbindung - konnte dann aber FLASH und EEPROM nicht schreiben (ICOM Error). Ich habe dann zusätzlich noch den Watchdog-Timer auf 4 Sekunden erhöht. Jetzt läuft alles wie es soll. Ausgezeichnet! Schöne Grüße - Peter
Datum:
>Ich habe dann zusätzlich noch den Watchdog-Timer auf 4 Sekunden erhöht.
Hm, das heist dann aber das die Programmierzeiten durch deinen so
niedrigen CPU_Clock so enorm langsam sind. In meinen EEPROM
Schreibroutinen habe ich das Zurücksetzen des WDT vor jedem
programmierten Byte schon vorgesehen und trotzdem gibts einen Timeout.
Naja, 128Khz, interner Oszillator, Schätzeisen, sind schon ziemlich
extreme Anforderungen für den Bootloader.
Gruß Hagen
Datum:
Hallo Hagen, ich hab schon wieder neue Sorgen. Der Bootloader funktioniert soweit ganz gut - aber ein Verhalten kann ich mir noch nicht erklären; nach einem Reset (getestet power up und external reset) startet die Applikation nicht automatisch. Statt dessen scheint der Bootloader ständig neu durchzustarten (zumindest wenn ich den Watchdog-Support aktiviere). Ich kann die Applikation nur starten, wenn ich die Bootloaderverbindung aufbaue und dann wieder beende. Ich hab mir jetzt schon Gedanken über das BootDelay gemacht. Aber daran scheint es nicht zu liegen. Ich bin gerade dabei immer mehr durch den Assembler-Code durchzusteigen. Trotzdem stelle ich mir jetzt die Frage, ob mein Problem daher kommt, daß meine RX- und TX- Leitungen mit 10 K pulled up sind. Kann ich mir aber nicht vorstellen. Vielleicht ist ja das Problem bekannt - dann würde ich mich mal wieder über einen Hinweis freuen. Ich werde derweilen mal genauer hinsehen, was hier passiert ist. Schöne Grüße - Peter
Datum:
Das Problem hatte Mark C. auch schon mal. Du musst in deiner Anwendung den Watchdog entweder selber periodisch zurücksetzen oder ihn deaktivieren. Falls du WinAVR GCC benutzt dann schaue dir mal das Test Projekt im ordner \test\ an. Im AVRootloader.ASM habe ich dazu schon Änderungen eingebaut in der AutoBaud und BootSign Detection Funktion so das dort immer der BootDelay Timeout berücksichtigt wird. Versuche mal UseResetDelay=0 zu setzen. Dann wird das BootDelay als Timeout über alles benutzt. Dh. selbst wenn der RX Pin floated oder andersweitig "getaktet" ist wird nach BootDelay Millisekunden die Anwendung gestartet, falls kein gültiger Connect zustande kam. Das ist ja der Grund warum man über UseResetDelay=0/1 das Timeout Verhalten des Bootloaders in der Baudraten/BootSign Detektion verändern kann. Wird UseResetDelay=1 gesetzt so verlängert sich der Timeout in diesen beiden Funktionsteilen immer auf BootDelay Millisekunden solange der RX Pin toggelt, eg. floated. Beides kann erwünscht sein und hat seine Nachteile je nach Hardware. PS: nochwas, du bist ja derjeninge mit den 128KHz CPU Takt, shit. Überprüfe mal was BootDelay für einen Wert bekommt. 128000/4 = 32000 div 2^16 = 0. BootDelay steht bei dir auf 0 und das ist doof. Defakto ist dein MCU Takt so gering das die Timeout Schleifen im Bootloader nicht mehr die korrekte Timeoutzeit warten. Hm, muß ich erstmal drüber nachdenken. Versuche mal BootDelay = 6 zu setzen. Gruß Hagen
Datum:
Hallo Hagen, ich habe natürlich daran gedacht den Watchdog-Timer in meiner Applikation abzuschalten. Das funktioniert ja auch. Was sich hinter dem Parameter UseResetDelay verbirgt denke ich auch verstanden zu haben. Ja, aber dieses BootDelay... da ist mir noch nicht so ganz klar, wie du damit den Timeout realisierst. Ich hatte gestern mit BootDelay = XTAL und BootDelay = XTAL/4 getestet. Heute hab ich dann mal BootDelay = 6 probiert - na das ging natürlich nicht. Ich hab nun wie gesagt versucht aus deinem Assembler-Code schlau zu werden. Aber bisher tue ich mich da noch schwer. Vielleicht kannst du mal ein bisschen beschreiben, wie du den Wert von BootDelay verarbeitest. Ich werde dann mal ne Debug-Session starten - vielleicht geht mir dann ein Licht auf. Viele Grüße - Peter
Datum:
In der Baudraten/BootSign Detektion wird ein 24 Bit Wert dekrementiert. das MSB dieses Wertes ist BootDelay/6. BootDelay/6 deshalb weil ein Dekrementationschritt samt Abfrage 6 MCU Takte benötigt. Der Bootloader wartet auf jeden Pegelwechsel am RX Pin und dekrementiert diesen 24 Bit Wert. Ist er runtergezählt hat der Bootloader annäherend exakt XTAL/BootDelay Millisekunden gewartet. Wenn also in BootDelay = XTAL/4 drinnen steht dann sind dies 1 Sekunde/4 = 250ms und in BootDelay steht die Anzahl der Takte für 250ms. Bei der Initialisierung des 24 Bit Zählers wird nur dessen MSB mit BootDelay/6 gesetzt. /6 weil die Anzahl der MCU Takte um den 24 Bit Wert zu dekrementieren/abzufragen/RX Pin abfragen 6 Takte benötigt. Die Minimale Taktfrequenz in XTAL damit dieser Zähler korrekt für 250ms arbeitet ist 4*6*2^16=1572864 ~1.6MHz. Also 1572864/4 = 393216 / 6 = 2^16 = 0x010000 und somit ist das MSB des 24 Bit Zählers = 1. Für einen Timeout von 1 Sekunde sind es 1*6*2^16=393kHz. Die Timeout Schleifen sind auf Grund ihrer Konstruktion also ungeeignet für geringe XTAL Frequenzen. Das lässt sich aber abändern: Gruß Hagen
Datum:
Ändere:
; baudrate and identifier scanning .if UseResetDelay abd: .endif ldi cmdl, byte3(BootDelay / 6) ldi xh, byte2(BootDelay / 6) ldi xl, byte1(BootDelay / 6) .if !UseResetDelay abd: .endif |
Kostet 1 Word mehr an Code, dafür ist der Timeout auf 6 Takte exakt und bei deinem kleinen XTAL besser. Vorher war es nur auf 2^16 Takte exakt. Gruß Hagen
Datum:
Hallo Hagen, vielen Dank für die Anpassung. Jetzt funktioniert das BootDelay wie erwartet. Schöne Grüße & schönes Wochenende!
Datum:
Angehängte Dateien:Hier eine korregierte Version. Das RS485 Problem vom Markus C. wurde gefixt. Nun funktioniert der Bootloader verifiziert auch mit RS485 Bussen. Getestet habe ich mit einen FTDI FT232R an MAX487 -> SN75LBC176 an ATMega162 bis 256kBaud. Das Problem mit extrem geringen XTAL Werten (siehe oben 128kHz) und den Timeout Schleifen ist ebenfalls gefixt. Desweiteren wurden einige Watchdog Reset Aufrufe anders plaziert. Gruß Hagen
Datum:
Hallo, Hagen, erst sage ich besten Dank für deine Arbeit! Dein Bootloader funkzioniert perfekt. Nur habe ich festgestellt, dass mit letzte AVRootloader.exe habe ich mein streng schiffrierte EEPROM aus Mega32 ohne Problem gelesen! Obwohl schreiben kann ich nicht (natürlich ich habe keine gültige Password angegeben). Device Information--------------- Connection : 2-Wire Device name : ATmega32, ATmega32A Device signature : 1E9502 SRAM size : 2048 Byte EEPROM size : 1024 Byte FLASH size : 32768 Byte FLASH size for application : 31744 Byte FLASH pagesize : 128 Byte Bootloader size : 1024 Byte Buffersize for data : 1944 Byte SRAM start address : 96 Bootloader version : 2 Use bootsection : Yes Versioning supported : No Cryptography supported : Yes FLASH data must be encrypted : Yes EEPROM data must be encrypted : Yes Protocol------------------------ 12.03.09-13:19:19-258 > Connecting on port COM1... 12.03.09-13:19:19-628 > Connecting on port COM4... 12.03.09-13:19:19-929 > Error: no Device found 12.03.09-13:19:26-757 > Connecting on port COM1... 12.03.09-13:19:27-137 > Connecting on port COM4... 12.03.09-13:19:27-307 > Device connected 12.03.09-13:20:00-736 > Reading EEPROM... 12.03.09-13:23:50-751 > Writing EEPROM... 12.03.09-13:23:50-811 > Cmd.SetBuffer.ResCheck(2) Error: Decryption failed 12.03.09-13:24:13-835 > Reading EEPROM... Also Reading geht anwandfrei ;-) Habe Ahnung, dass genau so leicht kann man Flash einlesen. mfg Vladimir
Datum:
Ja das ist richtig und auch Absicht so. Übrigens ist dieses Verhalten seit Anbeginn im Bootloader so. Einen kryptographischen Schutz beim Auslesen von Speichern die man per Konfiguration auslesbar gemacht hat gibt es nicht. Möchte man das Auslesen der Speicher verhindern so muß per Konfiguration einfach diese Lesefunktion deaktiviert werden. Der beste kryptographische Schutz ist es immer noch eine potentiell angreifbare Funktion erst garnicht zu unterstützen, wo nichts ist kann nichts geknackt werden. Der FLASH kann gernerell nur geschrieben werden, ein Auslesen ist als Funktion nicht vorhanden. Das ist ua. der Grund für eine separate Verify-Funktion für den FLASH. Mit dieser kann man ohne eine Lesefunktion zu haben denoch den Inhalt des FLASHs überprüfen. Kryptographisch gesehen bedeutet dies das nur Derjenige der das korrekte FLASH File extern besitzt auch die Möglichkeit hat den aktuellen Inhalt des FALSHs zu überprüfen. Benutzt man verschlüsselte ACY Dateien ist auch dieses Verify kryptograpisch sicher für den Herausgeber dieser ACY. Ein Verify mit aktivierter Verschlüsselung akzeptiert nur verschlüsselte Daten. Wenn also UseCryptFLASH=1 ist kann nur mit verschlüsselten ACY Dateien ein Verify gemacht werden. Ein Auslesen des FLASHs ist im Bootloader nicht vorhanden auch nicht als Backdoor oder so, egal ob mit oder ohne aktivierter Verschlüsselung. Möglich wäre es schon das man den Bootloader so umschreibt das man Daten nur lesen kann wenn vorher eine korrekte Authentifizierung übermittelt wurde. Dies wäre sogar relativ einfach möglich. Aber welchen Sinn würde das machen ? Möchte man das Auslesen des EEPROMs seinen Kunden nicht gestatten dann wird einfach UseE2Read=0 gesetzt und schon ist diese komplette Funktion garnicht mehr im Bootloader vorhanden. Nichts Vorhandenes kann nicht geknackt werden. Eine Ausnahme ist UseSRAM=1. Diese dient zum "Mini-Debuggen" der Anwendung. Mit ihr kann man zb. den aktuellen Inhalt des SRAMs, Register und IO Ports auslesen und auch schreiben. Möchte man sichere Kryptographie so muß UseSRAM=0 gesetzt werden. Fazit: bei korrekter Konfiguration sehe ich keinen anderen Weg als den AVR mit echt fetten Geschützen knacken zu müssen, also mit Reverse Engineering auf Chip Ebene. Das Bootloader Protokoll und die unterstützten Funktionen des Bootloader im Zusammenhang mit der Arbeitsweise der verschlüsselten ACY Dateien, der verwendeten Verschlüsselung und ihrer kryptographischen Komplexität und benutzten Passwortlänge, ist aus meiner Sicht kryptographisch wasserdicht und nicht knackbar mit praktisch vorhandenem Equipment, heutigem Wissenstand und in praktikabler Zeit. Aus meiner Sicht ist im Rahmen des Möglichen das kryptograpisch maximal Machbare gemacht worden. Bei mathematisch betrachtetem infinitimalem Aufwand ist jede Verschlüsselung in unendlich kurzer Zeit knackbar. >Habe Ahnung, dass genau so leicht kann man Flash einlesen. Diese Vermutung kann ich also klar verneinen, es gibt keine Funktion zum Lesen des FLASHs. Gruß Hagen
Datum:
Selbst solche erweitereten Angriffe wie den Strombedarf des AVRs und damit der Bootloader Software zu überwachen dürften enormst schwierig sein. Alle kryptographischen Operationen die zb. den Schlüssel aus dem FALSH lesen oder ihn später dann im Algorithmus weiterverarbeiten sind gleich gewichtet im Strombedarf. Dh. an Hand des Strombedarfes ist auf Grund der symmmetrischen Operationen im XTEA Algorithmus kein Rückschluß auf den verwendeten Schlüsselinhalt herzustellen. Diese Annahme von mir ist aber mit Vorsicht zu genießen da ich nicht sicherstellen kann wie Atmel seine Chips intern konstruiert hat. Es wäre aber schon sehr fragwürdig das ein Opcode wie xor r1, r2 abhängig vom Inhalt in r1 und/odr r2 unterschiedlich Strombedarf bedeuten würde. Gruß Hagen
Datum:
Bei der Konfiguration UseCrypt=1 UseCryptE2=1 UseE2Write=1 UseE2Read=1 kann man also 1.) nur verschlüsselte Daten in das EEPROM schreiben, nur der Herausgeber des Modules ist also in der Lange den EEPROM zu schreiben 2.) alle Daten im EEPROM lesen, also auch die Endkunden können den EEPROM lesen. Dies dient auch einem ganz speziellem Zweck. Man kann auf sichere Art die Veränderung der Konfigurationen im EEPROM updaten, der Kunde kann sie sich auslesen aber eben nicht verändern. Damit dient diese Funkionalität quasi als indirekte Kommunikationsschnittstelle zwischen Herausgeber und Kunde. Über diese Konfiguration hat man also einen kryptographsichen Writeonly Schutz. Soll der Kunde diese Daten nicht lesen können dann muß UseE2Read=0 konfiguriert werden. Das sichere Auslesen dieser Daten muß dann vom Herausgeber über seine eigene Anwendung programmiert werden. Dies ist dann auch flexibler durchführbar, zb. nur bestimmte Sektionen des EEPROMs sind auslesbar für den Kunden. Gruß Hagen
Datum:
Danke für schnelle und volständige Antwort. Respect! mfg Vladimir
Datum:
Hallo Hagen, habe folgendes Problem, Tiny24, 1-wire, nur WDR und UartInvert ein. Flashen geht, meine App. läuft auch, aber nur wenn der Bootloader Connect wurde. Wenn der Loader ohne Connect verlassen wird, (wird er auch und WDR wird auch abgeschaltet) hängt mein App. sich auf. Es sieht so aus, als wenn er keine Interrups mehr ausführt, als wenn noch ein Flag an ist. Bevor ich alles zerrlege, hast Dueine Idee? Gruß Willi
Datum:
Das Problem gab es hier schon mehrmals. Du brauchst extern einen Pullup/Pulldown widerstand, wenn du den Programmierstecker nicht die ganze Zeit am Pin anliegen hast. Für UartInvert=1 brauchst du einen Pullup für UartInvert=0 einen Pulldown. Oder du passt diese neue BootDelay-Funktion an. Hoffe ich hab es richtig rum im Gedächtnis gehabt.
Datum:
Bei UartInvert=1 und 1-Wire benötigst du einen externen Pullup. Ist im Schematik auch zu sehen. Setze auch noch UseResetDelay=0. Ansonsten ist es schwierig zu beurteilen wo das Problem liegt. Ich könnte auf deinen Source mal einen Blick werfen, vielleicht liegts nur an einem kitzekleinem Detail. Schicke ihn mir bitte per PN. Ich habe nämlich gerade am Connect-Timeout usw. in den letzten Versionen stark gearbeitet, da sollte es keinerlei Probleme mehr mit geben. Übliche Verdächtige: - Brownout nicht aktiviert - VCC schlecht - WDT nicht ordentlich deaktiviert oder benutzt - SEI Aufruf vergessen - ISRs nicht korrekt (Register sichern, wiederherstellen) - extrem geringe Taktfrequenz Gruß Hagen
Datum:
Guten Morgen, Hallo Mark, Hallo Hagen, ich habe nicht das Problem mit dem PullUp bei UartInv=1 (PullUp ist vorhanden). Der Bootloader wird ja auch nach 0,3 sek verlassen (hab extra einen Pin in meiner App. gesetzt) dann sieht es so aus, als wenn kein Interrups mehr ausgeführt werden. Mein Code ist folgender: [[http://www.mikrocontroller.net/attachment/47695/DC...]] die Version mit Tiny24 ohne Programierung.inc (ist sonst zu groß). Komisch ist nur, das wenn der Bootloder 1x Connect und gleich wieder verlassen wird, läuft meine App.. War gestern schon sehr spät, muß ich heute Abend schaun, wo er hängen bleibt. Bei dieser Gelegenheit gleich noch eine Frage: ich will den Loader für meinen DCC Lokdecoder benutzen, hier kann er aber nur explizit aus meiner Software aufgerufen werden ( weil der Lokdecoder ja ständig keinen Kontakt zur Schiene hat und somit immer wieder einen PowerOnReset bzw BrownOutReset macht) und da sind 0,3 sec Verzögerung nicht drinn. Das würde ja mit Deinem Loader und Mode 4 "nur aus App starten" kein Problem sein. Dann muß ich aber das erste mal meine App. und den Loader in einem HEX zusammenfassen und in den Flash schreiben, sonst hab ich ein "Henne-Ei" Problem. Hast Du hier noch einen Tip für mich? Gruß Willi
Datum:
>in einem HEX zusammenfassen und in den Flash schreiben, sonst hab ich >ein "Henne-Ei" Problem. Hast Du hier noch einen Tip für mich? Nein hast du nicht das habe ich schon berücksichtigt ;) Also du hast nur den Bootloader das erste mal geflasht. Alle Bytes im FLASH vor dem Bootloader sind somit 0xFF. Der Bootloader reagiert nur wenn in MCUCSR = 0x00 drinnen steht. Der Bootloader benutzt UseWDT=1. Der AVR wird eingeschaltet und MCUCSR <> 0. Bootloader initialsiert WDT und dabei wird MCUCSR = 0 gesetzt. Bootloader möchte Anwendung aufrufen springt aber an eine Stelle im FLASH die mit 0xFF gefüllt ist, genaugenommen springt er bei ATTinys an BootStart -2 und dort steht 0xFFFF statt einem RJMP MainApp. 0xFF ist so wie der NOP Code, ergo läuft die MCU wieder in den Bootloader Code rein. Da nun aber MCUCSR = 0 ist bedeutet dies das der Bootloader aus der "Anwendung" heraus aufgerufen wurde. Ergo: im Bootmode=4 und UseWDT=1 wird der Bootloader auch aufgerufen wenn keine Anwendung im FLASH installiert wurde. Und zwar beim zweiten Aufruf des Bootoaders nach einem RESET, PowerUp, Brownout, WDT Reset. Denoch erachte ich diese BootMode=4 als "gefährlich". Warum nicht auf den WatchDog triggern ? Ist viel eleganter. Denn wenn BootMode=4 und UseWDT=0 ist dann wird der Bootloader tatsächlich nur durch eine Anwednung aufrufbar sein, es sei denn man ändert AVRootloader.asm so ab das das MCUCSR Register gelöscht wird. Benutzt du aber den WDT mit UseWDT=1 und BootMode=3 ist das wesentlich cleverer. Du hast erstens ein wesentlich stabileres Verhalten des Bootloader und deiner Anwednung auf unvorhersehbare Ereignisse. Zweitens kannst du den Botloader per RJMP oder per WDT Timeout starten. Startest du per WDT Timeout wird ein "echter" RESET des AVRs gemacht und somit sind alle Register/Ports etcpp. immer korrekt initialisiert. Das könnte auch dein Problem im aktuellen Projekt sein. Du rufst den Bootloader per RJMP auf hast aber vorher schon bestimmte Einstellungen wie Timer etcpp. getroffen. In deiner Main() deiner Anwednung verlässt du dich nun darauf das alle Register und Ports wie nach einem RESET initialisiert wurden, und initialsiierst sie demzufolge nicht explizit neu. Der Bootloader kehrt selber per RJMP zu Main() zurück und somit übernimmmt dein Code eine teilweise initialisierte Hardware vom vorherigen Aufruf der Main() weil du den Bootlaoder per RJMP aufgerufen hast. Ich empfehle immer den WDT zu benutzen, sowohl im Bootloader per UseWDT=1 wie auch in der Anwendung beim Aufrufen des Bootloaders. In deiner Anwednung elber kannst du den WDT ja deaktivieren, musst du sogar wenn du ihn nicht für deine App benutzen möchtest. Gruß Hagen
Datum:
Vergessen: drittens könnte es theroretisch zu dem Fall kommen das der Bootloader beim Programmieren einer neuen Anwendung Scheiße baut. Diese halb geflashte Anwendung könnte somit später aufgerufen werden. Sie läuft dann ab einem gewissen Punkt in den unprogrammierten FLASH rein und somit am Ende in den Bootloader. Bei BootMode=4 und UseDT=0 und ohne Zurücksetzen des MCUCSR Registers würde der AVR quasi tot geflasht sein. Mit UseWDT=1 aber würde eine "fehlerhafte" Anwendung quasi nicht reagieren und der durch den Bootloader programmierte Watchdog würde spätestens nach 2 Sekunden einen RESET erzwingen der schlußendlich den Bootloader aufruft. AVR nicht tot geflasht und der Bootloader interagiert für die Anwednung als Failsave ;) Gruß Hagen
Datum:
Möchtest du denoch UseWDT=0 und BootMode=4 benutzen dann ändere AVRootloader.asm so ab
.if UseWDR ldi cmdl, (1 << WDE) | (1 << WDCE) ldi cmdh, (1 << WDE) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0) xout MCUCSR, zerol ; WDRF must be explicite cleared to take changes on WDT xout WDTCR, cmdl ; activate Watchdog and set to 2 seconds timeout xout WDTCR, cmdh .elif UseBootMode == 4 xout MCUCSR, zerol .endif ; .if UseWDR |
Gruß Hagen
Datum:
Ich habe mal kurz den DCC Source angeschaut. Variable BitZaehler und einige andere werden in Main nicht initialisiert. Diese Variablen werden in den ISR mit Daten gefüllt aus denen später das DCC Kommando dekodiert wird. Sind sie aber nicht initialisiert und mit Daten des vorherigen Runs der Applikation gefüllt funktioniert der Code nicht mehr sauber. Dh. der Code erwartet im Grunde das er aus einem RESET mit definierten Startbedingungen heraus aufgerufen wird. Wurde der Bootloader aber per RJMP aufgerufen so springt dieser selber per RJMP Main wieder in die Anwendung. Der Bootloader sleber läuft korrekt da er jede Hardware die er für sich benötigt initialisiert und ansonsten ohne ISRs oder andere HW lauffähig ist. Das gilt dann aber nicht mehr für den DCC Dekoder. Würdest du den Bootloader per WDT Timeout starten so wird ein RESET des AVRs ausgelösst und dann der Bootloader gestartet. Dieser wiederum ruft dann per RJMP Main den DCC Dekoder auf und dieser hat einen vollständig neu initialsierten AVR vor sich. Ändert aber nichts an der Sache das du die uninitialiserten Variablen des DCC dekoders trotzdem im Main() korrekt initialisieren musst. Denn diese vaiablen liegen in Register oder dem SRAM der ja durch den Bootloader Code ebenfalls modifiziert wird. Gruß Hagen
Datum:
Hallo Hagen, ich habe leider ein Probelm mit deinem Bootloader. Ich verwende einen AtMega16 und einen FTDI 232 BM und kann keine Verbindung aufbauen um die Software einzuspielen. Das angepasste AssemblerFile ist im Anhang. Der letzte Versuch war auch schon mit 9600 Baud fix eingestellt und brachte auch keinen Erfolg. Danke vielmals Michael
Datum:
Hallo Hagen, ersteinmal Danke für die vielen und vor allem schnellen Tips! Das mit meiner nicht initialisierten Variablen überprüf ich gleich einmal, momentan hab ich den Bootloader aber noch mit WDT getestet! Die Geschichte wie das in dem fertigen Projekt aussehen kann, darüber habe ich mir bis jetzt nur ein paar Gedanken gemacht, aber nach Deinen Erläuterungen, denke ich, das ich es dann über den WDT mache, ich würde den dann in Abhängigkeit einer Variablen ein/ausschalten und somit die Programmierfunktion im normalen Betrieb deaktivieren, das mit dem durchlaufen des leeren Flash ist natürlich richtig daran habe ich nicht gedacht. Gruß willi
Datum:
Ich nocheinmal, die Variabelen werden alle Initialisiert, Bitzaehler wird vor jedem gebrauch in der DCC Schleife gelöscht, ich habe die Variablen, welche eh immer wieder vor gebrauch erst neu gesetzt werden im main nicht nocheinmal gesetzt. Aber schauen wir mal, das findet sich schon. willi
Datum:
@Michael: >ich habe leider ein Probelm mit deinem Bootloader. Ich verwende einen >AtMega16 und einen FTDI 232 BM und kann keine Verbindung aufbauen um die >Software einzuspielen. >Das angepasste AssemblerFile ist im Anhang. Welcher Anhang ? Hast du UseUartInvert=1 gesetzt, wie im ASM gefordert wenn man einen Pegelwandler wie den MAX oder FTDI benutzt ? Gruß Hagen
Datum:
Angehängte Dateien:Oh, sorry, hab ich vergessen, denn Anhang mit hochzuladen... Aber jetzt... Ja habe ich, bei meinem letzten Versuch habe ich die automatische Baudrate deaktiviert und eine fixe Baudrate von 9600 eingestellt, hat aber leider auch nicht funktioniert. Danke
Datum:
@Toralf, probier den Bootloader per WDT zu starten das schließt schomnmal par Möglichkeiten aus:
cli wdr ldi r16, (1 << WDE) | (1 << WDCE) out WDTCR, r16 ldi r16, (1 << WDE) out WDTCR, r16 wd1: rjmp wd1 |
Wenns damit geht muß irgendwas in Main() bei der Initialisierung noch fehlen. Gruß Hagen
Datum:
@Michael: ich fasse also mal zusammen: - ATMega16 - 8 Mhz Takt, entsprechend Fuses gesetzt, zb. CHKDIV8 ist nicht gesetzt - FTDI Pegelwandler - RX,TX liegt auf PORTD an PD0/PD1 und wurde am FTDI korrekt verbunden - UseAutoBaud=1 wieder setzen, das korregiert evntl. Fehler beim XTAL etcpp. - UseSRAM=1 ist im Zusammenhang mit UseCrypt=1, UseCryptFLASH=1 ein Sicherheitsrisiko, spielt zwar nichts zur Sache aber denoch wichtig zu bemerken - BOOTRST Fuse wurde gesetzt - Boot Section Fuses wurde auf 1024 Bytes = 512 Words gesetzt - in AVRootloader.exe auf dem PC wurde "BOOTLOADER" als BootSign augewählt - in AVRootloader.ini [Timeouts] Options =1 setzen und schauen was im Protokollfenster als "received:" angezeigt wird. Den Inhalt des Protokollfensters hier posten, nachdem du den Connect Button gedrückt hast. - auf dem PC wurde alles soweit vorbereitet das über den virtuellen COM Port der FTDI erreichbar ist, eventl. noch mal testen ob das alles geht. Dazu am FTDI den RX-TX Pin brücken und per PC-Software einen Connect versuchen, sollte dann 1-Wire Modus erkennen und das empfangen was gesendet wurde. Falls du ein Oszi hast wird es Zeit es zu befeuern und mal zu schauen was am RX Pin des AVRs ankommt. Gruß Hagen
Datum:
Hallo Hagen, so, Fehler gefunden, lag bei mir. Mein Code+Bootloader war zu groß für den Tiny24 und beim zusammenkürzen war dann doch ein Register nicht mehr ordentlich initialisiert. Habe jetzt folgenden Stand: Bootloader mit UseBootMode = 3, UseWDR = 1, UseUartInvert = 1, RX=TX Port, feste Bautrate im AVR. App. läßt sich problemlos laden und läuft auch. Aber der Bootloader wird immer aufgerufen (bei Mode=3 sollte das aber nur nach einem WDT Reset geschehen), wenn kein "Connect" wartet er "BootDelay" ab und startet dann meine App.. Das sollte er eigentlich nicht. Er sollte nur gestartet werden, wenn ich in meiner App. einen WDT Reset erzeuge (so wie Du oben gezeigt hast). Nocheinmal zusammengefasst, momemtan schalte ich den WDT sofort in meiner App. aus, das bedeutet, Der Loader solte eigentlich nur beim leeren Flash aufgerufen werden, sobald meine App. im Flash ist gibt es keinen WDT Reset mehr und somit sollte der Bootloader bei Mode = 3 immer sofort übersprungen werden, macht er aber nicht, er wartet immer "BootDelay" ab und startet erst dann meine App.. Hast Du hier noch ein Tip für mich? Gruß Willi
Datum:
Habs gerade nochmal getestet und bei mir funktioniert das einwandfrei, ATMega162. Erklärung könnte sein das deine Anwendung irgendwie in den Bootloader reinläuft. Kannst du mal eine Minimal Anwendung bauen in der eine LED an einem Pin ausgeschaltet wird. Im AVRootloader.asm lässt du diese LED dann leuchten und zwar nach der Abfrage des UseBootMode und vor der Initialisierung der Ports. Wenn jetzt der Bootloader durchstartet beginnt diese LED zu leuchten. Ohne die Minimal-App leuchtet sie also dauerhaft. Sobald die App geflasht wurde leuchtet die LED nicht mehr. Die App sollte einen Pin abfragen der extern auf LOW gezogen wird wenn der Bootloader gestartet werden soll. Sie benutzt dann den WDT um den Boootloader zu starten. Du kannst jetzt einen externen RESET, PowerUp usw. machen die LED darf nicht leuchten. Erst wenn der Pin auf Low gezogen wird sollte sie für BootDelay Millisekunden leuchten. Gruß Hagen
Datum:
Hallo Hagen, danke für deine Antwort, ich habe die Einstellungen getroffen, leider hilft dies nicht. Ja ich habe schon mit dem Oszi gemessen, am RX Pin liegen die Pakete an, jedoch sendet der uC nichts zurück. Die Kommunikation funktioniert zwischen Pc und uC mit der "richtigen" Software, nur leider kann ich keine Verbindung für ein Bootloaderupdate aufbauen. Reicht es eigentlich nur den Bootloader in den AtMega zu laden und anschließend das "richtige" Hex File mittels deinem Programm zu laden. Oder muss von Beginn an das "richtige" Hex File mit kompiliert werden? Danke schonmal für deine Antwort. Michael
Datum:
Hallo Michael > Die Kommunikation funktioniert > zwischen Pc und uC mit der "richtigen" Software, nur leider kann ich > keine Verbindung für ein Bootloaderupdate aufbauen. Wenn das funktioniert muß es auch mit Bootloader gehen. Ist also ein Fehler in den Einstellungen. Mach mal folgendes:(wie Hagen oben schon gesagt hat) - in AVRootloader.ini [Timeouts] Options =1 setzen und schauen was im Protokollfenster als "received:" angezeigt wird. Den Inhalt des Protokollfensters hier posten, nachdem du den Connect Button gedrückt hast. > Reicht es eigentlich nur den Bootloader in den AtMega zu laden und > anschließend das "richtige" Hex File mittels deinem Programm zu laden. Ja ! > Oder muss von Beginn an das "richtige" Hex File mit kompiliert werden? Auf keinen Fall ! Gruß Stefan
Datum:
Angehängte Dateien:Hallo Hagen, Hallo Stefan, ich habe die ini- Datei geändert und das Protokoll gespeichert befindet sich im Anhang, bei diesem Versuch habe ich das asm- File mit euren Tipps aktualisiert. Welche Einstellung kann ich mit "UseBootVector" treffen? Danke im Voraus Michael
Datum:
aja, eine Frage noch, wie führt ihr den Reset durch. Ich habe einen PullUp vom Reset zu Vcc und mit einem Taster ziehe ich Reset gegen GND. LG Michael
Datum:
UseBootVector=1 speichert ganz am Ende des FLASH einen Sprung zu BootStart. Da diese Address fix ist ist es nun ein leichtes einen universellen Aufruf des Bootloaders aus der Applikation durchzuführen. Wenn du den Bootloader aus deiner Anwendung heraus aufrufen möchtest dann kannst du dies über einen Sprung über diesen Vektor oder per Watchdog Timeout. Ich empfehle per WDT. Schau dir das Test-Projekt im Ordner \test\ an, das sollte eigentlich alles demonstrieren. RESET per Pullup nach VCC und Taster an GND, ist schon richtig wie du das machst. Zurück zum eigentlichen Problem. Gehe mit dem Oszi an den TX Pin des AVRs und schaue ob der AVR sendet. Oder setze UseRS485=1 und definiere einen freien Pin bei DE_PORT und DE_PIN. Dieser Pin geht High wenn der Bootloader sendet und Low wenn er empfängt. Falls du schon eine LED auf deinem Board hast dann benutze deren Pin & Port für DE_PIN & DE_PORT. Du solltest dann ein Blinken sehen wenn der AVR sendet, geringe Baudrate dann aber einstellen. Ich denke du hast irgendwas nicht korrekt konfiguriert oder mit deiner HW stimmt was nicht. An und für sich ist es eigentlich ganz simpel den Bootloader zum Laufen zu bekommen. Ich weiß nicht wie einfacher ich noch alles bauen soll ;) Wie hast du den AVR angeschlossen ? Erkläre mal deine Hardware. Achso: in deinem Protokoll antwortet der AVR nicht. Trenne deinen FTDI vom AVR und verbinde dessen RX-TX Leitung per Brücke. Versuche dann erneut einen Connect über die PC-Software und sage mir was du im Protokollfenster siehst. Gruß Hagen
Datum:
Angehängte Dateien:Hallo Hagen, ich habe Rx und Tx miteinander verbunden und das Protokoll in den Anhang gehängt. Die Hardware funktioniert bestimmt, den Fehler können wir ausschließen, denn der uC redet aktuell mit Matlab und bekommt davon wieder Befehle zurück. Danke Michael
Datum:
Juhu, es klappt, frag mich nicht wieso? Ich debugge und gebe einen externen Reset und drücke anschließend im Debugger Start ist die Verbindung da. Werde es noch mal analysieren und dir dann bescheid geben. Danke vielmals für deine Bemühungen und für diesen spitzen Bootloader Michael
Datum:
Hallo Hagen,
habe mein Problem mit dem Start des Bootloaders gefunden, der Loader
startet in Mode 3 auch bei einem Brown_Out_Reset. Kannst es ja Bitte
einmal überprüfen, ich habe folgenden Code in den T24 geladen:
Main:
MCUSR_ausgeben:
ldi w,0b11111111
out DDRA,w
pop w ; MCUSR holen (im Loader
gesichert)
rol w ; LEDs sind an A1 bis A5
(nichtA0-)
out PORTA,w
WDT_off: ; WDR ausschalten
(nachBootloader9
WDR
; Clear WDRF in MCUSR
; ldi w, (0<<WDRF)
; out MCUSR, w
; Write logical one to WDCE and
WDE
; Keep old prescaler setting to
prevent unintentional Watchdog Reset
; in w, WDTCSR
; ori w, (1<<WDCE)|(1<<WDE)
; out WDTCSR, w
; Turn off WDT
; ldi w, (0<<WDE)
; out WDTCSR, w
port_tog:
cbi Porta,5
nop
nop
sbi Porta,5
rjmp PC-4
LED 1-4 zeigen dann den MCU Status an. LED 5 toggelt wenn er fertig ist.
Folgendes verhalten:
1. ext Reset erzeugt -> Loader wird sofort verlassen, ist richtig
2. Brown_OUT_Reset -> Loader wird angesprungen, ist falsch
3. WDR_Reset erzeugt -> Loader wird angesprungen, ist Richtig
Danke Willi
Datum:
Habs gefunden, ist ein logischer Fehler
andi paral, (1 << WDRF) | (1 << EXTRF) | (1 << PORF)
breq bm1
|
ist natürlich falsch, ändere es so ab
andi paral, (1 << WDRF) | (1 << EXTRF) | (1 << PORF) | (1 << BORF)
breq bm1
|
Noch besser ist es so
tst paral
breq bm1
|
Da es einige AVRs gibt die noch andere Reset Quellen haben als obige, zb. USB-AVRs haben noch USBRF oder es gibt noch den JTAG-Reset JTRF oder OCDRF = Onchip Debug Reset. Allerdings baut die letzte Methode darauf das undefinierte Bits im MCUCSR auf 0 stehen. Gruß Hagen
Datum:
Ich habe das einmal so abgeändert, kannst ja einmal schauen, ob das mit
dem rest von Deinem Code passt:
.if UseBootMode != 0
andi paral, (1 << WDRF) | (1 << BORF) | (1 << EXTRF) | (1 << PORF)
breq bm1
.ifdef BootModeFlag
sbrs paral,BootModeFlag
.endif
Jetzt wird Brown_OUT nur noch bei Mode 0 mit berücksichtigt. Mein Mode 3
läuft so auch.
Willi
Datum:
Hast es schon gefunden, Danke. Ist ein super Bootloader, den Du da geschaffen hast. Danke nocheinmal Willi
Datum:
Angehängte Dateien:@Willi: ändere es so ab:
.if UseBootMode .ifdef BootModeFlag sbrc paral, BootModeFlag .endif cpse paral, zerol jmpapp .endif ; .if UseBootMode |
Für alle anderen die korregierte Version im Attachment. Gruß Hagen
Datum:
welches Letzte ? Hast du mal das neue ZIP getestet ? Sollte eigentlich funktionieren, es sei denn es ist tatsächlich so das undefiniert Bits im MCUCSR auf 1 stehen. Gruß Hagen
Datum:
Ja das meine ich, es reicht schon das wie vorgeschlagen zu ersetzen:
"ändere es so ab:.if UseBootMode
.ifdef BootModeFlag
sbrc paral, BootModeFlag
.endif
cpse paral, zerol
jmpapp
.endif ; .if UseBootMode"
Eigentlich sind nur die Vier Bits wie oben im MCUSR vorhanden, aber wer
weiß was die nicht benutzten so machen. Das mit dem BORF geht doch auch.
Guten Morgen Willi
Datum:
Angehängte Dateien:> Guten Morgen Willi
jo man sollte am Sonntag Abend nicht an 4 Projekten gleichzeitig basteln
(Fernsehen im Hintergrund, Unterhaltung mit Freundin, Arbeit am
Bootloader und meine DSSS Simulation). Habs wieder geändert auf deine
Version, hat den Vorteil das es Bulletproof ist und wenn man auf den
Spezial-AVRs deren Resetquellen benutzen möchte ist die Änderung im
Source trivial. Dachte halt im Übereifer das man noch par Bytes Code
einsparen könnte, falsch gedacht.
Gruß Hagen
Datum:
>Eigentlich sind nur die Vier Bits wie oben im MCUSR vorhanden, aber wer >weiß was die nicht benutzten so machen. Das mit dem BORF geht doch auch. Atmel ;) Aber der Source im letzten ZIP maskiert nur die bekannten Bits aus, alle unbekanten werden auf 0 ausmaskiert. Somit ist das jetzt sauber, aber das mit dem tst paral denke ich hätte auch funktioniert. Der Unterschied ist eben das mit dem andi paral, (1 << WDRF) | (1 << EXTRF) | (1 << PORF) | (1 << BORF) wirklich nur auf diese Resetquellen getriggert wird. Dh. im Klartext, lösst auf einem USB-AVR der USB Reset aus so wird der Bootloader durch einen solchen Reset gestartet u.u.A. einem direkten RJMP. Bei der Methode mit tst paral wird der Bootloader aber durch einen USB-Reset nicht gestartet. Möchte man dieses Verhalten erreichen so muß jetzt der Source manuell geändert werden und in die andi Maskierung noch (1 << USBRF) hinzugefügt werden, gleiches gilt für JTRF und OCDRF, die auch noch überschneidend definiert sind. Andererseits gibts im MCUCSR noch ungenutzte Bits und die könnten da sie undefiniert sind auch auf 1 stehen. Ohne Ausmaskierung dieser Bits würde der Code dann auch nicht mehr das machen was er sollte. Lange Rede kurzer Sinn: solche Fragen, nach der universellsten Lösung, beschäftigen einen Programierer der ein Projekt pflegt das auf möglichst allen AVRs laufen soll. Gruß Hagen
Datum:
Hallo Hagen, Danke noch einmal, schläfst Du überhaupt, einmal? Gruß Willi
Datum:
Hi Hagen, erstmal danke für die saubere Arbeit! Habe festgestellt, dass die Implementierung des Bootloaders per ISP mit dem neuen AVR-Studio (4.16) nicht mehr funktioniert (mega644P). Ist dir das auch schon aufgefallen? Mit 4.15 (letzte Version) gibt's keine Probleme. [OT] Übrigens scheint's den mega644 bei Reichelt nicht mehr zu geben, habe unter dessen Bestellnummer den mega644P geliefert bekommen. [/OT]
Datum:
Angehängte Dateien:Version 6.0 Das von Thilo angesprochene Problem ist ein Fehler im neusten AVRStudio 4.16. Alle ASM Files die nicht bei .org 0 anfangen werden durch die Programmiersoftware des AVRStudio nicht korrekt aus dem HEX File ausgelesen. Soweit meine Vermutung zu diesem Problem. In der AVRootloader aus dem Attachment habe ich mit einem kleinen Fix dieses Problem behoben (AVRootloader.inc). Es werden einfach zwei Bytes 0xFF an Addresse 0 des FLASHs geschrieben. Beruhigend zu wissen das nicht nur mir solche dämlichen Fehler unterlaufen ;) Dies ist aber nicht der Grund gleich eine komplett neue Version zu bauen. Es wurden einige Umbauten am Source getätigt mit Sicht auf den XMega. Das Problem mit dem UseBootMode und den verschienden Reset Sourcen der unterschiedlichen AVRs wurde vollständig gelösst. Neu ist das man mit UseBootMode=4 nun auch auf einen USB Reset bei USB AVRs triggern kann. Zu beachten ist aber das einige dieser AVRs und deren Includes in \AVR Assembler2\ nicht vollständig, eg. korrrekt definiert sind. Ein weiterer Fehler im neuen AVR Studio den ich entdecken durfte. Falls also beim Kompilieren von AVRootloader.asm für USB AVRs eine Meldung kommt das USBRF nicht definiert wäre so sollte man erstmal das entsprechende Include von Atmel mit dessen Datenblättern vergleichen und eventuell das Flag USBRF von Hand deklarieren. Desweiteren wurde natürlich die AVRootloader.dev Datei und das ASM um alle neu im AVRStudio 4.16 hinzugekommenen AVRs aktualisiert. Die Reihenfolge der einzelnen Codebestandteile des Bootloader wurde geändert. Der eigentiche Bootloader Code beginnt bei BootStart und endet nach BootKey. Die kompletten Funktionen aus Special.inc samt der RJMP Vektortabelle bei FLASHEND wurde an das Ende des FLASHs verschoben. Neu zu diesen Funktionen ist die Funktion "dospm" verschoben wurden. Dies alles dient zur Vorbereitung der Möglichkeit den Bootloader selber updaten zu können. Im Minimalfall setzt man UseSpecialBootVect=1. In diesem Moment wird in den letzten 16 Bytes des FLASHs die dospm Funktion und eine 2 Entry Sprungtabelle kompiliert. Über die so eingebaute "dospm" Funktion kann die Anwendung den SPM Opcode ausführen und über diesen den Bootloader selber updaten. Natürlich müssen die Lockbits entsprechend so gesetzt sein das die Bootsection per SPM geschrieben werden darf. Bei dieser Konfiguraton verbraucht man den geringsten FLASH und hat denoch alle Möglichkeiten offen. Oder man bindet die komfortableren Funktionen writeflash und readflash mit ein. Sollte per Fuses das Lesen der Bootloader Section per LPM deaktiviert worden sein so muß readflash sowieso mit eingelinkt werden. Dazu UseSpecialRead=1 setzen. Mit der Funktion write_flash(), UseSpecialWrite=1 und UseSpecialWriteBoot=1 hat man eine wesentlch komfortablere Methode um den FLASH zu schreiben. Einfach x Bytes im SRAM puffern und per write_flash() an die Zieladdresse schreiben lassen. Diese Funktion kümmert sich dann autom. um das Page Aligment/Boundary, IRQs und EEPROM Writes usw. Geht man über die einfachere "dospm" Funktion muß man sich natürlich um alles selber kümmern, spart aber bischen was an FLASH. Auf ATTinys ist das alles natürlich unnötig da dort der SPM immer ausführbar ist (SELFPRG Fuse). Gruß Hagen
Datum:
Hallo Hagen, wirklich toller Bootloader den du programmiert hast. Mir ist dennoch eine Kleinigkeit im Windows-Programm, zum Flashen der Firmware, aufgefallen. Sobald man im EEPROM-Editor die Zeichen etwas schneller tippt, scheint dieses einzufrieren. Dann lassen sich keine Zeichen mehr bearbeitet. Abhilfe schafft dann, die Verbindung zum Gerät zu unterbrechen und anschließend wieder aufzubauen. Danach ist das EEPROM-Editor-Fenster wieder bedienbar. Weiterhin noch viel Erfolg mit dem großartigen Projekt "Bootloader" Micha
Datum:
@Micha, danke, und der HEX Editor ist ein 3'rd Party Produkt, muß ich wohl mal in deren Sourcen stöbern gehen. Gruß Hagen
Datum:
wow, coole Sache hagen. Deine ausführlichen Beiträge sind immer wieder ein Genuß. cu chris
Datum:
@Micha, konnte dein Problem nicht reproduzieren. Ich vermute du hast 1. die Baudrate sehr gering eingestellt und 2. in AVRootloader.ini [Timeouts] KeepAlive sehr klein eingestellt. Der Wert in KeepAlive sollte zwischen 250 bis 1000 ms betragen. Er bedeutet das alle KeepAlive Millisekunden die Software im Hintergrund ein Packet an den AVR sendet. Wenn man also verbunden ist entsteht so eine periodische Hintergrund Aktivität die je nach Baudrate schnell oder langsam abgearbeitet wird. Falls du in deinem AVR Bootloader UseWDT=0 gesetzt hast dann kannst du KeepAlive auch weitaus höher setzen. Sollte UseWDT=1 sein so sollte KeepAlive nicht 1000 ms überscheiten da ja der WDT im AVR spätestens all 2 Sekunden zurückgesetzt werden muß. Gruß Hagen
Datum:
@Hagen Danke für deine Tests und die ausführliche Antwort. Ich betreibe den Bootloader tatsächlich mit einer sehr geringen Baudrate von 1200Baud/s. Der KeepAlive Timeout steht bei 250ms. Ich werde morgen probieren ob eine Erhöhung des Timeout eine Verbesserung mit sich bringt. Den Watchdog hab ich im Code manuell auf 4 Sekunden erhöht, damit dürfte ich noch genug Luft für den KeepAlive Timeout haben. MfG Micha
Datum:
Hallo Hagen Versuch gerade deinen Bootloader auf einem mega32m1 mit externen clock von 14,758 Mhz zu bekommen. Der Chip meldet sich einfach nicht. Habe das ganze auf einem mega16 mit internen clock von 8 Mhz probiert. Da läuft alles wunderbar. Das Programm kann ich für beide avr compilieren. keine Fehler. Kannst du mir bitte weiterhelfen. Vielen Dank im Voraus.
Datum:
@Alex: > Kannst du mir bitte weiterhelfen. Und wie ? Übliche Verdächtige: 1.) BootCodeSize nicht gesetzt, also erstmal auf 0 setzen, neu kompilieren und das was im Messagewindow bei cseg [used] im AVRStudio steht nach BootCodeSize schreiben, neu kompilieren und nicht stören daran das in der neusten Version nun bei cseg [used] ein Wert der um +2 Bytes größer ist drinnen steht (AVRStudio 4.16 Bugfix) 2.) Fuses und Lockbits richtig ? Wenn du AVRootloader.ASM kompilierst schaue in das Messagewindow vom AVRStudio was dort steht wie du die Fuses setzen sollst. Exakt so im AVRStudio auch einstellen (BOOTSZ Fuses) Clock-Fuses korrekt ? CKDIV8 Fuse ? 3.) geht die Kommunikation ? also erstmal RX-TX am Dongle verbinden und schauen das AVRootloader.exe bei [Timeouts] Options=1 eine 1-Wire Verbindung erkennt. Im Protokoll Fenster siehst du das einmal das empfangen wird was gesendet wurde. Mit diesem Test hat man also die Kommunikation bis nach dem Dongle (MAX232, FTDI usw.) getestet. Bei 1-Wire RS232 Dongle aus 1-Wire.png ist das natürlich inklusive. 4.) nun in AVRootloader.asm UseRS485=1 setzen und DE_PORT/DE_PIN auf einen Pin an dem zb. eine LED nach VCC angeschlossen wurde, oder UseRS485Invert=1 setzen invertiert die Logik. Nun solltes du jedesmal wenn der Bootloader selber sendet die LED aufleuchten sehen (evntl. Baudrate geringer setzen) 5.) BootSign: ist identisch zum BootSign im AVRRootloader.exe ? 6.) UseAutoBaud=1 gesetzt ? 7.) BootDelay nicht zu knapp bemessen ? 8.) überschneiden sich RX/TX Pin/PORT mit dem ISP/DebugWire ? Wenn ja könnte sich beides gegenseitig stören. 9.) eigene Hardware überprüfen, VCC stabil ? 10.) Schwingt der Quarz ? Falls irgendwas von diesen Tipps dein Problem lösen sollte bitte teile es mir mit, so kann ich bei ähnlichen Anfraen gezielter reagieren. Gruß Hagen
Datum:
Hallo Hagen. Danke für die prompte Antwort. Habe die aktuellste Version von dir genommen und da ging es auf anhieb. Finde es ein bischen blöd im Forum die ganzen Beiträge durchzuschauen um die aktuellste Version herauszufinden. Aber dein Bootloader ist echt gut. Vielen vielen Dank. MFG Alex
Datum:
Hallo zusammen, zunächst einmal SUPER, daß es mit diesem Bootloader prinzipiell extrem einfach ist eine neue Software auch in das Pollin AVR-Net-I/O-Board zu bekommen. Endlich kann ich meinen ISP-Programmer beiseite legen. Soweit so gut. Konkret habe ich vor die EtherSex-Firmware mittels AVRootloader aufzuspielen. Mit einem über die Webseite vom ethersex erstellten image (Größe 72k) klappt das auch bestens, jedoch beinhaltet die so erstellte Version außer einer HTML-Seite nichts - und das reicht mir verständlicherweise nicht aus. Daher habe ich mir mittels GIT das gesamte respository auf den Linux-Rechner geladen. Compilieren klappt auch bestens, jedoch läßt sich das erstellte HEX-File (trotz 55K Größe) partout nicht mittels AVRootloader auf den ATMega32 aufspielen. Ich bekomme immer folgende Fehlermeldung:
19.03.09-10:02:34-640 > Program... 19.03.09-10:02:34-656 > Error: Invalid HEX file "ethersex.hex" |
Diese Fehlermeldung ist mir leider nicht aussagekräftig genug und hilft mir nicht wirklich weiter. Hier noch der Output vom Compilieren des ethersex:
=============================== ethersex compiled for: atmega32 size is: Program: 20126 bytes (.text + .data) Data: 1124 bytes (.data + .bss) Imagesize: 20126 bytes (61.41%) Available flash: 32768 bytes (atmega32) =============================== |
Platz sollte im mega32 noch genügend vorhanden sein. Frage daher: Woran liegt´s?
Datum:
Hi, vielleicht sind es einfach die Zeichen am Zeilenende ? Mal mit einem Editor von UNIX nach Windows wandeln der Hex Datei ? zB. mit Notepad++.... Gruß Sven
Datum:
Zeige mal das HEX File. Dieser Fehler bedeutet exakt das was er aussagt: das HEX File ist ungültig und fehlerhaft. Entweder ist es kein gültiges Intel HEX Format, oder es enthält Records die nicht im Standard definiert sind, oder in den einzlenen Zeilen mit den Daten sind Sonderzeichen drinnen also kein HEX, oder die CRC über eine Zeile stimmt nicht. Das ich das jetzt nicht genauer in der Fehlermeldung aufgechlüsselt habe möge man mir verzeihen, aber wann kommt solch ein Fehler schon vor. Gruß Hagen
Datum:
@Sven: >vielleicht sind es einfach die Zeichen am Zeilenende ? >Mal mit einem Editor von UNIX nach Windows wandeln der Hex Datei ? Nee das kann es nicht sein. Grundsätzlich baue ich solche Parser immer so das es Sonderzeichen wo Sonderzeichen möglich sind auch ignoriert. Dh. an irgendeiner Stelle, wo laut Standard klar definiert wurde was da zu stehen hat, steht in seinem HEX File irgendwas was da nicht hingehört. Gruß Hagen
Datum:
@Alex: >Finde es ein bischen blöd im Forum die ganzen Beiträge durchzuschauen um >die aktuellste Version herauszufinden. Ja ich weiß und ich hatte auch schonmal angedacht im Wiki ein Artikel zu bauen. Aber die liebe Zeit reicht nicht aus. So bleibt nur ein Tipp von mir: lese den Thread von Unten nach Oben, dann wirst du mit Sicherheit die aktuellste Version als erstes finden. Denn ich verspreche dir das ich chronologisch betrachtet nicht in der Lage bin eine zukünftige Version schon in der Vergangenheit fertig zu stellen ;) Gruß Hagen
Datum:
Hallo Hagen, danke für die schnelen Rückantworten (auch Dank an Sven) Hagen Re wrote: > Dh. an irgendeiner Stelle, wo laut Standard klar definiert wurde was da > zu stehen hat, steht in seinem HEX File irgendwas was da nicht > hingehört. Feature-Request: fehlerhafte Stelle anzeigen und genaueren Grund angeben Da ich die Original Debian-Pakete OHNE jegwelche Änderungen verwende kann ich mir eigentlich nicht vorstellen, daß der Compiler hier Murks macht. Aber vielleicht hilft dennoch folgender Hinweis: In einer funktionierenden Datei endet diese beispielsweise mit:
:1066A000B1F6D363BA6B8B95869F12841FEB668617 :1066B0007FF6B6B56AB249D283E3D1713A62B66663 :0C66C000C8E77F006C0B23456810000049 :00000001FF |
Eine nichtfunktionierende Datei sieht am Ende hingegen so aus:
:104E2000CE010E94DE2708C0E114F10419F0F70159 :104E3000C1937F019A9449F7E114F104A9F0F701B5 :104E4000108 |
gezeigt sind jeweils die letzten Zeilen. EVentuell hilft das ja noch zr Fehlereingrenzung
Datum:
Jo das hilft sehr, deine fehlerhafte HEX Datei wurde abgeschnitten, es
fehlt der Rest.
Letzte Zeile :104E4000108
Es folgen 0x10=16 Bytes die an Adresse 0x4e40 gespeichert werden sollen
da Recordtyp 0x00. Danach folgen die Datenbytes 0x10 und 0x8? aber wo
ist der Rest der angeblichen 16 Bytes und deren CRC ?
>Feature-Request: fehlerhafte Stelle anzeigen und genaueren Grund angeben
Jo das wäre sinnvoll aber aus der Abwägung diverser Zeitgründe heraus
nicht sofort.
Gruß Hagen
Datum:
>>Feature-Request: fehlerhafte Stelle anzeigen und genaueren Grund angeben > > Jo das wäre sinnvoll aber aus der Abwägung diverser Zeitgründe heraus > nicht sofort. OK, das passt schon. Dann werde ich in der Zwischenzeit mal in Erfahrung bringen, warum das Paket der aktuellen DEBIAN-Installation (lenny, 5.0) den Murks macht oder ob es das FTP-Programm zwischen Linux und Windows-Rechner war. Ich werde berichten.
Datum:
Hagen Re wrote:
> ...deine fehlerhafte HEX Datei wurde abgeschnitten, es fehlt der Rest.
In der Tat, auf dem Linux-System ist die Datei korrekt, packe ich sie
mit GZIP und transferiere sie dann und entpacke sie anschließend auf dem
WIndoff-System wieder ist sie auch auf diesem korrekt. Lediglich beim
direkten Transfer wird die Datei immer an der selben Stelle
abgeschnitten. Selbst wenn ich als Transferart BINARY einstelle passiert
dies. Nun ja, ganz herzlichen Dank für den Hinweis, aber da hätte ich im
Traum nicht dran gedacht, ist mir auch noch nie passiert. Aber nun
behelfe ich mir halt immer mit vorangegangenem GZIP und gut ist.
Nochmals Danke!
Den Feature-Request lasse ich natürlich trotzdem bestehen. :-)
Datum:
Hello all, I´m sorry, I dont know German language, my apologies. Is there a way to get the email of Mr. Hagen, please, in order to contact him? I would like to know more about the bootloader. Best regards, Luiz luiz,catalan at gmail.com
Datum:
Sorry again, wrong email. the correct one is luiz.catalan at gmail.com
Datum:
Hi Luiz, you can register here: http://www.mikrocontroller.net/user/register If you are registered and logged in, you can send him a mail by clicking the link behind his name.
Datum:
Angehängte Dateien:Hallo, ich versuche mit dem Bootloader einen Mega88 über einen FTDI FT232R zu flashen, leider ohne Erfolg. Die "üblichen Verdächtigen" habe ich schon durchgearbeitet. Problem: Der Bootloader funktioniert mit MAX232, aber nicht mit dem FT232R Der AVRootloader findet zwar das Device korrekt, aber kann's nicht Flashen. Immer ähnliche Fehler:
03.04.09-19:45:35-250 > Cmd.SetBuffer.WriteData() ICOM: write error. |
Ab 115200baud kommt ab Version 4 auch keine Verbindung mehr zustande. Es klappt auch, den 1-Wire-Modus wird zu erkennen, wenn ich RXD und TXD verbinde. Mit H-Term kann ich über den FT232R Daten zum µC schicken und bekomme auch Welche zurück. An der Schaltung kann es also eigentlich nicht liegen, das
.equ UseUartInvert = 1 |
ist auch korrekt, denn beim MAX ist es auch nötig, und da funktioniert es ja auch. Bin ratlos! Habe schon verschiedene Quarze, Einstellungen ausprobiert, immer der gleiche Fehler. Wäre sehr dankbar für jegliche Ratschläge!! Gruß Jan
Datum:
>wie berechnet sich auch F_CPU/x die 250ms?? Was für ein Teiler ist für >18,432MHz empfehlenswert? XTAL/x, möchtest du 1 Sekunde / 4 = 250 Millisekunden warten so setze BootDelay = XTAL/4 da 250ms = 1 Sekunde / 4 ist. Weist du wieviele Takte eine MCU mit XTAL = 18,432MHz benötigt für 1 Sekunde ? Ich denke das wird die Lampe zum leuchten zu bringen ;) Die schlußendliche Wartezeit in BootDelay ist eher eine Funktion der eingestellten Baudrate un damit immer ein Kompromiß. Je höher die Baudrate und das BootDelay desto öfter kann die PC Software einen kompletten Connectionstring wiederholt aussenden, ergo desto wahrscheinlicher ein gültiger Verbindungsaufbau. Je geringer die benutzte Baudrate und je kürzer das BootDelay desto weniger Connectiongsrings kann die PC Software senden. Nun zu deinem eigentlichen Problem: Öffne AVRootloader.ini und setze in Sektion [Timeouts] das Topic "Base=" mal auf 100. Statt wie im Standard 50ms auf 100ms. Dieser Timeoutwert ist bei Treibern wie dem des FTDI, virtueller COM Port, manchmal sehr entscheidend. Die VCOM-Treiber sind in ihrem Timing angewiesen auf das Gesamttiming der CPU, eg. Tasksheduler und laufende Task im Gesamtcontext des Betriebsystemes. Benutze bitte die aktuellste Version, diese ist zZ. Version 6. Gruß Hagen
Datum:
Ansonsten scheint es bei dir irgndwelche sporadischen Timing-/Kommunikationsfehler zu geben. Die fehlermeldungen sind also nicht speziell auf ein Modul, eg. eine spezielle Aktion/Kommando wie Erase, Program, FLASH oder EEPROM etc.pp. bezogen sondern auf das Timing oder Datenübertragung. Deswegen kann ich dir nur den Tipp geben mal den Timeout.Base Wert in der INI zu erhöhen. Ansonsten mal schauen ob deine Spannungsversorgung des FTDI stabil ist. Ich weiß ja nicht ob dein FTDI Modul ein fertig gekauftes oder selber aufgebautes ist, bei Selbstbau stellt sich die Frage ob die USB Anbindung ordentlich terminiert ist. Mit BootDelay=XTAL/4 habe ich gute Erfahrungen gemacht. Damit konnte ich in diversen Projekten immer eine Verbindung aufbauen, speziell wenn UseResetDelay=1 eingestellt ist. Also zb. ATTiny45/44/461 mit internem RC-Oszillator und/oder 64MHz PLL Takt oder 20Mhz ext. Quarz bei Baudraten von 4800 bis 112500 oder ATMega162 mit ext. Quarz, alles jeweils in 1/2-Wire mit USB-RS232 Wandler, normaler RS232 mit/ohne MAX Pegelkonverter oder sogar an XPORT TCP/IP-RS232 Wandler bis 256000 Baud oder am USB-RS485 Bus. Hm, also im Grunde in jeder möglichen Konfiguration und bisher in diesem Thread erwähnter Hardware. Gruß Hagen
Datum:
Angehängte Dateien:Hallo Hagen, danke für die schnelle Antwort! Ok, jetzt ist das mit dem Delay und dem Teiler klar - war mir wohl zu einfach, um es zu verstehen :-) Hatte auch schon mal mit den Timings herumprobiert. Mit Basis 100 kommen folgende Fehler, je nach Baud: unter 115200Baud Dieser:
04.04.09-14:42:17-281 > Device connected 04.04.09-14:42:17-281 > Program... 04.04.09-14:42:17-281 > execute compiled data 04.04.09-14:42:17-281 > selected options in compiled file: 04.04.09-14:42:17-281 > - programming FLASH 04.04.09-14:42:17-406 > Cmd.SetBuffer.WriteData() ICOM: write error. 04.04.09-14:42:17-484 > Device disconnected |
und drüber Jener:
04.04.09-14:31:51-234 > Timer released 04.04.09-14:31:51-234 > Program... 04.04.09-14:31:51-234 > execute compiled data 04.04.09-14:31:51-234 > selected options in compiled file: 04.04.09-14:31:51-234 > - programming FLASH 04.04.09-14:31:51-328 > Cmd.SetBuffer.ResCheck(2) Error: 00 operation failed 04.04.09-14:31:51-343 > Timer created |
Leider immer wieder das gleiche, Connecten klappt, Falshen nicht. Gruß, Jan
Datum:
Angehängte Dateien:Hallo, hier mein Schaltplan, wonach ich das Board geroutet, -ätzt und -lötet habe. Bye, Jan
Datum:
... das verbinde ich dann mit einem ca. 100mm langen Flachbandkabel an folgendes Board: http://www.minimexle.de/shop/links.php Schaltplan siehe Bauanleitung MiniMEXLE V2.0 Seite 7 von 35. Bye, Jan
Datum:
Hast du vielleicht einen kommerziellen USB-RS232 Konverter rumliegen ? Falls ja probiere es mal mit dem. Ich denke nämlich das irgendwas mit deinem Aufbau nicht stimmt. Die Fehlermeldungen die du bekommst sind nicht nachvollziehbar und an Stellen bei denen mit funktionierender Datenübertragungen nie irgendwelche Fehler auftreten. Zb. "Cmd.SetBuffer.ResCheck(2) Error: 00 operation failed", der Code 0x00 ist normalerweise garkein Fehlercode, Fehlercodes sind 0xC? kodiert. Dh. an eine Stelle im Code erwartet die PC-Software einen Returncode wie 0x3? oder 0xC? bekommt aber ein falschen Code zurückgemeldet. Das kann nur passieren wenn irgendwas bei der Datenübertragung schief gelaufen ist. Denn es gibt nur zwei Gruppen von gültigen Returncodes, 0x3? die SUCCESS-Codes und 0xC? die ERROR-Codes, kannst du in AVRootloadr.inc nachlesen. Die PC-Software empfängt aber den Wert 0x00 als Returncode und der ist falsch. "Cmd.SetBuffer.WriteData() ICOM: write error." deutet darauf hin das ein Timeout beim Schreiben=Senden von Daten auftrat. Nun ist es aber so das normalerweise niemals Timeouts beim Schreiben passieren da die Treiber ja gepuffert mit einem sehr großen Sendebuffer arbeiten. Dieser Fehler dürfte garnicht auftreten und deutet eher daraufhin das der USB Kanal hardwartechnisch gestört sein könnte. Deshalb meine Frage mit deinem Aufbau. Gruß Hagen
Datum:
Hagen wrote: > Hast du vielleicht einen kommerziellen USB-RS232 Konverter rumliegen ? --> LogiLink USB zu RS232 Adapter und davon weiter mit MAX-Adapterplatine funktioniert, so wie nur mit MAX-Adapter am COM des PC Muss wohl wirklich irgendwie an der FT232R Platine liegen, obwohl die nun wirklich überschaubar ist und für puren Datentransfer in beide Richtungen funktioniert. Habe gerade eine andere Platine fertiggelötet, dort ist ein FT232BL drauf, werd's gleich mal damit probieren, evtl. geht es ja bei dem Layout. Grüße, Jan
Datum:
Hallo, scheinbar liegt es ja an meiner kleinen Adapterplaine. Kann jemand andere Werte für die Kondensatoren vorschlagen, mit denen es erfolgreich funktioniert? (Habe die Werte direkt aus dem Datenblatt von FTDI übernommen.) Schaltplan siehe 4 Beiträge Schaltplan FTDI FT232RL (4 Beiträge zurück nach oben). Danke im Voraus, Jan
Datum:
>--> LogiLink USB zu RS232 Adapter und davon weiter mit >MAX-Adapterplatine funktioniert, so wie nur mit MAX-Adapter am COM des >PC Probiere doch mal den 1-Wire-RS232 Adapter den ich im Bild 1-Wire.png im ZIP beigelegt habe am LogiLink Adapter. Du kannst auch 2-Wire direkt an der RS232-DB9 anschließen, habe ich auch schon so am Laufen. Dazu nur einen 2k7 Widerstand in der TX-Leitung und RX direkt am Pin des AVRs. Bei direktem Anschluß an der DB9 immer UseUartInvert=0 setzen. Gruß Hagen
Datum:
Hi Hagen, nachdem der Thread mittlerweile, in meinen Augen, ein wenig unübersichtlich geworden ist, spricht was dagegen, das ich einen Artikel drüber anlege, anfange? Grüße Wolfgang
Datum:
Nicht im Geringsten, ich wäre dir sogar sehr dankbar da meine Zeit sehr knapp ist. Wenn du aber Fragen haben solltest dann melde dich bei mir per PN damit ich dir eine ausführlichere Antwort geben kann. Ich bin bis jetzt noch nichtmal zur Dokumentation des Protokolles gekommen. Gruß Hagen
Datum:
Habe heute meine andere Platine (USB<->433MHz) mit dem FTDI FT232BL in Betrieb genommen. Da funktioniert der Rootloader 6.0 bestens! Werde bei Gelegenheit mal die Adapterplatine für den FT232R neu Routen, evtl. geht es ja dann. Bye, Jan
Datum:
So, hal mal den Artikel http://www.mikrocontroller.net/articles/AVR-Bootlo... "AVR-Bootloader mit Verschlüsselung von Hagen Re" angelegt und die Historie aus diesem Thread, soweit nachvollziehbar rüber genommen. Jetzt sollte man rangehen und die ganzen Connect-Möglichkeiten (Schaltbläne mal auflisten, bzw. die mittlerweilen vielen Paramter auflisten, erklären.
Datum:
@Jan Spieler > scheinbar liegt es ja an meiner kleinen Adapterplaine. > Kann jemand andere Werte für die Kondensatoren vorschlagen, mit denen es > erfolgreich funktioniert? > (Habe die Werte direkt aus dem Datenblatt von FTDI übernommen.) Hallo Jan ! Mein Aufbau sieht eigentlich genauso aus, auch die Kondensatoren wie im Datenblatt. Was für einen Ferrit nutzt du denn (abgesehen davon das du ein Symbol von ner Diode genommen hast) ? Ich hab bei mir 10 µH ! Meine Kommunikation läuft mittlerweile sehr stabil auf 128.000 Baud. Gruß Stefan PS: Und immer den neuesten Bootloader verwenden ! Kann Wunder bewirken ! :-)
Datum:
Stefan R. wrote: > Was für einen Ferrit nutzt du denn (abgesehen davon das du > ein Symbol von ner Diode genommen hast) ? > Ich hab bei mir 10 µH ! > Meine Kommunikation läuft mittlerweile sehr stabil auf 128.000 Baud. > > Gruß Stefan > PS: Und immer den neuesten Bootloader verwenden ! Kann Wunder bewirken ! > :-) Hallo Stefan, vielen Dank für die Rückmeldung!!! Ich habe bei Pollin folgenden Artikel bestellt:
Perlendrosseln 250 309 |
--> Die Diode fand sich nur grad so am schnellsten als passendes Package (ich weis: schlechter Grund) Leider ist bei Pollin keine Induktivität der Ferritperle angegeben! Habe auch folgendes von Reichelt, kann ja mal die Ferritperle gegen die Spule austauschen (einziges Problem --> SMD statt THT):
SMD-Induktivität, G0805, 10µH Reichelt JCI 2012 10µ |
Erst mal vielen Dank für die Infos, habe auch noch vor, mit dem Oszi die Spannungsversorgungspins des FTDI zu prüfen, ob das Layout evtl. einen schlechten Einfluss hat. Bei meinem FT232B-Board ist eine Massefläche zw. den Daten und VCC Leiterbahnen, beim FT232R-Board nicht. Hab heut leider keine Zeit mehr, aber morgen werd ich das mal prüfen und die Induktivität einlöten. Grüße, Jan
Datum:
> Ich habe bei Pollin folgenden Artikel bestellt: >
Perlendrosseln 250 309 |
> --> Die Diode fand sich nur grad so am schnellsten als passendes Package > (ich weis: schlechter Grund) > Leider ist bei Pollin keine Induktivität der Ferritperle angegeben! > Habe auch folgendes von Reichelt, kann ja mal die Ferritperle gegen die > Spule austauschen (einziges Problem --> SMD statt THT): >
SMD-Induktivität, G0805, 10µH Reichelt JCI 2012 10µ |
Reichelt hat die auch als THT Bauteil: SMCC 10µ > Erst mal vielen Dank für die Infos, > habe auch noch vor, mit dem Oszi die Spannungsversorgungspins des FTDI > zu prüfen, ob das Layout evtl. einen schlechten Einfluss hat. Bei meinem > FT232B-Board ist eine Massefläche zw. den Daten und VCC Leiterbahnen, > beim FT232R-Board nicht. Ich glaub nicht das es am Layout liegt ! Die RX u. TX-Leitungen sind nach meiner erfahrung relativ unempfindlich, außer du hättest irgendwelche Bauteile die enorme EMV abstrahlen ! Gruß Stefan
Datum:
@ All Perlendrossel von Pollin ist nicht für FT232R geeignet!! Es lag an der Perlendrossel von Pollin. Ich habe diese gegen die 10µH-Induktivität getauscht und siehe da, Alles klappt bestens!! Sogar bis 256.000baud!! Danke nochmals für die Hilfe an Hagen und Stefan! Wünsche noch schöne Oster-Tage, Grüße, Jan
Datum:
Hallo Hagen! Ich würde bei mir gerne eine Art Zweites AppVersion einbauen (also eine Zahl die im AVR gespeichert ist und die ich mittels Programm auslesen kann) Auf AVR Seite sehe ich da kein Problem, da ich einfach ne Kopie von AppVersion nehmen kann, aber wie kann ich die aus Delphi heraus abfragen ? Kannst du mir da vielleicht nen Tip geben ? Wie weit ist eigentlich die Funktion um den Bootloader abzudaten ? Funktioniert das schon ? Viele Grüße Stefan
Datum:
Hallo, super Bootloader. Habe mit Tiny13 ein kleines Problem Bekomme beim Versuch des programmieren folgende Fehlermeldung: Error: Can not find RJMP to Main Wo finde ich Beschreibung der Fehlermeldungen? Vielen Dank im Voraus, Grüße Oliver
Datum:
@Stefan, die AppVersion besteht aus 4 bytes, wie eine IP Addresse, und der Wert 255 ist reserviert. Was spricht nun dagegen diese AppVersion als zwei 2 Bytes Versionsnummern zu betrachten ? Aus Delphi heraus mit der AVRootloader.dll meinst du wohl. Das IAVRootloader Interface unterstützt einige Sub-Interfaces. Das wären IAVRootloader.COM: ICOM das Kommunikationsinterface, i.A. zur RS232 des Betriebssystemes, das .Command: ICommand Interface zum Zugriff auf die Lowlevel Kommandoebene eg. Protokoll des Bootloaders und das .Device: IDevice Interface zum Zugriff auf alle Parameter des aktuell connected AVRs. Letzeres ist das was du brauchst. Das IDevice Interface sieht so aus:
IDevice = interface
['{9EC8A92B-F6BB-47F3-A9C9-DF8F4F481F49}']
function Signature: Integer; stdcall;
function Name: WideString; stdcall;
function Info: WideString; stdcall;
function FlashSize: Integer; stdcall;
function AppFlashSize: Integer; stdcall;
function AppVersion: Integer; stdcall;
function AppVersionString: WideString; stdcall;
function EepromSize: Integer; stdcall;
function RamSize: Integer; stdcall;
function RamStartAddress: Integer; stdcall;
function PageSize: Integer; stdcall;
function BufferSize: Integer; stdcall;
function Version: Integer; stdcall;
function UseBootSection: Bool; stdcall;
function RetCode: Byte; stdcall;
function Support: Integer; stdcall;
function XMLFileName: WideString; stdcall;
end;
|
und die Methode .AppVersion: Integer ist das was du suchst. Also mit
if AVRootloader.DoConnect(True) then
try
Version := AVRootloader.Device.AppVersion;
finally
AVRootloader.DoDisconnect;
end;
|
fragst du das ab. Gruß Hagen
Datum:
>Wie weit ist eigentlich die Funktion um den Bootloader abzudaten ? >Funktioniert das schon ? Ja und Nein ;) Ja in dem Sinne das der Assemblerteil das schon voll unterstützt. Er kann je nach Wunsch verschienden Funktionen einbinden über die es mögich ist den Bootloader selber neu zu programmieren. Das hatte ich oben im Thread schonmal beschrieben. Essentiell ist es so gelösst das in der letzten FLASH Page diese Funktionen ausgerichtet sind. Man kann also mit diesen Funktionen alle FLASH Pages bis zum Begin der letzten FLASH Page mit diesen Funktionen auf sichere Weise neu programmieren. Über die Sprungtabelle ganz am Ende des FLASHs kann die eigene Anwendung diese Funktionen aufrufen. Nein in dem Sinne das es noch keine vorgefertigte Anwendung für die AVRs gibt die nun diese Funktionen benutzt um einen neuen Bootloader zu programmieren. Dh. konzeptionell bin ich von Anfang an davon ausgegangen das der Bootloader selber sich nicht selbst updaten kann. Sondern das er erstmal eine Update-Anwednung in den normalen App-FLASH programmiert, diese dann startet und erst diese Anwendung updated den Bootloader. Die letzte FLASH Page aller Botloader wäre dann immer identisch. Dieses Vorgehen hat mehrere Vorteile aus Sicht der Sicherheit und Stabilität. 1.) würde diese Anwendung im aktuellen Gerät keinen Schaden anrichten da sie keinerlei Pins benötigt. 2.) würde diese Anwendung solange gestartet werden wie sie im AVR ist und der neue Bootloader noch nicht programmiert. 3.) würde diese Anendung universell für alle AVRs funktionieren. 4.) das HEX File dieser Anwendung enthält am Ende als Datenbereich im FLASH den neuen Bootloader. 5.) sie würde ein Prüfsummenverfahren benutzen um sicherzustellen das der soeben programmierte Bootloader mit dem in der Anwendung gespeicherten Kopie identisch ist. Die gleiche Prüfsummenlogk kann auch benutzt werden um beim Start der Anwendung zu überpüfen ob der neue Bootloader schon installiert wurde. Extern bräuchte man ein vorkompiliertes HEX File dieser Anwendung. Das landet zusammen mit dem neuen Bootloader HEX in eine kleine EXE die beie HEX Files merged. Diese HEX File könnte dann mit Hilfer der PC-Sowftare in ein kryptographsich geschütztes ACY File umgewandelt werden und man hat somit auch hier wieder den Updateschutzt integriert. Diese Funktion des Zusammenfassens beider HEX Files könnte in die PC-Software integriert werden. So jedenfalls wäre mein Konzept. Allerdings brauche ich es perönlich nunmal garnicht und stehe zur Auffassung das ein Bootloader einmal konfiguriert wird und sich danach nie wieder ändert sobald er im Gerät programmiert wurde. Gruß Hagen
Datum:
Bezw. wo muss ich Sprungadresse zur meinem Programm einfügen. Danke Oliver
Datum:
@Oliver: >Error: Can not find RJMP to Main Lass mich raten, dein Source ist in Assembler programiert und du benutzt bei .org 0 im Source keinen Reset Vektor ? Dh. an der ersten Addresse (0x0000) im Program steht normalerweise immer ein RJMP Main, also ein Sprung zu deiner Hauptroutine des Programmes. Die Addresse 0x0000 wird immer dann angesprungen wenn der AVR gestartet/resetted wurde. Meine PC-Software sucht nun nach diesem RJMP um die Startadresse der Main zu berechnen. Denn bei den Tinys gibt es ja keine eigene Bootloader Section im FLASH und deshalb wird getrickst indem die Software diese RJMP Main in RJMP BootStart patcht. Der Orgiginale Sprung zu Main wird in die 2 Bytes vor BootStart in das HEX File gepatcht. Somit weis der Bootloader später wo er hinspringen muß wenn der die Anwendung starten möchte. Falls meine Vermutung richtig ist so baue mit
.org 0 rjmp Main Main: |
diesen Sprung bitte ein. Ansonsten bliebe noch die Möglichkeit das dein HEX File beschädigt ist. Gruß Hagen
Datum:
Hallo Herr Hagen, danke für die Info,
.org 0 rjmp Main Main: |
Hatte natürlich in meinem ASM Programm keine Sprung am Start Danke Oliver
Datum:
Hallo Hagen ! > die AppVersion besteht aus 4 bytes, wie eine IP Addresse, und der Wert > 255 ist reserviert. Was spricht nun dagegen diese AppVersion als zwei 2 > Bytes Versionsnummern zu betrachten ? Stimmt eigentlich ! Daran hab ich noch garnicht gedacht ! >
> if AVRootloader.DoConnect(True) then
> try
> Version := AVRootloader.Device.AppVersion;
> finally
> AVRootloader.DoDisconnect;
> end;
> |
Das hab ich schon implementiert ! Genauso wie die Neuprogrammierung der AppVersion. >So jedenfalls wäre mein Konzept. Allerdings brauche ich es perönlich >nunmal garnicht und stehe zur Auffassung das ein Bootloader einmal >konfiguriert wird und sich danach nie wieder ändert sobald er im Gerät >programmiert wurde. Hast du eigentlich auch wieder Recht. Ist für mich auch nicht ausschlaggebend. Hat mich nur interressiert, weil du es mal erwähnt hattest. Danke ! Gruß Stefan
Datum:
Hallo an alle, kann mir vielleicht irgendjemand ein paar Informationen geben, wie ich mit der AVRootLoader.dll unter C++ umzugehen habe? In Delphi scheint das ja alles ganz einfach zu sein - einfach den 'Header' unter 'uses' angeben, die nötigen Methoden der IApplication implementieren und fertig. Aber auch nach ausgiebiger Netzrecherche habe ich nicht herausgefunden, wie man selbiges in C++ anzustellen hat. Wie muss ich grundsätzlich vorgehen um diese DLL einzubinden, das IApplication-Interface zu implementieren und letzten Endes ein IAVRootloader Objekt zu erhalten? Für jeden auch noch so kleinen Ansatz einer Hilfestellung wäre ich sehr dankbar :) Gruß Marcel
Datum:
Hi Marcel, im Grunde exakt so wie in Delphi, mit dem Unterschied das diese Interface Unit als C++ Header transliert werden muß. Im einfachsten Falle einen Recordtyp deklarieren. Es müssen nun alle Methoden angefangen bei IUnknown bis zu meinen Interfaces in exakt der gleichen Reihenfolge als procedurale Member, Funktionszeiger, in diesem Record deklariert werden. Ich kenne mich in C++ und seiner Unterstützung für Interfaces nicht aus, aber da diese Form der Interfaces eine unterstützte Methode bei Microsoft Windows Produkten ist, siehe ActiveX,COM,DCOM usw., dürfte das auch vom C++ unterstützt werden. Ich kann dir aber den grundsätzlichen und internen Aufbau, sprich Funktionsweise von solchen Interfaces und deren allozierten Objekten quasi in prozeduraler Sprache erklären. Ein alloziertes interfaced Objekt ist ein Zeiger auf einen Record. Dieser Speicherbereich enthält als erstes Member einen Zeiger auf die VMT-> Virtual Method Table, also wiederum einen Record in dem alle Methoden als Zeiger eingetragen sind. Jede dieser Methoden wird einen impliziten unsichtbaren 1. Parameter erwarten, nämlich Self oder This, der Zeiger auf diesen Record = alloziertes Objekt. Nach dem VMT zeiger kommen schon private Member, quasi Objekt/Klassenbezogene Datenfelder. Das ist quasi schon der ganze Trick der sich OOP nennt. Entscheidend ist das der Compiler das als "Sprachfeature" uterstützt und nun zb. diesen impliziten Parameter Self/This einer Objektmethode unsichtbar macht, das er bei Interfaces abgeleitet von IUnknown automatisch die Stanardmethoden ._AddRef und ._Release aufruft um eine Referenzzählung/Lebenszeitzähler/Garbage Collection und wie das alles bennant wird, machen zu können. Und als dritter wesentlicher Punkt wird der Compiler eine Unterstützung von Typcast solcher Objekte implementieren indem er transparent und unsichtbar für den Entwickler die Methode ._QueryInterface() eines Objektes aufruft. Nungut in Delphi/PASCAL sähe also ein manuell erzeugtes IUnknown Interface/Objekt so aus:
type
PMyObj = ^TMyObj;
PMyVMT = ^TMyVMT;
TMyVMT = packed record
QueryInterface: function(Self: PMyObj; const IID: TGUID; out Obj): hResult; stdcall;
AddRef: function(Self: PMyObj): Integer; stdcall;
Release: function(Self: PMyObj): Integer; stdcall;
end;
TMyObj = packed record
VMT: PMyVMT;
RefCounter: Integer;
end;
function QueryInterface(): HResult;
const
E_NOINTERFACE = HResult($80004002);
begin
Result := E_NOINTERFACE;
end;
function AddRef(): Integer;
begin
InterlockedIncrement(Self.RefCount);
Result := Self.RefCount;
end;
function Release(): Integer;
begin
InterlockedDecrement(Self.RefCount);
Result := Self.RefCount;
if Result <= 0 then
FreeMem(Self);
end;
const
MyVMT: TMyVMT = (@QueryInterface, @AddRef, @Release);
procedure Test;
var
MyObj: PMyObj;
begin
MyObj := AllocMem(SizeOf(TMyObj));
MyObj.VMT := @MyVMT;
MyObj.RefCount := 0;
MyObj.VMT.AddRef(MyObj);
MyObj.VMT.Release(MyObj);
end;
|
Wie du siehst so schwierig ist das Konzept OOP als Umsetzung in unsere Programmiersprachen garnicht. Da meine DLL schon den ganzen Quatsch mit der Allozierung/Freigabe usw. selber macht brauchts du eigentlich nur den richtigen Recordtyp für deren VMTs zu deklarieren und musst dann den Zeiger auf das Objekt, ergo IAVRootloader usw. alle den Methoden die du aufrufen möchtest als ersten Param übergeben. Aber das wäre der manuelle Weg und C++ sollte eigentlich von Hause aus Interfaces unterstützen. Schau auch mal hier rein dort habe ich ein anderes Beispiel gepostet: http://www.delphipraxis.net/topic7357_waitcursor.h... In diesem Thread und folgende beschreibe ich wie und warum ich solche Interfaces in meinem DEC Math benutzt habe: http://www.delphipraxis.net/topic14699,0,asc,77.html Du könntest also auch den manuellen prozeduralen Weg gehen und damit auf die C++ Sprachfeatures für die Unterstützung von Objketen und deren Interfaces ganz verzichten. Leider kenne ich mich in diesem Punkt eben mit C++ nicht praktisch konkret aus und würde hier auch PASCAL/JAVA oder sogar moderen BASIC Dialekte dem C++ vorziehen. Gruß Hagen
Datum:
Übrigens findet man eine Menge im Netz zu C++ und Interfaces, zb. hier http://www.learncpp.com/cpp-tutorial/126-pure-virt... ab Abschnitt "Interface-Classes". Du musst halt nur darauf achten das die Interfaces in meiner DLL schon abgeleitet von IUnknown (IInterface in Delphi) sind und damit die 3 vererbten Methoden .QueryInterface(), ._AddRef() und ._Release() nicht vergessen. Gruß Hagen
Datum:
Hallo Hagen, ich versuche einen ATmega128 per Bootloader(V6) zu flashen. Das funktioniert immer genau 1 mal, danach kommt keine Verbindung zum AVR mehr zustande. Also wird vermutlich der Bootloader überschrieben. Habe jetzt alle möglichen Lockbit-Kombinationen getestet, der Bootloader wird trotzdem wohl jedesmal überschrieben. Habe die Lockbits nach einem früheren Beispiel mit einem AtMega8535 programmiert = gleiches Ergebnis. Also LB = disabled,BLB0=SPM prohibited in App.Sektion,BLB1=No lock on SPM and LPM.(andere Kombinationen im Bootbereich auch erfolglos getestet) Bootflashsize and Bootreset sollten passen. Irgendwie sehe ich den Baum vor lauten Wäldern nicht. Gruß bandgap
Datum:
BOOTSZ Fuses nicht gesetzt. Dh. du hast die Boot Section nicht aktiviert was dazu führt das der Bootloader nicht per RESET angesprungen wird. Stattdessen startet der AVR bei Adresse 0x0000 und da ab diesen Speicherzellen bis zum Bootloadercode alles der Opcode 0xFFFF steht, gleich wie NOP, läuft der AVR in den Bootloader rein. Aber sobald der Bootloader eine Anwendung geflasht hat wird er selber niemehr aufgerufen es sei denn deine Anwendung macht dies. Dh. setze deine BOOTSZ Fuses richtig, aktiviere damit die Bootloader Section im FLASH damit der Bootloader beim RESET auch gestartet wird, dann klappt es auch und du hast Zeit die Datenblätter im Bereich "Memory-Progarmming" nochmals zu lesen ;) Gruß Hagen
Datum:
Hallo Hagen, vielen Dank für die Hinweise. Der Fehler war in den Einstellungen der PC-Software. Connect-Timeout war auf 0, der Verbindungsaufbau wurde einfach zu schnell abgebrochen. Hab ich jetzt auf 500ms geändert, funktioniert nun alles bestens. Gruß bandgap
Datum:
Wenn der Connect-Timeout <= 0 ist wird stattdessen der Wert in Base benutzt. Ein guter Wert für Base ist 50 Millisekunden. Aber diese Timeouts sind keine direkte Erklärung für das Verhalten bei dir. Denn der Verbindungsaufbau erfolgt immer von PC-Seite und wenn diese einen Versuch startet dann im Normalfalle ohne zeitliches Ende, also nur durch manuellen Eingriff des Benutzers wird dieser dann abgebrochen. Ich kenne deine Konfiguration des Bootloaders leider nicht aber jenachdem wie dieser konfiguriert ist, zb. UseAutoBaud=0 oder BootDelay sehr klein, müssen stiktere Timings eingehalten werden. Ein Überschreiben des Bootloaders ist eigentlich nicht möglich es sei denn du hast die Spezialfunktionen so aktiviert und nutzt diese auch aus deiner Anwendung heraus und überscheibst den Bootloader absichtlich. Gruß Hagen
Datum:
>Hab ich jetzt auf 500ms geändert, funktioniert nun alles bestens.
das bedeutet die PC-Software wartet jetzt 500ms auf eine Antwort vom
Bootloader. Entweder arbeitest du mit einer extrem geringen Baudrate
oder es ist noch irgendwas an der Kommunikation nicht sauber und stabil.
Normalerweise wird man im Connect Timeout einen Wert kleiner Base, also
so 10 oder 20 Milisekunden vorgeben damit man schneller einen Scan über
alle COM Port im AUTO Modus machen kann. Dh. diesee Einstellung ist
dafür gedacht noch schneller statt langsammer zu sein.
Ich empfehle dir also UseAutoBaud=1 zu setzen, BootDelay auf XTAL/4 =
250ms, UseResetDelay=1, UseWDT=1, UseBootMode=0. XTAL auf den richtigen
Wert des eingestellten Taktes.
Ein weiterer häufiger Fehler ist es BootCodeSize=0 zu setzen, bzw. nicht
korrekt berechnen zu lassen.
Sollte all dies nicht bei dir der Fall sein, dann kann es nur noch an
einer geringen Baudrate liegen oder eben schlechte Übertragung über die
RS232, sprich HW-Aufbau checken.
Gruß Hagen
Datum:
Hallo Hagen, ich habe die Einstellungen nochmal zurückgeändert nach deinen Empfehlungen: meine Einstellungen: XTAL=7372800 Boot Delay=XTAL/4 UseBootMode=0 UseWDR=1 UseAutobaud=1 UseResetDelay=1 BootCodeSize liegt bei 516Bytes mit UseSRAM=1 RX_TX_Port=E => RS-232 / STK300 Controller Mega128 so kommt nur beim ersten Verbindungsaufbau eine problemlose Verbindung zum Controller zustande.Nach dem flashen des Programms ist ein erneutes Beschreiben des Controllers über den Bootloader nicht mehr möglich. Es kommt keine Verbindung mehr zustande.Die PC-Software versucht über COM1 und COM3(USB-Serial-Port) eine Verbindung zu erstellen bricht dann aber mit :Error:no device found ab. Wenn ich dann den BootDelay auf XTAL/2 hochsetze und den ConnectTimeout auf 500ms so funktioniert der Verbindungsaufbau.(auch bei wiederholtem flashen) Mein erster Verdacht mit dem Überschreiben des Bootloader-Bereichs war eine Schlussfolgerung aus der Tatsache das der erste Verbindungsaufbau immer problemlos ist, wenn dann das erstemal über den Bootloader geflasht wurde aber keine Verbindung mehr zustande kam.(Error:no device found) Grüße bandgap
Datum:
Ok, setze in der PC-Software als erstes mal den COM Port von AUTO auf den Port an dem sich der AVR befindet. Probiere es dann nochmal mit meinen empfohlenen Einstellungen. Möchtest du AUTO benutzen dann verändere statt Connection Timeout den Wert in [System] ConnectTrials auf zb. 6 oder mehr. Er steht jetzt auf 3 und das kann uU. ein ungünstiges Timing im AUTO Modus bedeuten. Wie startest du den Bootloader ? Durch einen RESET ? Gruß Hagen
Datum:
Hallo Haagen, ich habe Heute Deinen Bootloader mal getestet, voll cool, hat auf Anhieb funktioniert :-) Jetzt wollte ich jedoch meinen Atmega8 via 1Wire flashen, und da bekomme ich zwar eine Verbindung. Connection : 1-Wire Device name : ATmega8, ATmega8A Device signature : 1E9307 SRAM size : 1024 Byte EEPROM size : 512 Byte FLASH size : 8192 Byte FLASH size for application : 7680 Byte FLASH pagesize : 64 Byte Bootloader size : 512 Byte Buffersize for data : 984 Byte SRAM start address : 96 Bootloader version : 6 Use bootsection : Yes Versioning supported : No Cryptography supported : No ... doch leider wird diese sofort wieder abgebaut. 04.05.09-23:19:15-218 > Connecting on port COM2... 04.05.09-23:19:15-593 > Switch to 1-Wire mode 04.05.09-23:19:15-593 > Device connected 04.05.09-23:19:16-436 > Device disconnected Als Anschaltung an RS232 habe ich die Schaltung aus dem Bild 1-Wire.png verwendet. UasUartInvert=0, direkt an RS232 das untere Bild ohne Schottky Dioden einfach direkt auf die Schnittstelle. Ich dachte mir, wenn das so einfach funzt brauche ich keinen MAX232 :-) doch nun komme ich irgendwie nicht weiter. PS:Kann es daran liegen das ich im Moment den internen Osczilator verwende? Schöne Grüße Hannes
Datum:
Angehängte Dateien:Hallo Haagen, vielleicht bringt die Logdatei von Portmon (Sysinternals) was Gruß Hannes
Datum:
Hallo Hagen (jetzt auch richtig ;-)) sorry war mein Fehler, hab den Fehler jetzt gefunden! Bei der Umstellung auf 1Wire habe ich vergessen BootCodeSize von 432 auf 430 anzupassen. Kaum macht man's, wie es beschrieben ist, so funzt es auch. Schöne Grüße und nochmals besten Dank für diesen coolen Bootloader. Gruß Hannes
Datum:
Schön das sich das Problem von selbst erledigt hat ;) Denoch kann ich nicht nachvollziehen warum das an der falschen BootCodeSize gelegen haben soll. Hast du irgendeine der UseSecialXXX Funktionen aktviert ? Das wäre für mich jetzt die einzige Erklärung warum es zu Problemen kommen sollte. Da du einen ATmega8 benutzt, der die Bootsections auch unterstützt, berechnet das ASM an Hand des Wertes in BootCodeSize den korrekten Reallocationspunkt, eg. Startadresse des Bootloaders. Nun, beim AVRMega muß der natürlich an einer Grenze alloziert werden die mit einer der programierbaren Bootsections begint. In deinem Falle also die letzten 512 Bytes im FLASH. Ob in BootCodesize nun 432 oder 430 Bytes drinnen steht macht ausschließlich nur dann einen Unterschied wenn man die UseSecialXXX Funktionen aktiviert hat, in deinem Fall. Ich hoffe also das dies der Fall ist ansonsten könnte ich mir nämlich nicht erklären warum das bei dir nicht funktioniert haben sollte. Die Standardvorgehensweise für die Installation des Bootloaders ist folgende: 1.) ASM konfigurieren 2.) BootCodeSize=0 setzen 3.) kompilieren 4.) aus dem AVRStudio Message Window den Wert bei CSEG Used in BootCodeSize setzen 5.) erneut das ASM kompilieren 6.) im Message Window nachschauen welche BOOTSZ Fuses man setzen soll 7.) HEX File in AVR flashen 8.) Fuses entsprechend setzen 9.) AVR mit PC verbinden, je nach Konfiguration 10.) Connect Versuch und Test Anwendung flashen lassen Gruß Hagen
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
Hi Hagen, hab einen ATMEGA32 mit internen Takt , funkt da der bootloader? wie muss ich denn den einstellen?
Datum:
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
Datum:
Angehängte Dateien: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.
Datum:
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
Datum:
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
Datum:
@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
Datum:
>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
Datum:
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.
Datum:
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
Datum:
Hagen Re schrieb:
> Was hast du da für einen COM Port bzw. Betriebsystem ?
hab Xp sp3
Datum:
@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
Datum:
@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
Datum:
@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
Datum:
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
Datum:
Angehängte Dateien:@ 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?
Datum:
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!
Datum:
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?
Datum:
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
Datum:
@Thilo, folge mal Thomas seiner Vermutung, das ist auch meine. Gruß Hagen
Datum:
Ü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
Datum:
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.
Datum:
@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
Datum:
>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.
Datum:
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
Datum:
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.
Datum:
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.
Datum:
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
function TMainForm.OpenCommunication(Index: Integer): ICOM; var PortName: String; begin Result := nil; if AnsiCompareText(Port, 'AUTO') = 0 then begin if Index >= CBPort.Items.Count then begin Output('Error: no Device found', ocError); Exit; end; PortName := CBPort.Items[Index]; try Result := OpenCOM('\\.\' + PortName, Self); except Output(Format('Info: can not open port %s', [PortName]), ocInfo); raise EAbort.Create(''); end; end else begin if Index > 1 then Exit; PortName := Port; try Result := OpenCOM('\\.\' + PortName, Self); except raise Exception.CreateFmt('Error: can not open port %s', [PortName]); end; end; try Result.SetParams(Baudrate); except raise Exception.CreateFmt('Error: can not setup baudrate to %d', [Baudrate]); end; Output('Connecting on port ' + PortName + '...', ocInfo); end; |
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
Datum:
>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
Datum:
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
Datum:
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
Datum:
Ü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
Datum:
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
Datum:
>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
Datum:
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.
Datum:
>..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
Datum:
@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 ?
Datum:
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.
int main(void) { cli(); // read MCUSR saved by bootloader uint8_t lSavedMCUSR = *(uint8_t*)(RAMEND); ... } |
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
Datum:
Mache es so
void init_MCUSR(void) __attribute__((naked)) __attribute__((section(".init5"))); void init_MCUSR(void) { // lese Kopie von MCUCSR gespeichert durch Bootloader vom Stack _MCUCSR = *(uint8_t*)(RAMEND); } |
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
Datum:
Übrigens das CLI() ist nicht notwendig, erst recht nicht wenn du meinen Vorschlag benutzt.
Datum:
Angehängte Dateien:Hi Hagen, habe die Options mal auf 3 gesetzt. Ergebnis siehe Protokollfile.
Datum:
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
Datum:
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).
Datum:
@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
Datum:
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:
void init_MCUSR(void) __attribute__((naked)) __attribute__((section(".init5"))); void init_ports(void) { // read MCUSR saved by bootloader gvaResetFlags = *(uint8_t*)(RAMEND); } |
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.
void __attribute__((naked)) __attribute__((section(".init5"))) init_ports(void) { // read MCUSR saved by bootloader gvaResetFlags = *(uint8_t*)(RAMEND); } |
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.
// Reset cause flag register, saved at startup extern volatile uint8_t gvaResetFlags __attribute__ ((section (".noinit"))); |
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
Datum:
Sorry muß heisen
void init_MCUSR(void) __attribute__((naked)) __attribute__((section(".init5"))); void init_MCUSR(void) { // read MCUSR saved by bootloader gvaResetFlags = *(uint8_t*)(RAMEND); } |
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
Datum:
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
Datum:
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
Datum:
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
Datum:
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:
.if UseSpecialVersion getappversion: ldi zl, byte1(AppVerAddr) ldi zh, byte2(AppVerAddr) ldi r22, byte3(AppVerAddr) xout RAMPZ, r22 lpm r22, z+ lpm r23, z+ lpm r24, z+ lpm r25, z+ ret .endif |
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:
.if UseSpecialWrite || UseSpecialRead || UseSpecialMsg || UseSpecialVersion bjmp getappversion, UseSpecialVersion bjmp getbootmsg, UseSpecialMsg bjmp readflash, UseSpecialRead bjmp writeflash, UseSpecialWrite bjmp dospm, BLS rjmp bootstart .elif UseSpecialBootVect .if BLS rjmp dospm .endif rjmp bootstart .endif |
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
static inline uint32_t get_appversion(void) __attribute__((always_inline)); #define GETVER_VEC FLASHEND -11 uint32_t get_appversion(void) { unit32_t (*proc)(void) = (void*)GETVER_VEC; return proc(); } |
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
Datum:
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.
Datum:
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
Datum:
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
Datum:
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.
Datum:
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
.org BootStart init: ldi r16, 0xFF cli xwdr clr zerol ldi cmdl, byte1(RamEnd) xout SPL, cmdl ;portd pin6 auf low ldi r16, 0b01000000 out DDRD, r16 cbi PORTD, 0b0000000 ; turn on LED ldi r16, 0xFF |
Datum:
.org BootStart init: cli xwdr clr zerol ldi cmdl, byte1(RamEnd) xout SPL, cmdl ;portd pin6 auf low sbi DDRD, PD6 cbi PORTD, PD6 ; PORTD PIN6 auf High sbi PORTD, PD6 |
Register r16 ist benutzt für paral, kannst du an dieser Stelle nutzen, solltest du aber im weiteren Source unterlassen. Gruß Hagen
Datum:
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:
.include "AVRootloader.inc" ;.listmac .list .org BootStart ;Vorher .def temp=r27 ;---------------------------------------------- ir: ldi temp,TCCR2 ldi temp, (1 << WGM21) | (1 << COM20) | (1 << CS20) out TCCR2,temp ;Timer2 Register ldi temp,0x6e ;36Khz einstellen out OCR2,temp sbi DDRD,7 ;-------------------------------------------------------- init: cli xwdr ......usw. |
Datum:
@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
Datum:
Angehängte Dateien: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/Inf... Und die PC-Seite http://www.asurowiki.de/pmwiki/pmwiki.php/Main/Inf... Im Anhang: die Beschaltung der IR-LED.
Datum:
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
Datum:
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
Datum:
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!
Datum:
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
Datum:
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
Datum:
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
Datum:
InitVector = 0x0000 FinitVector = 0x0000 Polynom = 0xA001 Die empfangene CRC einfach mit durch den CRC Algo jagen und es muß 0x0000 rauskommen.
uint16_t crc_update(uint16_t crc; uint8_t data) {
crc ^= data;
for (i=8; i>0; i--) {
if (crc & 1) {
crc >>= 1;
crc ^= poly;
} else {
crc >>= 1
}
}
return crc;
}
|
das ist der vereinfachte code. Gruß Hagen
Datum:
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
Datum:
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
Datum:
@Fabian, sieht korrekt aus. Ich würde es aber so machen:
uint16_t crc16(unt16_t crc, const uint8_t* data, uint16_t length) { uint16_t poly = 0xA001; while (length--) { crc ^= *data++; for (uint8_t i=8; i>0; i--) { if (crc & 1) { crc >>= 1; crc ^= poly; } else { crc >>= 1; } } } return crc; } |
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:
; r25:r24 CRC, r23:r22 data, r21:r20 Length movw ZL, r22 ldi r23, hi8(0xA001) ldi r22, lo8(0xA001) @loop: sbiw r20, 1 brcs @exit ld r0, Z+ eor r24, r0 ldi r19, 8 @crc: lsr r25 ror r24 brcc @skip eor r25,r23 eor r24,r22 @skip: dec r19 brne @crc rjmp @loop @exit: ret |
Gruß Hagen
Datum:
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
Datum:
>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
Datum:
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
Datum:
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
Datum:
@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
Datum:
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.
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
@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
Datum:
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)
Datum:
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.
Datum:
>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
Datum:
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)
Datum:
>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
Datum:
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
Datum:
@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
Datum:
Wie man die ACY-file ohne Anschließen MCU zu vorbereiten?
Datum:
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
Datum:
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?
Datum:
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
Datum:
Angehängte Dateien: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
Datum:
Angehängte Dateien:hier noch das Binary für Kompilierfaule..
Datum:
@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
Datum:
@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
Datum:
@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
Datum:
Hi, Hagen! You have news concerning to "offline ACY"? Sorry, but my Deutsch is much worse than English.
Datum:
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
Datum:
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?
Datum:
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.
Datum:
Ä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
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
Args, ich bin noch nicht dazu gekommen das zu testen, wird noch nachgeholt. Louis
Datum:
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
Datum:
Nachfolgend die zwei Stellen im ASM die du änderst:
check: xwdr sbrs PIND, PD0 sbrc PIND, PD1 rjmpapp ; baudrate and identifier scanning .if UseResetDelay abd: .endif ... ... ; identifier (BootSign) scanning with timeout and checksum id1: sbiw xl, 1 ; UART getc with timeouts sbc cmdl, zerol rx_1 brne id1 id2: breq check; exit id3: sbiw xl, 1 sbc cmdl, zerol rx_0 brne id3 breq check; exit rcall getx ... ... |
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.
Datum:
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
Datum:
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
Datum:
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.
Datum:
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
Datum:
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
Datum:
PS. - ist eine 1Wire Verbindung - per Hand funktioniert alles bestens
Datum:
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
Datum:
@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
Datum:
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;
Datum:
Versuche folgendes
procedure TForm1.Button8Click(Sender: TObject);
var
Buffer: array of Byte;
begin
with FLoader do
if DoConnect(True) then
try
try
SetLength(Buffer, 64);
if Command.ReadEeprom(@Buffer[0], Length(Buffer)) then
begin
FNameEEPROM := ExtractFilePath(ParamStr(0)) + 'temp1.eep';
Hex_File_Write;
end;
except
on E: Exception do
ShowMessage(E.Message);
end;
finally
DoDisconnect;
end;
end;
|
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
Datum:
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
Datum:
Danke, und
.equ UseUartInvert = 1 ; invert UART levels (for RS232 drivers such as MAX232) |
so steht's im AVRootloader.asm ;) Was ist 666p ? Gruß Hagen
Datum:
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
Datum:
Grüß Hagen! Danke für schnelle Antwort und deine Tips, den Code habe ich Ausprobiert, genau das, was ich brauchte.
Datum:
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.
Datum:
Hat sich erledigt.... Ich mach halt mein eigenes Interface über RS232.
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
> "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
Datum:
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
Datum:
Debug=1 ist veraltet. Probiere [Timeouts] Options=1. Du müsstest dann im Protokoll Fenster wesentlich mehr Infos sehen. Poste diese hier. Gruß Hagen
Datum:
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.
40 Seiten lang 27.11.09-20:55:53-642 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 dann 27.11.09-20:55:53-642 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:55:53-730 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:55:53-819 > received data $93 07 06 08 30 27.11.09-20:55:53-828 > Timer created 27.11.09-20:55:53-833 > Device connected 27.11.09-20:55:54-084 > send keepalive 27.11.09-20:55:54-338 > send keepalive 27.11.09-20:55:54-598 > send keepalive 27.11.09-20:55:54-864 > send keepalive 27.11.09-20:55:55-114 > send keepalive 27.11.09-20:55:55-378 > send keepalive 27.11.09-20:55:55-644 > send keepalive 27.11.09-20:55:55-902 > send keepalive 27.11.09-20:55:56-158 > send keepalive 27.11.09-20:55:56-424 > send keepalive 27.11.09-20:55:56-679 > send keepalive 27.11.09-20:55:56-938 > send keepalive 27.11.09-20:55:57-203 > send keepalive 27.11.09-20:55:57-453 > send keepalive 27.11.09-20:55:57-718 > send keepalive 27.11.09-20:55:57-722 > Timer released 27.11.09-20:55:57-725 > keepalive failed, terminate connection 27.11.09-20:55:57-772 > Device disconnected |
Datum:
Hier die Ausgabe: Das Teil sendet sporadisch irgendwelchen Mist zurueck.
27.11.09-20:57:27-453 > Connecting on port COM1... 27.11.09-20:57:27-453 > Timeout.Connect = 100 ms 27.11.09-20:57:27-453 > Timeout.Base = 50 ms 27.11.09-20:57:27-453 > Timeout.Erase = 10 ms 27.11.09-20:57:27-453 > Timeout.Flash = 15 ms 27.11.09-20:57:27-453 > Timeout.Eeprom = 10 ms 27.11.09-20:57:27-453 > Timeout.Buffer = 1 ms 27.11.09-20:57:27-453 > Timeout.AppCmd = 0 ms 27.11.09-20:57:27-453 > Timeout.KeepAlive = 250 ms 27.11.09-20:57:27-453 > Timeout.RTSPulse = 0 27.11.09-20:57:27-453 > Timeout.RTSInterval = 0 27.11.09-20:57:27-453 > Timeout.ConnectTrials = -1 27.11.09-20:57:27-453 > Timeout.MaxPacketSize = 0 27.11.09-20:57:27-453 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 . . . 27.11.09-20:57:42-765 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:42-937 > received data $96 09 06 04 37 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 27.11.09-20:57:42-937 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:43-125 > received data $C2 27.11.09-20:57:43-125 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 . . . 27.11.09-20:57:44-171 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:44-343 > received data $96 09 06 04 37 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 27.11.09-20:57:44-343 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:44-531 > received data $C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 27.11.09-20:57:44-531 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:44-703 > received data $C2 C2 27.11.09-20:57:44-703 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:44-875 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 . . . 27.11.09-20:57:49-109 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:49-281 > received data $96 09 06 04 37 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 C2 27.11.09-20:57:49-281 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:49-468 > received data $C2 C2 27.11.09-20:57:49-468 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 . . . 27.11.09-20:57:51-046 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 27.11.09-20:57:51-171 > aborted by User |
Datum:
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
Datum:
@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
Datum:
$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
Datum:
Was hast du bei AVRootloader.ini [Timeouts] -> Options stehen ?
Datum:
Angehängte Dateien: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
Datum:
Angehängte Dateien: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
Datum:
@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
Datum:
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
Datum:
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
Datum:
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
Datum:
Hallo Hagen, habe bei [Timeouts] -> Options=1 stehen. Heute Nachmittag werde ich das Teil mal an einem anderen Rechner testen. Vielen Dank. Manuel
Datum:
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?
Datum:
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?
Datum:
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
Datum:
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...
Datum:
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 > >
> // Pinchange ISR für PB6, bei LowLevel springen wir den Bootloader an > __attribute__ ((naked)) ISR(PCINT_vect) { > > if (PINB & (1 << PB6)) { > asm volatile("reti"); > } else { > asm volatile("rjmp __vectors"); > } > } > > int main(void) { > > MCUSR = 0; > WDTCR = (1 << WDE) | (1 << WDCE); > WDTCR = 0; > // RX Pin auf Eingang mit Pullup > DDRB = 0; > PORTB = (1 << PB6) > // PinChange on PB6, Bootloader Pin > GIMSK = (1 << PCIE1); > PCMSK1 = (1 << PCINT14); > sei(); > > .. blabla > while (1) { > } > } > |
> > 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
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
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?
Datum:
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? ;)
Datum:
CKOPT habe ich auch schon probiert. Auch alle Geschwindigkeiten der Schnittstelle. Und die Startzeit des Atmel ......
Datum:
Ändere in AVRootloader.inc
.equ BaudTolerance = 3 |
zb. auf den Wert 5 um. Vielleicht "lindert es die Symptome" ohne die Ursache zu kennen. Gruß Hagen
Datum:
Ok, danke, werde ich testen. Gibt es noch eine Möglichkeit dem "Symptom" auf die Schliche zu kommen?
Datum:
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 ...
Datum:
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
Datum:
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 ...........
Datum:
Da bleibt nur eins übrig: zukünftig eine 100% - Prüfung vor dem Vergießen. ;)
Datum:
>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
Datum:
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
Datum:
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?
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
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
Datum:
Angehängte Dateien: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
Datum:
Hallo, ich habe jetzt auch versucht den Bootloader auf meinem Atmega8 zu verwenden. Leider bekomme ich keine Verbindung! Meine Einstellungen:
.include "m8def.inc" .equ UseAutobaud = 0 .equ UseResetDelay = 1 .equ RX_PORT = PORTD .equ RX = PD0 .equ TX_PORT = PORTD .equ TX = PD1 .set XTAL = 12000000 .set BootDelay = XTAL/4 .set BootBaudrate = 9600 .set BootVersion = 6 .set BootCodeSize = 466 |
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?
Datum:
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
Datum:
@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
Datum:
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
Datum:
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
Datum:
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
Datum:
@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
Datum:
@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
Datum:
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
Datum:
Hallo Hagen ! Ich hab mal zwei kurze Fragen zu UseSpecialWrite. Da mein ganzes Projekt in ASM ist, hab ich den Aufruf folgendermassen programmiert:
ldi r18, low(Puffer) ;Buffer ldi r19, high(Puffer) ldi r20, low(32) ;size ldi r21, high(32) ldi r22, 0x00 ;Adresse die Überschrieben wird (0x0f00) ldi r23, 0x0f clr r24 clr r25 RJmp Flashend -5 |
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
Datum:
>>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
Datum:
@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
Datum:
@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
Datum:
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:
ldi r18, low(Puffer) ;Puffer im SRam ldi r19, high(Puffer) ldi r20, low(32) ;Anzahl der zu schreibenden Bytes ldi r21, high(32) ldi r22, Byte1(Adresse*2) ;Adresse im Flash die Überschrieben wird ldi r23, Byte2(Adresse*2) ldi r24, Byte3(Adresse*2) ;wird nur bei großen AVR's benötigt, sonst ldi r25, Byte4(Adresse*2) ;einfach auf 0x00 setzen RCall Flashend -2 ;Rücksprung aus Bootloader mittels 'Ret' |
Gruß Stefan
Datum:
Hagen schrieb: > @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 BTM-222 läuft auf jeden Fall korrekt. Inzwischen habe ich hiermit http://forum.pololu.com/viewtopic.php?f=23&t=651 meinen eigenen Bootloader geschrieben. Mein Bootloader ist nicht so funktionsreich (nur feste Baudrate, keine Verschlüsselung usw.), ist total simpel. Ich brauche aber auch nicht mehr. Damit kann ich aber über Bluetooth oder sonstige langsame Funkverbindungen problemlos übertragen. Auf dem Microcontroller gibt es nämlich gar keine Timeouts mehr, wenn man im Bootmodus ist. Theoretisch kann man auch mit dem Terminal Zeichen für Zeichen an den Controller senden und flashen. Gruß, Etumic
Datum:
@Stefan: ich weiß nicht ob es von dir so beabsichtig ist aber die FLASH Adresse für WriteFlash() kann byteadressiert sein und muß nicht zwangsläufig mit zwei multipliziert werden um wordbasiert zu sein. Das Besondere an WriteFlash ist es das man an beliebige FLASH Adresssen beliebig große Datenbereiche schreiben kann. Man brauch nicht auf Wordalignment oder die Pagesize des FLASHs achten. Man kann also im Minimalfall nur 1 Byte an eine ungerade FLASH Adresse schreiben. Diese Funktion lädt dann die betroffene FLASH Page, modifiert an der richtigen Stelle das zu schreibende Byte aus dem SRAM Buffer und schreibt dann diese FLASH Page zurück. Gruß Hagen
Datum:
Hallo, ich setzte den Bootloader schon längere Zeit ein und möchte ihn nicht mehr missen. Ich habe eine ältere Version im Einsatz die bisher super funktioniert hat. Bisher... Diesen Bootloader habe ich compiliert und sie wie er ist mehrfach auf identische Hardware gebrannt. Das lief immer problemlos. Gestern wollte ich noch zwei der Gerätchen bauen, nach dem Test habe ich den Bootloader drauf geschrieben, und bekomme keinen Kontakt. Hardware ist ein Mega644p, wenn ich meine Software direkt drauf flashe läuft alles prima, der Bootloader ist aber nicht ansprechbar. Alle Fuses sind korrekt gesetzt, die Speichergröße im ASM-File auch, habe jetzt alles zigmal kontrolliert. Ebenso die Bootstrings usw. Alles wie früher. Ich habe sogar ein uraltes Backup zurück geschrieben um sicher zu gehen, dass ich wirklich denselben Bootloader habe. Nix klappt.. Was könnte das verursachen? PC-Macke? Mit der Windows-Software des Bootloaders kann ich auch auf die alten Geräte nicht mehr zugreifen, da kommt immer Checksum error. Mit meiner eigenen über die DLL klappt es dagegen mit den alten Geräten prima. Ich habe mit der DLL damals eine Funktion in meine PC-Softwar eingebaut mit dem der Anwender neue Firmware flashen kann. Wenn ich jetzt die neueste Version des Bootloaders nehme, kann ich dann mit der alten DLL noch darauf zugreifen? Oder hat sich da immer wieder viel verändert? Meine Version ist aus dem Mai 2008. Ansonsten müssten alle ihre Software updaten, das wäre schlecht. Louis
Datum:
Probiere in der AVRootloader.ini in [Timeouts] Options=2 oder Options=0. Der "Login" Prozess beim Senden/Empfangen des BootSigns hat sich zwischen den Versionen geändert. Mit Options=2 wird der alte Loginstring gesendet und mit Options=0 der neue. Beim Neuen wird über das gesendete BootSign noch eine CRC erzeugt, mit gesendet und im Bootloader dementsprechend geprüft. Zudem solltest du in Zukunft zu jedem deiner Projekte bei denen du den Bootloader einsetzen möchest ein kompletes Backup der entsprechend konfigurierten Bootloader Software dazu legen. Das beinhaltet auch die PC Software. So mache ich das immer und Speicherplatz ist heutzutage kein Problem mehr. Gruß Hagen
Datum:
Hallo Hagen, danke, das werde ich mal testen. Ich habe ja ein Backup des Bootloaders, auch die Originale Version aus dem Backup, die schon mehrfach verwendet wurde, antwortet nicht mehr, das ist ja das seltsame. Heute werde ich mal weiter versuchen es wieder zum Laufen zu bekommen, und einen anderen PC nehmen, mal sehen ob es daran liegt. Louis
Datum:
Tach auch,
gibts irgendwo noch eine Demo wie man die neue DLL in Delphi Programme
einsetzt? Irgendwie klappt das so wie im alten Beispiel nicht mehr, da
hagelt es Fehlermeldungen..
Vor allem meckert er wegen
function GetAppCmd: WideString; stdcall;
function GetAppCmdResponse: WideString; stdcall;
function GetAppVersion(Masked: Bool = False): Integer; stdcall;
function GetACYInfo: WideString; stdcall;
Welchen Sinn haben diese Funktionen? Kann man das irgendwo nachlesen?
Louis
Datum:
Das was die Methodennamen aussagen. Im Grunde geben sie die Werte zurück die in meiner EXE aus der INI datei gelesen werden oder im GUI eingebbar sind. Dein Objekt das dieses Interface benutzt muß also bei - function GetAppCmd: WideString; stdcall; + aus AVRootloader.ini -> AppCmd - function GetAppCmdResponse: WideString; stdcall; + aus AVRootloader.ini -> AppCmdResponse - function GetACYInfo: WideString; stdcall; + aus GUI das Edit "ACY Info" - function GetAppVersion(Masked: Bool = False): Integer; stdcall; + aus GUI die Edits/UpDown Controls bei Versionsnummer zurückgeben. Spezialfall ist GetAppVersion() und das kannst du weiter oben im Thread nachlesen. Es gibt keine weitere Dokumentation als die Beschreibung des aktuellen Interfaces, leider. Das liegt aber auch daran das die Nachfrage gegen Null geht und ich deswegen nicht Stunden meiner Freizeit opfern möchte. Wenn dann würde ich eher das Demoprojekt auf den neusten Stand bringen wollen da das weitaus weniger Zeit kostet als eine Doku. Gruß Hagen
Datum:
>Ich habe ja ein Backup des Bootloaders, auch die Originale Version aus >dem Backup, die schon mehrfach verwendet wurde, antwortet nicht mehr, >das ist ja das seltsame. Dann würde ich aber eher auf ein Fehler in deinem PC-System, COM Schnittstelle tippen. Denn wenn selbst die alten, schonmal funktionierenden Module, mit den Backups nichts gehen, dann kann ja nur dort die Ursache sein. Falschen COM Port eingestellt ? Manchmal sind es wirklich solche trivialen Fehler die man konsequent übersieht. Gruß Hagen
Datum:
Hagen schrieb: > Wenn dann würde ich eher das Demoprojekt auf den neusten Stand bringen > wollen da das weitaus weniger Zeit kostet als eine Doku. Au ja Hagen, das wäre toll. Ich weiß, auch das ist viel Aufwand... Am einfachsten wäre natürlich die Source von Deiner GUI, dann wäre keine DLL und keine Doku nötig. Aber Du wirst schon Deine Gründe haben, warum Du die Sourcen nicht veröffentlichst.
Datum:
Achim schrieb: > dann wäre keine > > DLL und keine Doku nötig Btw., wenn ich grade DLL höre: DLLs mit demselben Namen können nicht alle beim System registriert werden, nur die zuerst veröffentlichte wird verwendet. Vielleicht liegt der Fehler einiger User hier? Wenn die alte DLL nachträglich aufgespielt wurde (in anderem Verzeichnis), dann bleibt die neuere, zuerst aufgespielte, gültig. Evtl. mal alle DLLs löschen und nur die benötigte aufspielen, Neustart des Rechners nicht vergessen! ;-)
Datum:
Na ja, eine "normale" Dll wird ja nicht unbedingt beim System registriert sondern i.d.R statisch oder dynamisch gelinkt, also zur Laufzeit geladen. Man kann hier die Suchreihenfolge für Windows u.U. ändern, aber die erste gefundene wird halt geladen, es sei denn man gibt explizit die Datei vor.
Datum:
Guten Tag... Ich nutze seit einiger Zeit diesen Bootloader (in V6.0) für ein Projekt, das programmieren über die beiliegende Windows-Software funktioniert auch wunderbar und alles könnte schön und gut sein. Aber dann habe ich mir in den Kopf gesetzt, das Firmware-Update mit in die Software zu integrieren, mit der ich die Hardware konfiguriere, bevor das Ding Standalone seinen Dienst verrichtet. Praktischerweise holt sich diese Software (Delphi) das aktuellste ACY-File aus dem Internet. Auch hier ist alles schön und gut, und nun kommt das aber: Mit denselben Timeout-Parametern wie in der beiliegenden Flash-Software will die DLL (v6) nicht mit dem Bootloader (ebenfalls v6, selbes Archiv wie die DLL). Nun habe ich den Thread mehrfachst durchforstet, finde aber nichts zu meinem konkreten Fehler:
268435456 - Connecting on port COM13... 268435456 - Timeout.Connect = 50 ms 268435456 - Timeout.Base = 50 ms 268435456 - Timeout.Erase = 10 ms 268435456 - Timeout.Flash = 15 ms 268435456 - Timeout.Eeprom = 10 ms 268435456 - Timeout.Buffer = 10 ms 268435456 - Timeout.AppCmd = 0 ms 268435456 - Timeout.KeepAlive = 250 ms 268435456 - Timeout.RTSPulse = 0 268435456 - Timeout.RTSInterval = 0 268435456 - Timeout.ConnectTrials = 100 268435456 - Timeout.MaxPacketSize = 0 268435456 - send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 268435456 - received data $95 02 06 08 37 268435456 - send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 268435456 - send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 268435456 - received data $95 02 06 08 37 268435456 - send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 268435456 - received data $95 02 06 08 37 268435456 - send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 268435456 - received data $95 02 06 08 37 268435456 - send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 268435456 - received data $95 02 06 08 37 268435456 - send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 301989888 - aborted by User |
Die DLL sendet ihren Ident (BOOTLOADER), die Antwort vom mega32 ist auch richtig, nur "irgendwie" verschläft die DLL diese Antwort, oder erkennt sie nicht gültig an.. ein Spielen mit den Timeouts blieb 2 Stunden "Intensivtest" ohne Erfolg. Die Ausgabe wurde mit (result.)Options = 1 ausgegeben. Als Grundlage für das Delphiprogramm nehme ich die Interface-Unit, die meisten Deklarationen habe ich aus den älteren Beispielen übernommen, auf den aktuellen Stand angepasst (Rückgabewert bei ProcessMessages, als Beispiel) und natürlich die "fehlenden" Deklarationen ergänzt. Alles erscheint funktionsgfähig, ich habe mal nur den Bootloader aufgespielt, die beiliegende Software connected/disconnected problemlos, nur die in die eigene Software eingebundene DLL mag nicht. Interessant ist noch ein Punkt: ohne (result.)Baudrate := 115200; in der Timeouts-Function bekomme ich mit der letzten geposteten Variante von OpenCommunication() keine Antwort von der MCU, wenn ich es setze, bekomme ich eine ICOM: Read Error Exception (in der Delphi-IDE mit allen "negativen" Konsequenzen, wird das Programm per Doppelklick ausserhalb der IDE gestartet, kommt es zu keiner Meldung, und die Kommunikation von MCU an PC wird zumindest im Memo-Feld wie oben zitiert dargestellt. Entweder sehe ich den Wald vor lauter Bäumen nicht mehr, oder irgendwas anderes ist im argen. Gruss, Tim O.
Datum:
>Die Ausgabe wurde mit (result.)Options = 1 ausgegeben. Options = 2 setzen und/oder schauen das die Datei AVRootloader.dev auf den neusten Stand ist. Dein Auszug oben sieht gut aus und die einzige Erklärung ist die das die PC-Software aus den gesendeten Signaturdaten nicht die Infos zum richtigen AVR aus der AVRootloader.dev Datei laden kann. Gruß Hagen
Datum:
Moment.. Mit der Software geht es ja... benötigt die DLL denn überhaupt das DEV File ? Das connect-Problem hab ich mit der DLL, nicht mit der "originalen" (=deiner) Software. Der Auszug ist aus dem Memo-Feld, das zu debugging-Zwecken in meine Software gesetzt wurde. GRuss, Tim
Datum:
... ja, die DLL braucht die DEV Datei ... ... mit derselben DEV Datei wie im Windows-Ordner in "meinen Ordner" kopiert funktioniert es nun... argh.. seltsamerweise war sogar ne DEV Datei vorhanden die ich sicher nicht hinkopiert hatte), nur 74 Byte gross.. Gruss, Tim
Datum:
Mein Programm das ich mit den BOOTLOADER drauf geladen hat wird immer nur 2 sek ausgefürt danach startet sich das Programm neu habt ihr ein Lösungsvorschlag?
Datum:
Watchdog zurücksetzen oder in main() am Anfang deaktivieren, falls du ihn nicht per Fuses permanent aktiviert hast. Gruß Hagen
Datum:
Hallo Hagen, bin gerade mit Delphi User interface und Flashen von Acy Dateien beschäftigt. Funktioniert auch ganz gut indem ich einfach alles rübersende, aber ein bisschen würde ich gern verstehen, was ich da mache. "AVRootloader" $06 (Bottloaderversion?) $26 (??) "ACYInfo" $20 (Leerzeichen?) "1.0.0.0" (Version Software) $00 (Terminierung?) $1E$xx$xx (Device Sign) $00 (??) $0F (??) $06 (??) $00 (??) $2F (??) Ab hier Befehle $FE $FE $XX $XX... Datenblöcke und Kommandos 1. Gibt es irgendwo eine Doku über den Aufbau der Datei? 2. das Kommando $FE hab ich nicht so ganz klar. Dahinter kommt $00 wenn ich ins EEProm unverschlüsselt schreibe. In der ACY Datei aber $FE mit 24 Byte irgendwas und danach $FF. Also "$FE $?? (highbyte Size) (lowbyte Size). Wäre nett, wenn Du etwas die ?? aufklären könntest ... Vielen Dank!
Datum:
Hallo Hagen, ich habe mit der DLL die gleichen Probleme wie Tim O. Mit Deiner Anwendung funktioniert alles. Mit der DLL bekomme ich einfach keine Verbindung. Ich habe bei dem Demo-Programm aber nur den COM-Port verändert. Als Prozessor verwende ich einen Mega328P mit 20MHz. Ich würde die DLL gerne mit einem Konfigurationsprogramm an dritte weitergeben. Darf man diese als Freeware weitergeben oder gibt es hier eine Lizenzbestimmung. Vielen Dank für Deine Antworten.
Datum:
Hallo Franz. Nachdem ich die .dev Datei mit in das Verzeichnis der DLL kopiert habe, funktioniert alles. Gruss Tim
Datum:
Marcus Stangl schrieb: > OK,ich weiß - eigentlich läßt sich Dein Bootloader ohne nennenswerte > Modifikationen verwenden. Das ist bei meinem Projekt (Funkvernetztes > Multicontrollersystem) so nicht möglich. Ich würde mich deshalb sehr > freuen wenn Du mir das Protokoll im Detail beschreiben könntest. Hi Leute, Ich habe ebenso ein Multiprozessor System mit 4 ATmega8 (bzw. ATmega168) die ich am liebsten in einem Rutsch flashen würde. Der Bootloader funktioniert so weit prima auf einem Controller. Da ich die RXD und TXD Leitungn jedes Controllers über 1k Widerstände miteinander verbunden habe dachte ich mir ich könnte jeden Controller mit einer unterschiedlichen individuellen "Bootsign" versehen und dann individuell mit der Programmiersoftware ansprechen. Leider erzeugen alle Bootloader beim Empfang auf RXD auf TXD ein Signal und der "angesprochene" kommt nicht durch. Hat jemand eine bessere Idee wie man das geschickt lösen kann? Grüsse, Andreas
Datum:
Hi Leute, zum Thema Multicontroller-System bin mittlerweile etwas weiter gekommen. Also: Bootloader im Zweidraht-Mode, alle RXD-Pins sind über 1k Widerstände und alle TXD-Pins sind über 1k Widerstände zusammen verbunden. Über Max232 gehen alle an PC. Jeder Controller erhält eine eindeutige BootSign:
BootSign: .db "BOOTLOAD01" ; alle weitern haben BOOTLOAD02,03,04 etc. BootMsg: .db "Controller No. 1 (2,3,4)" BootInfo: .db SIGNATURE_001, SIGNATURE_002, BootVersion, BootPages |
Zudem werden noch in der AVRotloader.ini die BootSigns bekant gemacht:
[Signs] 0=BOOTLOAD01 1=BOOTLOAD02 2=BOOTLOAD03 3=BOOTLOAD04 |
Problem ist, dass jeder Controller mit "frischem" Bootloader und ohne Firmware sofort auf die RXD Leitung reagiert und auf TXD antworted. Geholfen hab ich mir damit, dass ich die Controller einzeln nacheinander mit Bootloader und gleich darauf Firmware geflashed hab. Wenn auf allen Controllern bereits eine Firmware läuft, dann antwortet nur der jeweils angesprochene nach dem Reset. So weit funktioniert es also. Die Progammier-Sequenz aller vier Controller läuft jetzt folgendermassen:
1. Power-off 2. In AVRootloader.exe die jeweilige sign auswählen z.B. "Bootload01". 3. Connect to device klicken 4. Power-On (jetzt connected sich der jeweilige controller) 5. Program klicken |
Diese Sequenz muss dann 4-mal wiederholt werden. Daher hätte ich einen Wunsch: Der Windows-App "AVRloader.exe" können zwar beim Aufruf Parameter übergeben werden, allerdings erfolgt der Flash-Vorgang nicht automatisch, mann muss trotzdem noch auf "Connect to device" und "Program" klicken. Praktisch wäre es wenn die AVRloader.exe auch als reines Kommandozeilen Programm lauffähig wäre. Dann könnte man mit einem kleinen Batchfile die Progammierung aller 4 Controller automatisieren. (Ähnlich wie mit der "FBOOT.EXE" von Peter Dannegger).
:start echo #----------------------------------------------------# echo Power aus und einschalten (PORST) fboot.exe /c1 /b9600 /pHk_I2Cm1.hex /iBOOTLO01 if errorlevel 1 goto error echo Controller 1 erfolgreich geflashed echo #----------------------------------------------------# echo Power aus und einschalten (PORST) fboot.exe /c1 /b9600 /pHk_I2Cm2.hex /iBOOTLO02 if errorlevel 1 goto error echo Controller 2 erfolgreich geflashed echo #----------------------------------------------------# echo Power aus und einschalten (PORST) fboot.exe /c1 /b9600 /pHk_I2Cm3.hex /iBOOTLO03 if errorlevel 1 goto error echo Controller 3 erfolgreich geflashed echo #----------------------------------------------------# echo Power aus und einschalten (PORST) fboot.exe /c1 /b9600 /pHk_I2Cm4.hex /iBOOTLO04 if errorlevel 1 goto error echo Controller 4 erfolgreich geflashed echo #----------------------------------------------------# echo Fertig! echo PORST machen und echo beliebige Taste zum Beenden druecken pause goto ende :error echo das flashen war leider nicht erfolgreich! echo mit beliebieger Taste neu starten pause goto start :ende |
Mit einem solch einfachem Batchfile wäre dann eine einfache Programmierung aller 4 Controller möglich. Es muss nur 4-mal hintereinander die Power-supply aus und eingeschalten werden. @ Hagen: Siehst Du die Möglichkeit ein solches Kommandozeilen "AVRloader.exe" zur Verfügung zu stellen? Gruesse an alle!
Datum:
Sollte doch eigentlich schon gehen:
-A Automatikmodus/Befehle für den Bootloader e erase, lösche FLASH vor dem Programmieren, wird diese Option nicht angegeben so gelten die Einstellungen in AVRootloader.exe p program, schreibe FLASH/EEPROM mit der Datei die bei -F/-E angegeben wurde v verify, Überprüfe den FLASH Inhalt, wird diese Option nicht angegeben so gilt das was in AVRootloader.exe eingestellt wurde c close, Beende AVRootloader nach den Aktionen, aber nur falls keine Fehler aufgetreten sind |
Datum:
Mensch! Jetzt fällt es mir wie Schuppen von den Augen...! Wer lesen kann ist klar im Vorteil. Hab ich doch glatt den Schalter -A überlesen...Jetzt klappts sogar mit Batchfile. Dankeschön für den Tip! Mich zerreists fast vor Begeisterung für diesen genialen Bootloader. Danke an alle die das Möglich gemacht haben und insbesondere an den Hagen Re! So gehts jetzt wunderbar:
AVRootloader.exe -Apc -PCOM1 -SBOOTSIGN01 -FFIRMWARE01.hex |
Viel Grüsse!
Datum:
Guten Tag ;) hab ein kleines Problem mit dem Bootloader, Wenn ich den SourceCode mit .set BootCodeSize = 0 Kompiliere klappt Alles! Wenn ich dann aber den Wert aus .cseg Eintrage also: .set BootCodeSize = 8192 bricht er mit nem Error ab: C:\Dokumente und Einstellungen\chris\Desktop\AVRootloader\AVR\AVRootloader.asm(75): Including file 'C:\Programme\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8def.inc' C:\Dokumente und Einstellungen\chris\Desktop\AVRootloader\AVR\AVRootloader.asm(143): compile for ATmega8 C:\Dokumente und Einstellungen\chris\Desktop\AVRootloader\AVR\AVRootloader.asm(211): Including file 'C:\Dokumente und Einstellungen\chris\Desktop\AVRootloader\AVR\AVRootloader.inc' C:\Dokumente und Einstellungen\chris\Desktop\AVRootloader\AVR\AVRootloader.asm(216): error: Overlap in .cseg: addr=0x0 conflicts with 0x0:0x1 C:\Dokumente und Einstellungen\chris\Desktop\AVRootloader\AVR\AVRootloader.asm(796): Including file 'C:\Dokumente und Einstellungen\chris\Desktop\AVRootloader\AVR\Special.inc' Assembly failed, 1 errors, 0 warnings Hat jemand nen Idee was da schief läuft? lg
Datum:
Chris, Du musst den wert von USED nicht den von SIZE ! HTH
Datum:
@Andreas: >Problem ist, dass jeder Controller mit "frischem" Bootloader und ohne >Firmware sofort auf die RXD Leitung reagiert und auf TXD antworted. Bist du dir wirklich sicher das der Bootloader schon antwortet obwohl er nicht die korrekte BootSign empfangen hat ? Normalerweise sollte der Bootloader nur auf RXD lauschen bis er die korrekte "Loginsequenz" empfangen hat. Das sind par Nullen gefolgt von #13 der BootSign und dadrüber eine 16Bit CRC berechnet. Vorher darf er nichts auf TXD machen. Allerdings arbeitest du im 2-Draht Modus und somit geht der Bootloader immer davon aus das er TXD auf definierte Pegel ziehen muß. Physikalisch würde ich also alle RXDs parallel verschalten ohne Serienwiderstände. Es sei denn du möchtest auf Nummer sicher gehen und verhindern das die AVRs am RXD Pin gegeneinander treiben, was bei ausschließlicher Nutzung vom RXD als Input, eg. hochohmig, nicht passieren sollte. Ergo: diese Serienwiderstände in RXD sichern nur gegen Softwarefehler ab. TXD-Pins müssen mit Serienwiderstände geschützt werden. Man könnte den Bootloader so umschreiben das er TXD als Opendrain/-collector ansteuert und dann auf die Serienwiderstände verzichten. Eine andere Möglichkeit ist es vom MAX232 die RXD/TXD über Widerstand zu verbinden und so ein 1-Wire mit invertierten Pegeln im Bootloader zu benutzen. Die Serienwiderstände für die 1-Wire Pins an den AVRs entfallen dann und du benötigst pro AVR nur noch einen Pin. Am MAX232 also RX/TX mit zb. 2k verbinden. Vom TX des MAX gehts dann an die AVRs. Der 2k dient dann einerseits zur Verschaltung von TX/RX und andererseits als Pulldown für TX da wir ja intern den 1-Wire-Modus mit invertierten Pegeln benutzen. Gruß Hagen
Datum:
Hallo Hagen wäre schön, wenn Du bei Gelegenheit auch mein Posting mal anschauen könntest... Beitrag "Re: AVR-Bootloader mit Verschlüsselung" Ist wohl untergegangen bei alle Posts hier momentan. ;) Grüße
Datum:
@Achim: bin schon am arbeiten es dauert aber noch par Tage wegens zeitmangels. Sorry das du noch warten musst.
Datum:
Hallo, Hagen, erstmal vielen Dank für den Superbootloader mit dem schönen Frontend! Ich habe eine Frage: Ich hab den Bootloader mit einem Mega88 im OneWire-Modus benutzt. Mein Hauptprogramm ist sehr einfach und zählt nur cycles und schaltet einzelne Ports (sowas wie ein Pulsgenerator). Ausgelöst wird es durch INT0. Mit ISP programmiert reagiert es innerhalb der vorgesehenen Zeit (~2mu s). Wenn die Bootloaderfirmware drauf ist, kommt es ab und an (etwa bei jedem 20. Trigger) zu einem "Aussetzer", d.h. der Interrupt wird anscheinend nicht ausgelöst. Kann sowas durch den Bootloader kommen? Pollt der den Pin für die serielle Kommunikation? Ich hab es jetzt mit Peter Daneggers Bootloader probiert, da tritt das nicht auf. Und da wird ja ein reset benötigt zum flashen. Nochmal vielen Dank! Viele Grüße Nicolas
Datum:
Wenn du UseWDT=1 im Bootloader aktiviert hast dann benutzt dieser den WatchDog Timer. In deiner Anwendung musst du diesen entweder deaktivieren oder regelmäßig zurücksetzen (WDT Opcode). Andere Alternative ist es mit UseWDT=0 den Bootloader zu kompilieren. Allerdings würde ich dir das nicht anraten da mit dem WDT der Bootloader viel robuster=sicherer arbeitet. Besonders eben wenn es zu unvorhersehbaren Störungen kommt, die ja immer nur per WDT, als letztes Mittel, behandelt werden können. Peters Bootloader nutzt den WDT nicht soviel ich weiß. So bald deine Anwendung angesprungen wurde ist der Bootloadercode absolut inaktiv. Gruß Hagen
Datum:
Hallo Hagen, das wars tatsächlich - jetzt läuft es wie vorgesehen! Danke und Viele Grüße Nicolas
Datum:
Hallo Hagen, bin echt ein großer Fan deines Bootloaders. Leider hab ich gerade ein Problem damit. Ich habe eine Schaltung, die ich mit Atmega8 und Atmega168 betreiben will. Je nach Softwareumfang. Hab ein serielles Kabel nach der Onewire Anleitung umgebaut (Dioden). Wenn ich den Bootloader für den Atmega8 erstelle und Flashe, klappt alles wunderbar. Wenn ich aber das selbe für den Atmega168 mache, findet AVRootloader den Controller wohl nicht. Wie gesagt, die Schaltung und das Kabel sind immer die gleichen. Daran kann es nicht liegen. Am µC kann es auch nicht liegen. Wenn ich den Atmega168 in nem Entwicklerboard mit MAX232 und nicht Onewire-Mode teste, klappt es auch. Weiß leider nicht weiter. Grüße, Hige.
Datum:
Beide Bootloader benutzen ein anderes BootSign und sind ansonsten in den Kommunikationsparametern identissch konfiguriert ? Gruß Hagen
Datum:
Hallo Hagen, ich hab in der avrootloader.asm nur den jeweiligen Controller ausgewählt. Die Fuse hab ich auch richtig gesetzt, habs x-mal kontrolliert.
Datum:
Hagen schrieb: > Beide Bootloader benutzen ein anderes BootSign Die Controller befinden sich nicht gleichzeitig in der Schaltung. Ich verwende entweder den Mega8 oder Mega168. Mega8 funktioniert ohne Probleme. Mega168 funktioniert leider nicht.
Datum:
Hallo, der Bootblock funktioniert soweit, Kommunikation läuft, SRAM, EEPROM lesen und Flash löschen geht auch. Sobald ich aber was programmieren will schmiert die Kommunikation ab (siehe Log). Was muss ich ändern? Gruß, Daniel
17.06.10-17:26:14-129 > Connecting on port COM2... 17.06.10-17:26:14-129 > Timeout.Connect = 100 ms 17.06.10-17:26:14-129 > Timeout.Base = 100 ms 17.06.10-17:26:14-129 > Timeout.Erase = 10 ms 17.06.10-17:26:14-129 > Timeout.Flash = 25 ms 17.06.10-17:26:14-129 > Timeout.Eeprom = 10 ms 17.06.10-17:26:14-129 > Timeout.Buffer = 1 ms 17.06.10-17:26:14-129 > Timeout.AppCmd = 0 ms 17.06.10-17:26:14-129 > Timeout.KeepAlive = 500 ms 17.06.10-17:26:14-129 > Timeout.RTSPulse = 0 17.06.10-17:26:14-129 > Timeout.RTSInterval = 0 17.06.10-17:26:14-129 > Timeout.ConnectTrials = -1 17.06.10-17:26:14-129 > Timeout.MaxPacketSize = 0 17.06.10-17:26:14-129 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 4C 4F 41 44 45 52 17.06.10-17:26:14-534 > received data $95 02 06 04 30 17.06.10-17:26:14-534 > Timer created 17.06.10-17:26:14-534 > Device connected 17.06.10-17:26:15-049 > send keepalive 17.06.10-17:26:15-548 > send keepalive 17.06.10-17:26:16-063 > send keepalive 17.06.10-17:26:16-297 > Timer released 17.06.10-17:26:16-297 > Reading SRAM... 17.06.10-17:26:19-105 > Timer created 17.06.10-17:26:19-604 > send keepalive 17.06.10-17:26:20-119 > send keepalive 17.06.10-17:26:20-244 > Timer released 17.06.10-17:26:20-259 > Reading EEPROM... 17.06.10-17:26:21-617 > Timer created 17.06.10-17:26:22-131 > send keepalive 17.06.10-17:26:22-646 > send keepalive 17.06.10-17:26:22-880 > Timer released 17.06.10-17:26:22-880 > Erase FLASH... 17.06.10-17:26:24-003 > FLASH erased in 1,12 sec 17.06.10-17:26:24-019 > Timer created 17.06.10-17:26:24-518 > send keepalive 17.06.10-17:26:25-033 > send keepalive 17.06.10-17:26:25-532 > send keepalive 17.06.10-17:26:25-579 > Timer released 17.06.10-17:26:25-579 > Program... 17.06.10-17:26:25-579 > execute compiled data 17.06.10-17:26:25-579 > selected options in compiled file: 17.06.10-17:26:25-579 > - programming FLASH 17.06.10-17:26:25-579 > - erase FLASH during programming 17.06.10-17:26:29-479 > Cmd.SetBuffer.ReadByte() ICOM: read error. 17.06.10-17:26:29-495 > Timer created 17.06.10-17:26:30-015 > send keepalive 17.06.10-17:26:30-115 > Timer released 17.06.10-17:26:30-115 > keepalive failed, terminate connection 17.06.10-17:26:30-215 > Device disconnected |
Datum:
Hm, schwierig. Mir fällt auf das du Timeout.Base mit 100ms ziemlich groß gewählt hast, gehst du über einen USB-RS232 Wandler ? Ansonsten mal Timeout.Flash von 25ms auf 50ms oder 100ms erhöhen. Und was hat sich geändert so das es jetzt zumindest teilweise geht ? Gruß Hagen Ähm ? daniel == hige ?
Datum:
Hallo Hagen, gibt es eine moeglichkeit nach beenden des programms AVRootloader.exe die RTS leitung auf High zu setzen ? ich weis ist unueblich aber so kann das programmerkabel angeschlossen bleiben. (1wire mit RTS auf reset) ich rufe den bootloader in der kommandozeile auf und da waehre sowas ganz praktisch, oder gibts das schon und i habs uebersehen ? vlg Charly
Datum:
Nee gibts nicht und würde auch nicht gehen. Die EXE muß die COM Schnittstelle freigeben und setzt diese dann freundlicher Weise auf ihren Zustand zurück den die EXE beim Öffnen vorgefunden hat. Das nennt sich guter Ton und Rücksichtnahme auf andere Softwareentwickler ;) Davon abgesehen habe ich die EXE so programmiert das sie die COM Schnittstelle nur dann öffnet wenn sie benötigt wird und ansonsten anderen Programmen zur Verfügung stellt. Ich denke auch das dein Problem anders lösbar sein könnte. 1.) verzichte auf RTS and Reset 2.) benutze nur den 1-Wire-Pin am AVR exklusiv für den Bootloader 3.) überwache in alle deinen Programmen diesen Pin auf Aktivität und wechsel per Watchdog Timeout in den Bootloader, heist führe einen "Software-Reset" durch. Konzeptionell bedeutet dies zwar das deine Anwendungsprogramme ein Teil der Funktionalität des Bootloaders werden und du damit immer ein wenig an Source extra pflegen musst, aber ich habe die Erfahrung gemacht das das mit bischen Routine wirklich unproblematisch und am cleversten ist. Und natürlich benötigst du dann nur noch einen Pin am AVR. Gruß Hagen
Datum:
Gebe doch einfach den Quellcode Deiner Exe raus, so kann er sich den Progger selber umschreiben wie er ihn braucht!
Datum:
Hallo Hagen, danke für die schnelle Antwort. Ja, ich benutze einen USB-RS232 Wandler (PL2303). Deswegen ist der Timeout bereits so weit oben. Den Flashtimeout (und sämtliche anderen Timeouts) hab ich schon um Dimensionen erhöht, hat leider nichts gebracht. Der Fehler tritt nur bei Verify und Flash auf. :/ Gruß, Daniel (Nicht Higi)
Datum:
hier noch als Nachtrag die wechselnden Fehlermeldungen: 18.06.10-01:15:57-758 > - programming FLASH 18.06.10-01:15:58-627 > Cmd.SetBuffer.ReadByte() ICOM: read error. .. 18.06.10-01:16:01-367 > - programming FLASH 18.06.10-01:16:01-881 > Cmd.SetBuffer.ResCheck(2) Error: 00 operation failed .. 18.06.10-01:16:04-652 > - programming FLASH 18.06.10-01:16:05-522 > Cmd.SetBuffer.ReadByte() ICOM: read error. .. 18.06.10-01:16:07-835 > - programming FLASH 18.06.10-01:16:08-335 > Cmd.SetBuffer.WriteData() ICOM: write error. .. 18.06.10-01:16:10-786 > - programming FLASH 18.06.10-01:16:10-887 > Cmd.SetAddr.ReadByte() ICOM: read error. .. Komische Sache, hm?
Datum:
@Daniel: Kannst du den USB-RS232 umgehen und eine echte RS232 verwenden ? Die Fehlermeldungen sind sporadisch und immer wenn mir solche Probleme gemeldet wurden lag es an Übertragungsfehlern (zb. USB Wandler VCC nicht sauber) oder an den Treibern für den USB-RS232-Wandler. Gruß Hagen
Datum:
Zb. hier >18.06.10-01:16:01-881 > Cmd.SetBuffer.ResCheck(2) Error: 00 operation >failed Empfängt die EXE einen Fehlercode 00 den es als solches garnicht im definierten Protokoll gibt. Gruß Hagen
Datum:
Angehängte Dateien:Hallo Hagen, also ein Test mit einem anderen Board + µC ergab keinerlei Probleme. Skeptisch wie ich war hab ich mal auf meinen luftverdrahteten RS232 Pegelwandler getippt. Da ich eh ein wenig mit dem Ding unzufrieden war hab ich mir jetzt ein paar Stunden Zeit genommen und einen neuen entworfen, geätzt, bestückt und getestet (siehe Anhang, speziell für die Heimätzer mit Tonermethode). Fazit: geht immer noch nicht! Also nochmal den anderen µC mit anderem Wandler ran - zack, geht. µC getauscht, neuer Wandler dran, geht auch. Also musste es was mit dem anderen µC zu tun haben. Und letztendlich Hand an den Kopf hau wars mir klar. 16MHz Quarz und CKOPT nicht gesetzt! Aahh... :-) Naja, jetzt letztendlich läuft alles 1A. Und immerhin hab ich jetzt einen funktionierenden 2-Kanal-RS232-TTL-Pegelwandler mit optionalem RTS/CTS. Gruß und Dank Daniel
Datum:
@hige: >ich hab in der avrootloader.asm nur den jeweiligen Controller >ausgewählt. und dann 1.) BootCodeSize = 0 geändert 2.) erneut alles kompiliert 3.) aus CSeg Used im Messagewindow vom AVRStudio den Wert in BootCodeSize geschrieben 4.) alles nochmals kompiliert ? Gruß Hagen PS: wenn nicht dann 5.) den Thread hier und die Readme nochmals gelesen ? ;)
Datum:
@Daniel: somit steht es geschätzte 534 zu 1 für die Fehlerquote bei den Anwendern zu AVRootloader ;)
Datum:
@Hagen: Hauptsache letztendlich siegt Köpfchen über Frust. :) Eine Frage... weißt du wie sich die Implementierung eines Bootloaders in C größenmäßig zur Implementierung in Assembler verhält? Gruß Daniel
Datum:
Es ist schwer objektive Aussagen zu machen. Das einizige Projekt bei dem ich mal die gleiche Library in C und handmade Assembler programmiert habe war meine Nokia Grafik Library. Entwickelt in WinAVR GCC einmal als fast reiner C Source und einmal als handmade Assembler aber auch in WinAVR GCC. Ergebisse waren: 1.) Assembler war nur 50% so groß 2.) Assemblerversion war weitaus schneller in der Ausführung 3.) der nutzbare Funktionsumfang der Assemblerversion ist größer Aber alle Punkte waren das Resultat der gewonnenen Freiheiten die man im Assembler hatte. Zb. wurde in der Assemblerversion die Aufrufkonventionen der einzelnen Funktionen und die dabei benutzten Register/Stack usw. so manuell verteilt das es auch in den übergeordneten Funktionen nicht notwendig war diese Register zu sichern. Dann gibt es Zeichenroutinen zb. für Ellipsen und Linien die in C intern mit 32Bit Variablen rechnen mussten. In Assembler konnte das aber so optimiert werden das zb. nur 24Bit Berechnungen nötig waren. Desweiteren gibt es verschiedene Funktionen die im Grunde sich nur in den Parametern unterschieden und dann immer die gleiche Unterfunktion aufrufen. Hier kann man im Assembler einigen an unötigem Code wegoptimieren indem man die Einsprungpunkte quasi inmitten einer Basisfunktion legt. Das spart im Vergleich zum C Compiler ne Menge an Stackrame, Register sichern, CALLs und sogar RETs. Alles zusammen genommen bewirkte also obige drei Resultate. Die dazu benutzten Optimierungen zeigen aber auch deutlich das bewusst die technologisch bedingten Schwachstellen des Compiliers ausgenutzt wurden. Und somit ist der Vergleich C Copmiler vs. Mensch und Assembler unfair und wenig aussagekräftig. Wir Menschen sind immer noch besser als die Maschinen. Übrigens falls das Argument kommt: Mit dem C Compiler wäre man schneller. Das ist in diesem Falle nicht so gewesen. Da ich zuerst die C Version gebaut habe, mich sowohl in C, den C Compiler Eigenheiten gut auskennen und weiß was der C Compiler in Assembler hätte optimalerweise erzeugen können, wusste ich bei der Asseblerversion von Anfang an was ich wie exakt wollte. Das Schreiben der Assemblerversion hat mich weit weniger Zeit, < 2 Tage, gekostet. Aber auch hier wieder das Argument das es ohne die vorherige C Version und der Vorarbeit des C Compilers eben nicht so gewesen wäre. Den AVRootloader.asm Source habe ich nach den gleichen Regeln codiert und ich bin mir ziemlich sicher das eine reine C Version mindestens doppelt so groß wäre. Verzichtet man auch alle zusätzlichen Funktionen in AVRootloader so ist dieser schon sehr kompakt, ca. 360 Bytes groß. Selbst für einen erfahrenen ASM Programmierer dürfte es schwierig sein da noch > 32 Bytes rauszuholen (und nur das macht Sinn auf Grund der Pagesize des FLASHs). Gruß Hagen
Datum:
Und um Diskussionen über Sinn und Unsinn eines solchen Aufwandes vorzubeugen. Ja, beim AVRootloader, der ja alle selbst programmierbaren AVRs unterstützt ist es schon wichtig auch auf die geringste Codegröße hin zu programmieren. Als Zielsetzung wars von Anfang an auch die kleinen AVRs angestrebte oberste Priorität. Damit ist die Wahl der Mittel defakto entschieden. Gruß Hagen
Datum:
Hallo Hagen, ich will mit der Frage sicher nicht die alte Diskussion vom Zaun brechen. Beide Sprachen haben ihre Daseinsberechtigung. Worüber ich mir allerdings Gedanken mache, ist, inwiefern ein ASM Projekt mit einem in C geschriebenen Projekt erweitert werden kann. Ich kenne zwar Projekte in einzelne Funktionen/teile dank Assembler auf Geschwindigkeit oder Größe optimiert wurden, jedoch kenn ich es bisher nicht, dass eine handgestrickte ASM Software einige in C codierte Routinen einbindet. Ich kenne zwar Assembler aber da ich nie damit arbeite kann ich mir auch keinen Eindruck davon machen, ob das möglich wäre. Wahrscheinlich müsste man alle "notwendigen" Register vor dem Aufruf der C-Routine wegsichern, quasi eine Stack-Implementierung, dann den assemblierten C-Code aufrufen, und später die Register rücksichern. Gruß, Daniel
Datum:
Nö das geht in beide Richtungen. Klar ist jedoch das man die Aufrufkonventionen festlegen und beachten muß. Aber das ist nicht das Problem da das auch bei Assemblerstücken innerhalb eines C Projektes der Fall ist. Ich sehe es so: beides sind Werkzeuge, ein Mittel um ein Ziel zu erreichen. Die unterschiedlichen Möglichkeiten beider Werkzeuge erhöhen, clever benutzt, doch nur die Flexibilität die wir uns leisten können um eben das Ziel zu erreichen. Eine Diskussion über das für und wider, ob C, Delphi, Assembler, VHDL usw. exitiert für mich garnicht, bzw. ist am Thema vorbei. Am besten man beherrscht alle und nutzt sie als Mittel zum Zweck, es sind eben nur Werkzeuge. Das wäre ja so als ob man sich streitet das nun die Statue der Athene viel besser künstlerisch aussehen würde wenn man statt Hammer und Meisel einen elektrischen Vorschlaghammer genommen hätte. Der künstlerische Anspruch, warum uns die Athene gefällt, hat doch nichts mit den benutzten Werkzeugen primär zu tun. Punkt. Gruß Hagen
Datum:
Hagen schrieb: > und dann > > 1.) BootCodeSize = 0 geändert > 2.) erneut alles kompiliert > 3.) aus CSeg Used im Messagewindow vom AVRStudio den Wert in > BootCodeSize geschrieben > 4.) alles nochmals kompiliert > > ? Ja, so mach ich es immer. Nutze deinen Bootloader nicht zum ersten mal. Verstehs auch nicht. Werd die Onewire-Verbindung mal in einem anderen Board testen. Grüße Hige
Datum:
Angehängte Dateien:Moin moin Hagen & Co. nachdem sich Hagen 'weigert' RTS auf High zu lassen beim beenden des Bootloaders damit der AVR weiter laeuft habe ich nach Lösungen gesucht und gefunden, siehe Schaltplan i hoffe der ein oder andere kann es gebrauchen... vielen Dank nochmals an Hagen fuer den super Bootloader vlg Charly
Datum:
@Charly: >nachdem sich Hagen 'weigert' RTS auf High zu lassen beim beenden des >Bootloaders ich weigere mich ja nicht, es ist technisch nicht sauber oder sogar möglich weil das Betriebsystem nicht mitspielt. Wird der Bootloader beendet so werden auch alle genutzten Resourcen wieder freigegeben. Würde ich das nicht explizit machen dann würde spätestens das OS dies für mich machen. Danach ist die COM Schnittstelle wieder frei für andere Software und ich kann ja schlecht deren Funktion beeinflussen. Gruß Hagen
Datum:
@Hagen das 'weigern' war nicht als vorwurf gemeint, ich hatte deine Argumente verstanden und deswegen nicht weiter nachgefragt und nach einer anderen Loesung gesucht, und gefunden. Ich verwende den Bootloader per Komandozeile und so ist es halt praktisch wenn der Bootloader einfach alles uebernimmt und ich in meiner Soft es nicht beruecksichtigen muss, halt was fuer 'Faulpelze' wie ich ;) vlg Charly
Datum:
Angehängte Dateien:Hi, nach dem mir bei PeDas fastboot wichtige Features fehlen bin ich auf AVRootloader gestoßen. Von der Featureliste und Konfigurierbarkeit ist der ja ein Traum. Leider bekomme ich ihn nicht zum laufen. will ihn auf einem mega168 mit 16Mhz Quarz bekommen. ich habe ein paar configs geändert, ihn übersetzt, die Größe eingetragen, noch mal übersetzt geflasht und die fuses gesetzt (e/h/l 0x04/0xDF/0xF7) (angepasstes Projekt im Anhang) allerdings kann ich nicht mit dem Bootloader verbinden. In dem Tool habe ich die Baudrate eingestellt und connect geklickt, dann am Target ein Reset ausgeführt. Dann versucht er ewig eine Verbindung herzustellen.
Datum:
Ließ dir mal den Thread hier durch. 1.) in AVRootloader.ini [Timeouts] Options=2 setzen um Debug Infos anzuzeigen 2.) einen Connect probieren 3.) den Output in der Protokollpage hier posten Gruß Hagen
Datum:
Hagen Re schrieb: > Ließ dir mal den Thread hier durch. ich habs mit ein paar Suchworten probiert. aber ein 2 Jahre, 6 Sofftwareversionen und 600-Beiträge alten Thread komplett durchzuarbeiten bringt halt meistens auch nicht so viel, da auch eine Menge veraltete Infos drinstehen. Das einfachste wäre, wenn die relevantesten Infos im Artikel zusammengetragen wären. > > 1.) in AVRootloader.ini [Timeouts] Options=2 setzen um Debug Infos > anzuzeigen > 2.) einen Connect probieren > 3.) den Output in der Protokollpage hier posten Am Output ändert das irgendwie gar nix. es ist weiterhin nur folgendes zu lesen: 11.07.10-07:54:20-093 > Connecting on port COM4... zwischendurch habe ich mehrere Male am Target die Stromzufuhr unterbrochen bis ich dann irgendwann selbst auf abort klicke 11.07.10-07:55:27-656 > aborted by User
Datum:
Hallo Hagen, schade, falls Du doch noch mal Zeit/Lust haben solltest ein bisschen Doku zu machen, würde ich Dich an mein Post vom 30.04 erinnern: [Beitrag "Re: AVR-Bootloader mit Verschlüsselung"]
Datum:
@Vlad >Ließ dir mal den Thread hier durch. Damit meinte ich das deine Infos einfach zu wenige sind um dir helfen zu können. Also fange ich nochmal an: Wie sieht deine Hardware aus ? Laut deiner Konfiguration des Bootloaders gehe ich davon aus das du - 19200 Baudrate hast - das du keinen RS232 Pegelwandler benutzt - das du 2-Wire RS232 benutzt - das dein AVR mit 16MHz läuft und auch die Fuses entsprechend gesetzt wurden Da das eine ziemlich ungewöhnliche Konfguration ist gehe ich davon aus das du einen Pegelwandler benutzt. Setze: .equ UseAutobaud = 1 .equ UseUartInvert = 1 UseAutoBaud nimmt dir nicht viel mehr an FLASH weg, dafür macht es den Bootloader unabhängig von einer festen Baudrate und unabhängig von falschen Quarzen und falschen Quarzfusebits. UseAutoBaud=0 ist also nur für Spezialanwendungen, bei denen der User weiß was er tut, interessant. UseUartInvert muß 1 sein wenn mit einem Pegelwandler wie den MAX232 oä. gearbeitet wird. In meinem letzten Posting sagte ich: Poste hier dein Protokoll Auszug, dann kann ICH mehr erkennen. Wo ist er ? Ändere auf [Timeout] Options=1 und teste dann nochmal. Gruß Hagen
Datum:
@Achim: ja ich weiß :| und ich arbeite dran. Da ich heute nicht sonderlich viel zu tun habe, außer das ich mal ausspannen wollte, sehe ich mal zu deine Fragen zu beantorten. Schicke dir dann eine PN. Gruß Hagen
Datum:
Na dann spann mal erst aus! PN gerne, wenn Du soweit bist. Gruß Achim
Datum:
@Achim: du bist ja garnicht angemeldet, PN fällt flach. "AVRootloader" $06 (Bottloaderversion?) $26 (??) Das ist der File Format Identifier. String AVRootloader gefolgt von 1 Byte Haupotversionsnummer -> 6. Am Ende $26 = EOF = End Of File. Ein ASCII Text Editor/Viewer zeigt nur bis hierhin Daten an. "ACYInfo" $20 (Leerzeichen?) "1.0.0.0" (Version Software) $00 (Terminierung?) Ein benutzerdefeinierbarer Info-String über diese Datei. ACYInfo wird im GUI durch den User eingetragen. Wird Versioning benutzt so steht mit Leerzeichen getrennt die eingestellte Version aus dem GUI mit in diesem String. Null terminiert. $1E$xx$xx (Device Sign) $00 (??) $0F (??) $06 (??) $00 (??) $2F (??) - 4 Bytes Device Signature - 1 Byte Anzahl der FLASH Pages die der Bootloader benutzt - 1 Byte Hauptversion des Bootloaders - 2 Bytes Flags, bitkodierte Informationen über die Fähigkeiten des Bootloaders, zb. Verschlüsselung usw. Die Infos sind unverschlüsselt und im Grunde identisch mit dem was der Bootloader im AVR bei einem Connect zurück meldet. Das GUI benutzt beim flshen einer ACY diese Infos und vergleicht sie mit denjenigen die sie vom AVR geliefert bekommt. Nur wenn diese übereinstimmen wird das GUI das ACY flashen. Dh. gleicher AVR, Bootloader usw. mit der die ACY erzeugt wurde und der aktuell programmiert werden soll. > Ab hier Befehle $FE $FE $XX $XX... Datenblöcke und Kommandos Korrekt. >2. das Kommando $FE hab ich nicht so ganz klar. Dahinter kommt $00 wenn >ich ins EEProm unverschlüsselt schreibe. In der ACY Datei aber $FE mit >24 Byte irgendwas und danach $FF. Also "$FE $?? (highbyte Size) (lowbyte >Size). Bei Verschlüsselten Daten muß der AVR erstmal die Entschlüsselung initialisieren. Dazu wird ein verschlüsseltes Initialisierungs-Packet benutzt. Dieses Packet ist entweder 16 Nutzbytes oder 24 Bytes groß. - 8 Bytes Zufall, quasi ein innerer zufälliger Initialisierungvektor = IV. Nirmalerweise überträgt man den in vielen Verfahren unverschlüsselt. Ich bevorzug dies verschlüsselte Variante, der Rest ist aus kryptographischer Sicht identisch zu den gewohnten Verfahren Nun unterscheidet es sich jenachdem ob man Versioning benutzt oder nicht. Ohne Versioning: - 2 Bytes Signature des AVRs - 1 Byte Bootloader Version - 1 Byte Anzahl FLASH Pages des Bootloaders - 4 Bytes, die ersten 4 Bytes des Schlüssels Mit Versioning: - 4 Bytes weiterer Zufall, ergibt 12 Bytes Zufallsblock am Anfang des Packetes - 4 Bytes die Versionsnummer aber maskiert zur Überprüfung - ab hier wieder gleich zu oben - 2 Bytes Signature des AVRs - 1 Byte Bootloader Version - 1 Byte Anzahl FLASH Pages des Bootloaders - 4 Bytes, die ersten 4 Bytes des Schlüssels Dieser 16/24 Bytes Block wird verschlüsselt übertragen. Kommando $FE$FE, 2 Bytes LÄnge der nachfoldenenden Daten, 16 Bytes Daten Da der Verschlüsselungalgo., sprich der modifizierte Doppel-CBC-Feedback-Cipher-Mode nicht zurückgesetzt wird heist dies das sich die verschlüsselten 8/12 Bytes Zufallsbytes komplett durch die ganzen verschlüsselten Datenblöcke fortpflanzen. Würde man also die exakt gleiche HEX Datei mit exakt gleichen Info wie Passwort usw. mehrfach in ACY Dateien compilieren so würde sich denoch jedesmal ein komplett anderes verschlüsseltes Resulat ergeben. Das verhindert eine ganze Reihe von kryptologischen Angriffen. Nachdem der AVR nun dieses 16/24 Bytes große verschlüsselte Packet empfangen hat wird er es erstmal entschlüsseln. Damit wird er sich, eg. sein internes Feedback Register auch mit den richtigen Zufallswerten synchronisieren. Er vergleicht erstmal die letzten 4 Bytes des entschlüsselten Datenblockes mit den ersten 4 Bytes seinen Passwortes. Sollten diese nicht identisch sein so wurde entweder mit falschem Passwort verschlüsselt, der AVR benutzt ein falsches Passwort zur Entschlüsselung, der Datenstrom wurde falsch übertragen (wir nutzten extern nur eine 16 Bit CRC) mit dem XTEA nutzen wir eine 64 Bit CRC die aber auf 32Bit truncated ist (unser 4 Bytes Vergleich mit dem Passwort). Dieser 4 Bytes Vergleich erfolgt immer, egal ob Init-Packet oder später die einzelnen verschlüsselten Datenpackete empfangen wurden. Beim Init-Packet vergleicht der AVR nun die Signature, Version, BootPages mit seinen eigenen. Stimmen sie nicht überein so gibts wieder einen Fehler. Bei jedem Fehler den die Entschlüsselung meldet wird jeder Befehl der verschlüsselt sein kann gesperrt. Dh. nur mit einem korrekt empfangenen und entschlüsselten Init-Packet arbeitet die interne Bootloader-FSM weiter ansonsten blockiert sie. Wurde mit Versioning gearbeitet so lädt nun der AVR die entschlüsslte Versionsmaske und vergleicht sie mit der im AVR gespeicherten Version. Je nach Maskeneinstellung führt dies dazu das der AVR zb. erkennt das schon eine neuere Version installliert wurde und verhindert dann wiederum durch einne Fehlercode das man auf Downgrade machen kann. So damit wäre die Initialisierung der Entschlüsselung im AVR abgeschlossen. Da alle wichtigen Infos auch im ACY verschlüsselt gespeichert wurden, sie nur vom Erzeuger der ACY und des AVR ver/entschlüsselt werden können, ist das ziemlich sicher. Auch wenn man die unverschlüsselten Daten im Header der ACY Datei manipulieren würde so würde man nur das GUI austricksen damit aber nicht den AVR Bootloader. Wenn also mit Verschlüssleung gearbeitet wird so überprüft der AVR selber ob die ACY Daten für ihn die richtigen sind. Wird ohne Verschlüsselung gearbeitet so überprüft das das GUI. Sonstige Kommandos im ACY File: - CmdSetAddr: $FF, 3 Bytes Addresse, setzt die EEPROM,FLASH,SRAM Schreib/Leseadresse - CmdWriteBuffer (unverschlüsselt): $FE00, 2 Bytes Datengröße, Daten - CmdWriteBuffer (unverschlüsselt): $FE01, 2 Bytes Datengröße, Daten, dieses Kommando schreibt die empfangenen Daten in den SRAM an die mit CmdSetAddr übergebenen Speicheradresse. Siehe unten. - CmdWriteBuffer (verschlüsselt): $FEFF, 2 Bytes Datengröße immer durch 8 teilbar, Daten - CmdWriteBuffer (verschlüsselt Init): $FEFE, 2 Bytes Datengröße (16/24), Daten - CmdWriteFlash: $01, 1 Byte Wiederholungszähler, diese Kommando schreibt die mit CmdWriteBuffer empfangenen und eventl. entschlüsselten Daten an die mit CmdSetAddr angegebenen FLASH Addresse. Dabei werden soviele Bytes geschrieben wie mit CmdWriteBuffer empfangen wurden. Der Wiederholungszähler gibt an wie oft diese Operation nacheinander wiederholt wird, wobei aber der internen Addresszähler immer weiter inkrementiert wird. Man könnte also mit CmdWriteBuffer() nur das Zeichen $AA senden. Dann mit $01 $80 dieses Zeichen 128 mal in den FLASH schriben lassen, also einen Buffer der aus 128 mal $AA bestünde. Somit unterstützt das Bootloader Protokoll/Dateiformat etc.pp. schon eine primitve Komprimierung die redundante Daten entfernen kann. - CmdEraseFlash: $02, 1 Byte Page Anzahl. Löscht die Flash Pages ab CmdSetAddr Addresse. - CmdVerifyFlash: $03, 1 Byte Page Anzahl. Die mit CmdSetBuffer empfangenen/entschlüsselten Daten werden mit den Daten im FLASH ab Addresse mit CmdSetAddr vergliche - CmdWriteEEPROM: $05, 1 Byte Wiederholungszähler, siehe CmdWriteFlash Das sind die Kommandos die in einem ACY vorkommen dürfen. Der Bootloader versteht zusätzlich noch: - CmdKeepAlive: $FD, $00, diese Kommando ist defakto garnicht implementiert. Das GUI sendet es im Interval < 2 Sekunden ab, der Bootloader empfängt es als illegales Kommando, sendet Fehler zurück, setzt aber auch intern seinen WDT zurück bei jedem Kommando/Kommunikation. Somit erzielen wir zwei Vorteile: der AVR Bootloader startet autom. die eigene Anwendung wenn sich das GUI nicht mehr meldet. Das GUI trennt autom. eine Verbindung wenn der AVR sich nicht mehr meldet. - CmdReadEEPROM: $04, 1 Byte Anzahl Bytes, lese aus EEPROM - CmdReadSRAM: $06, 1 Byte Anzahl Bytes, lese den SRAM - CmdWriteSRAM: wird über CmdWriteBuffer() simuliert. Man setzt mit CmdSetAddr() erstmal die Startaddresse und mit CmdWriteBuffer() werden dann diese Daten ab dieser Address gespeichert. Dh. ab Address 0x0000 bis 0x001F liegt das Registerfile. Man überschreibt somit die internen Register des AVRs. Danach kommen die Ports usw. dh. man überschrebt die Ports usw. Danach kommt der normale SRAM in den man schreiben kann. Mit CmdRead/WriteSRAM: kann man also aus dem GUI heraus den AVR komplett steuern. Das ist so wie ein kleiner Mini-Debugger. Deshalb gilt: nieamls UseSRAM=1 setzen wenn man Kryptographie benutzt da das eine Hintertüt für einen Angreifer öffnen könnte. Im Gegensatz zu den Kommandos in der ACY Datei werden alle Kommanods und Daten während der Kommunikation von/zum AVR mit einer 16 Bit CRC abgesichert. Es gibt also 2 oder 4 Bytes Kommandos. Danach kommen 2 Bytes CRC üder diese Kommandos. Wenn Daten folgen dann kommen jetzt die Daten und darüber am Ende wieder 2 Bytes für die 16 Bit CRC. Das ist auch beim Lesen vom SRAM/EEPROM so. Werden verschlüsselte Datenblöcke gesendet, also nachdem man die Initialisierung hinter sich hat so sind das immer glatt durch 8 teilbare Packetlängen. Es werden die Daten verschlüsselt gesendet mit einem 8 Bytes abschließenden Datenpacket. Dieses Datenpacket ist so aufgebaut - 3 Bytes Addressfeld, das ist die Addressinformation die man normalerweise mit CmdSetAddr sendet. Bei verschlüsselter Kommunikation steht diese Addresse natürlich hier in verschlüsselter Form. Manipulationen durch umsortieren der Addressen also ausgeschlossen - 1 Bytes Daten-Längen-Korrektur-Byte. Alle verschl. Datenpackete müssen 8 Bytes lang sein. Sollten Daten verschl. werden die nicht ein mehrfaches von 8 Bytes lang sind so werden diese mit Zufallsdaten aufgefüllt so das das Packet ein Mehrfaches von 8 Bytes lang wird. Die Anzahl der dafür nötigen Zufallsbytes kann von 1 bis 7 gehen und steht in diesem Datenfeld. Nach empfang aller Datenpackete und deren Entschlüsselung wird das interne Daten-Längen-Register durch Subtraktion mit diesem Korrekturbyte korregiert. - 4 Bytes Prüfsumme = ersten 4 Bytes vom Passwort Der AVR empfängt also das letzte 8 Bytes Packet, entschlüsselt es und vergleicht wiederum die 4 Bytes Prüfsumme. Gibts einen Fehler gilt das oben schon gesagte. Ansonsten nimmt der die Addressinfos und speichert die in sein internes bis zu 3 Bytes großes Addressregister. So das wäre im Grunde das komplette Protokoll. Gruß Hagen PS: Ich habe nicht nochmal Korreturgelesen, sorry, Schreibfehler gehören euch
Datum:
>@Achim: du bist ja garnicht angemeldet, PN fällt flach.
Jetzt habe ichs schon gepostet, hab dein Posting nicht gesehen ;)
Datum:
Angehängte Dateien:Hagen Re schrieb: > @Vlad > >>Ließ dir mal den Thread hier durch. > > Damit meinte ich das deine Infos einfach zu wenige sind um dir helfen zu > können. Also fange ich nochmal an: > > Wie sieht deine Hardware aus ? > > Laut deiner Konfiguration des Bootloaders gehe ich davon aus das du > - 19200 Baudrate hast ja, die hatte ich runtergesetzt um Verbindungsprobleme auszuschließen > - das du keinen RS232 Pegelwandler benutzt richtig > - das du 2-Wire RS232 benutzt 2-Wire UART um genau zu sein (USB-UART-Adapter) > - das dein AVR mit 16MHz läuft und auch die Fuses entsprechend gesetzt > wurden jep, die passen. wenn ich ein eigenes Programm draufflashe klappt die Kommunikation mit 19200Baud reibungslos > > Da das eine ziemlich ungewöhnliche Konfguration ist gehe ich davon aus > das du einen Pegelwandler benutzt. nein, es ist wirklich eine UART wieso ungewöhnlich? es ist ein atmega168 mit 16Mhz in Minimalbeschaltung (reset, pullup, quarz+C, Abblock-C) > > Setze: > > .equ UseAutobaud = 1 habe ich auch schon probiert. > .equ UseUartInvert = 1 > > UseAutoBaud nimmt dir nicht viel mehr an FLASH weg, dafür macht es den > Bootloader unabhängig von einer festen Baudrate und unabhängig von > falschen Quarzen und falschen Quarzfusebits. UseAutoBaud=0 ist also nur > für Spezialanwendungen, bei denen der User weiß was er tut, interessant. die Autobaudrate macht den Unterschied zwischen 512Byte bootloader und 1k, deswegen wollte ich die ausschalten. Wie gesagt, hatte ich es aber auch schon mit probiert - mit den selben Symptomen. > > UseUartInvert muß 1 sein wenn mit einem Pegelwandler wie den MAX232 oä. > gearbeitet wird. > > In meinem letzten Posting sagte ich: Poste hier dein Protokoll Auszug, > dann kann ICH mehr erkennen. Wo ist er ? mit Protokoll meinst du doch den Protocol-Tab, oder? da tauchen wirklich nur diese beinde Zeilen auf. > > Ändere auf [Timeout] Options=1 und teste dann nochmal. ok, jetzt ist das ganze etwas gesprächiger:
11.07.10-12:09:17-218 > Connecting on port COM4... 11.07.10-12:09:17-218 > Timeout.Connect = 50 ms 11.07.10-12:09:17-218 > Timeout.Base = 50 ms 11.07.10-12:09:17-218 > Timeout.Erase = 10 ms 11.07.10-12:09:17-218 > Timeout.Flash = 15 ms 11.07.10-12:09:17-218 > Timeout.Eeprom = 10 ms 11.07.10-12:09:17-218 > Timeout.Buffer = 1 ms 11.07.10-12:09:17-218 > Timeout.AppCmd = 0 ms 11.07.10-12:09:17-218 > Timeout.KeepAlive = 250 ms 11.07.10-12:09:17-218 > Timeout.RTSPulse = 0 11.07.10-12:09:17-218 > Timeout.RTSInterval = 0 11.07.10-12:09:17-218 > Timeout.ConnectTrials = -1 11.07.10-12:09:17-218 > Timeout.MaxPacketSize = 0 11.07.10-12:09:17-234 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-12:09:17-437 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-12:09:17-640 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 [... (bis auf die Zeiten immer das gleiche)] 11.07.10-12:09:28-421 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-12:09:28-625 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-12:09:28-718 > aborted by User |
Und nochmal danke für die Zeit, die du dir für die Erklärungen nimmst. Gruß, Vlad Edit: Im Anhang mal die Fuses-Eisntellungen. Die sollten aber eigentlich passen.
Datum:
Suppi!!! Danke herzlichst Hagen! Hagen Re schrieb: > Jetzt habe ichs schon gepostet, hab dein Posting nicht gesehen ;) Ich kopiers mir ;-)
Datum:
Mensch Kommando 0x00 vergsssen: - CmdRestart: 0x0000, startet den Bootloader neu - CmdStartApp: 0x00??, startet die geflashte Anwendung Ist ein 2 Bytes Code. CmdRestart -> 0x0000 würde mit 2 Bytes CRC also 0x00 0x00 0x00 0x00 sein, da 16 Bit CRC über 0x0000 = 0x0000 ist. Somit werden alle sich wiederholenden 0x00 Bytes Sequenzen autom. als Soft-Reset des Bootloaders interpretiert. Der Bootloader startet dann normalerweise wieder seine AutoBaud Detektion, ermittelt Baudrate neu, prüft BootSign erneut und sendet bei Erfolg seine Informationen wie BootInfo erneut zum GUI. Somit erklärt sich auch warum man kein extra Kommando für die Ermittlung der Fähigkeiten des Bootloaders benötigt, also Ermitteln von FLASH/EEPROM/Version usw. Zudem hat man so, auch bei falschen Baudraten einen Weg wie der Bootloader aus seiner FSM wieder neu gestartet werden kann. Die Wahscheinlichkeit ist groß das bei falscher Baudrate und dem Senden von wiederholten 0x00 der Bootloader das denoch als CmdRestart Kommando erkennen kann und somit neu startet, neu Baudrate usw. usw. wie oben schonmal erklärt. Letzendlich dient das und der WDT (CmdKeepAlive), UseResetDelay=1 usw. alles dazu den Bootloader äußerst stabil zu machen. Wird als 2. Byte <> 0x00 benutzt so wird die Applikation gestartet. Gruß Hagen
Datum:
>> - das du keinen RS232 Pegelwandler benutzt >richtig >> - das du 2-Wire RS232 benutzt >2-Wire UART um genau zu sein (USB-UART-Adapter) Gut dann benutzt du also einen RS232-Pegelwandler, nicht einen MAX232 aber einen USB-RS232. Es muß UseUartInvert=1 gesetzt werden. Aus dem Protokoll erkennt man das nichts empfangen wird. Überprüfe 1.) USB Treiber 2.) virtuellen COM4 Port, oder benutze mal AUTO 3.) sind RX/TX an PD0 und PD1 richtig ? 4.) Oszi an RX/TX dran und schauen 5.) Debug-Trick - UseRS485=1 setzen - DE_PORT und DE setzen auf einen freien Pin oder auf einen an dem eine LED dran ist - UseRS485Invert=0 oder 1 setzen je nach LED Polarität Wenn der AVR nun korrekte Daten empfangen hat wird der den in DE_PORT/DE konfigurierten Pin, deine LED beim Senden ein/ausschalten. Du siehst also wenn die LED flackert das der Bootloader auf den gesendeten Connect Versuch reagieren möchte. 6.) BootSign in GUI und AVRootloader.asm identisch ? In ARRootloader.asm am Ende des Sources. Denke das ist bei dir der Fall, BOOT im ASM und BOOT im Protokoll. 7.) verbinde mal RX/TX des USB-RS232 miteinander. Dann schaue dir nochmal das Protokoll beim Connect an. Du solltest dort den gesendeten Ident als empfangenen sehen. Wenn nicht, USB-RS232 Scheiße, dort Fehler suchen... Gruß Hagen
Datum:
>die Autobaudrate macht den Unterschied zwischen 512Byte bootloader und >1k, deswegen wollte ich die ausschalten. Darum kümmern wir uns später, jetzt erstmal UseAutoBaud=1 setzen, bis es bei dir funktioniert. Deine Fuses sehen erstmal richtig aus, auch wenn ich die Software nicht kenne. Im Compiler-Message-Window vom AVRStudio siehst du nach der Compilation welche Fuses (BOOTSZ) du setzen musst. Gruß Hagen
Datum:
Hagen Re schrieb: >>> - das du keinen RS232 Pegelwandler benutzt >>richtig >>> - das du 2-Wire RS232 benutzt >>2-Wire UART um genau zu sein (USB-UART-Adapter) > > Gut dann benutzt du also einen RS232-Pegelwandler, nicht einen MAX232 > aber einen USB-RS232. nein, gar kein RS232. einen reinen USB-UART um genau zu sein: http://www.recursion.jp/avrcdc/ > > Es muß UseUartInvert=1 gesetzt werden. > > Aus dem Protokoll erkennt man das nichts empfangen wird. Überprüfe > 1.) USB Treiber > 2.) virtuellen COM4 Port, oder benutze mal AUTO beides funktioniert. Wenn ich den Adapter kurzschließe, bekomme in einem Terminalprogramm das echo > 3.) sind RX/TX an PD0 und PD1 richtig ? Ich habs an die Hardware-UART-Pins angeshlossen (PD0, PD1). > 4.) Oszi an RX/TX dran und schauen hab kein Oszi > 5.) Debug-Trick > > - UseRS485=1 setzen > - DE_PORT und DE setzen auf einen freien Pin oder auf einen an dem eine > LED dran ist > - UseRS485Invert=0 oder 1 setzen je nach LED Polarität > > Wenn der AVR nun korrekte Daten empfangen hat wird der den in DE_PORT/DE > konfigurierten Pin, deine LED beim Senden ein/ausschalten. Du siehst > also wenn die LED flackert das der Bootloader auf den gesendeten Connect > Versuch reagieren möchte. > > 6.) BootSign in GUI und AVRootloader.asm identisch ? In ARRootloader.asm > am Ende des Sources. Denke das ist bei dir der Fall, BOOT im ASM und > BOOT im Protokoll. ja, die sind identisch > > 7.) verbinde mal RX/TX des USB-RS232 miteinander. Dann schaue dir > nochmal das Protokoll beim Connect an. Du solltest dort den gesendeten > Ident als empfangenen sehen. Wenn nicht, USB-RS232 Scheiße, dort Fehler > suchen... > > Gruß Hagen wenn ich RX/TX an meinem UART-Adapter kurzschliße und das Tool benutze, kommt folgendes Log:
11.07.10-13:44:49-484 > Connecting on port COM4... 11.07.10-13:44:49-484 > Timeout.Connect = 50 ms 11.07.10-13:44:49-484 > Timeout.Base = 50 ms 11.07.10-13:44:49-484 > Timeout.Erase = 10 ms 11.07.10-13:44:49-484 > Timeout.Flash = 15 ms 11.07.10-13:44:49-484 > Timeout.Eeprom = 10 ms 11.07.10-13:44:49-484 > Timeout.Buffer = 1 ms 11.07.10-13:44:49-484 > Timeout.AppCmd = 0 ms 11.07.10-13:44:49-484 > Timeout.KeepAlive = 250 ms 11.07.10-13:44:49-484 > Timeout.RTSPulse = 0 11.07.10-13:44:49-484 > Timeout.RTSInterval = 0 11.07.10-13:44:49-484 > Timeout.ConnectTrials = -1 11.07.10-13:44:49-484 > Timeout.MaxPacketSize = 0 11.07.10-13:44:49-484 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-13:44:49-703 > received data $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 10 60 11.07.10-13:44:49-703 > Switch to 1-Wire mode 11.07.10-13:44:49-703 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-13:44:49-921 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-13:44:50-125 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-13:44:50-328 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 11.07.10-13:44:50-484 > aborted by User |
Merkwürdig finde ich, dass da noch ein 10 60 dahinter kommt (\n>) Aber da er in den 1-Wire-Modus wechselt scheint das normal zu sein. Das sollte für ein Funktionieren der Schnittstelle sprechen, oder? Hagen Re schrieb: > Deine Fuses sehen erstmal richtig aus, auch wenn ich die Software nicht > kenne. Im Compiler-Message-Window vom AVRStudio siehst du nach der > Compilation welche Fuses (BOOTSZ) du setzen musst. jep, das habe ich gesehen und gemacht. Das Tool ist der AVR8-Burn-O-Mat, das ist eine JAVA-GUI für avrdude. Edit: Ach so, die Sache mit dem RS485 debug-Trick: da passiert überhaupt nix, egal, ob invert, oder nicht (die LED ist über den Pin nach GND geschalten) Ich habe das gefühl, dass die ich entweder beim Bauen, oder beim Flashen irgendwas falsch mache.
Datum:
Hast du einen kommerziellen USB-RS232-Wandler oder vielleicht sogar einen echten COM Port an deinem Rechner ? Wenn ja probier es mal damit aus, einfach um Fehler in der exotischen HW ausschließen zu können. Sehr oft, ja sogar am häufigsten lag es nämlich bisher immer an der SW oder HW der USB-RS232 Wandler. >Merkwürdig finde ich, dass da noch ein 10 60 dahinter kommt (\n>) Ist die 16 Bit CRC Prüfsumme, die sichtbar wird beim Empfangen. >Aber da er in den 1-Wire-Modus wechselt scheint das normal zu sein. >Das sollte für ein Funktionieren der Schnittstelle sprechen, oder? Ja, aber das soll noch nichts heissen. Eine Idee hätte ich noch: Öffne die AVRootloader.dev Datei mit einem Texteditor. Suche darin nach dem ATMege168, der muss da drinnen stehen. Hm, auch blöder Voschlag, wir wissen ja das überhaupt nichts zurück kommt. Tja, versuch es mit kommerziellen USB-RS232 Wandler, vielleicht stimmt bei deinem ja irgendwas mit den Pegeln nicht oder so. Hast du schon einen anderen Bootloader mit der gleichen HW zum laufen bekommen ? Gruß Hagen PS: USB-RS232 == USB-UART
Datum:
ich habe jetzt mal ganz am Anfang des Bootloaders folgenden Code eingebaut:
.org BootStart init: cli xwdr clr zerol sbi DDRC,0 ; die sbi PORTC,0 ; und die ldi cmdl, byte1(RamEnd) |
damit sollte doch direkt nach einem Reset eine LED an dem Pin angehen, oder sehe ich das falsch?
Datum:
jupnöö, also jain, oder Ja und Nein. Blöde Fragestellung.
Datum:
Um sicher zu gehen: 1.) konfiguriere alle Use???? Defines in AVRootloader.asm 2.) setze BootCodeSize = 0 3.) compiliere mit AVRStudio 4.) nun aus Messagewindow CSEG [used] nach BootCodeSize kopieren 5.) compiliere mit AVRStudio 6.) achte im Messagewindow auf die BOOTSZ Einstellungen 7.) flashen 8.) Fuses Gruß Hagen
Datum:
Hagen Re schrieb: > Hast du einen kommerziellen USB-RS232-Wandler oder vielleicht sogar > einen echten COM Port an deinem Rechner ? Wenn ja probier es mal damit > aus, einfach um Fehler in der exotischen HW ausschließen zu können. Sehr > oft, ja sogar am häufigsten lag es nämlich bisher immer an der SW oder > HW der USB-RS232 Wandler. bevor ich den alten laptop rauskrame: ist dein Programm auf win95 lauffähig? Hagen Re schrieb: > Hast du schon einen anderen Bootloader mit der gleichen HW zum laufen > bekommen ? jep, mit PeDas hatte ich es schon mal > > Gruß Hagen > > PS: USB-RS232 == USB-UART RS232 heißtfür mich "Hochspannung" und invertierte Pegel. Was ich gerade noch gecheckt habe: Die Adresse im Hex-file stimmt auf jeden fall mit der zu der Fuse-Config überein. und nach dem Auslesen des Controllers passt auch alles. Hagen Re schrieb: > jup "jup, ich sehe das falsch", oder "jup, die sollte angehen" an geht nämlich nichts. ich werd mal vorsichtshalber nen anderen Controller dranhängen, kann aber erst später weitermachen. Nochmal danke, für die Hilfe.
Datum:
Vlad Tepesch schrieb: > "jup, ich sehe das falsch", oder "jup, die sollte angehen" ok, das hast du schon beantwortet. > an geht nämlich nichts. habs nochmal überprüft. es geht doch an, ich hatte nur vergessen RS485 zu deaktivieren und es auf den selben Pin gelegt.
Datum:
Ich habs jetzt nochmal mit einem anderen Kabel (USB->Nokia-FBUS (ist auch ein usb-Uart)) probiert gleicher Effekt (gar keiner). Die Kabel miteinander reden zu lassen, klappt aber super, so dass ich da eine Fehlfunktion für unwahrscheinlich halte. Habe testweise auch mal probiert in der Gerätesteuerung die Puffer abzuschalten, hat aber auch nix gebracht. Hab einen anderen mega168 und sogar einen mega8 probiert. Irgendwie klappt gar nix. kannst du mal ein Codesnippet posten, dass man direkt am Anfang einfügen kann, welches ein "Hallo" per UART verschickt? (am besten per fester Baudrate) wenn ich das in ASM hinschreibe, bin ich mir immer noch nicht sicher, ob, wenn nix ankommt, mein Code oder die Verbindung schuld ist. Gruß, Vlad
Datum:
Gebe mir lieber die Konfiguration die du benötigst, ich compiliere es dann für dich undmaile dir das HEX. Gruß Hagen
Datum:
die Konfiguration, die ich oben schon gepostet habe. Aber was das bringen soll, frage ich mich. Ob du oder ich das kompiliere, sollte ja egal sein. Dass es an meiner Hardware liegt, kann man ja mittlerweile auch fast ausschließen. 2 verschiedene Kabel, die miteinander und mit Pedas Bootloader funktionieren. In anderen Projekten wurde das eine ja auch schon oft benutzt. Am interessantesten im Sinne des Debugging wäre jetzt ein Test-Bootloader, der mit deinem aktuellen Code ein paar Zeichen am Anfang rausschickt. ich habe das hier mal probiert
[...] .endif ; .if UseAutobaud sbi DDRC, 1 ; von mir sbi PORTC, 1 ; von mir ldi paral,'H' ; von mir rcall putc; ; von mir ; identifier (BootSign) scanning with timeout and checksum [...] |
Ob ich was übersehen habe und ob es so funktionieren kann, weiß ich nicht. Die LED geht nach dem Boot an, Zeichen kommen keine. Seh ich das richtig, das das ganze rein auf SW-Uart basiert?
Datum:
hallo hagen Ich möchte über Ihre Bootloader-Programm fragen. Nach dem Lesen einiger Kommentare Ich weiß, dass Sie XTEA verwenden, um die kompilierte Programm zu verschlüsseln. Aber ich bin wenig über die Verschlüsselung verwechselt. Wo sind die Verschlüsselung verwendet? Ist es in injiziert Programm AVR's oder in der GUI-Software? Wenn ich mein Programm verwendet werden, um die Firmware mit Hilfe gegeben makefile kompilieren, ist es nur kompiliert oder zusammengestellt und verschlüsselt? Ich bin auf Ihre Antwort warten. Was Favian
Datum:
@Favian: I try a answer in english, think thats better ;) With the GUI you can encrypt your HEX files into so called ACY files. You deliver this encryted ACY file to your customers. Your customers use the same GUI to download the ACY content encrypted to your preprogrammed AVR devices with installed AVRootloader. This bootloader receives the encrypted content and decrypt it. Thus, only your GUI and your AVRootloader.asm Bootloader knows the password and any communication, thus upgrades are encrypted. Otherwise it would be useless. Please remember follow important points to make it secure: - newer deliver any keys to your customer - thus ensure that in AVRootloader.ini at your customers in section [System] the topic Password= is empty - compile AVRootloader.asm with follow defines * UseCrypt = 1 * UseCryptFLASH = 1 * UseCryptE2 = 1, iff you want secure EEPROM updates * UseSRAM = 0 - choose always for each of your projects a new uniqe password, use the GUI and click the "Make Password" button. - make a full backup of the AVRootloaderproject to each of your projects - never deliver unencrypted HEX files to your customers - always setup the right security fuses of your AVR device !! - to increase upgrade security activate the versioning -> UseVersioning = 1. With this options you can finecontrol up/downgrading process and the versionnumber help you for better supports. Best regards, Hagen PS: as a little job i provide the possibility to you to costumize the GUI to your needs. As example changing the logo to your own ;)
Datum:
@Vlad:
>Seh ich das richtig, das das ganze rein auf SW-Uart basiert?
Ja, sehr ähnlich zu PeDa's Bootloader. Infact stammen die relevanten
Teile von Peter und ich habe sie an die Bedürfnisse vom AVRootloader
angepasst.
Wenn du also PeDa's Bootloader zum laufen bekommen hast dann sollte der
AVRootloader ebenfalls auf Anhieb laufen. Die
Konfigurierbarkeit/Compilation ist für Anfänger beim AVRootoader in
meinen Augen sogar noch einfacher.
[...] .endif ; .if UseAutobaud sbi DDRC, 1 ; von mir sbi PORTC, 1 ; von mir ldi paral,'H' ; von mir rcall putc; ; von mir ; identifier (BootSign) scanning with timeout and checksum [...] |
Das bringt garnichts. Die wichtigen Parameter für "putc" und damit SW-UART sind noch garnicht initialisiert.
; fixed baudrate ldi yl, byte1(Baudrate) ldi yh, byte2(Baudrate) movw baudl, yl .endif ; .if UseAutobaud ; identifier (BootSign) scanning with timeout and checksum ;id1: sbiw xl, ;... brne id1 ;... alles auskommentieren ; send info about chip/bootloader (BootMsg + BootInfo) info: ldi parah, (BootInfo - BootSign) * 2 +4 in1: xlpm paral, z+ rcall putc dec parah brne in1 |
probier es mit obiger Änderung. Nach der Baudraten Detektion -> UseAutoBaud=1 setzen, wird sofort das BOOTSIGN, BOOTMSG und BOOTINFO gesendet. Du solltest das dann als HEX-Antwort im Protokollfenster des GUIs sehen. Gruß Hagen
Datum:
Hagen Re schrieb: > PS: as a little job i provide the possibility to you to costumize the > GUI to your needs. As example changing the logo to your own ;) i think it would be great if the gui could contain a possibility to create a little Stand-Alone-Firmware-Updater. So the customer only need to select the com-port and hit flash and he does not have to configure that many options. This should not be difficult. You only need a template program that loads the logo, the firmware, eeprom (if any) and some parameters (signature, baudrate, version) from the exe-ressources. If i get the loader running and you will publish the delphi sources of the gui, maybe i can do that.
Datum:
;) @Vlad: I provide this as little job to earn a realy small fee, such as small that as example the normal money transfer from france to germany make it useless ;) Thus no public delphi sources of the GUI and no feature to make these changes self. Are the bootloader now running ? Best regards, Hagen
Datum:
@Vlad: >You only need a template program that loads the logo, the firmware, >eeprom (if any) and some parameters (signature, baudrate, version) from >the exe-ressources I do'nt prefer this solution. The GUI supports already commandline options, including automatic updates. And the compiled ACY files are infact like encrypted scripts supporting in one file the data for FLASH and EEPROM programming and FLASH verifications. Packing all into a single EXE provide no effects - EXE size is already and always big, separate distributations lead to only transfer the small ACY files - todays anti-spam, anti-virus technologie dont like self modified EXEs, or packed EXE stubs and so on A distibutation contains - AVRootloader.exe - AVRootloader.ini - AVRootloader.dev - ????.acy, your ACY file contaning FLASH/EEPROM data - ????.bat or ????.lnk to start AVRootloader.exe per commandline in automatic mode Iff we register the ACY extension to AVRootloader.exe then we store in registry all paramaters and thus we do need only the ACY file it self, no BAT/LNK files needed. Best regards, Hagen
Datum:
Hagen Re schrieb: > Wenn du also PeDa's Bootloader zum laufen bekommen hast definitiv, habs grad auch noch mal ausprobiert -> geht. Hagen Re schrieb: > Konfigurierbarkeit/Compilation ist für Anfänger beim AVRootoader in > meinen Augen sogar noch einfacher. jep, seh ich genauso Hagen Re schrieb: > probier es mit obiger Änderung. Nach der Baudraten Detektion -> die Änderung setzt doch an der selben Stelle an, wie meine. Aber auch hier passiert nix - zum Verzweifeln.
Datum:
@Vlad: >die Änderung setzt doch an der selben Stelle an, wie meine. Jo das sehe ich jetzt auch. Baue dort noch den Code für deine LED ein. > Aber auch hier passiert nix - zum Verzweifeln. dann kommt der Bootloader nicht über die Baudraten Detektion hinaus. Ich weiß so langsam auch nicht weiter, was bei dir da schief läuft. Überprüfe nochmal ganz genau deine Fuses. Lösche den AVR komplett und programiere AVRootloader.hex und Fuses nochmal. Und kauf dir mal ein Oszi ;) Ach und überprüfe ob du mehrere Installationen von AVRootloader hast und lösche alle bis auf die aktuelleste. Lösche auch das HEX File vor dem Compilieren. Meine Erfahrung sagt mir das manche Programmierer echte Schlampen sind, das unterstelle ich dir nicht, aber manchesmal arbeitet man auf den falschen Daten und wundert sich (ist mir auch schon passiert). Gruß Hagen
Datum:
Thanks for your reply... I'm glad that you understand English... About the GUI, would you like to share the source code before compiled (C/C++ program)? So that I can modify some parts, like the logo, the appearance, and the other parts. I try to understand this part ; follow bytes should be keept secret and choosen randomly, 128 Bit Password, first 32 bit used as Signature BootKey: .db $A7,$39,$C9,$AD,$A2,$D1,$1E,$F6,$45,$7F,$75,$7A,$6D,$4C,$21,$41 As I know, the GUI software generate password from that Boot key. am I right? If I'm wrong, what does that boot key mean? thanks. regards. Favian
Datum:
>As I know, the GUI software generate password from that Boot key. am I >right? If I'm wrong, what does that boot key mean? Thats the password, eg. key for the XTEA decryption. The GUI can make for you a random password. The GUI can patch your AVRootloader.asm source file with this new random key for you. The GUI copy the random key into your clipboard. The GUI can store the random key into your AVRootloader.ini iff you want this. If you click "compile" in the GUI the program use the given FLASH + EEPROM File + checked Options + Versionsnumber + even the password = bootkey to compile a encryted ACY file with all this content. Thus the data in this ACY file are encryted with the same password as stored into BOOTKEY. Thus: the AVRootloader.hex must be secure, your AVR devices must be secured by the fuse settings, and in the customers AVRootloader.ini you must delete thePassword topic. In your production AVRootloader.ini you can store the actual used Password, or the GUI ask you everytime for the password. Try it. >About the GUI, would you like to share the source code before compiled >(C/C++ program)? So that I can modify some parts, like the logo, the >appearance, and the other parts. No. As i told some postings prior, i make with this a small fee. All other remains free, even for commercial purpose. The only thing where i can get a small return are the customization of the GUI or protocoll for commercials. Once more i provided a AVRootloader.dll wich contains COM/DCOM compatible interfaces to all functionality of the bootloader. It's even free. A expirienced developer can access with his own GUI to the bootloader features. Thus, i think thats all fair and enough "free of charge work". Over the time i tend even more to not publish my work again in this manner. Best regards, Hagen
Datum:
Hm, ok step by step: 1.) start the GUI and press "Make Password" button, let patch the AVRootloader.asm source, let save this key into AVRootoader.ini 2.) configure AVRootloader.asm to your need and compile it as descripbed 3.) program your device with the AVRootloader.hex 4.) setup fuses of your device to protect it from reading back, protect even application access to the bootloader section 5.) in the GUI choose your HEX File for the FLASH and EEPROM, setup all option checkboxes to your need 6.) press "Compile" Button and create a ACY file 7.) your customer get from you - AVRootloader.exe, AVRootloader.dev, AVRootloader.ini with PAssword topic empty - your device, with AVRootloader bootloader and protected by fuses - the compiled and encrypted ACY file 8.) the customer select this ACY file in the FLASH file combobox and press the "Program" button. All options, contents and so on thats was configured on creation of this ACY file are now executed, regardless of the options checked in the GUI. Thus, Your developement computer and your devices shares the same password=key=BOOTKEY, nobody others should knew it. You alone provide compiled and encryted ACY files. Thus all upgrades are secure. Regards, Hagen
Datum:
Dear Hagen I have tried to follow your instruction to create *.acy file from AVRootloader.exe. But until now I always fail. why it can happen? Can you explain to me? this is my step to make *.acy 10) run AVRootloader.exe and configure parameters (COM port, baud rate, daily organizer) 11) pick in the input field "FLASH" a HEX file to be compiled 12) pickin the box "EEPROM" an EEP file to be stored in the EEPROM 13) press switch "compile" 14) pick from the file dialog, the name and location of the file ACY In my case, I don't use eeprom, so I let eeprom empty. Is it OK with my way? Thanks
Datum:
do you have a AVR device, with right installed bootloader, already connected on the COM port ? The GUI won't work offline, because it get from bootloader important params like signature, version, crypto support and so on.. If you let the comboboxes for FLASH and/or EEPROM empty they would be ignored. You can choose - only a *.HEX into FLASH File - only a *.EEP into EEPROM File - *.HEX into FLASH File and *.EEP into EEPROM File - only a *.ACY into FLASH File, EEPROM File are ignored then If you now press "Compile" then both files are compiled and, maybe if the AVR device support encryption, encrypted into ACY file. Prior the GUI must be connected to AVR. If you press "Program" button then the GUI try to connect, if not already connected, to the AVR, and program the FLASH and/or EEPROM dependend of selected files in combobox. Dependend of features installed on AVR bootloader the GUI encrypt live the FLASH/EEPROM communication suppose the AVR can be only updated encrypted. If you have configured the Bootloader to support encryted and unencryted the GUI choose the unencrypted communication. This configuration is UseCrypt=1 -> Bootloader supports encrytion. UseCryptFLASH=0 UseCryptEEPROM=0 -> Bootloader accepts encrypted and not encryted communication. UseCryptFLASH=1 UseCryptEEPROM=1 -> Means FLASH/EEPROM datas must be encryted. Unencryted are'nt allowed. If the GUI have to encrypt the communication it looks into AVRootloader.ini on topic Password=. If is empty the GUI ask you for the password. Think not to deeply about all possible combinations, do and try it, it's bullet proof and idiot secured ;) Watch the caption and the "connect" Button of the GUI when you do any actions. Regards, Hagen
Datum:
@hagen Ich geh kaputt, ich hab jetzt nochmal ganz von vorn angefangen und jetzt funktionierts. Ein diff zu dem Projekt, was ich hochgeladen habe zeigt keine Unterschiede, außer dem UARTInvert, was ich ja aber vorher auch schon (und zwischendurch immer wieder) probiert hatte. Mir ist aber noch unklar, warum die invertiert werden muss. Wenn ich sonst die UART verwende, häng ich die auch direkt an meinen Adapter. Wenn ich den UseWDR konfiguriere, disconnected sich das device aber immer wieder.
13.07.10-16:30:26-843 > Connecting on port COM4... 13.07.10-16:30:26-843 > Timeout.Connect = 500 ms 13.07.10-16:30:26-843 > Timeout.Base = 500 ms 13.07.10-16:30:26-843 > Timeout.Erase = 100 ms 13.07.10-16:30:26-843 > Timeout.Flash = 150 ms 13.07.10-16:30:26-843 > Timeout.Eeprom = 100 ms 13.07.10-16:30:26-843 > Timeout.Buffer = 10 ms 13.07.10-16:30:26-843 > Timeout.AppCmd = 0 ms 13.07.10-16:30:26-843 > Timeout.KeepAlive = 2500 ms 13.07.10-16:30:26-843 > Timeout.RTSPulse = 0 13.07.10-16:30:26-843 > Timeout.RTSInterval = 0 13.07.10-16:30:26-843 > Timeout.ConnectTrials = -1 13.07.10-16:30:26-843 > Timeout.MaxPacketSize = 0 13.07.10-16:30:26-859 > send ident $00 00 00 00 00 00 00 00 00 0D 42 4F 4F 54 13.07.10-16:30:27-500 > received data $94 06 06 04 30 13.07.10-16:30:27-515 > Timer created 13.07.10-16:30:27-515 > Device connected 13.07.10-16:30:30-015 > send keepalive 13.07.10-16:30:30-515 > Timer released 13.07.10-16:30:30-515 > keepalive failed, terminate connection 13.07.10-16:30:31-031 > Device disconnected |
Ist da vielleicht ein Bug? der Bootloader müsste den WDT doch am Anfang deaktivieren und am Ende wieder aktivieren, oder hab ich den Sinn der Option falsch verstanden. Gibt es eine Option, mit der man den WDT einfach nur deaktivieren kann. Ich will den WDT benutzen um ein Reset auszulösen. Am allerliebsten wäre mir jedoch, wenn ich per UART ein Kommando schicke, dass der µC den Bootloader startet. Da gibt es allerdings 2 Probleme: wie komme ich zum Bootloader ohne fixe Addressen in meinem C-Code zu haben? Der Sprung zum Bootloader ginge ja nur über inline-Asm, oder? Ich vermute genau hierfür ist das UseSpecialBootVect, aber wie benutze ich das? das 2. ist, dass das Flashtool, dieses Kommando senden müsste, oder man müsste die Wartezeit am Anfang sehr lang machen.
Datum:
>Mir ist aber noch unklar, warum die invertiert werden muss. >Wenn ich sonst die UART verwende, häng ich die auch direkt an meinen >Adapter. Das ist eine Frage des Standpunktes ;) Die Soft-UART des Bootloaders kann direkt mit ihren Pins an ein RS232-Kabel angeschlossen werden. Das nennen wir mal 1-zu-1 Pegel. Wird ein RS232-Pegel-Konverter benutzt so werden die Signalpegel defakto invertiert. Aus RS232 wird TTL Pegel mit invertierter logischer Bedeutung was nun ein 1- oder 0-Datenbit darstellt. Siehe http://de.wikipedia.org/wiki/RS-232 Desweiteren kann der Bootoader im 2-Wire und 1-Write-RS232 Modus arbeiten. Statt also mit getrennten RX/TX Leitungen, invertiert oder nicht invertiert, kann man mit einer einizgen Leitung für RX/TX, also 1-Wire arbeiten. Ebenfalls invertierte und nicht invertierte Pegel. Im 1-Wire Modus kann man mit einem kleinen Adapter (Schaltplan ist im JPG) auch direkt an die RS232 ohne Pegelwandler. Aber auch mit Pegelwandler wie MAX232, USB-UART usw. kann man noch 1-Wire benutzen, dann mit UseUARTInvert=1. Im 1-Wire-Modus kann man mehrere AVRs mit meinem Bootloader auf einem Board platzieren und alle sind am gleichen 1-Wire-Bus angeschlossen. Wenn die einzelnen Bootloader dieser AVRs alle unterchiedliche BOOTSIGNs koinfiguriert haben dann kann man damit alle AVRs updaten über eine einizige Leitung und einem einzigen Windows-Program. Gruß Hagen
Datum:
>Wenn ich den UseWDR konfiguriere, disconnected sich das device aber >immer wieder. >13.07.10-16:30:27-515 > Timer created >13.07.10-16:30:27-515 > Device connected >13.07.10-16:30:30-015 > send keepalive >13.07.10-16:30:30-515 > Timer released >13.07.10-16:30:30-515 > keepalive failed, terminate connection Das Protokoll sagt es schon: 1.) keepalive failes, termnate connection 2.) Timeouts.KeepAlive=2500 ms Der WDT im AVR wird im Bootloader immer auf 2 Sekunden=2000ms programmiert. Ergo 2500ms KeepAlive Interval ist bei weitem zu lange, ich habe das so nie konfiguriert. Setze es auf 500ms bis 1000ms wieder zurück. Selbst 1500ms wären zu lang, bedenke das Nyquist Theorem. Nutzt du UseWDT=1 so hat das mehrere Vorteile: 1.) der WDT wird auf 2s Timeout programmiert 2.) wenn eine Bootloader Software connected ist so muß diese alle max. 2s ein Kommanod senden oder irgendwas senden. 3.) erfolgt dies nicht so geht der Bootloader von einer gebrochenen Kommunikation, startet über WDT-Reset sich quasi selber erneut, kommt in seine Baudrate Detektion und/oder BootSign Detektion, Timeouted dort und ruft dann final die istallierte Anwendung auf. 4.) sendet nun das GUI periodisch Daten oder eben ein KeepAlive und der Bootloader antwortet nicht mehr so trennt das GUI die Verbindung autom. Also auch hier wartet es dann nicht unendlich. 5.) du kannst in deiner Anwendung selber über einen absichtlichen WDT-Timeout den Bootloader starten. Ich empfehle das exakt so weil es technologisch den saubersten und stabilsten Programablauf ermöglicht. Der AVR wird auch aus unvorhersehbaren Situationen immer sauber recovern. Naja, du lässt also den WDT mit zb. 20ms und einer Endlosschleife bei gesperrten IRQs "timeouten". Daraufhin wird der AVR zurückgesetzt, also auch alle Register und Ports in jedem Falle neu iniatilisiert. Der Nachteil oder auch ein Vorteil: Nutzt du den WDT in deiner Anwendung nicht dann musst du den WDT in deiner Anwendnung sofort beim Startup deaktivieren. Nun kann das aber auch ein Vorteil sein, denn wenn deine Anwendung vorher schon hängt, weil FLASH kaputt oder irgendwas falsch programmiert wurde, dann würde deine App den WDT nicht deaktieren. Da mein Bootloader vor dem Aufruf deiner Anwendung den WDT zurück gesetzt hat hast du somit rund 2 Sekunden Zeit den WDT zu deaktivieren oder ihn zurück zu setzen. Erfolgt das wie geagt auf Grund enes Fehler nicht so entsteht ein RESET und schwups sind wir wieder im Bootloader. Somit Kreislauf geschlossen, auf unvorhergesehene Fehler reagiert das System indem es den Bootloader startet, ergo AVR ist erreichbar per GUI. Ich empfehle dir also dringends den WDT zu benutzen, über ihn den Bootloader zu starten. Damit erledigt sich auch dein Problem den Bootloader per JUMP anspringen zu wollen. Wobei aucn das sehr simpel ist: 1.) UseSecialBootVec=1 setzen 2.)
void bootloader_start_jump(void) { asm volatile("jmp -2"); } void bootloader_start_wdt(void) { cli(); wdt_reset(); _WD_CONTROL_REG = (1 << WDE) | (1 << _WD_CHANGE_BIT); _WD_CONTROL_REG = (1 << WDE); for (;;); } |
Durch die Arithmetic führt dieser Sprung bei allen AVR deren addressierbarer FLASH eine Größe einer Potenz von 2 hat immer dazu das an die letzte FLASH Addresse, bzw. OpCode gesprungen wird. Aber beachte dabei auch folgendes: Alle deine gemachten Einstellungen an den Ports, ISRs, IRQs musst du manuell sauber zurücksetzen damit der Bootloader eine saubere Umgebung vorfindet. Der Bootloader, erbt also alle deine Einstellungen. Das kann von Nutzen sein wenn du den Bootloader als "Mini-Debugger" benutzen möchtest, dann möchtest du ja das zb. im SRAM/PORT Fenster des GUIs das steht was du in deiner Applikation eingestellt hast. >Am allerliebsten wäre mir jedoch, wenn ich per UART ein Kommando >schicke, dass der µC den Bootloader startet. Das geht auch schon ;) 1.) in AVRootloader.ini setze - AppCmd=StartBoot/0D - AppCmdResponse=BootStart - Timeouts.AppCmd=20 2.) in deiner Applikation nutzt du eine eigene UART Library mit gleichen RX/TX Pins wie der Bootloader 3.) in dieser Library warte nun auf den Befehl "StartBoot" + 0x0D 4.) wenn eingetroffen sende "BootStart" 5.) aktiviere Bootloader mit bootloader_start_wdt(), ergo 20ms Timeout Wenn du mit dem GUI einen Connect versuchst sendet es 1.) StartBoot + 0x0D 2.) wartet auf BootStart, also AppCmdResponse wenn da was drinnen steht 3.) wenn es AppCmdResponse empfangen hat oder es leer ist 4.) wartet es TimeOuts.AppCmd Millisekunden 5.) und beginnt dann einen Connect zum Bootloader Das wäre die SW-Lösung. Die HW-Lösung 1.) verbinde RTS der RS232 mit RESET am AVR 2.) setze in ARootloader.ini -RTSPulse= -RTSInterval= entsprechend dem was dort beschrieben ist 3.) das GUI pulst nun die RTS=RESET Leistung des AVRs vor jedem x'ten Connect Versuch Gruß Hagen
Datum:
aso, die Timeouts hatte ich testweise mal vergrößert und wieder vergessen zurückzusetzen. jetzt gehts alles. Hagen Re schrieb: >>Am allerliebsten wäre mir jedoch, wenn ich per UART ein Kommando >>schicke, dass der µC den Bootloader startet. > > Das geht auch schon ;) > > 1.) in AVRootloader.ini setze > - AppCmd=StartBoot/0D > - AppCmdResponse=BootStart > - Timeouts.AppCmd=20 Super! Stand das irgendwo? ich hatte extra die txts überflogen. Nochmal vielen Dank für dieses super Stück Software und deine Zeit für Erklärungen.
Datum:
Hi Favian, as might saw it in this thread, there is simple opensource alternative gui for that bootloader. Beitrag "Re: AVR-Bootloader mit Verschlüsselung" Once i programmed it since of a lack of a GUI working under Linux. (This one is compilable for windows aswell as linux) Unfortunately its really simple and you cant create encrypted files on your own like the original can do. Thus you have to use the original loader to create your acy image which you can upload by that alternative one then. Another restriction by now is that it only supports Atmega8 processors. Just because i was lazy and just needed support for that uC. But it shouldn't be any problem to add other uC signatures with their matching memory layout to extend its functionality. Feel free to do it! @Hagen: Es wäre echt super, wenn deine GUI ein ACY File auch in Abwesenheit eines uC erstellen könnte. Dass die ganzen Prozessordaten stimmen für mein ACY Image stimmen, dafür nehme ich gerne die verantwortung. :-) Regards, Grüße, Arne
Datum:
@Arne: ja du bist nicht der Einzige der diesen Wunsch hat. Dummerweise war das nicht konzeptionell geplant und somit wird es mehr Arbeit werden als nur nebenbei mal das Logo auszutauschen oder par Buttons zu verschieben. Es steht auf der Todo Liste als erster Punkt. Gruß Hagen
Datum:
Hagen Re schrieb: > @Arne: ja du bist nicht der Einzige der diesen Wunsch hat. Dummerweise > war das nicht konzeptionell geplant und somit wird es mehr Arbeit werden > als nur nebenbei mal das Logo auszutauschen oder par Buttons zu > verschieben. schon klar. Kein Stress! Wollte nur mal den Wunsch etwas auffrischen.. > Es steht auf der Todo Liste als erster Punkt. Yeah! > Gruß Hagen Gruß, Arne
Datum:
@Hagen: Du hast in dem Bootloader.zip leider keine Texte, die auf die Lizenz schließen lassen. Auch die Sourcen enthalten nix dahingehendes. Ich würde diesen Bootloader gerne in der Word Clock* verwenden. Der Einfachheit halber wäre es schön, wenn ich den Bootlader mit den Sourcen und dem Flash-Tool dort dazupacken könnte, da dies das unkomplizierteste wäre und die Leute, es so nicht separat herunterladen, in ein vorgegebenes Verzeichnis entpacken und konfigurieren müssen. Bitte schreib, wie du dazu stehst. Gruß, Vlad * ein GPL-Projekt -> http://www.mikrocontroller.net/articles/Word_Clock -> Beitrag "Brauche Hilfe beim Bau einer Uhr")
Datum:
Jo geht so. Der Bootloader ist so wie du ihn hier findest Freeware, wie alles was ich veröffentliche. Einziger Wunsch ist das Copyright, bzw. ein Hint in deiner ReadMe/AboutBox auf meinen Bootloader, aber selbst das kann ich nich kontrollieren. Alles was in Richtung kommerzielle Nutzung geht kann, muß aber nicht, mit mir per EMail nochmal abgesprochen werden und ich bin gerne bereit Modifikationen zb. im GUI der Windows Software vorzunehmen. Gruß Hagen
Datum:
Hallo Hagen, Hallo an andere 1-wire Nutzer! Ich habe ein kleines Problem in der 1-wire Nutzung sobald ich mehrere Mega8 am gleichen Draht habe. Habe hier Brushlessregler, jeder hat noch einen 220R vor dem einzigen Nutzbaren Pin (PD1/RXD). Dazu die letzt Schaltung aus dem Wiki an einem FTDI Breakout von Sparkfun, 2k7 zwischen FTDI TX & RX, FTDI RX and AVR-RX/Bootloaderpin und noch ein 100k Pullup. TTL Pegel, UartInvert =1 und die Sache funktioniert soweit auch. Auch wenn nur 1 Regler angeschlossen ist komme ich nicht immer sofort in den Bootloader, muss immer wieder 3-4x den AVR resetten um in den Connected-Status zu kommen, ist er aber mal connected bleibt er das aber auch tagelang, flashen funktioniert,... ist das so normal - das mehrfach reset's notwendig sind...? Und jetzt geht es daran, mehrere der Regler über den Bootloader anzusprechen. GND und die Bootloader-Pins verbinden und an die Schaltung die am FDTI hängt dran. Hier hätte ich maximal bedenken das bei n Reglern die nx vorgeschaltenen 220R ein Problem sind. Jeder hat seine eigene ID (BLCLOADER1..8) und kann einzeln auch angesprochen werden. Sobald ich einen 2ten Regler anschließe, komm ich nicht mehr zum connect, egal wie oft ich die AVRs resette, die PC-Anwendung geht nie in den Connected-Status. Im Testaufbau habe ich die Verbindung über ein Steckbrett, trenne ich hier den 2. Regler, sodaß nur ein AVR verbunden ist, komme ich sofort wieder in den connected-status. Bin ich in diesem und verbinde dann den 2ten regler, so bleibt alles connected und ich kann, trotz des 2ten Reglers flashen. Connected-Status kann ich mit Disconnect beenden, oder den Regler 1 abstecken, dann wird dies auch erkannt. D.h. ich gehe davon aus, das sich die AVR betreff kommunikation nicht in die quere kommen (die Regler-Soft aktiviert den UART-RX), sonst würde ja die Kommuniktation beim Flashen, der Keepalive,... nicht funktionieren. Nur warum kann ich nicht connecten? Hat irgendjemand ein ähnliches Problem? Hab hier zwar ein paar Stunden gelesen, aber in diesem langen Thread nichts dazu gefunden, bzw. hoffentlich nichts übersehen? Danke für die Unterstützung & lG, Martin.
Datum:
Hi Martin, Zur Verbesserung des Connects: * in AVRootloader.asm - UseAutobaud = 1 - UseResetDelay = 1 - BootDelay vergrößern zb. auf XTAL/2, XTAL/1 -> 500ms, 1sec * in AVRootloader.inc - BaudTolerance = 3 oder langsam höher setzen, je größer der Wert desto größer der Fangbereich bei abweichenden Baudraten. Ich empfehle max. 5 bis 6 * in AVRootloader.ini - Baudrate=115200 - [timeouts] Base = 25 Je höher die Baudrate und desto kleiner der Base-Wert desto mehr Connect-Versuche im gleichen Zeitraum können stattfinden, desto höher die Wahrscheinlichkeit eines Connects im Zeitbereich. Aber auch desto kritischer das Timing bei der Kommunikation. Je geringer die Baudrate und je größer Base desto stabiler wird die Kommunikation aber der Connecttrial wird pro Zeitspanne weniger häufig stattfinden können. Zum 1-Wire: Ich habe den Multi-Bus-1-Wire nur mit physikalischen RS232 Pegeln getestet. Du benutzt einen TTL Pegelwandler und dadurch invertieren sich alle Signale und damit auch das Verhalten der DDR-Ansteuerung. Die AVRs kennen nur interne PullUps und keine PullDowns. Versuche also auch mal extern einen PullUp oder PullDown Widerstand dran zu pappen. Die Bootloader SW übernimmt erst dann die Kontrolle über den 1-Wire-Bus wenn sie das korrekte BootSign und demnach die korrekte Baudrate ermittelt hat. Gruß Hagen
Datum:
Hallo Hagen, ich benutzte dein prg sehr gerne. Auch von mir ein super Danke für dieses tolle Tool. Ich glaube einen kleinen Fehler entdeckt zu haben. Wenn ich AVRootloader per Batch aufrufe und ein '-' (Minuszeichen) im Pfad oder Dateinamen sich befindet, wird danach alles abgeschnitten und es geht natürlich nicht mehr weiter! Tausche ich alle 'Minus' z.B. gegen ein Unterstrich aus, gehts. MfG. Tom
Datum:
@Thomas: ja da wirds immer ein Problem geben. Ich bekomme den kompletten Parameter als Kommandozeile. In dieser befindet sich der Pfad + der Name der EXE + die Parameter. Im Pfad können fast alle Zeichen vorkommen, so auch - und Leerzeichen. Ich muß aber irgendein Token/Zeichen benutzen um den Begin eines Parameters zu signalisieren. Leerzeichen im Pfad würde den Pfad als solches abschneiden. Minus im Pfad würde die SW als Parameter interpretieren. Ich könnte nun beim Parsen das Minus nur dann als Parameterstart akzetieren wenn vor dem Minus und Leerzeichen steht. Das würde die Fehlerwahrscheinlichkeit reduzieren aber das Problem nicht real sauber lösen. Andere Option wäre es die Pfade in Anführungsstriche zu setzen. Dummerweise geht das aber nicht autom. wenn Windows eine Anwendung startet. Geht also nur bei Batches/Verknüpfungen etc.pp. Egal wie ich es drehe: - Windows hat mit seinen langen Dateinamen und dem Zulassen von bisher unter DOS illegalen Zeichen in den Pfaden uns Progrmmiern die Arbeit erschwert - ich müsste das komplette Parameter-Format abändern Ergo: Verzichte auf Minus in deinen Pfadangaben. Gruß Hagen PS: ich könnte das Minus durch Slash ersetzen., weiß aber jetzt nicht aus dem Stand heraus ob das wirklich eine gute Idee ist oder ob ich mir damit neuen Ärger einfange.
Datum:
Hagen Re schrieb: > @Thomas: > > ja da wirds immer ein Problem geben. Ich bekomme den kompletten > Parameter als Kommandozeile. In dieser befindet sich der Pfad + der Name > der EXE + die Parameter. Im Pfad können fast alle Zeichen vorkommen, so > auch - und Leerzeichen. Ich muß aber irgendein Token/Zeichen benutzen um > den Begin eines Parameters zu signalisieren. Nimm doch testweise den nächsten Token, füge ihn an den alten an und prüfe, ob der Pfad existiert. Wenn nicht -> als Paramter interpretieren, wenn nicht, ists der Pfad. Oder alternativ, falls du Delphi verwendest, Parameterstring nach ExtractFileName(application.exename) durchsuchen und bis dahin alles abschneiden. Dann besteht der String nur noch aus Paramtern. Wäre eine Zeile. > Egal wie ich es drehe: > - Windows hat mit seinen langen Dateinamen und dem Zulassen von bisher > unter DOS illegalen Zeichen in den Pfaden uns Progrmmiern die Arbeit > erschwert Hab auch schon oft Erfahrungen mit gemacht... Viele Grüße, Arne
Datum:
@Arne: das hatte ich mir auch schon überlegt, fixt aber das Problem auch nicht vollständig. Man kann als Parameter einen Arbeitspfad und Pfade zu ACY/EEP/HEX Dateien angeben. Auch dort tritt das Problem dann auf und dort kann ich das mit dem EXEPath Trick nicht erschlagen. Ich werde es wohl so bauen das man in der AVRRootloader.ini das Parameter-Token angeben kann. Standard wird Slash, ersetzt man es durch Minus gibts keine Probleme mehr mit veralteten Kommandozeilen. Die Benutzer der Kommandozeilenaufrufe müssen dann halt ihre Kommandozeilen bei Bedarf anpassen. Übrigens arbeite ich mit Delphi. Ich bin aber gezwungen einen eigenen Parser für die CommandLine zu schreiben da man der Delphi RTL nicht eine andere CommandLine unterjubeln kann. Das bräuchte ich aber da ich nur Single Instances der EXE zulasse und wenn die EXE mehrfach gestartet wird so kommuniziert die neu gestartet EXE ihre Kommandozeile zur schon gestarten Instanz und terminiert sich dann selber. Die schon laufende Instanz lädt dann ihre Parameter neu auf Grund der Parameter die man der zweiten Instanz übergeben hat, und setzt sich in den Vordergrund. Ergo: ich muß die Commandline per Hand auswerten und kann nicht die RTL Funktionen von Delphi benutzen. Gruß Hagen
Datum:
@Hagen: Danke für die rasche Rückmeldung, hatte nur selbst nicht eher Zeit ;) UseAutoBaud hatte ich schon auf 1, UseResetDelay geht nicht - im regulären (Flug-)Betrieb könnte der Regler abstürzen, bekommt ständig Daten zugesendet, da muss der Reboot so rasch wie möglich durchlaufen, sonst stürzt das Modell ab. UseResetDelay=1 würde bedeuten das er für immer im Bootloader bleibt. BootDelay hatte ich schon auf XTAL/2 bzw. 500ms. [TimeOuts] Base=25 ist in Zusammenhang mit 57600 Baud in 95% der Fälle sofort beim ersten Reboot vom AVR erfolgreich - also mehr als ausreichend! Beim 1-wire Problem hatte ich schon mal mit/ohne Pullup/down probiert... Hab jetzt unterschiedliche Werte ausprobiert, bei 2 Reglern funktioniert es mit einem 10k Pulldown mit sehr guter Connect-Rate! In diesem Sinne DANKE für diesen genialen Bootloader!!! lG, Martin.
Datum:
>bei 2 Reglern funktioniert >es mit einem 10k Pulldown mit sehr guter Connect-Rate! Je nachdem was du als Widerstand zwischen RX/Tx geschaltet hast würde ich den Pulldown sogar auf 4k7 reduzieren. >UseResetDelay geht nicht - im regulären (Flug-)Betrieb könnte der Regler >abstürzen, bekommt ständig Daten zugesendet, da muss der Reboot so rasch >wie möglich durchlaufen, sonst stürzt das Modell ab. UseResetDelay=1 >würde bedeuten das er für immer im Bootloader bleibt. Hm. Dann hätte ich aber den Bootloader über einen externen Pin angesprochen der nicht auch deinen Kommunikationskanal macht. Du kannst aber auch mit UseBootMode=1 den Bootloader so konfigurieren das er nur startet wenn: a) noch keine Applikation geflasht wurde b) wenn ein Powerup die Ursache des Resets war Damit schließt du "künstliche" Resets wie WatchDog und eben BrownOut Reset aus. Besonders letzere beide sollten für dich interessant sein da ich vermute das über diese beiden Reset Sources dein Regler recovert. Oder UseBootMode=2 startet den Bootloader dann nur bei externem absichtlichen Reset, falls du den noch nutzt ;) Eine andere, aber gefährlichere Einstellung wäre noch UseBootMode=5. Bei dieser Einstellung startet der Bootloader nur bei nicht installierter Applikation automatisch. Wurde einmalig eine Anwendung programiert so muß diese per CALL/JMP den Bootloader selber aufrufen. Somit entscheidet dann deine Anwerndung alleinig ob und wann der Bootloader gestartet wird. Ein Fehler in deiner Anwdnung führt dann aber zum Ausperren. Ich denke mal das UseBootMode=1 und aktiviertem WatchDog + Brownout die cleverste Wahl für dich wäre. Dein Regler recovert falls er per WDT timeouted, also bei Hängern in der Regler Software. Er recovert bei absinkender Spannung, eg. Spannungeinbruch über den Brownout Reset. Nur wenn der Regler komplettt neu mit Saft versorgt wird, er also längere Zeit als der Brownout, keine Spannung hatte wird der Bootloader in seine Warteschleife verzweigen. Ansonsten springt er sofort in deine Anwendung, ohne Zeitverzögerung. Hast du UseWDT=1 gesetzt so wird vorher sogar noch der WatchDog mit 2sec Timeout aktiviert. Mit UseSaveMCUSR=1 sichert er sogar noch auf dem Stack (OnTop an höchster SRAM Addresse) noch das oroginale MCUCSR/MCUSR Register bevor das mit 0x00 überschrieben wird. Dh. in der Anwendung kannst du über den Stack an die originalen RESET Sources gelangen um dann in deinem Startup Code gezielt auf die spezifischen RESETs reagieren zu können. Gruß Hagen
Datum:
wo finde ich denn eine aktuelle Version? oder ist die aus dem ersten Beitrag aktuell?
Datum:
Hello, I was looking for an alternative to AVR231 bootloader with encryption, and Luiz told me about this one he is very happy with. I see that ATmega328 is not in the list of supported devices. What do I need to do in order to make it work for ATmega328? ps: sorry I don't speak German. I started learning, but I am quite far from writing it. Best regards, David
Datum:
Angehängte Dateien:ATmega328P is supported. The Bootloader supports all self programmable AVR devices, except XMega series. Even future devices. To include these install newest AVRStudio on your computer. Delete AVRootloader.dev file and start AVRootloader.exe on your machine. The software parse on startup the AVRStudio XML part description and include files and create a new AVRootloader.dev file based on these files. Or you take manual the changes needed. First include follow line into AVRootloader.asm source
.include "m328Pdef.inc" ; ATmega328P |
then open AVRootloader.dev file an add follow line 950F=1E950F, ATmega328P , 32768, 1024, 2048, 256, 128, 4, 8, 16, 32 The parameters are as follow: - 950F, short hexadecimal ID of the device - 1E950F, full hexadecimal ID of the device, eg. same as first param with leading 1E - ATmega328P, the device name - 32768, FLASH size in bytes - 1024, EEPROM size in bytes - 2048, SRAM size in bytes - 256, start of SRAM or in other words the Register File and Port size in Bytes - 128, FLASH page size in bytes - 4, FLASH page count of FIRST_BOOT eg. the size for Bootloader section - 8, FLASH page count of SECOND_BOOT - 16, FLASH page count of THIRD_BOOT - 32, FLASH page count of FOURTH_BOOT The version in the attachment already known the ATmega328P. Best regards, Hagen
Datum:
Many thanks for the update! One more question, when I send the encrypted firmware to someone, he needs to update the firmware using the AVRootloader.exe, right? Is the source code of AVRootloader.exe available (the part for updating the firmware to the microcontroller)? (I would need to integrate the feature of updating the firmware in my own GUI) Regards, David
Datum:
The sources for the AVRootloader.exe are'nt free avaiable. There exists two possible ways for you: 1.) use the commandline to startup AVRootloader.exe. As example: AVRootloader.exe -PCOM1 -B115200 -Fc:\test\my.acy -Apc Startup AVRootloader.exe with COM1 and 115200 baudrate to execute file my.acy and close the GUI after successfully finishing all actions. If any error occur the GUI remains stay open. On creation of your encrypted ACY file you choose wich action are todo when a customer execute this file. Eg. you compile into you ACY file the HEX file for the FLASH and/or the EEP File for the EEPROM, maybe choose the application version number, and/or if the FLASH contents should be erased prior and/or verified later. 2.) give me a contract and i take any changes for you :) Please remember to clear in AVRootloader.ini the topic Password= if you use encryted ACY files. Otherwise your customers have full access to your devices. Setup in AVRootloader.asm UseCrypt=1 UseCryptFLASH=1 UseSRAM=0 and change the provided password in BootKey: (maybe withelp of AVRootloader.exe GUI) to provide the maximal security. Best regards, Hagen
Datum:
3.) i provide a AVRootloader.dll that export some DCOM/COM interfaces with all functionality needed of the bootloader, without any GUI. If you understand Delphi/PASCAL then you can in this way access with any other programming language that supports DCOM/COM/ActiveX interfaces the functionality of the bootloader. Best reagrds, Hagen
Datum:
Hello Hagen, Thanks again for your answer! Sending the firmware by USB "emulated RS232" has the problem that the user needs to install a driver such as this one: D2XX Direct Drivers: http://www.ftdichip.com/Drivers/D2XX.htm I saw that this AN10711 bootloader emulates a Mass Storage Class Device, so no drivers need to be installed. Then the user (or the application) updates the firmware by directly copying it to the MSCD. http://www.nxp.com/documents/application_note/AN10711.pdf Would it be possible to combine such a bootloader with the encryption? It's just an idea; I don't really have the budget to finance it. :'-) Regards, David
Datum:
>Would it be possible to combine such a bootloader with the encryption? yes if you have access to the source you can implement anything you want. As example should it possible to use a AVR that support USB. We have basicly to implement in AVRootloader.asm only USB initialization and two io-functions. But then you need even a driver for this custom USB device on your PC and the AVRootloader.exe must be rewritten or a VCOM driver to the custom USB driver must be written. Thus, useing todays mass-products like common USB-RS232 cables are most times cheaper. Best regards, hagen
Datum:
Hi Hagen, Versuche grad den Bootloader am ATMega128 auf PortF aber ich bekommen immer: C:\Data\AVR\AVRootloader.inc(308): error: Operand 1 out of range: 0x60 Gehts generell nicht oder mach ich was falsch ? Sonst erstmal vielen danke für diese geniale Arbeit Gruß

















