Hi, die Application-Note AVR230 (DES Bootloader) macht genau das, was ich suche. Nur leider für IAR. Hat schon jemand eine Portierung auf GCC gemacht? Bei Avrfreaks habe ich den Code für AVR231 (AES Bootloader) für GCC gefunden. Schlüssellängen ab 128 Bit sind aber für meine Anwendung total überdimensioniert. Zumindestens sind diese Sourcen eine gute Hilfe um zu sehen was für die Umstellung von IAR auf GCC nötig wird. mfg Nucor
Nucor schrieb: > Schlüssellängen ab 128 Bit sind aber für meine Anwendung > total überdimensioniert. Ja, und? "128 KiB Flash-ROM sind für meine Anwendung völlig überdimensioniert, mir würden 80 KiB bereits völlig genügen." Trotzdem würde es teurer, dir extra einen Controller mit 80 KiB zu bauen statt in dem mit 128 KiB einfach 48 KiB ungenutzt zu lassen. Solange nicht anderes dem im Weg steht, würde ich einfach AES benutzen, egal, ob das jetzt überdimensioniert erscheint oder nicht. Es ist ja ohnehin der designierte Nachfolger von DES.
Nee, nee, die jetzige Anwendung läuft auf einem Atmega64 und der ist bis fast zum letzten Byte voll. Da noch weitere Wünsche anstehen ist es sinnvoll sparsam mit dem Codeverbrauch (auch beim pinkompatiblen Atmega128) umzugehen. Irgendwann ist auch der Atmega128 zu und dann ist ein neues PCB - Layout fällig. Im Moment versuch' ich aber mit der aktuellen Platine weiter zu kommen. mfg Nucor
Und du meinst, dass DES nur deshalb weniger Code benötigen würde als AES, weil es eine geringere Verschlüsselungstiefe hat? Das halte ich für einen Trugschluss. Allerdings kann man AES auf sehr verschiedene Weise implementieren und damit den Tradeoff zwischen Laufzeit und ROM-Verbrauch festlegen. Wenn es schnell gehen soll, lagert man einen Teil des Codes in Tabellen aus, wenn man dagegen Platz sparen will, rechnet man das zur Laufzeit aus.
OK Jörg, hast mich überredet. Ich werde erst mal mit der AES - Variante weiter machen. Das ist der schnellste Weg um die Sache anzuschieben. Ja, ich hatte die Hoffnung, daß 56-Bit DES weniger Speicher als 128-Bit AES benötigt. Wobei mir klar ist, daß das stark von der Art der Implementierung abhängt. Wenn später der Speicher knapp wird kann ich immer noch daran drehen. mfg Nucor
Ich habe jetzt die Details auch nicht im Kopf, aber soweit ich mich erinnere wurde DES damals für eine Implementierung in Hardware entworfen. Da sind so Sachen wie Bits durcheinander werfen simpel, auf einer CPU nicht (entweder viele Schritte oder große Lookup-Tables). Weil sich seitdem viel Kryptographie auf CPUs abspielt, werden moderne Algorithmen wie auch der, der zum AES gewählt wurde, mit mehr Rücksicht darauf entworfen. AES kann also durchaus einfacher als DES sein.
Hi, nach einigen Schwierigkeiten habe ich mittlerweile den AES - Bootloader soweit, daß er mir den zu ladenden Code in den ATMEGA überträgt. Die ursprüngliche Überlegung mit DES Code zu sparen war unnötig, da der Bootloader - Bereich nur in Abschnitten (1K, 2K, 4K) zugewiesen werden kann. Ein Problem macht mir allerdings noch zu schaffen: beim Start (nach dem Laden) prüft der Bootloader mittels CRC den Applikationsbereich auf Fehler. Man kann es auch abschalten. Ich möcht' es aber verwenden. Der geladene Code entspricht exakt dem Inhalt des Hex-Files vor dem Verschlüsseln etc. Mit einem JTAG - Ice kann ich mir den Flash - Bereich ansehen. Die Abfrage nach der CRC - Routine geht in eine Endlos - Schleife wenn der Crc - Wert nicht 0 ist. Ermittelt wird aber 0x8002. Der ATMEGA wird vor dem Laden vom Bootloader gelöscht. Alle ungenutzten Speicherstellen sind mit FF gefüllt. Der Code ist relativ kurz: #if defined(CRC_CHECK) // Check that the Application Section contents is undamaged // by calculating the CRC of the whole memory. { uint16_t p = 0x000000; uint16_t crc = 0; do { crc = CRC(crc, pgm_read_byte(p)); } while (++p < MEM_SIZE); // Application Section damaged // -> do not jump to Reset Vector of the Application Section if (crc) { for(;;) { _delay_ms(1000); } } } #endif die Assembler - Funktion: // Polynome used in CRC calculations #define CRC_POLYNOME 0x8005 // unsigned int CRC (unsigned int crc, unsigned char ch); // r25:r24 r23:r22 .global CRC // CRC calculation routine CRC: ldi r18, 0x08 ldi r19, lo8(CRC_POLYNOME) ldi r20, hi8(CRC_POLYNOME) CRC_Loop: ; Rotate left. If MSb is 1 -> divide with Generator-polynome. lsl r22 rol r24 rol r25 brcc CRC_SkipEor eor r24, r19 eor r25, r20 CRC_SkipEor: dec r18 brne CRC_Loop ret Meine Kenntnis von CRC war bisher, daß für einen bestimmten Bereich oder einen Datenstrom-Abschnitt eine charakteristische Zahl erzeugt wird. Aber wieso steht hier 0 für einen korrekten Bereich ? Es wird beim Laden kein weiterer Code, wie bei einem Blockcheck - Verfahren, hinzugefügt. Im Moment stehe ich ratlos davor. mfg Nucor
Nucor schrieb: > Meine Kenntnis von CRC war bisher, daß für einen bestimmten Bereich oder > einen Datenstrom-Abschnitt eine charakteristische Zahl erzeugt wird. > Aber wieso steht hier 0 für einen korrekten Bereich ? Indem man die CRC selbst ans Ende schreibt, ergibt sich bei einem kompletten Test einschließlich der CRC anschließend eine 0, wenn die Daten in sich stimmig waren. CRC ist etwas tricky, da auch bei gleichem Generator-Polynom die Bitreihenfolge und natürlich der Startwert eine Rolle spielen.
Hi Jörg, der Code, der von Atmel stammt, checkt nur den Anwendungsbereich. Gesteuert wird das Ganze von einer Konstanten im Konfigurationsfile: MEM_SIZE - size of application section in target AVR (in decimal bytes). Die CRC - Routine beginnt bei 0 und endet mit dem Byte vor MEM_SIZE. Die CRC - Routine im Bootloader wird garnicht mit durchlaufen. Ich würde ja verstehen, wenn während der Umwandlungen und des Transports weiterer Code geladen wird um das Ergebnis auf 0 zu bringen. Allein, ich habe keine zusätzlichen Einträge gefunden. Der Code stimmt mit dem Hex-File überein, der Rest ist FF. In der application note AVR231 ist MEM_SIZE z.B. mit 14336 (= 3800 hex) angegeben. Ein ATMEGA16 hat 16383 (= 3FFF), die Differenz ist die bootloader section. mfg Nucor
Normalerweise legt man die CRC als letztes in den zu überprüfenden Bereich selbst mit hinein. Dann muss sich 0 ergeben.
Warum fängst du jetzt separat noch einen Thread bei AVRfreaks.net an, statt hier weiter zu diskutieren?
Weil ich hier nur Deutsche erreiche, außer Dir keiner geantwortet hat und ich im Moment nicht weiter weiss
Hast du denn nun die CRC selbst mit am Ende des überprüften Bereichs abgelegt? Nur so kann das doch am Ende alles zu 0 werden. Ein Beispiel aus der Kommunikationstechnik: Wenn ich für einen Frame (hier einer nach IEEE 802.15.4) eine CRC generieren will, dann nehme ich dessen Framedaten, sagen wir mal "1 2 3": $ ./gencrc 1 2 3 CRC = 0x5bf7 Wenn ich an den ursprünglichen Frame nun ebendiese CRC anhänge und den Algorithmus nochmal (diesmal über alle 5 Bytes) laufen lasse, dann ergibt sich 0: $ ./gencrc 1 2 3 0xf7 0x5b CRC = 0x0000 Das gencrc-Programm selbst ist im Wesentlichen der CCITT-Algorithmus aus der avr-libc, halt in C aufgeschrieben:
1 | #include <stdint.h> |
2 | #include <stdio.h> |
3 | #include <stdlib.h> |
4 | #include <unistd.h> |
5 | |
6 | uint16_t crc_ccitt_update (uint16_t crc, uint8_t data) |
7 | {
|
8 | data ^= crc & 0xff; |
9 | data ^= data << 4; |
10 | |
11 | return ((((uint16_t)data << 8) | ((crc & 0xff00) >> 8)) |
12 | ^ (uint8_t)(data >> 4) |
13 | ^ ((uint16_t)data << 3)); |
14 | }
|
15 | |
16 | static void |
17 | usage(void) |
18 | {
|
19 | fprintf(stderr, "usage: gencrc [-b base] number...\n"); |
20 | exit(64); |
21 | }
|
22 | |
23 | int
|
24 | main(int argc, char **argv) |
25 | {
|
26 | long i; |
27 | int c, base; |
28 | uint16_t crc = 0; |
29 | uint8_t byte; |
30 | |
31 | base = 0; |
32 | while ((c = getopt(argc, argv, "b:")) != -1) |
33 | switch (c) |
34 | {
|
35 | case 'b': |
36 | base = strtol(optarg, 0, 0); |
37 | break; |
38 | |
39 | default:
|
40 | usage(); |
41 | }
|
42 | argc -= optind; |
43 | argv += optind; |
44 | |
45 | while (argc-- > 0) { |
46 | i = strtol(argv[0], 0, base); |
47 | byte = (uint8_t)i; |
48 | crc = crc_ccitt_update(crc, byte); |
49 | argv++; |
50 | }
|
51 | printf("CRC = 0x%04x\n", crc); |
52 | return 0; |
53 | }
|
Das ist genau das was ich von der AVR231 und der Portierung von Raapeland auf GCC erwarte. Das nach dem Hexfile CRC - Bytes angehängt werden. Ich hatte bis jetzt immer einen Bedienungsfehler durch mich vermutet, da die Applikation schon lange existiert. Möglicherweise haben andere, die diesen Bootloader verwenden, auf die CRC - Prüfung verzichtet. Ich werde jetzt die Sourcen von Create.exe, ein C++ - Program, näher untersuchen um Ursache für die fehlenden CRC - Bytes zu finden. mfg Nucor
mittlerweile habe ich die Ursache für das CRC - Problem gefunden. Der unbenutzte Applikationsspeicher war nicht vollständig gelöscht. Abhilfe schafft das Setzen eines Switches (-d) beim Create - Tool. Nachfolgend sind die notwendigen Einstellungen für einen ATMeg64 aufgeführt. In der application note AVR231 wird für einen mit dem IAR - Compiler erzeugten Bootloader ein Wert von < 2K Byte (will fit nicely into 2kb of flash memory) angegeben. Mit dem GCC (-Os) komme ich auf 2242 Bytes. Auch wenn ich die paar Anweisungen zum Schalten von einigen Leds rausnehme sinkt die Größe nicht unter 2048 Bytes. Daher wird ein Bootloaderbereich mit 4096 Byte verwendet. Im AVR - Studio sind einige Einstellungen nötig: -DBAUD=57600 -DF_CPU=8000000UL Noch nicht getestet habe ich mit dem ATMEGA128 für den RAMPZ definiert werden muss damit lange Pointer verwendet werden. für den Linker: --section-start=.text=0xF000 Die BOOTSZ - Fuses sind auf 0 - BOOTSZ1 und 1 - BOOTSZ0 zu setzen. BOOTRST ist einzuschalten. Der Bootloader belegt den Bereich 0xF000 - 0xFFFF in Bytes. Im Memory - Window des JTAG - Ice werden Worte angezeigt. Dort beginnt der Bootloader bei 0x7800. Die beiden CRC - Bytes liegen im Word 0x77FF. Nicht, wie ich ursprünglich vermutete, direkt hinter dem Anwendungscode. GENTEMP.EXE wird einmal aufgerufen um ein Gerüst für den Config - File zu erzeugen. Im Config - File sind die folgenden Werte einzutragen: PAGE_SIZE = 256 MEM_SIZE = 61440 <== entspricht 0xF000 CRC_ENABLE = YES Danach werden mit dem Aufruf: GCreate -c Config.txt -h BootLdr.h -k AESKeys.h die Files BootLdr.h und AESKeys.h generiert. Diese sind in das Verzeichnis der Bootloadersourcen zu kopieren. (GCREATE.EXE für den GCC und CREATE.EXE für IAR verwenden) Die zu ladende Hex-Applikationsdatei Test.hex wird mit dem Aufruf: GCreate -c Config.txt -d -n -f Test.hex -o Update.hex in Update.hex umgewandelt. Wichtig ist dabei der Schalter -d damit der unbenutzte Flashbereich mit FFs beschrieben wird. Sonst schlägt die CRC - Prüfung fehl. GCREATE erzeugt Schlüsselwörter für den GCC, keine IAR - Schlüsselwörter wie APPFLASH. Nach dem Laden des Bootloaders muss die Fuse LB auf Mode 3 gesetzt werden damit kein Auslesen des Flashs über ISP oder JTAG mehr möglich ist. BLB0 - Mode wird auf 01 gesetzt: keine Beschränkungen für SPM und LPM. BLB1 - Mode wird auf 4 gesetzt: SPM und LPM sind nicht erlaubt. Mit dem Aufruf: Update Update.hex -COM3 -57600 wird das Anwendungsprogramm dann zum ATMEGA64 geschickt. Im Anhang sind zusätzlich Screenshots der Einstellungen. mfg Nucor
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.