Kampis Elektroecke

ATtiny406 – CRCSCAN

Neuer Modelle der ATtiny-Serie, bzw. der Mega-Serie, wie z. B. der ATtiny406 oder der ATtiny414, verfügen über ein eingebautes CRCSCAN-Modul, mit dem der Programmcode beim Starten automatisch auf Fehler untersucht werden kann. In diesem Tutorial möchte ich zeigen, wie das CRCSCAN-Modul genutzt werden kann und wie der Programmcode des ATtiny-Mikrocontrollers automatisch mit einer CRC versehen werden kann.

In diesem Beispiel soll das CRCSCAN-Modul dazu genutzt werden um den Inhalt des Flash-Speichers zu überprüfen. Das Testergebnis soll über eine grüne und eine rote LED signalisiert werden, wobei die grüne LED einen erfolgreichen Test symbolisiert.

Das CRCSCAN-Modul des Mikrocontrollers:

Das CRCSCAN-Modul verwendet den CRC-16-CCITT-Standard um eine CRC von dem kompletten Flash, dem Anwendungscode oder dem Bootcode zu berechnen. Die berechnete CRC wird dann automatisch mit einer abgespeicherten CRC verglichen, wobei sich diese abgespeicherte CRC immer in der letzten Speicherzelle der zu prüfenden Sektion befinden muss. Es ist nicht möglich die CRC im internen EEPROM oder in einem externen Speicher zu speichern und dann einmalig zu laden. Somit muss der erzeugte Programmcode immer mit einer gültigen CRC erweitert werden, doch dazu später mehr.

Zuerst werden die Ausgänge für die beiden LEDs konfiguriert. Die grüne LED soll sich an Pin C0 und die rote LED an Pin C1 befinden. Beide LEDs sollen bei einem High-Pegel leuchten.

PORTC.DIR = (0x01 << 0x01) | (0x01 << 0x00);
PORTC.OUTCLR = (0x01 << 0x01) | (0x01 << 0x00);

Im nächsten Schritt wird das CRCSCAN-Modul aktiviert. Im CTRLB-Register wird die Quelle für die CRC konfiguriert.

Damit der Flash-Speicher als Quelle ausgewählt wird, müssen die beiden ersten Bits des CTRLB-Registers gelöscht werden.

CRCSCAN.CTRLB = CRCSCAN_SRC_FLASH_gc;

Das CRCSCAN-Modul bietet die Option einen Interrupt auszulösen, wenn der CRC-Check nicht erfolgreich war. Im Gegensatz zu den anderen Interrupts des Mikrocontrollers kann dieser Interrupt nicht durch das GIE-Bit deaktiviert werden. Um den Interrupt nutzen zu können, muss das NMIEN-Bit im CTRLA-Register gesetzt werden.

CRCSCAN.CTRLA = CRCSCAN_NMIEN_bm;

In der ISR des CRCSCAN-Moduls soll die grüne LED deaktiviert und die rote LED aktiviert werden um einen Fehlerzustand anzuzeigen.

ISR(CRCSCAN_NMI_vect)
{
	PORTC.OUTCLR = (0x01 << 0x00);
	PORTC.OUTSET = (0x01 << 0x01);
}

Zum Schluss wird das CRCSCAN-Modul noch aktiviert, indem das ENABLE-Bit im CTRLA-Register gesetzt wird. Durch die Abfrage des OK-Bits im STATUS-Register kann die Software feststellen, ob der CRC-Check erfolgreich war. In diesem Fall soll die rote LED deaktiviert und die grüne LED aktiviert werden.

CRCSCAN.CTRLA = CRCSCAN_ENABLE_bm;

if(CRCSCAN.STATUS & CRCSCAN_OK_bm) 
{
	PORTC.OUTCLR = (0x01 << ROT);
	PORTC.OUTSET = (0x01 << GRUEN);
}

Damit ist die Konfiguration des CRCSCAN-Moduls abgeschlossen. Im nächsten Schritt zeige ich noch, wie die CRC des Programmcodes berechnet und in die erzeugte Hex-Datei geschrieben wird.

Berechnen der CRC mit srec_cat:

Die CRC des Programmcodes lässt sich am leichtesten mit dem Programm srec_cat berechnen, welches bei jeder aktuellen Atmel Studio Installation mitgeliefert wird. Über den Reiter Build Events in den Properties des aktuellen Projektes können Ereignisse definiert werden, die vor oder nach dem Kompilieren ausgeführt werden sollen.

In diesem Beispiel soll ein Post-build event, sprich ein Event, welches nach dem Kompilieren ausgeführt wird, definiert werden. Dieses Event soll srec_cat starten und die erzeugte Hex-Datei einlesen und eine CRC des Programmcodes berechnen. Dabei wird der folgende Parameterstring übergeben:

"$(OutputDirectory)\$(OutputFileName).hex" -intel -crop 0x00 0xFFE -fill 0xFF 0x00 0xFFE -CRC16_Big_Endian 0xFFE -broken -o "$(OutputFileName)_crc.hex" -intel -line-length=44
Parameter Funktion
„$(OutputDirectory)\$(OutputFileName).hex“ Quelldatei für srec_cat.
-intel Format der Quelldatei.
Hier ist es das Intel HEX-Format.
-fill 0xFF 0x00 0xFFE Fülle die Datei bis zur Adresse 0xFFE mit 0xFF.
-CRC16_Big_Endian 0xFFE -broken Berechne eine CRC16 und speichere das Ergebnis im Big Endian Format an der Adresse 0xFFE.
Es wird eine common-but-broken Berechnung mit einem Seed von 0x84CF genutzt.
-o „$(OutputFileName)_crc.hex“ Name der Ausgabedatei.
-intel -line-length=44 Format der Ausgabedatei.
Hier wieder das Intel HEX-Format mit einer Zeilenlänge von 44 Zeichen.

Bei dem Aufruf muss darauf geachtet werden, dass die Adressen korrekt sind. Ein ATtiny406 besitzt 4 KB Flash-Speicher. Da srec_cat die Datei byteweise einließt, ergibt sich ein Adressbereich von 0x000 bis 0xFFF.


Hinweis:

Pfade sollten bei einem Aufruf über die Build Events grundsätzlich in Anführungszeichen gesetzt werden, damit es keine Probleme gibt, wenn z. B. der Pfad ein Leerzeichen enthält.


Jetzt kann der Code kompiliert werden. Es entstehen zwei Hex-Dateien, wobei die Hex-Datei mit der Endung „_crc“ die berechnete CRC enthält. Wird nun die Hex-Datei ohne die Checksumme auf den Mikrocontroller kopiert, wird direkt nach dem Programmieren die rote LED angehen. Dies signalisiert einen ungültigen CRC-Check.

Wenn nun aber die Datei mit der CRC auf den Mikrocontroller kopiert wird, geht nach dem Programmieren die grüne LED an. Dies signalisiert einen erfolgreichen CRC-Check.

Das komplette Projekt ist in meinem GitHub-Repository zu finden.