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
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 ...?
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
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/
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
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!?
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?
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).
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...
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
Es könnte gefordert sein. Mir ist aber auch kein Fall bekannt.
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
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?!
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
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.
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.
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.
#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.
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
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.
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?
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).
Draco schrieb: > Und nun nochmal der Grund WARUM NICHT die CRC ins EEPROM legen?! Hat man dann das Flash getestet, oder die EEProm Zelle?
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
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.
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.
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?
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
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.
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.
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
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.
> 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.
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
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?
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.
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?!
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
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.
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
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
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>).
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.