Forum: Compiler & IDEs Suche AVR230 für GCC


von Nucor (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Nucor (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Nucor (Gast)


Lesenswert?

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

von Andreas B. (Gast)


Lesenswert?

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.

von Nucor (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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.

von Nucor (Gast)


Lesenswert?

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Normalerweise legt man die CRC als letztes in den zu überprüfenden
Bereich selbst mit hinein.  Dann muss sich 0 ergeben.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Warum fängst du jetzt separat noch einen Thread bei AVRfreaks.net an,
statt hier weiter zu diskutieren?

von Nucor (Gast)


Lesenswert?

Weil ich hier nur Deutsche erreiche,
außer Dir keiner geantwortet hat
und ich im Moment nicht weiter weiss

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

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
}

von Nucor (Gast)


Lesenswert?

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

von Nucor (Gast)


Angehängte Dateien:

Lesenswert?

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
Noch kein Account? Hier anmelden.