Heb je een microcontroller maar geen debugger? Of mogelijk een microcontroller die geen debugger ondersteunt? Dan zijn deze tips voor jou! Hoewel debuggers en hun mooie geïntegreerde ontwikkelomgevingen (IDE) slim en buitengewoon handig zijn, zijn er momenten waarop ze weinig of niet helpen. Deze debugging-tips geven een paar ideeën over hoe je kunt weten wat er in je microcontroller gebeurt als er geen andere manier is om te onderzoeken.

Hoewel de meeste microcontroller-ontwikkelboards een ingebouwde debugger hebben, zijn er nog genoeg die dat niet hebben. Een van de voordelen van een debugger is de mogelijkheid om de uitvoering van programma's te stoppen, de inhoud van variabelen te bekijken en regel voor regel door de code te lopen. Sommige boards, zoals de Arduino Uno en Mega, hebben echter geen ingebouwde debug-ondersteuning. Er zijn ook kleine 8-bit microcontrollers met maar weinig aansluitingen, zoals sommige van de Microchip PIC10/12/16 series, die niet eens een debugger ondersteunen (er is een oplossing met een debug header board).

Zelfs met een debugger kunnen sommige toepassingen niet gestopt worden tijdens het gebruik. Apparaten die communiceren via USB of Ethernet kunnen door een debugger niet midden in de communicatie onderbroken worden, omdat dit de bestaande verbinding verbreekt. Hetzelfde geldt voor een motorbesturing of digitale voeding, want daar kan het pauzeren van de processor leiden tot kortsluiting of grote stroomstoot door een MOSFET.

    Heeft u ooit zonder debugger gedebugd?


    De knipperende LED

    Verreweg het eenvoudigste debug-gereedschap is een weerstand en een LED naar keuze. Aangesloten op een extra general purpose I/O pin (GPIO) kan deze als een latch op een strategisch punt in het programma worden gebruikt om een elektronische broodkruimel achter te laten. Er zijn een paar voorbeelden van waar dit van pas kan komen:

    • Interrupt routines: Datasheets zijn notoir lastig te interpreteren, en alles wat met interrupts te maken heeft, is dat in het bijzonder. Veel randapparatuur heeft meerdere interrupts. Een seriële interface kan een interrupt genereren wanneer gegevens worden verzonden, wanneer ze worden ontvangen, wanneer de buffer vol is, bij een buffer overflow, en vele andere omstandigheden. Geen wonder dat het activeren van het juiste signaal en er code aan koppelen zo moeilijk is. Simpelweg een GPIO pin hoog zetten in de beoogde interrupt-routine kan bevestigen of je code wordt aangeroepen.
    • Switch en if/else statements: Logica schrijven in C/C++ is foutgevoelig. Wie heeft er niet per ongeluk & gebruikt in plaats van &&? Zonder debugger kun je je afvragen of een vertakking van de code wordt bereikt of dat een beslissing gedecodeerd wordt. Ook hier kan het hoog zetten van een GPIO pin onthullen of de code werd bereikt.
     
    LED for debugging without debugger
    Een LED volstaat om aan te geven of een gedeelte van het programma is bereikt.

    Het mooie van de mogelijkheid tot alleen het instellen van een GPIO is de eenvoud van de code en de snelheid. De meeste processoren kunnen deze taak uitvoeren in één of twee instructiecycli, waardoor de uitvoeringstijd van je code niet significant wordt beïnvloed.

    Helaas zijn sommige debug-uitdagingen complexer. In zulke gevallen zou je kunnen beginnen om de gebruikte pin op verschillende posities aan te passen. Het is echter onwaarschijnlijk dat je dan nog kunt zien dat de LED uit en aan gaat. Als je het geluk hebt een oscilloscoop of logic analyzer te bezitten, sluit die dan aan op de pin, en je zult kunnen zien wat er gaande is.

    De modembenadering - sluit een speaker aan voor geluid!

    Afhankelijk van de complexiteit van het probleem kun je in de verleiding komen om meer pinnen te gebruiken om het probleem op te sporen. Maar bij apparaten met weinig uitgangspinnen zijn er misschien geen meer over. Maar als je toepassing een pulsbreedtemodulatie (PWM) ondersteund, heb je misschien een alternatief.

    PWM's hebben meestal twee belangrijke configuratie-opties: frequentie en markeer-ruimte-verhouding. Eenmaal ingeschakeld schakelen ze zelfstandig een GPIO van de processor in op een frequentie die gerelateerd is aan de oscillator van het apparaat. Om de frequentie te veranderen is meestal een schrijfopdracht naar een enkel register nodig, dus het toevoegen van deze debug-code heeft minimale invloed op de uitvoeringstijd van het programma, net als de LED-aanpak. De mark-space ratio kan op 50% worden gelaten of worden aangepast als deze extra parameter het debug-proces helpt...

    PWM Audio Output schematic
    Een piëzo-speaker kan via een kleine condensator op een microcontrolleruitgang worden aangesloten.
    Anders kan via een transistor een luidspreker of hoofdtelefoon worden aangesloten.

    Om je code te debuggen kun je een piëzo-speaker op de PWM-uitgang aansluiten, of je kunt een transistor gebruiken om de uitgang te versterken om een luidspreker of koptelefoon aan te sturen. Door een regel code toe te voegen om de frequentie te veranderen op strategische punten waar je denkt dat er een probleem is, zal je code een melodie creëren terwijl hij wordt uitgevoerd. Door verschillende delen van de code te doorlopen verandert de 'muziek', en je leert met de tijd wat goed en fout klinkt. Voor degenen die oud genoeg zijn, kan het je doen denken aan de oude modems die we gebruikten om toegang te krijgen tot het Internet vóór het tijdperk van DSL!

    De tijd bijhouden

    Bij sommige microcontrollers is het eenvoudig te bepalen hoe lang een codedeel moet duren om te worden uitgevoerd. Bijvoorbeeld, de meeste assembler instructies van een PIC10/12 vereisen slechts één klokcyclus, behalve instructies die de programmateller veranderen. Met deze kennis kun je berekenen hoe lang een codegedeelte moet duren om uit te voeren onder jouw testconditie en dat vergelijken met een oscilloscoop of logic analyzer.

    De hardware opzet voor deze aanpak is hetzelfde als voor de LED, maar de LED is niet nodig. Het enige verschil is de voorbereiding die nodig is om de uitvoeringstijd van de code te bepalen.

     
    GPIO instrumentation
    Schakelende uitgangen in delen van code kunnen worden vastgelegd met een logic analyzer
    om het pad van de code-uitvoering te traceren.

    Als je geen zin hebt om assembler te decoderen, kun je in plaats daarvan de uitvoeringstijd van de code tussen verschillende punten meten. Door verschillende paden door je code te testen, zou je een gevoel moeten krijgen voor wat er mis zou kunnen gaan. Als bijvoorbeeld een for- of while-lus uitzonderlijk lang of kort is, kan het zijn dat een variabele verkeerd is geïnitialiseerd of dat een beslissing die een lus zou moeten beëindigen verkeerd is gecodeerd.

    Berichten weergeven

    Als je microcontroller geavanceerd genoeg is, kan hij een seriële interface hebben, zoals een U(S)ART of SPI. Evenals PWM zijn dit ook randapparaten die je kunt instellen en vergeten. Om te voorkomen dat gegevens moeten worden gebufferd, moet de interface worden geconfigureerd om op zijn hoogste frequentie te werken, zelfs als dat een vreemde, niet-standaard baud- of zendsnelheid is. De reden dat het niet uitmaakt, is dat we het niet met een ander apparaat verbinden. In plaats daarvan gebruiken we gewoon een logic analyzer.

    USB logic analyzers zijn tegenwoordig erg goedkoop, en de meegeleverde software kan worden geconfigureerd om seriële gegevens te decoderen. Als je er geen bij de hand hebt, kun je er zelf een bouwen om deze debugging-aanpak te ondersteunen met behulp van een Arduino met een snelle, krachtige Arm-processor.

    Deze interfaces vereisen meestal slechts het schrijven van een byte gegevens naar een zendregister, ook iets dat meestal in een enkele klokcyclus wordt uitgevoerd. Daarna worden de bits uitgestuurd volgens de ingestelde datasnelheid. Het enige dat nog moet gebeuren is het toewijzen van verschillende waarden die op verschillende punten in de code moeten worden geschreven. Terwijl de gegevens worden uitgestuurd, krijg je een spoor van het uitvoeringspad van je code. Als de interface snel genoeg is, zouden er geen gegevens verloren moeten gaan.

    De Serial Monitor van de Arduino IDE kan ook de ontvangen berichten timen, wat kan helpen om onverwacht lange delen van de code-uitvoering vast te stellen. De resolutie van de gebruikte timer kan echter onvoldoende zijn om korte gedeelten van de uitvoering van code vast te stellen.

    erial port instrumentation
    De seriële monitor van Arduino kan berichten van een tijdsaanduiding voorzien. Hier zien we een lange periode
    tussen '2' en '0' die kan wijzen op een probleem met de uitvoering van de code.

    Deze aanpak kan ook worden gebruikt voor de uitvoer van waarden die in variabelen of registers zijn opgeslagen, hoewel de output snel verwarrend kan worden om te decoderen vanwege de beperkte informatie.

    Geen debugger? Er is altijd een manier

    Dat je geen debugger hebt, betekent nog niet dat je de code niet kunt debuggen. Je moet alleen een beetje slimmer denken. De hier beschreven methoden, gekoppeld aan begrip van je code en de gebruikte microcontroller, kunnen helpen bij het oplossen van een groot aantal problemen. Ze kunnen zelfs helpen als een debugger dat niet kan! En als geen van de bovenstaande mogelijkheden geschikt is voor je, vind je misschien een ander soort tool of functie die je kunt gebruiken als hulpmiddel bij het debuggen.
     

    Vertaling: Hans Adams