Einstieg in die ARM Entwicklung

Wechseln zu: Navigation, Suche

Der Artikel wird zurzeit erweitert und überarbeitet um allgemein das Einrichten einer Entwicklungsumgebung für ARM (speziell AT91SAM7) zu beschreiben. Die Einrichtung der Toolchain wird dann am speziell Beispiel eines Olimex SAM7H256 Boards zusammen mit dem Olimex JTAG TINY, openocd und der IDE Netbeans sowohl Windows als auch Linux (Debian) beschrieben werden.

Der Artikel soll später einen ersten Einstig in die ARM Entwicklung bieten. Dazu gehören auch Erklärungen zur Speicherarchitektur, Linkerscripte, usw...

Ebenfalls sollen die Tools SAM-BA für Windows, sowie deren "Äquivalent" sam7utils für Linux erläutert werden. Die Anleitung soll allgemein genug gehalten sein, um auch die Nutzung anderer Hard- oder Software zu erlauben. Dazu sollen Hinweise an den entsprechenden Stellen in der Konfiguration die nötigen Hintergrundinformationen bereitstellen.

Wer möchte darf gerne beim Schreiben und Debuggen des Artikels mithelfen. Auch für Anregungen bin ich dankbar. Geschickt wäre allerdings eine vorherige Absprache.


Der Artikel beschreibt die Einrichtung und Inbetriebnahme von OpenOCD zusammen mit openocd unter Windows Vista und Windows Vista x64. Vor allem im Bezug auf die Toolchain lauern unter Vista (besonders x64) verschiedene Fallen die mit Hilfe des Artikels umschifft werden können. Als IDE für die grafische Entwicklung wird Netbeans beschrieben.

Beschreibung der eingesetzten Tools

Als Zielhardware zur Beschreibung dient ein Atmel AT91SAM7S256, auf einem Olimex SAM7-H256 Board. Die Anleitung ist aber auch auf andere ARM-Targets anwendbar. Auf die Unterschiede zwischen den eingesetzten Controller wird gezielt hingewiesen. Zur Programmierung wird Atmels SAM-BA Tool, sowie das JTAG-Interface ARM-USB-Tiny von Olimex eingesetzt.

Als Software kommen Entwicklungstools aus der Yagarto-Toolchain von Michael Fischer zu Einsatz. Die Toolchain kann unter www.yagarto.de heruntergeladen werden. Sie enthält neben den OnChipDebugger Tool OpenOCD von Dominic Rath [1] eine komplette GNU-Compiler-Collection zum Erstellen von C Programmen für ARM 7 und ARM 9 Targets.

Die Yagarto-Toolchain besteht aus vier Paketen. Das Paket „Open On-Chip Debugger” enthält den On-Chip-Debugger OpenOCD. Die „Yagarto Tools“, stellen grundlegende Linux Tools wie make und sh zu Verfügung. Das Paket „YAGARTO GNU ARM Toolchain“ schließlich enthält Compiler, Debugger und die restliche Entwicklungsumgebung. Im vierten Paket „Integrated Development Environment“ befindet sich eine Version von Eclipse, die speziell für die ARM Entwicklung geeignet ist. Auf dieses Paket kann im vorliegenden Fall verzichtet werden.

Als grafische Oberfläche für die Entwicklung wird Netbeans mit C/C++ Pack eingesetzt. Die hier beschriebenen Installationshinweise für die Toolchain gelten aber auch für die Verwendung einer anderen IDE wie z. B. Eclipse

Tabelle 1: Eingesetze Software und deren Versionsnummern
Software Version
Open On-Chip Debugger R717 2008-06-19
Yagarto Tools 2007-03-03
YAGARTO GNU ARM Toolchain 2008-09-28
Netbeans IDE + C/C++ Pack 6.1
Putty beta 0.60
ATMEL AT91-ISP v1.12
Windows Vista Command Shell (cmd) 6.0.6001

Hardwareinstallation

Das verwendete SAM7-H256 Board von Olimex kann auf zwei Arten angesprochen werden. Über den Atmel eigenen SAM-BA Booaloader im Controller über USB (theoretisch kann SAM-BA auch eine UART, CAN oder JTAG Verbindung verwenden, dies wird hier aber nicht betrachtet) oder über das standardisierte 20-Pin-JTAG-Interface. Für die Verbindung mit SAM-BA muss der Treiber für den SAM-BA Bootloader installiert werden. Für die JTAG-Verbindung ist der Treiber für das USB-OCD-TINY von Olimex nötig.

Treiberinstallation USB-OCD(-TINY)

Für die 32 Bit Version von Windows Vista liefert Olimex Treiber für die USB-OCD-Adapter mit, bzw. diese können auf der Homepage herunter geladen werden. Die Treiber können einfach installiert werden.

Für Vista x64 sind keine Treiber verfügbar, jedoch kann man die Treiber für den im USB-OCD eingesetzten FTDI-Chip verwenden. Dazu werden von der FTDI-Webseite [2] die aktuellen VCP bzw. D2XX Treiber (beide Links verweisen auf dieselbe Datei) herunterzuladen. Zu der Zeit als dieses Tutorial geschrieben wurde ist die Treiberversion 2.04.06 vom 20.03.2008 aktuell. Die heruntergeladene ZIP-Datei muss entpackt werden und im so entstandenen Ordner „CDM 2.04.06 WHQL Certified“ die Dateien „ftdibus.inf“und ftdiport.inf angepasst werden. Die Anpassungen betreffen die USB VID und PID, sowie den Device-String. Die VID und PID muss von den Werten von FTDI (VID 0403, PID 6001 und 6010) auf die von Olimex geändert werden. Suchen und ersetzen in einem einfachen Editor sollte ausreichen. Für das USB-OCD ist die neue VID 15BA und die PID 0003. Für das USB-OCD-Tiny gilt die VID 15BA und die PID 0004. Danach müssen noch die Device-Strings in beiden Dateien wie nachfolgend dargestellt angepasst werden. Nach der Änderung sollte z. B. der Abschnitt „Strings“ der ftdiport.inf-Datei folgende Zeilen enthalten:

[Strings]
FTDI="FTDI"
DESC="CDM Driver Package"
DriversDisk="FTDI USB Drivers Disk"
PortsClassName = "Ports (COM & LPT)”
VID_15BA&PID_0004.DeviceDesc="Olimex OpenOCD JTAG TINY PORT"
VID_15BA&PID_0004.DeviceDesc="Olimex OpenOCD JTAG TINY PORT"
SvcDesc="USB Serial Port Driver"
SerEnum.SvcDesc="Serenum Filter Driver"

Die ftdibus.inf sollte im Abschnitt „Strings“ folgendermaßen aussehen:

[Strings]
Ftdi="FTDI"
DESC="CDM Driver Package"
DriversDisk="FTDI USB Drivers Disk”
USB\VID_15BA&PID_0004.DeviceDesc="Olimex OpenOCD JTAG Tiny"
USB\VID_15BA&PID_0004&MI_00.DeviceDesc="Olimex OpenOCD JTAG Tiny 1"
USB\VID_15BA&PID_0004&MI_01.DeviceDesc="Olimex OpenOCD JTAG Tiny 2"
SvcDesc="USB Serial Converter Driver"
ClassName="USB"

Nachdem die Dateien entsprechend angepasst wurden kann das USB-OCD-(Tiny) an den USB-Port angeschlossen werden. Wird der Treiber nicht automatisch gefunden muss der Speicherort entsprechend angegeben werden. Die so angepassten Treiber können auch für die 32 Bit Version von Vista verwendet werden, da das Paket beide Versionen unterstützt.

Treiberinstallation Atmel SAM-BA

Zur Installation des USB-Treibers für SAM-BA muss SAM-BA aus dem ROM des AT91SAMS256-Controllers geladen werden. Das zu ist es beim vorliegenden Board nötig, den Test-Jumper zu schließen und den Controller für 10 Sekunden mit Spannung zu versorgen. Danach wird der Test-Jumper wider geöffnet und nach dem Anstecken an den USB-Port startet SAM-BA. Achtung: Bei anderen Atmel-Controllern bzw. Boards die Vorgehensweise der Anleitung entnehmen. SAM-BA funktioniert nur mit Atmel-Controllern. Nach dem Anstecken an den USB-Port sollte der PC“Neue Hardware gefunden“ melden. Ist das Programm AT91-ISP korrekt installiert, sollte der Treiber automatisch installiert werden. Für Windows Vista x64 gibt es bisher noch keinen Treiber.

Softwareinstallation

Bei der Installtion der Software gibt bezüglich der Pfade zu beachten, dass Teile der Yagarto Tools Probleme mit Klammern im Dateinamen haben. Dies führt vor allem unter Vista x64 zu Problemen, da das Standard-Verzeichnis unterhalb des Ordners „Progamm Files (x86)“ bzw. „Programme (x86)“ liegt. Mit Leerzeichen kommen die Tools jedoch zurecht, nur das Netbeans C/C++ Pack hat noch an einer Stelle ein Problem damit. Dieses Problem ist jedoch nicht von großer Bedeutung. Eine Installation in den „Program Files“ Ordner bzw. den Ordner „Programme“ in der deutschen Version ist also möglich. Im Folgenden wird davon ausgegangen, dass das Stammverzeichnis der installierten Programme ein Unterverzeichnis von „c:\Program Files\Devel\ARM“ ist.

YAGARTO GNU ARM Toolchain

Die Toolchain wird in „.\yagarto\“ installiert.

Yagarto Tools

Die Tools werden in „.\yagarto-tools\” installiert.

Neben den bereits erwähnten Problemen mit Klammern im Pfad haben die Yagarto Tools noch ein weiteres Problem. Klammer im Pfadnamen führen dazu, dass make unter bestimmten Bedingungen mit einer Exception abstürzt. Doch selbst wenn keine Klammern im Pfad vorhanden sind, kommt es immer noch zu Abstürzen. Dies liegt daran, dass die in den Tools enthaltene Shell „sh.exe“ beim Ausführen mit „sync_with_child“ abstürzt und damit make ebenfalls zum Absturz bringt. Dies geht auf einen Fehler im API-Aufruf „CreateProcess“ in der „msys-1.0.dll“ des zugrundeliegenden MSYS/MinGW Systems auf Vista x64 zurück. Details zu dem Problem, sowie eine gepachte Version der Datei (msys-1.0-vista64.zip) finden sich finden sich unter [3]. Mit der gepachten Version wird die msys-1.0.dll im Ordner „.\yagarto-tools\bin“ ersetzt. Danach sollten die Tools ordnungsgemäß funktionieren. Es gibt zwar bereits eine neuere Version der msys.dll, jedoch noch keine Toolchain die mit dieser übersetzt wurde.

Open On-Chip Debugger

OpenOCD wird in “.\openocd-r717\” installiert.

Netbeans IDE

Die Netbeans IDE kann an beliebiger Stelle installiert werden. Wer bereits eine aktuelle Java Runtime installiert hat, kann das C/C++ Bundle installieren. Sonst muss entweder zuvor eine Java Runtime installiert werden, oder man benutzt gleich das All-Bundle.

Putty

Putty dient als Terminal für testweise Telnet-Verbindungen zum OpenOCD Server. Da Vista von sich aus kein Telnet mehr an Board hat. Es kann unter [4] heruntergeladen werden und ist ohne Installation lauffähig.

ATMEL AT91-ISP

Das Atmel ISP Tool wird in ".\AT91-ISP" installiert. Es bringt zwei Programme mit sich. SAM-BA V2.8 und SAM-PROG v2.4. SAM-PROG erlaubt den einfachen Download von Binaries in den Controller, während SAM-BA auch Speicherinhalte anzeigen, auslesen und bearbeiten kann. Zudem lassen sich über TCL-Scripte Befehle automatisiert ausführen. Unter Windows Vista x64 fehlen leider die USB-Treiber für den USB-Bootloader, so dass SAM-BA hier leider noch nicht genutzt werden kann.

Software einrichten

Zuerst ist es sinvoll die Installation der Software auf grundlegende Funktion zu testen. Zur Überprüfung der Funktionalität des JTAG-Interfaces wechselt man in den bin-Ordner im Installationsverzeichnis von OpenOCD. Dort wird ein Terminal geöffnet. (Am schnellsten geht das mit einem Rechtsklick + Shift im Ordner und dann "Open Command Window here".) Nach dem Anschließen des Target Boards an den USB-OCD-Tiny Adapter und dessen Verbindung zum PC ruft man das Programm openodc-ftd2xx.exe auf. Ohne weitere Paramter beschwert sich OpenOCD dass es kein Script-File finden kann. Um ein Scriptfile anzugeben benötigt man den Parameter -f gefolgt vom Dateinamen des Scripts. Im Falle des verwendeten AT91SAM7S256 liefert OpenOCD bereits ein Script (sam7s_armusbocd.cfg) mit. Es liegt im Unterordner scripts\sam7s256. Der neue Aufruf lautet jetzt openocd-ftd2xx.exe -f scripts\sam7s256\sam7s_armusbocd.cfg. Allerdings ist die USB-Vid im Script für das USB-OCD-JTAG eingestellt. Bei Verwendung des USB-OCD-TINY muss diese noch von 0x003 auf 0x004 geändert werden. Ebenfalls muss in der Zeile "ft2232_device_desc" der Eintrag "Olimex OpenOCD JTAG A" in "Olimex OpenOCD JTAG TINY A" geändert werden. Um beide Tools USB-OCD ohne fortwährende Änderungen an der Script-Datei verwenden zu können bietet es sich an eine Kopie als sam7s_armusbocdtiny.cfg abzuspeichern.

Jetzt sollte ein Aufruf von OpenOCD die Ausgabe "JTAG Device found ausgeben".

Warscheinlich wird es dann mit "couldn't open script file" stehenbleiben. Das liegt daran, dass im sam7s256 Script auf eine weiteres Script mit dem Namen "sam7s_reset.script" verwiesen wird, welches sich im Ordner ./prj/ befinden soll. Ein Beispiel reset-Script liegt im selben Ordner wie das sam7s-Script auch. Später kann man dieses einfach in sein Projekt übernehmen und ggf. Inhalt und Pfade anpassen. Jetzt kann die Meldung erstmal ignoriert werden.

Um die Verbindung zum OpenOCD-Sever zu prüfen wird Putty geöffnet und eine Telnet-Verbindung zum localhost auf Port 4444 aufgebaut. Bei erfolgreichem Verbindungsaufbau sollte als Begrüßung "Open On-Chip Debugger" und eine Eingabezeile im Putty-Fenster erscheinen. Die Eingabe von "help" liefert eine Liste der verfügbaren Kommandos. Prinzipiell ist hiermit bereits ein Debugging möglich. Ein testweises "poll"-Kommando sollte Anzeigen, dass der Controller im Zustand halted ist. Mit "shutdown" wird der OpenOCD-Server beendet und die Telnet-Verbindung getrennt. Sind bis hier her keine Fehler aufgetreten funktioniert die JTAG Verbindung zum Target. Als nächstes steht die Einrichtung der Compiler in Netbeans an.

  • Bis hierhin kann der Artikel als allgemeiner Einrichtungshinweis für die Yagarto-Toolchain unter Windows Vista angesehen werden. Er ergänzt damit das sehr gute „Using Open Source Tools for AT91SAM7S Cross Development REV C" von James P. Lynch, das bei Atmel heruntergeladen werden kann. In diesem ist ausfühlich die Benutzung von Eclipse als IDE zur ARM Entwicklung beschrieben. Im Debugging ist Eclipse zurzeit der Netbeans Lösung voraus, da bei Netbeans das Debugging noch nicht funktioniert. Sonst sind beide etwa identisch.

Netbeans C/C++ Pack konfigurieren

Um die ARM Toolchain unter Netbeans nutzen zu können, muss diese dem C/C++-Pack bekannt gemacht werden. Dazu startet man Netbeans und wählt in der Menüleiste Tools, Options aus. Im Options-Fenster wahlt man die Konfiguration für C/C++ aus. Der erste Listenreiter enthält Angaben zu den Build-Tools. Hier kann man sogennannte Tool-Collections zusammenstellen. Evt. besteht bereist eine Collection, da Netbeans beim ersten Start in Pfad nach Compilern sucht und automatisch eine Collection erstellt.

Netbeans Version < 6.9

Mit dem Button Add lässt sich eine neue Collection erstellen. Als Base Direktory wird "C:\Program Files\Devel\ARM\yagarto\bin" gewählt. Für den Namen kann beispielsweise "Yagarto ARM" vergeben werden. Die Collection Family kann auf GNU stehen bleiben. Nach einem Klick auf OK, wird die neue Collection angelegt. Jedoch findet Netbeans die Compiler-Executables nicht, da es z. B. nach gcc sucht, die Compiler aber den Vorsatz arm-elf- im Dateinamen haben. Deshalb muss man die einzelnen Tools selbst auswählen. Der C-Compiler ist "C:\Program Files\Devel\ARM\yagarto\bin\arm-elf-gcc.exe". C++-Compiler ist "C:\Program Files\Devel\ARM\yagarto\bin\arm-elf-g++.exe". Make findet sich in "C:\Program Files\Devel\ARM\yagarto-tools\bin\make.exe" und der Debugger in "C:\Program Files\Devel\ARM\yagarto\bin\arm-elf-gdb.exe". Ein Fortran-Compiler wird nicht benötigt.

Netbeans >= 6.9

In neueren Netbeans Versionen (6.9) werden Toolchains nur noch automatisch erkannt und können nur noch bedingt manuell hinzugefügt werden. Um Yagarto nutzen zu können, kann ein kleines Plugin installiert werden:

Das Plugin unterstützt nur neuere Verionen von Yagarto, deren Dateien mit arm-none-eabi beginnen. Auf der obrigen verlinkten Seite gibt es unter Wiki eine Installationsanleitung.

Für Netbeans >= 7.3 funktioniert das Plugin (noch?) nicht. Hier kann einfach die Datei cnd/modules/org-netbeans-modules-cnd-toolchain.jar um Einträge für die Yagarto Toolchain ergänzt werden. Wie das geht, siehe: http://netbeans.org/bugzilla/show_bug.cgi?id=186180 und zugehöriges Diff: http://bugzilla-attachments-186180.netbeans.org/bugzilla/attachment.cgi?id=99022

  • Nach selbiger Vorgehensweise lässt sich auch die WinAVR-Toolchain (ohne Plugin) mit Netbeans nutzen.

Ein Beispielprojekt

Um mit der Entwicklungsumgebung vertraut zu werden lädt man die Beispiele der Atmel Applicaton Note "Using Open Source Tools for AT91SAM7 Cross Development" herunter. Zu finden sind diese auf der Atmel Homepage unter "Products > AT91SAM 32-bit ARM-based Microcontrollers > Application Notes" und dort im Abschnitt "Development Tools". Die im ZIP-File enthaltenen Beispiele und die Dokumentation ist für weitere Projekte ein sinnvoller Anlaufpunkt.

Aus dem Zip-File entpackt man den Ordner "demo_at91sam7_blink_flash" und die beiden Dateien "at91sam7s256-armusbocd-flash-program.cfg" und "at91sam7s256-armusbocd.cfg" an eine beliebige Stelle, beispielsweise "E:\arm".

Netbeans Projekt erzeugen

Zum Erstellen eines neuen Projekts wird Netbeans gestartet und man wählt im Dateimenü den Punkt "Neues Projekt" aus.

Erfolgreicher erster Build

Fehlgeschlagener Build aufgrund des oben erwähnten Fehler im MSYS/MinGW Systems

Das fertige Projekt, mit dem ab jetzt hier gearbeitet wird, kann hier heruntergeladen werden. Es basiert, wie zuvor beschrieben, auf dem Beispielprojekt zu "Using Open Source Tools for AT91SAM7S Cross Development REV C" von James P. Lynch. Jedoch wurden einige Veränderungen und Anpassungen an Netbeans vorgenommen sowie einige Dateien zur besseren Verständlichkeit umbenannt.

Makefile

Auch bei Netbeans 7.0.1 muss man bei den make-Options unbedingt die -f Option einfügen (siehe Bild).

Im 'makefile' selbst muß man in vielen verfügbaren Beispielen einfach ein paar Optionen löschen, die bei Yagarto so nicht gehen. z.B

  1. In GPFLAGS die Parameter -fpromote-loop-indices und -Wimplicit löschen
  2. "REMOVE = cs-rm -f" ändern zu "REMOVE = -rm -f"

Linker Script

Speicherbereiche der Atmel AT91SAM7 Controller-Serie mit Start- und Endadressen
Speicherverwendung durch das Linker-Script
Auszug des Speichers mit Positionen der einzelnen Datenfelder

Controller programmieren

Nach dem erfolgreichen Build des Projekts liegt das Ergebniss der vorgehenden Bemühungen in Form der Datei "main.bin" im Projektverzeichniss.

Diese gilt es jetzt noch auf den Controller zu übertragen, so dass sie dort ausgeführt werden kann. Hierbei wird auf zwei Methoden eingegangen. Zum einen die Variante der Programmierung über JTAG und OpenOCD, zum anderen die Variante über den SAM-BA Bootloader.

Programmierung mittels OpenOCD JTAG

Zum Programmieren reicht es im Verzeichniss "E:\arm\" den Befehl openocd -f at91sam7s256-armusbocd-flash-program.cfg in der Konsole (CMD) auszuführen. Je nach Art der Installation muss statt openocd der Befehl openocd-ftd2xx verwendet werden.

Die Konfigurationsdatei "at91sam7s256-armusbocd-flash-program.cfg" enthält Befehle die OpenOCD ausführt. In ihr wird auf eine weitere Datei "script.ocd" verwiesen. Diese enthält die eigentlichen Befehle zum Programmieren der Datei "main.bin" auf den Controller.

Nach dem erfolgreichen Durchlaufen des OpenOCD-Aufrufs, ist das Programm in den Controller übertragen. Auf der Konsole sollte dann folgendes zu sehen sein.

Erscheint eine Ausgabe wie folgt dargestellt, sind Teile des zu beschreibenden Speichers über sogenannte Lock-Bits gesperrt. Dies passiert beispielsweise dann, wenn man den SAM-BA Bootloader über Chip-Reset in den ARM geladen hat. Der Bootloader versucht sich dann nämlich vor dem überschreiben zu schützen. Da wir jedoch genau in die Speicherregion schreiben wollen müssen die Lock-Bits gelöscht werden. Dazu werden in der Datei "script.ocd" die beiden Zeilen

# mww 0xffffff64 0x5a000004	#Lockbit 0 löschen
# mww 0xffffff64 0x5a002004 #Lockbit 1 löschen

auskommentiert ( das führende # entfernt) und OpenOCD erneut aufgerufen. Danach sollte man allerdings den Ursprungszustand wieder herstellen, da sonst bei jedem Programmieren eine Löschung der Lock-Bits vorgenommen wird, obwohl das nicht nötig ist. Theoretisch kann ein zu häufiges Schreiben auf diese Speicherstellen den Controller zerstören.

Nach einem erneuten Ausführen des obigen Befehls sollte dann alles klappen. Das Programm ist nun im Controller und wird ausgeführt.

Programmierung mittels SAM-BA

tbc.

(für Linux evt. interessant sam7utils [[5]] als SAM-BA für Linux)

Debugging der Anwendung

mit Netbeans

Mit der Nightly Build 200909221401 von Netbeans ist die (funktionierende) Möglichkeit hinzugekommen zu einem GDBServer zu verbinden. Damit ermöglicht Netbeans Debugging im Zusammenspiel mit OpenOCD. Eine detaillierte Beschreibung folgt noch.

mit GDB(tui)

Ausblick

Die hier aufgeführten Konfigurationseinstellungen zur Einrichtung der Toolchain in Netbeans funktionieren genauso auch unter Linux. Hier kann z. B. die Toolchain aus dem Mikrocontroller Wiki (ARM_GCC_toolchain_for_Linux_and_Mac_OS_X) genommen werden. OpenOCD ist z.B Bestandteil der aktuellen Debian Distribution.

Sobald der Support eines externen GDB im Netbeans ordentlich funktioniert, wird der Artikel um ein Kapitel über Debugging erweitert.

Die Einrichtung der WinAVR Compiler unter Netbeans funktioniert genauso wie hier anhand der ARM-Compiler beschrieben. Damit kann Netbeans auch als IDE für die AVR-Entwicklung auf Windows und Linux verwendet werden.

Die Anmerkungen die für die Installation der Yagarto-Tools bezüglich der Dateinamen und des Patchens gemacht wurden gelten auch für die WinAVR-Umgebung unter Vista.

TODO/Hinweise

Alte Todoliste (obsolet)

  • Bilder zur Erläuterung einfügen?
  • Beschreibungen verbessern
  • Auf weitere Projekt Optionen in Netbeans eingehen
  • Einstellungen der Compiler und Pfade für vorhandene Bibliotheken erläutern
  • Build-Konfiguration bei der man wählen kann, ob für Flash oder RAM kompiliert wird
  • Debugging in Netbeans erläutern