Forum: Mikrocontroller und Digitale Elektronik Speicherzelle für Flashtest unter Atmel Studio reservieren


von Dittmar L. (dittmarlange)


Lesenswert?

Hallo zusammen,

auch auf die Gefahr hin, mich zu blamieren... eine Frage zum Thema 
"Speicherzelle für Flashtest unter Atmel Studio reservieren".

Zu meinem Problem: ich möchte den Flash meines ATmega168PB testen bevor 
ich in die Applikation springe. Dazu gibt es verschiedene Möglichkeiten 
um die es mir aber nicht geht.
Nehmen wir an ich habe eine Funktion, die von Adresse FLASH_START bis 
FLASH_END durch den Flash läuft und als Ergebnis einen Wert uint16_t 
zurück gibt. Ich würde nun gern den Simulator benutzen, um das 
Soll-Ergebnis zu ermitteln und das Ergebnis anschließend in meinen 
Quell-Code einbinden OHNE das sich das Ergebnis der Funktion nach dem 
erneuten Compilieren dadurch ändert!
Ich hab mal ein ähnliches Projekt auf einem PIC18 "geerbt" - man kann 
mit dem C18-Compiler eine Variable direkt an eine Adresse in den Flash 
schreiben:
#pragma romdata crcsumme = 0x7FFE
  rom const int CRC_CHECKSUMME = 0x417F;
Die 0x7FFE ist dabei die Speicheradresse im Flash und CRC_CHECKSUMME ist 
der Name der Variable mit der ich auf den Wert 0x417F zugreifen kann. 
Der Clou dabei ist, dass eine Änderung des Wertes im Quellcode keinen 
Einfluss auf das Ergebnis der Flashtestfunktion hat, da die Funktion nur 
den Bereich bis einschließlich 0x7FFD testet.
Das Gleiche würde ich nun gern auch mit meinem Atmega168PB machen! Weiss 
jemand wie das geht?
Wäre auch denkbar den Wert im EEPROM anstatt im Flash zu speichern...

Danke und Gruß
DL

von H.Joachim S. (crazyhorse)


Lesenswert?

Dittmar L. schrieb:
> Nehmen wir an ich habe eine Funktion, die von Adresse FLASH_START bis
> FLASH_END

Nehmen wir an, du schreibst eine Funktion, die von Adresse FLASH_START 
bis
FLASH_END-2 ...?

von Dittmar L. (dittmarlange)


Lesenswert?

mir ist schon klar, dass ich den Test nicht bis zum Ende des Flashs 
laufen lassen kann...
#define FLASH_START  0x0000
#define FLASH_END  0x7FFC

von Dominik S. (dasd)


Lesenswert?

Mit dem GCC-Attribut "section" kannst du eine Variable an eine fixe 
Stelle ablegen.

z.B.
1
unsigned char __attribute__((section (".myBufSection"))) buf[128];

".myBufSection" musst du entsprechend im Linker-File definieren.

Schau mal hier:
https://mcuoneclipse.com/2012/11/01/defining-variables-at-absolute-addresses-with-gcc/

von H.Joachim S. (crazyhorse)


Lesenswert?

Ok, kurz gesagt suchst du also eine Möglichkeit, eine Konstante an eine 
feste Adresse zu schreiben? Das Problem hatte ich auch schon mal...

#asm
       .cseg
       .equ ver_adr=0x1dfe
       .equ oldpc=pc
       .org ver_adr
_version:
       .db  0,0,0,1
       .org oldpc
#endasm

von Dittmar L. (dittmarlange)


Lesenswert?

Vielen Dank schon mal!

Allerdings kann ich mit

#asm
       .cseg
       .equ ver_adr=0x1dfe
       .equ oldpc=pc
       .org ver_adr
_version:
       .db  0,0,0,1
       .org oldpc
#endasm

nicht so viel anfangen!? Ich gehe jedoch davon aus, dass es sich um 
Befehle handelt, die im Quell-Code eingebunden werden und dann das 
Ergebnis des Flashtests beeinflussen würden!? Das will ich jedoch 
vermeiden. Ich denke, man kommt nicht am Linkerscript vorbei!?

von gärtner (Gast)


Lesenswert?

H.Joachim S. schrieb:
> Nehmen wir an, du schreibst eine Funktion, die von Adresse FLASH_START
> bis
> FLASH_END-2 ...?

Und was ist nun so falsch daran die Prüfsumme in die letzten Zellen zu 
schreiben und diese bei der Berechnung nicht zu berücksichtigen?

von Dominik S. (dasd)


Lesenswert?

gärtner schrieb:
> Und was ist nun so falsch daran die Prüfsumme in die letzten Zellen zu
> schreiben und diese bei der Berechnung nicht zu berücksichtigen?

Du hast das Problem bzw. die Frage vermutlich nicht verstanden.

Er hat nicht gefragt, wohin er die Prüfsumme schreiben soll, sondern 
wie er die Prüfsumme dahin bekommt, ohne dass Sie sich dadurch wieder 
ändert (weil sich der ausführbare Code ändert).

von c-hater (Gast)


Lesenswert?

Dittmar L. schrieb:

> nicht so viel anfangen!? Ich gehe jedoch davon aus, dass es sich um
> Befehle handelt, die im Quell-Code eingebunden werden und dann das
> Ergebnis des Flashtests beeinflussen würden!?

Nur dann, wenn "ver_adr" auf eine Adresse zeigt, die in dem Bereich 
liegt, den dein "Flashtest" beackert...

Da stellt sich dann die Frage: Wie legst du diesen Bereich eigentlich 
genau fest? Ich nehme mal an, dass die Antwort auf diese Frage ein 
heftiges, ununterdrückbares Kichern in meiner Kehle initiieren wird...

von spess53 (Gast)


Lesenswert?

Hi

>Zu meinem Problem: ich möchte den Flash meines ATmega168PB testen bevor
>ich in die Applikation springe.

Wozu soll das gut sein?
Wir benutzen AVRs seit fast 20 Jahren in der Firma und ich kann mich an 
keinen Fall von korrupten Flash erinnern. Oder hat das Ganze 
akademischen Charakter?

MfG Spess

von H.Joachim S. (crazyhorse)


Lesenswert?

Es könnte gefordert sein.
Mir ist aber auch kein Fall bekannt.

von spess53 (Gast)


Lesenswert?

Hi

Wäre eine Moglichkeit

>Mir ist aber auch kein Fall bekannt.

Der TO sollte sich erst hier

http://www.atmel.com/about/quality/reliability.aspx

informieren, bevor er unnütz Zeit investiert.

MfG Spess

von Draco (Gast)


Lesenswert?

Was spricht dagegen die Prüfsumme im EEPROM abzulegen, statt im Flash 
selbst?! Oder verstehe ich die Aufgabenstellung nicht?!

Mir macht es denn Anschein als wolle er, über einen Bootloader(??) den 
Flash auslesen, eine CRC erstellen, diese als uint16 speichern / 
verifizieren? Also warum nicht diese ins EEPROM legen? Du weißt aber 
schon das sich dann nach jeder Programmänderung auch diese, 
logischerweise, CRC ändert??

Aber warum macht man sowas?!

von Dittmar L. (dittmarlange)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

erst mal Danke für eure Inputs!

Zu der Frage wozu das Ganze: es geht um das Thema "Funktionale 
Sicherheit" von Maschinen. Dazu gibt es Richtlinien, die fordern, dass 
ein Prozessor vor der eigentlichen Applikation verschiedene Tests 
absolviert. Und dazu gehört u.a. der Flashtest...

Wie Dominik richtig erkannt hat, besteht mein Problem nicht darin, in 
den Flash oder EEPROM zu schreiben, sondern darin: wie schreibe ich die 
Prüfsumme in einen Speicherbereich OHNE dass der dazu notwendige Code 
den Programmcode (und damit den Flash) verändert. Denn das würde ja 
wieder das Ergebnis des Flashtests verändern!

Im Atmel Studio 6.2 habe ich unter Project -> Properties -> Toolchain -> 
AVR/GNU Linker -> Memory Settings -> EEPROM Segment (siehe Anhang) eine 
Einstellmöglichkeit gefunden, die wahrscheinlich genau für diesen Zweck 
gedacht ist. Leider ist die Hilfe dazu wenig hilfreich...!?

Kennt sich jemand da aus?

Gruss
DL

von Stefan F. (Gast)


Lesenswert?

Du musst beim berechnen der Prüfsumme einfach diese eine Speicherzelle 
auslassen. Dann kannst du da rein schreiben, was immerdu willst, ohne 
dass sich die Prüfsumme ändert.

Ist doch naheliegend, oder nicht?

Auch würde würde der Einfachheit halber lieber das EEPROM verwenden.

von Einer K. (Gast)


Lesenswert?

Stefan U. schrieb:
> Du musst beim berechnen der Prüfsumme einfach diese eine Speicherzelle
> auslassen

Würde ich nicht tun!

Mein Vorgehen/Idee wäre:
Eine Variable im Flash ablegen. Das Prüfsummen Wort.
Aus den, vom Compiler generierten Dateien, die Adresse des Wortes 
fischen.
In der erzeugten Hexdatei das Wort umschreiben, so dass die Prüfsumme 
Null ergibt.

Erledigen könnte das ein kleines Hilfsprogramm.
Entweder im Makefile, oder im Arduinofall ein PostLinkingHook

Frei nach dem Motto:
Einmal schreiben, nie wieder kümmern.

von Soul E. (Gast)


Lesenswert?

Dittmar L. schrieb:

> Wie Dominik richtig erkannt hat, besteht mein Problem nicht darin, in
> den Flash oder EEPROM zu schreiben, sondern darin: wie schreibe ich die
> Prüfsumme in einen Speicherbereich OHNE dass der dazu notwendige Code
> den Programmcode (und damit den Flash) verändert. Denn das würde ja
> wieder das Ergebnis des Flashtests verändern!

Wie oben vorgeschlagen kürzt Du im Linker Command File die Section 
".text" (das ist der Platz für den Programmcode) um zwei bytes und legst 
eine neue Section ".cksum" mit der Länge von 2 bytes an.

Da kommt Deine Prüfsumme rein. Die ist als Zahlenwert bekannt.

const unsigned short chksum = 0x55AA;
unsigned short  __attribute__((section (".cksum"))) chksum;


Der Linker sollte Dich dann warnen, wenn der Programmcode (".text") so 
lang wird, dass er in Deine selbst definierte section ".cksum" 
überlappt.

von H.Joachim S. (crazyhorse)


Lesenswert?

#include <stdint.h>
#include <avr/eeprom.h>

uint16_t eeFooWord EEMEM = 12345;

Obiges Beispiel für den flash (ich dachte das wäre selbsterklärend) 
nennt sich inline-Assembler

#asm                             //start Assembler
       .cseg                     //codesegment
       .equ ver_adr=0x1dfe       //Adresse im Codesegment
       .equ oldpc=pc             //merken des aktuellen pc
       .org ver_adr              //setzen der og. Adresse fürden 
Assembler
_version:
       .db  0,0,0,1              //2 Byte an 0x1dfe (16bit)
                                 //2 Byte an 0x1dff (16bit)
       .org oldpc                //alten pc-Stand wiederherstellen
#endasm
Es werden also die 4 Byte (0,0,0,1) an die letzten beiden flash-Adressen 
geschrieben.

von Stefan (Gast)


Lesenswert?

Ich hatte so etwas mal wie folgt gebaut:
- Der Compiler hat eine Binärdatei erzeugt.
- Ein Skript (Postbuild) füllt den Rest bis zum Flashende mit 0xFF auf, 
berechnet die CRC und schreibt diese in die letzten beiden Bytes zum 
Flashende
- Diese Datei wurde in den Chip geflasht
- Im Code befindet sich eine Routine welche die CRC über das gesamte 
Flash berechnet. Das Ergebnis muß dann 0 sein, sonst wird nicht 
gestartet

Stefan

von H.Joachim S. (crazyhorse)


Lesenswert?

Jo, im Falle einer ROM-CRC ist das sicher der beste Weg von allem, man 
braucht sich nicht bei jeder kleinen binär-Änderung (dafür reicht ja oft 
schon ein simples Compilerupdate) die Sache wieder händisch eintragen.
Lässt sich auch prima im Hexfile bewerkstelligen.

von Draco (Gast)


Lesenswert?

Und nun nochmal der Grund WARUM NICHT die CRC ins EEPROM legen?! Da 
spart man sich den ganzen Quatsch mit zwei Bytes auslassen, Linker 
ändern etc?? Lässt sich leicht anpassen, lässt sich leicht extern 
auslesen ohne überhaupt den Flash anzutasten? Denn genau für sowas ist 
er doch da!

Also warum nicht ins EEPROM?

von Peter D. (peda)


Lesenswert?

Draco schrieb:
> WARUM NICHT die CRC ins EEPROM legen?!

Weil es umständlicher ist, man muß ein extra EEP-File erzeugen lassen 
und dieses mit flashen.
Und wenn man noch andere Settings im EEPROM speichert, möchte man die 
nur ungern bei jedem FW-Update verlieren (ISP kann keine einzelnen Bytes 
im EEPROM löschen).

von Einer K. (Gast)


Lesenswert?

Draco schrieb:
> Und nun nochmal der Grund WARUM NICHT die CRC ins EEPROM legen?!

Hat man dann das Flash getestet, oder die EEProm Zelle?

von Jay (Gast)


Lesenswert?

Hallo,

was Stefan da vorschlägt gibt es schon so gut wie fertig(vorallem, wenn 
man das richtige Polynom wählt) und nennt sich srec_cat.

Gruss,
Jay

von Draco (Gast)


Lesenswert?

Arduino F. schrieb:
> Hat man dann das Flash getestet, oder die EEProm Zelle?

Hä? Er will doch nicht die einzelnen Flashzelle testen, in welcher die 
Variable liegt - sondern den kompletten Flashbereich und dieses CRC dann 
mit der Variable vergleichen. Ob diese nun im Flash, EEPROM, extern oder 
auf nem Blatt Papier steht ist doch völlig irrelevant.

Peter D. schrieb:
> Weil es umständlicher ist, man muß ein extra EEP-File erzeugen lassen
> und dieses mit flashen.
> Und wenn man noch andere Settings im EEPROM speichert, möchte man die
> nur ungern bei jedem FW-Update verlieren (ISP kann keine einzelnen Bytes
> im EEPROM löschen).

Nunja, also wenn ich schon ne Funktion implementier welche mir den CRC 
liest / erzeugt, dann mach ich mir auch Gedanken darüber was passiert 
wenn der CRC nicht stimmt. Sei es das Programm abzubrechen bzw. nicht zu 
starten, oder von dem Programm selbst eine neue CRC erzeugen lassen - 
wenn ich weiß das diese nicht stimmen kann (durch ein FW Update oder 
allg. durch eine selbst herbeigeführte Änderung des Flash) sei es über 
nen Jumper, nen Knopf oder seriell.

von Einer K. (Gast)


Lesenswert?

Draco schrieb:
> sondern den kompletten Flashbereich
Richtig!

Und wenn die Prüfsumme im EEProm steckt, kann der ganze Flash zu 100% OK 
sein, und es wird trotzdem nicht gestartet.
Entspricht irgendwie nicht der Anforderung, finde ich.

Draco schrieb:
> oder von dem Programm selbst eine neue CRC erzeugen lassen
Hier wurden Sicherheitsanforderungen gestellt....
(was immer das auch sein mag)
Das was du vorschlägst, geht Richtung selbst modifizierendem Code.

Vergleich: (nicht alles was hinkt...)
Jede Bank, jede Versicherung, usw. hat eine Revisionsabteilung. Denn 
niemand kann sich selber "objektiv" prüfen. Je mehr man von diesem 
Gedöns außerhalb des Regelbetriebs machen kann, desto besser.

Draco schrieb:
> dann mach ich mir auch Gedanken darüber was passiert
> wenn der CRC nicht stimmt.
Ja klar!
Gutes Vorgehen: Roten Leuchtmelder an, und "endlos Halt Schleife".
Sonst gibts da nix zu denken, oder zu tun.
Mit einer spontanen Selbstheilung ist nicht wirklich zu rechnen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Arduino F. schrieb:
> Draco schrieb:
>> sondern den kompletten Flashbereich
> Richtig!
> Und wenn die Prüfsumme im EEProm steckt, kann der ganze Flash zu 100% OK
> sein, und es wird trotzdem nicht gestartet.
> Entspricht irgendwie nicht der Anforderung, finde ich.
Und wenn nur die Prüfsumme im Flash kaputt ist, wird das Programm nicht 
gestartet, obwohl es tadellos in Ordnung ist. Arg viel besser ist dieses 
Verhalten auch nicht.
Zumindest sollte ein "zufällig" manipuliertes EEPROM für 
sicherheitskritische Anwendungen ebenfalls ein Warnsignal sein...

Peters Argument ist das Beste: wenn alles im Flash ist, muss ich bei der 
Programmierung (Inbetriebnahme und Update) nur das Flash konsistent 
halten. Und muss mich nicht auch noch ums EEPROM kümmern...

> Jede Bank, jede Versicherung, usw. hat eine Revisionsabteilung.
> Denn niemand kann sich selber "objektiv" prüfen.
Und wer prüft den Prüfer? Oder andersrum: die Revisionsabteilung gehört 
doch zur Bank, oder nicht? Woher bekommen die Revisionisten ihren Lohn?

von Peter D. (peda)


Lesenswert?

crc.c:
1
#include <stdint.h>
2
3
uint16_t CRC __attribute__ ((section (".sect_crc"))) __attribute__((used));
4
uint16_t CRC = 0x1234;

Compiler:
-Wl,--section-start=.sect_crc=0x7000

von Stefan F. (Gast)


Lesenswert?

Ich würde ja die Prüfsumme einfach beim ersten Testlauf vom Programm 
selbst ermitteln lassen und speichern. Also nix mit Compiler und Linker. 
Wenn sich danach das Programm verändert, kann man das erkennen und 
(hoffentlich noch) anzeigen.

Der erste Testlauf sollte ohnehin vor der Auslieferung in der 
Produktionsstätte stattfinden.

von Draco (Gast)


Lesenswert?

Die Idee von Stefan ist nicht schlecht. Dazu noch eine "Firstboot-flag" 
setzen, wie auch immer, ebenfalls im Flash und gut ist. Ist der 
Firstboot-flag nicht gesetzt, berechnet er dir CRC und speichert sie, 
setzt die Flag und gut.

von Stefan K. (stefan64)


Lesenswert?

Ich mache sowas auf der Output-Binärdatei mit srec_cat am Ende des 
Makefiles. Das komplette Binary mit Checksumme wird dann ins Flash 
geschrieben. Allerdings nicht unter dem AtmelStudio.

Viele Grüße, Stefan

von H.Joachim S. (crazyhorse)


Lesenswert?

Draco schrieb:
> Die Idee von Stefan ist nicht schlecht. Dazu noch eine "Firstboot-flag"
> setzen, wie auch immer, ebenfalls im Flash und gut ist. Ist der
> Firstboot-flag nicht gesetzt, berechnet er dir CRC und speichert sie,
> setzt die Flag und gut.

Hat aber auch Nachtteile. Eine wackliges Bit könnte beim flashen/verify 
noch ok sein. Beim first_boot aber vielleicht schon nicht mehr -> 
korrumpierter Code würde mit dazu passender CRC als ok gekennzeichnet.
Des weiteren braucht die ganze Sache Programmspeicher, und Routinen, die 
den flash verändern können, will man je nach Sicherheitsanforderungen 
gar nicht im Speicher haben. Fuses können auch deren Ausführung 
verhindern. Ist ein Schutzmechanismus gegen Ausspähen und könnte je nach 
echter, gefühlter oder einfach nur geforderter Sicherheit gesetzt sein.

von Stefan F. (Gast)


Lesenswert?

> Eine wackliges Bit könnte beim flashen/verify noch ok sein.

Wenn du so paranoid bist, dann mach halt den Verify nach dem ersten 
Programmstart. Normalerweise ergibt sich das von ganz alleine, wenn man 
die beiden Aktionen Write und Verify nicht in einem Rutsch ausführt.

> Des weiteren braucht die ganze Sache Programmspeicher,

Den Algorithmus zum Berechnen der Prüfsumme brauchst du so oder so, wenn 
die Prüfsumme zur Laufzeit kontrolliert werden soll. Und wenn sie 
stattdessen nur über einen Programmieradapter geprüft werden soll, ist 
sie vollkommen überflüssig. Denn kannst du gleich einen normalen Verify 
machen.

Hinzu kommt, dass Anwendungen bei denen Datenschutz wichtig ist, ohnehin 
mit Prüfsummern arbeiten. Denn sie müssen mindestens ihre externe 
Kommunikation damit absichern, eventuell sogar den Inhalt des RAM. Also 
ist ein geeigneter Algorithmus ohnehin vorhanden.

Der zusätzliche Code zum Prüfen des Flash beansprucht daher nur wenige 
zusätzliche Bytes. Ich schätze weniger als 100 Bytes.

Wer sich wegen dem bisschen ankackt, der sollte nicht von Sicherheit 
sprechen.

PS: Prüfsumme verwende ich hier stellvertretend für die ganzen 
Alternativen. CRC ist besser aber auch komplexer.

von Dittmar L. (dittmarlange)


Lesenswert?

Hallo zusammen,

noch mal Dank für die vielen Kommentare!

Inzwischen habe ich eine Lösung gefunden die mit dem EEPROM arbeitet und 
zwar nur suboptimal funktioniert aber immerhin.

#include <avr/eeprom.h>
...
const uint16_t EEMEM CRCSUMME = 0x1234;
uint16_t crcsumme_eeprom,crcsumme_flash;

Im Mainprogramm mache ich dann

crcsumme_eeprom = eeprom_read_word((uint16_t*)0);   // Wert aus dem 
EEPROM holen
crcsumme_flash = crcsumme_berechnen(FLASH_START, FLASH_END); // 
berechnet die Checksumme
if (crcsumme_flash!=crcsumme_eeprom)   // wenn ungleich
    while(1);                          // Endlosschleife

Zusätzlich muss man bei den Projekt-Einstellungen ein Häkchen bei 
AVR/GNU Common -> OutputFiles -> .eep (Generate eep file) machen.

In dem elf-File, das dann standardmäßig erzeugt wird, ist das eep-File 
dann leider noch nicht enthalten. Ich musste erst über das Device 
Programming Tool ein neues ELF production file aus dem .hex und dem .eep 
files erzeugen. Dann hat's endlich funktioniert. Allerdings ist das 
Erzeugen der ELF Datei etwas nervig! Gibt es in den Einstellungen nicht 
irgendwo eine Möglichkeit, so dass in der elf-Datei, die vom Atmel 
Studio beim Compilieren erzeugt wird, gleich die .eep-Datei eingebunden 
wird?

Vielen Danke und beste Grüße
Dittmar

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Dittmar L. schrieb:
> Inzwischen habe ich eine Lösung gefunden die mit dem EEPROM arbeitet und
> zwar nur suboptimal

Was gefällt Dir an meiner Lösung mit der Flash-section nicht?

von Thomas (kosmos)


Lesenswert?

Man kann doch die 2 Bytes oder 4 Bytes einer CRC Prüfsumme im AVR- 
Studio ins .eseg schreiben bein Flashen muss man doch nur den Hacken 
setzten das auch das Eeprom gebrannt wird.

Da die Checksumme aber nur vor dem Beginn des eigentlichen Programms 
stattfindet kann man keinen Fehler ausschließen der während der 
Ausführung Auftritt, den ein Bit kann auch während der Ausführung 
kippen. Es könnte ja sein das die Maschine mehrere Jahre durchgängig 
arbeitet und danach eine Zelle kippt. Diese Startprüfung würde also 
nichts bringen.

von Draco (Gast)


Lesenswert?

Thomas O. schrieb:
> Da die Checksumme aber nur vor dem Beginn des eigentlichen Programms
> stattfindet kann man keinen Fehler ausschließen der während der
> Ausführung Auftritt, den ein Bit kann auch während der Ausführung
> kippen. Es könnte ja sein das die Maschine mehrere Jahre durchgängig
> arbeitet und danach eine Zelle kippt. Diese Startprüfung würde also
> nichts bringen.

Das ist richtig, man kann ja Zwischenprüfungen durchführen?!

von Dittmar L. (dittmarlange)


Lesenswert?

Peter D. schrieb:
> Dittmar L. schrieb:
>> Inzwischen habe ich eine Lösung gefunden die mit dem EEPROM arbeitet und
>> zwar nur suboptimal
>
> Was gefällt Dir an meiner Lösung mit der Flash-section nicht?

Hallo Peter,

du schreibst:
Compiler:
-Wl,--section-start=.sect_crc=0x7000

heisst das, die section wird ab Startadresse 0x7000 abgelegt?

Wie erkläre ich Atmel Studio diese zusätzliche Compiler Option?

Gruß
DL

von Peter D. (peda)


Lesenswert?

Dittmar L. schrieb:
> heisst das, die section wird ab Startadresse 0x7000 abgelegt?

Ja.

Dittmar L. schrieb:
> Wie erkläre ich Atmel Studio diese zusätzliche Compiler Option?

Die Zeile unter: "Custom Options", "Linker Options" hinzufügen.

von Dittmar L. (dittmarlange)


Angehängte Dateien:

Lesenswert?

Peter D. schrieb:
> Dittmar L. schrieb:
>> heisst das, die section wird ab Startadresse 0x7000 abgelegt?
>
> Ja.
>
> Dittmar L. schrieb:
>> Wie erkläre ich Atmel Studio diese zusätzliche Compiler Option?
>
> Die Zeile unter: "Custom Options", "Linker Options" hinzufügen.

Hallo Peter,

danke für den Tip! Ist ne super Lösung! Ich habs dann auch bei den 
Linker Options gefunden und hat im Prinzip auch funktioniert.
Aber - jetzt hab ich ein neues Problem: ich hab mal ein kleines 
Beispielprogramm dazu geschrieben und auf einem ATmega168PB Xplained 
Mini im Debugmode getestet. Siehe Anhänge...
Man kann auch sehen, dass sowohl die Variable CRC als auch die 
crcsumme_flash an den Stellen im Programmspeicher liegen, die vom Watch 
angegeben werden. Beide Variablen haben laut Watch-Fenster den gleichen 
Wert! Trotzdem führt der Vergleich (CRC==crcsumme_flash) in den 
Nein-Zweig!? Kann mir das mal jemand erklären!?

Danke
DL

von Einer K. (Gast)


Lesenswert?

Dittmar L. schrieb:
> Trotzdem führt der Vergleich (CRC==crcsumme_flash) in den
> Nein-Zweig!? Kann mir das mal jemand erklären!?

Kein Problem!
CRC holt, so wie du es tust, den Wert aus dem RAM.
Aber da steht bestimmt ganz was anderes, als im Flash.

Es gibt bestimmt eine Funktion/Macro welches ReadFlashByte( )  oder so 
heißt.

http://www.atmel.com/images/atmel-2575-c-functions-for-reading-and-writing-to-flash-memory_applicationnote_avr106.pdf

von Peter D. (peda)


Lesenswert?

Ich weiß jetzt nicht, wie das bei neuen Versionen ist.
Aber beim alten AS4.18 muß man aus dem Flash mit 
pgm_read_word(address_short) lesen (#include <avr/pgmspace.h>).

von Einer K. (Gast)


Lesenswert?


von Dittmar L. (dittmarlange)


Lesenswert?

Peter D. schrieb:
> Ich weiß jetzt nicht, wie das bei neuen Versionen ist.
> Aber beim alten AS4.18 muß man aus dem Flash mit
> pgm_read_word(address_short) lesen (#include <avr/pgmspace.h>).

Servus Peter,

juhu es funktioniert!

Noch mal vielen Dank an alle, die geholfen haben!

Hier noch zum Abschluss die Lösung...

Quell-Code:
1
#include <avr/pgmspace.h>
2
3
// mit noch einer kleinen Vereinfachung...
4
uint16_t __attribute__ ((section (".sect_crc"))) __attribute__((used)) CRC = 0x1234;
5
6
uint16_t crcsumme_flash,crc_from_sect;
7
8
int main (void)
9
{
10
  crcsumme_flash = 0x1234;                // hier muss dann die CRC-Check-Funktion hin 
11
  crc_from_sect = pgm_read_word(0x3FFE); 
12
  
13
  if (crc_from_sect==crcsumme_flash)  // alles gut
14
  else          // Fehler
15
  {
16
    while(1);
17
  }
18
}
Einstellung in den Project properties -> Toolchain -> AVR/GNU Linker -> 
Miscellaneous -> Other Linker Flags:
-Wl,--section-start=.sect_crc=0x3FFE

Danke
Dittmar .L

: Bearbeitet durch User
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.