AVR Debuggen met Atmel-ICE en MPLAB X IDE onder Linux
Hoe een Atmel/Microchip AVR of SAM Microcontroller debuggen onder Linux met een Atmel-ICE Debugger en MPLAB X IDE
Als je aan een microprocessor project werkt en je wil deze debuggen dan heb je hiervoor een hardware-debugger nodig (zoals de Atmel-ICE of een andere compatibele debugger) en de nodig software.
Microchip (vroeger Atmel) heeft een uitgebreide IDE1 gebaseerd op Microsoft® Visual Studio® (Atmel Studio 7 op dit moment), maar deze is enkel beschikbaar voor Windows®, dus als Linux (of macOS) gebruiker blijf je in de kou staan.
Gelukkig hebben ze ook hun zogenaamde MPLAB X IDE, een op NetBeans gebaseerde IDE die werkt op zowel Linux, macOS als Windows. Deze gaan we dan ook gebruiken om onze microcontroller te "debuggen".
Laten we eerst een kijken wat we allemaal nodig hebben:
- Atmel-ICE programmer/debugger of andere compatibele debugger.
- 8, 16 of 32bit microcontroller compatibel met de Atmel-ICE (ik gebruik een ATMega168P)
- 5volt voeding, breadboard, steekkabeltjes, LED, … om een schakeling te maken die je wil debuggen.
- MPLAB XC Compiler voor jouw microcontroller (XC8, XC16 of XC32), deze is gratis tenzij je gebruik wil maken van de geavanceerde opties. Maar het prijskaartje van een licensie ligt ver boven de prijs die een hobby gebruiker kan betalen. De goedkoopste optie is een maandelijks abonnement dat je eventueel kunt nemen als je de pro functies maar voor 1 project/maand nodig hebt.
- MPLAB X IDE om te programmeren/debuggen.
- optioneel de AVR/ARM Toolchain voor de microcontroller die je gebruikt, Dit is optioneel en kan gebruikt worden als een alternatief voor de XC Compiler. Deze zijn gebaseerd op de GNU Compiler Collection met enkele "optimalisaties" van Atmel/microchip.
Laten we beginnen met het installeren van de software:
Installatie
Het eerste dat we moeten doen is het installeren van de nodig software, na het downloaden van de IDE en Compiler kunnen we deze installeren.
Compiler
Voordat je de compiler kunt installeren op een 64-bit Linux distribtie moet je eerst de "32-bit compatibility packages" installeren, de compiler is op dit moment nog 32-bit.
- sudo dpkg --add-architecture i386
- sudo apt update
- sudo apt install xx:i386 (de xx vervang je door het nodig pakket).
Als er een pakket ontbreekt zal het installatie programma daar een foutmelding over geven en aan de hand hiervan kun je kijken wat je precies moet installeren. Let er op dat je achter het pakket :i386 zet, ander zal Debian het 64-bit pakket installeren of melden dat het al geïnstalleerd is.
Open een terminal venser en navigeer naar de directory waar je de installer gedownload hebt (meestal is dat ~/Downloads). De Compiler komt als een .run programma, dus je moet deze enkel uitvoerbaar maken met chmod +x xc8-v2.20-full-install-linux-installer.run (als je een nieuwere versie download, moet je natuurlijk de bestandsnaam aanpassen).
Vervolgens installeren we deze met root previleges: sudo ./xc8-v2.20-full-install-linux-installer.run.
Geef het wachtwoord van de root gebruiker in en volg het installatieprogramma.
De volgende stap is het installeren van MPLAB X IDE:
MPLAB X IDE
MPLAB X IDE komt in een tarball en deze moeten we eerst uitpakken, maak een tijdelijke directory aan en plaats de MPLAB X IDE tarball in deze directory. Geef nu het commando tar xf MPLABX-v5.40-linux-installer.tar in en wacht tot het pakket is uitgepakt.
Je kunt gewoon de standaard opties gebruiken, bij proxy stel ik wel in dat ik geen proxy heb, de rest zijn de standaard opties.
Als de installatie met success in afgerond kun je MPLAB X IDE opstarten, helaas staat deze nog niet in het menu, dus moeten we deze de eerste keer manueel vanuit de commandoregel opstarten.
het commando hiervoor is mplab_ide
MPLAB X IDE is nu geïnstalleerd, Microchip stelt voor om enkele plugins te installeren (deze worden ook vermeld in het installtieprogramma op het einde van de installatie), het installatie programma opent op mijn computer geen browser naar deze 3, maar 1 ervan is de XC compiler die we al geïnstalleerd hebben, en de andere 2 kunnen we gemakkelijk installeren via:
Als deze geïnstalleerd zijn zal MPLAB X IDE vragen om het programma opnieuw op te starten om de plugins beschikbaar te maken.Programma Maken
Om te testen gaan we een kort programma maken dat een LED zal doen knipperen, dit kunnen we dan wegschrijven naar de microcontroller en vervolgens debuggen:
Het programma:
Begin een nieuw project:
Omdat ik een ATMega 168P gebruik, kies ik voor Microchop Embedded en Standalone Project
Geef bij Select Device eerst aan welke familie van microcontroller je gebruikt, daarna het typenummer van deze controller (ATMega168P in mijn geval) en de programmer/debugger (Atmel-ICE), deze moet aangesloten zijn anders krijg je enkel de 2 opties (no tool, en simulator).
Kies een compiler als je de XC8, XC16, en/of XC32 correct geïnstalleerd hebt staan deze in dit menu en kun je de geschikte compiler kiezen. Ook zie je de mogelijkheid om de AVR compiler te kiezen, de AVR v1.00 compiler stonden al op mijn systeem, en de AVR v5.4.0 is de Atmel/Microchip AVR8 Compiler Toolchain, die ik voor het gemak in mijn $HOME directory heb geplaatst (zoals eerder vermeld is deze optioneel).
Tenslotte moeten we het project nog een naam geven en een directory kiezen voor ons project.
We voegen een sourcecode bestand toe door rechts te klikken op
MPLAB X IDE zal nu een broncode bestand aanmaken met daarin wat boilerplate code
/*
* File: blinkLED.c
* Author: Patrick Kox
*
* Created on 14 July 2020, 12:39
*/
#include <avr/io.h>
#include <util/delay.h>
int
main (void)
{
DDRB = 0xff; // Data Direction Register B, alle pinnen instellen voor OUTPUT
PORTB = 0xff; // Alle pinnen op DDRB naar HIGH (5 Volt) dit zorgt ervoor dat de LEDs om mijn prototyping board uit gaan
while (1) // Eeuwigdurende loop (dit programma stop nooit)
{
_delay_ms(1000); // wacht 100 miliseconden
PORTB |= (1 << PB1); // Schrijd een 1 (HIGH/5V) naar PB1 (de 2de pin van DDRB);
_delay_ms(1000); // wacht 100 miliseconden
PORTB &= ~(1 << PB1); // Schrijf een 0 (LOW/0V) naar PB1
}
return (0); // dit is niet nodig omdat de code hier nooit komt, maar bepaalde compiler klagen als dit er niet bij staat.
}
Programma Schrijven
Nu kunnen we het programma wegschrijven naar de AVR en een Debug sessie beginnen.
- Atmel-ICE PCBA (dit is enkel de printplaat zonder behuizing of kabels)
- Atmel-ICE Basic (dit is de printplaat in een behuizing, usb kabel en de flatcable in de afbeelding hierboven met de 6-pin header (dit is voldoende voor een ATMega168P.
- Atmel-ICE (de volledige kit zoals hierboven is afgebeeld).
De prijs zit tussen de €80 en €180 voor de goedkoopste en de duurste.
Sluit de Atmel-ICE aan, in het geval van de ATMega168P in mijn voorbeeld is dat simpelweg de 6-pin header aansluiten op de ISP aansluiting van de microcontroller.
Schrijf of laad het project in en klik op de knop Make and Program Device Main Project
Bij een microcontroller die enkel debugWire ondersteund (zoals de ATTiny en ATMega168P/328P) krijg je bovenstaande foutmelding, dat komt omdat debugWIRE standaard is uitgeschakeld (and deze is ingeschakeld kun je namelijk geen ISP programmer gebruiken om de microcontroller te programmeren).
schakel de AVR kortstondig uit en klik binnen de 10seconden na het inschakelen op de knop OK
Waarschuwing | |
---|---|
- Begin het project in MPLAB X IDE versie 5.35 en open het daarna in versie 5.40
- Bewerk het bestand configurations.xml en stel daar de
correcte snelheid
in.
<property key="communication.speed" value="0.125"/>
Beide workarounds moeten voor ieder project harhaalt worden. De oplossing die ik hieronder aangeef werkt ook nog. Enkel de aangegeven snelheid is niet correct. Dit is wat Microship Support hierover zegt
- Open project properties
- klik op Atmel-ICE
- Kies "communication" in het drop-down menu
- Zet interface op ISP (in debugWIRE modus kun je de snelheid niet aanpassen).
- Stel de snelheid in op 0.01 (negeer de foutmelding)
- Zet de interface opnieuw op debugWIRE
- klik Apply/OK
Let op! | |
---|---|
debugWIRE
DebugWIRE uitschakelen2:
MPLAB X IDE zal dit automatisch doen bij het beëindigen van een debug-sessie, is er om de een-of-andere reden iets foutgelopen en kun je de microcontroller niet meer benaderen met de Atmel-ICE of enig andere ISP programmer.
Klik voor de zekerheid op Apply manual fuse bit settings.
Zoals je ziet zijn de mensen van deze website zo vriendelijk om ons de correcte AVRDUDE parameters te geven zodat we deze enkel moeten kopieren en plakken. doe dit ook! een typefout is snel gemaakt.
Om deze fuse settings te programmeren openen we dus een commandoregel en geven het volgende commando in:
Waarschuwing | |
---|---|
De ATMega328 is de standaard microcontroller op de Arduino Uno, en veel winkels verkopen een ATMega328 welke al is voorgeprogrammeerd met de Arduino Uno bootloader waardoor je deze kunt gebruiken om een kapotte microcontroller te vervangen of om een Arduino project over te zetten op een breadboard of printplaat.
Een nadeel van de ATMega328 met Uno bootloader is dat deze is ingesteld om gebruik te maken van een externe 16MHz oscillator terwijl een standaard ATMega328 is ingesteld om gebruik te maken van de interne 8MHz oscillator met een pre-scaler van /8.
Voor een ATMega328 met Uno bootloader moet je een externe oscilator met condensatoren voorzien anders werkt de microcontroller niet, en kun je hem ook niet programmeren. Het is mogelijk dat de winkel een kit verkoopt met Microcontroller, Oscillator en 2 condendatoren. Doen ze dat niet dan moet je deze erbij kopen. Wel kun je dit uitzetten door de correcte fuse instellingen te doen en vanaf dat moment heb je geen externe oscillator meer nodig.
Voor de standaard ATMega328 heb je dus geen externe oscillator nodig, maar houd er rekening mee dat deze niet op 8MHz draait, maar slechts op 1MHz! (de pre-scaler van /8). Dit klinkt mischien raar want ze laten een CPU die 8MHz aankan draaiën op slechts 1/8, maar dit is gedaan om stroom te besparen en omdat veel projecten voldoende hebben met een kloksnelheid van 1MHz.
- Int RC Osc. 8MHz. Startup time PWRDWN/RESET:6
- Divide clock by 8 internally [CKDIV8=0]
In het drop-down menu kun je aangeven of je een interne of externe oscillator wil gebruiken (en nog enkele andere opties) en het vinkje voor Divide clock by 8 geeft aan dat we de interne oscillator delen door 8.
Debuggen
Open het project dat je wil programmeren/debuggen in MPLAB X IDE.
Bij mijn opstelling werkt het nieuwe programma pas na het uit en terug inschakelen van de spanning. Dit mag je straks als we in debug-modus zijn dus absoluut niet meer doen!.
Breakpoints:
Ik heb nog geen breakpoints toegevoegd, dus de LED op mijn proefinstelling blijft gewoon knipperen. Als ik links op het regelnummer klik wordt hier zo'n breakpoint toegevoegd en zal de microcontroller stoppen op dit punt.
Willen we dat het programma verder gaat naar het volgende breakpoint, dan klikken we op de knop continue (F5) en het programma zal verder gaan tot het volgende breakpoint bereikt is.
Debug-sessie stoppen:
Als je klaar bent met debuggen, kun je zoals eerder vermeld niet gewoon de Microcontroller en Atmel-ICE (of andere debugger) loskoppelen.
Ik weet niet of het noodzakelijk is, maar voor de veiligheid verwijder ik alle breakpoints en klik daarna op de knop Finish Debugger Session (SHIFT-F5).
Configuration bits
Terug naar ISP modus
Als je klaar bent met debuggen moet je de microcontroller terug omzetten naar ISP modus, anders kun je deze niet benaderen met een ISP programmer of met de Atmel-ICE is ISP modus (via avrdude bijvoorbeeld).
Om dit te doen openen we de project properties en navigeren we naar en zetten we de interface van debugWIRE naar ISP en bevestig met OK:
Je krijg een melding dat verbinden via ISP niet mogelijk is omdat je misschien in debugWIRE modus zit, met de vraag of je terug wil omschakelen naar ISP modus. Klik op Yes en de microcontroller zal weer omgeschakeld worden naar ISP en is weer te gebruiken met iedere ISP programmer.
We kunnen dit controleren met avrdude in de commandoregel:
[patrick@Commandoregel:~]$ avrdude -c atmelice_isp -p m168p
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x50
avrdude: stk500v2_jtag3_recv(): error in jtagmkII_recv()
avrdude: AVR device initialized and ready to accept instructions
Reading | | 0% 0.00savrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_send(): Unexpected response 0xf0, 0x14
avrdude: stk500v2_command(): command failed
avrdude: stk500isp_read_byte(): timeout/error communicating with programmer
avr_read(): error reading address 0x0000
read operation not supported for memory "signature"
avrdude: error reading signature data for part "ATmega168P", rc=-2
avrdude: error reading signature data, rc=-2
avrdude: jtag3_edbg_recv(): Inconsistent fragment number; expect 1, got 0
avrdude: stk500v2_jtag3_recv(): error in jtagmkII_recv()
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_send(): Unexpected response 0x00, 0x00
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x50
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_send(): Unexpected response 0x00, 0x00
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_recv(): Unexpected response 0x40
avrdude: Short read, read only 0 out of 512 bytes
avrdude: jtag3_edbg_signoff(): failed to read from serial port (0)
avrdude done. Thank you.
debugWIRE modus is nog actief en we kunnen de microcontroller niet benaderen via ISP. Als je dit doet zullen alle LEDS op de Atmel-ICE branden. Je kunt de Atmel-ICE dan niet meer gebruiken tot je deze gereset hebt, koppel dan de USB kabel even los en verbind hem weer.
[patrick@Commandoregel:~]$ avrdude -c atmelice_isp -p m168p
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.01s
avrdude: Device signature = 0x1e940b (probably m168p)
avrdude: safemode: Fuses OK (E:F9, H:DF, L:62)
avrdude done. Thank you.
We kunnen de ATMega168P weer gewoon gebruiken.
Om later weer te debuggen zet je de communicatie terug in debugWIRE modus en MPLAB X IDE doet de rest.