AVRSH: Ein Command Interpreter Shell für Arduino / AVR.

6 Schritt:Schritt 1: Was Sie benötigen Schritt 2: Lesen und Schreiben von Registern Schritt 3: Lesen und Schreiben von Sicherungen Schritt 4: Weitere Kommandos Schritt 5: Anpassen der Shell Schritt 6: Zusammenfassung

AVRSH: Ein Command Interpreter Shell für Arduino / AVR.
Wollten Sie schon immer zu Ihrer AVR-Mikrocontroller "angemeldet" werden? Immer dachte, es wäre ein Register, um den Inhalt zu sehen cool, "cat"? Haben Sie einen Weg an die Macht und Power-Down einzelnen peripheren Subsystemen Ihres AVR oder Arduino in Echtzeit * * schon immer? Ich auch, so schrieb ich den AVR Shell, eine UNIX-ähnliche Shell.



Es ist UNIX-ähnlichen, weil es erinnert an die Shell-Account Sie ging hinaus und kaufte zu Ihrem IRC-Bots auf nick Kollision führen, sowie mit einem Befehl oder zwei gemeinsam. Es hat auch ein Dateisystem, das UNIX EXTFs ähnelt, mit einem externen EEPROM, aber das ist zu einem Projekt für sich so werde ich separat Freigabe dieses Modul unter einem anderen instructable wenn es produktionsfertigen.

Hier ist eine Liste der Dinge, die Sie derzeit mit dem AVR Shell zu tun:

    Lesen Sie alle Ihre Data Direction Register (DDRn), Ports und Pins in Echtzeit schreiben, um alle Ihre DDRn ist, Ports und Pins auf Motoren das System einschalten, LEDs oder Lesesensoren in Echtzeit Liste aller bekannten Register erstellen und Speichern von Werten in benutzerdefinierte Variablen unterstützt durch EEPROM. Erstellen Sie ein Root-Passwort authentifizieren und gegen sie (für den Telnet-Zugriff verwendet werden) Lesen Sie die projektierte CPU-Taktrate ändern CPU-Takt, indem Sie einen Vorteiler starten und stoppen 16-Bit-Timer für verschiedene Dinge Einschalten und / oder Ausschalten peripheren Unter -systeme: D-Wandler (ADC), Serial Peripheral Interface (SPI), Zwei-Draht-Interface (TWI / I2C), UART / USART. Nützlich, wenn Sie den Stromverbrauch des Mikrocontrollers zu reduzieren oder um bestimmte Funktionen aktivieren möchten. Geschrieben in C ++ mit wiederverwendbaren Objekte.
    Diese instructable wird durch die Installation, Verwendung und Anpassung von avrsh gehen.
    Schritt 1: Was Sie benötigen

    AVRSH: Ein Command Interpreter Shell für Arduino / AVR.
    Diese instructable erfordert nicht viel, außer dass Sie:

      Hast Du ein Arduino oder ATmega328P. Andere AVR könnte funktionieren, aber möglicherweise müssen Sie den Code ändern, um Register, die speziell auf Ihre MCU sind, aus. Die Namen müssen nur zu entsprechen, was im <avr / io * .h> Header-Datei nur in Ihrem MCU aufgeführt ist. Viele der Registernamen sind dieselben zwischen AVRs, so die Leistung kann bei der Portierung variieren. Eine Möglichkeit haben, an den seriellen USART Ihrer Arduino / AVR zu verbinden. Das System wurde sehr ausgiebig mit dem getesteten AVR-Terminal , einer Windows-Anwendung, die eine serielle Verbindung über USB-oder COM-Port macht. Kompatibel mit Arduinos mit dem USB-Anschluss und jede AVR mit Hilfe der USB-BUB von Moderndevice.com . Andere Terminaloptionen gehören: Putty, minicom (unter Linux und FreeBSD), Bildschirm (Linux / FreeBSD), Hyperterminal, Teraterm. Ich habe festgestellt, Kitt und TeraTerm senden einige Müll beim Anschließen so Ihre erste Befehl verstümmelt werden. Haben die AVR Shell-Firmware installiert ist und läuft, der Ihnen ermöglicht diesen Seiten herunterladen oder erhalten immer die neueste Version auf BattleDroids.net .
      Um den AVR-Terminal installieren, einfach entpacken und ausführen. So installieren Sie den AVR Shell Firmware herunterladen und entweder direkt laden Sie die Hex-Datei und schließen Sie Ihr serielles Terminal mit 9600 Baud oder kompilieren Sie es sich mit "make" und dann "make-Programm", um die Hex hochladen. Beachten Sie, müssen Sie möglicherweise die AVRDUDE Einstellungen ändern, um Ihren COM-Port zu reflektieren.

      Hinweis: Die PROGMEM Attribut in der aktuellen AVR GCC-Implementierung für C ++ gebrochen und dies ist ein bekannter Fehler. Wenn Sie es zu kompilieren, erwarten, zu bekommen viele Warnmeldungen zu sagen ". Achtung: nur initialisierten Variablen können in Programmspeicherbereich gelegt werden" Abgesehen davon, dass ärgerlich zu sehen, ist diese Warnung harmlos. Als C ++ auf dem Embedded-Plattform ist nicht ganz oben auf der Prioritätenliste AVR GCC ist nicht bekannt, wann dies behoben werden. Wenn Sie einen Blick auf den Code, werden Sie sehen, wo ich Arbeit arounds gemacht, um diese Warnung durch die Umsetzung meiner eigenen Attribut-Anweisungen zu reduzieren.

      Ziemlich einfach. Downloaden und installieren Sie alles, was Sie benötigen, um dann drehen Sie die Seite und lassen Sie uns crackin.
      Schritt 2: Lesen und Schreiben von Registern

      AVRSH: Ein Command Interpreter Shell für Arduino / AVR.
      Der AVR Shell wurde in erster Linie geschrieben, einige Sensoren, die ich zu meinem AVR angeschlossen hatte zuzugreifen. Es begann mit einem einfachen LED zog dann nach Lichtsensoren, Temperatursensoren, und schließlich auf beiden Ultraschallwandler. avrsh können die digitalen Komponenten dieser Sensoren durch das Schreiben auf die Register, die sie steuern.

      Manipulation AVR Register während der Ausführung
      Um eine Liste aller bekannten Register auf Ihrem Arduino, Typ zu erhalten:
       Druckregister 
      und du wirst einen Ausdruck suchen, wie dieses ...
       Ich weiß, über die folgenden Register: TIFR0 PORTC TIFR1 PORTD TIFR2 DDRD PCIFR DDRB EIFR DDRC EIMSK PINB EECR PINC EEDR PIND SREG EEARL GPIOR0 EEARH GPIOR1 GTCCR GPIOR2 TCCR0A TCCR0B TCNT0 OCR0A OCR0B SPCR SPDR ACSR SMCR MCUSR MCUCR SPMCSR WDTCSR CLKPR PRR OSCCAL PCICR EICRA PCMSK0 PCMSK1 TIMSK0 TIMSK1 TIMSK2 ADCL ADCH ADCSRA ADCSRB ADMUX DIDR0 DIDR1 TCCR1A TCCR1B TCCR1C TCNT1L TCNT1H ICR1L ICR1H OCR1AL OCR1AH ​​OCR1BL OCR1BH TCCR2A TCCR2B TCNT2 OCR2A OCR2B ASSR TWBR TWSR TWAR TWDR TWCR TWAMR UCSR0A UCSR0B UCSR0C UBRR0L UBRR0H UDR0 PORTB root @ ATMEGA328P> 
      Um zu sehen, wie die einzelnen Bits in jedem Register gesetzt, verwenden Sie die Katze oder Echo-Befehl:
       cat% GPIOR0 
      Hier bitte ich den Befehlsinterpreter zum Anzeigen oder Echo, der Inhalt des General Purpose I / O-Register # 0. Beachten Sie das Prozentzeichen (%) vor dem Registernamen. Diese benötigen Sie, um mit der Schale, dass dies ein reserviertes Schlüsselwort identifiziert ein Register angeben. Die typische Ausgabe von einem Echo-Befehl sieht wie folgt aus:
       GPIOR0 (0x0) auf [00000000] 
      Der Ausgang wird der Name des Registers, der hexadezimale Wert im Register und der Binärdarstellung Register (welches jedes Bit als eine 1 oder 0). Um ein bestimmtes Bit in jedem Register gesetzt, verwenden die "index of" operator []. Zum Beispiel, sagen wir, ich will das 3. Bit auf eine 1.
       GPIOR0% [3] = 1 
      und die Schale wird Ihnen eine Antwort, die anzeigt es die Aktion und das Ergebnis:
       GPIOR0 (0x0) auf [00000000] -> (0x8) auf [00001000] 
      Nicht 'vergessen, das Prozentzeichen, um die Schale Sie mit einem Register Arbeits erzählen. Beachten Sie auch, dass, indem Sie die 3. Bit, das in 4 Bits, weil die Verwendung unseres AVR einem nullbasierten Index. Mit anderen Worten, das Zählen bis zur 3. Bit Sie Anzahl 0, 1, 2, 3, die den 4. Platz, aber das 3. Bit ist. Sie kann ein Bit in der gleichen Weise, indem ein Bit auf Null zu löschen.

      Durch Setzen der Bits so können Sie das Funktionieren Ihres AVR im laufenden Betrieb zu ändern. Zum Beispiel, indem Sie die CTC-Timer-Wert in Übereinstimmung OCR1A gefunden. Außerdem können Sie in bestimmte Einstellungen, die Sie müssten programmatisch prüfen im Code, wie das UBBR Wert für Ihr Baudrate spähen.

      Arbeiten mit DDRn, PORTn und PINn
      Die I / O-Pins werden auch Register zugeordnet und kann in genau derselben Weise festgelegt werden, sondern eine spezielle Syntax erstellt wurde, mit diesen Arten von Registern arbeiten.

      In Code, es ist ein normaler Prozess für, sagen wir, das Einschalten einer LED oder einem anderen Gerät, das einen digitalen hoher oder niedriger erfordert. Es erfordert die Einstellung der Datenrichtungsregister, um den Stift zeigen, ist für die Ausgabe, und klicken Sie dann auf die jeweilige Bit in den richtigen Anschluss Schreiben einer 1 oder 0. Angenommen wir haben eine LED-Digital-Stift 13 (PB5) verbunden sind, und wir, um es einzuschalten möchten, hier ist, wie zu tun, dass, während die AVR läuft:
       Set pin PB5 outputwrite pin PB5 Hoch 
      Die Ausgabe, abgesehen davon, in der Lage zu sehen, Ihre LED komm schon, würde so aussehen:
       root @ ATMEGA328P> gesetzt pin PB5 outputSet PB5 für outputroot @ ATMEGA328P> Schreibstift PB5 highWrote logisch hoch zu PB5 Stift 
      Der "root @ ATMEGA328P>" ist der Shell-Eingabeaufforderung, die es bereit ist, Befehle von Ihnen zu akzeptieren ist, zeigt. So schalten Sie die LED aus, würden Sie einfach einen niedrigen auf den Stift. Wenn Sie den Digitaleingang von einem Stift lesen möchten, verwenden Sie den Lesebefehl. Mit unserem obigen Beispiel:
       root @ ATMEGA328P> lesen Stift pb5Pin: PB5 HOCH 
      Alternativ Echo nur die Pin-Register, dass Pin-Anschluss steuert. Zum Beispiel, wenn wir Dip-Schalter, um digitale Stift 7 und 8 (PD7 und PD8) verbunden ist, können Sie den Befehl zu senden:
       echo% PIND 
      und die Schale dann den Inhalt des Registers angezeigt werden, zeigt Ihnen alle Ein- / Ausgangszustände der angeschlossenen Geräte und ob der Zustand des Schalters war ein oder aus.

      Schritt 3: Lesen und Schreiben von Sicherungen

      AVRSH: Ein Command Interpreter Shell für Arduino / AVR.
      Sicherungen sind besondere Arten von Registern. Sie steuern alles von der Taktgeschwindigkeit Ihres Mikrocontroller, was Programmiermethoden zur Verfügung, um Schreibschutz EEPROM. Manchmal müssen Sie diese Einstellungen ändern, vor allem wenn Sie die Schaffung eines eigenständigen AVR-System. Ich bin nicht sicher, sollten Sie Ihre Sicherungseinstellungen auf Arduino ändern. Seien Sie vorsichtig mit der Sicherung; können Sie sich selbst aussperren, wenn Sie sie nicht richtig eingestellt.

      In einer früheren instructable zeigte ich, wie man lesen und stellen Sie Ihre Sicherungen mit Ihrer Programmierer und avrdude. Hier werde ich Ihnen zeigen, wie zur Laufzeit wieder lesen Sie Ihre Sicherungen, um zu sehen, wie Ihr MCU tatsächlich setzen sie. Beachten Sie, dass dies nicht der Compile-Zeit einstellen, dass Sie von den Definitionen in erhalten <avr / io * .h> aber die tatsächlichen Sicherungen wie die MCU liest sie zur Laufzeit.

      Aus Tabelle 27-9 im ATmega328P Datenblatt (Databook, mehr wie es) die Bits der Fuse Low Byte sind wie folgt:
        CKDIV8 CKOUT SUT1 SUT0 CKSEL3 CKSEL2 CKSEL1 CKSEL0 
      Eine interessante Sache zu beachten ist, dass mit Sicherungen, 0 bedeutet programmiert und eine 1 bedeutet, dass das jeweilige Bit ist nicht programmiert. Etwas counter-intuitive, aber wenn Sie es wissen, dass Sie es wissen.
        CKDIV8 setzt Ihre CPU-Takt von 8 unterteilt werden Die ATmega328P stammt aus der so programmiert, dass seine internen Oszillator bei 8 MHz mit CKDIV8 programmiert verwenden Fabrik (dh auf 0 gesetzt) ​​gibt Ihnen eine letzte F_CPU oder CPU-Frequenz von 1 MHz. Auf Arduino ist, wird dieses verändert, seit sie konfiguriert sind, um einen externen Oszillator bei 16 MHz zu verwenden. CKOUT wenn programmierten Ausgangs Ihre CPU-Takt auf PB0, die digitalen Stift 8 auf Arduinos ist. SUT [1..0] gibt die Startzeit für Ihren AVR. CKSEL [3..0] wird die Taktquelle, wie zum Beispiel den internen RC-Oszillator, externen Oszillator, etc.When Sie Ihre Sicherungen zu lesen, wird es Ihnen in hexadezimale zurückgegeben werden. Dies ist das Format, die Sie brauchen, wenn Sie die Sicherungen über avrdude schreiben möchten. Auf meinem Arduino, ist hier, was ich, wenn ich lesen Sie die untere Sicherung Byte:
          root @ ATMEGA328P> lesen lfuseLower Sicherung: 0xff 
        So werden alle Bits auf 1 gesetzt Ich habe diesen Vorgang auf einem Arduino Klon und bekam den gleichen Wert. Überprüfen einer meiner eigenständigen AVR-Systemen, bekam ich 0xDA die der Wert hatte ich vor einiger Zeit bei der Konfiguration des Chipsatzes ist.

        Das gleiche Verfahren wird für die Überprüfung der Hoch Fuse Byte, Erweiterte Fuse Byte verwendet, und Lock-Sicherungen. Die Kalibrierung und Unterschrift Sicherung Bytes im Code mit einem #if 0 Präprozessordirektive, die Sie ändern, wenn Sie das Gefühl, scrappy deaktiviert.
        Schritt 4: Weitere Kommandos

        AVRSH: Ein Command Interpreter Shell für Arduino / AVR.
        Es gibt mehrere andere Befehle, dass der Standard-Befehlsinterpreter versteht, dass Sie nützlich sein können. Sie können alle umgesetzt und Zukunft-release-Befehle durch die Ausgabe von Hilfe oder Menü an der Eingabeaufforderung angezeigt. Ich werde hier schnell zu decken, wie sie sind größtenteils selbsterklärend.

        CPU-Taktfrequenz Einstellungen
        Sie können herausfinden, was Ihre Firmware wurde so konfiguriert, wie die CPU-Takteinstellungen mit dem Befehl fcpu verwenden:
          root @ ATMEGA328P> fcpuCPU Freq: 16000000 
        Das ist 16 Millionen oder 16 Millionen herz, besser bekannt als 16 MHz bekannt. Sie können dies im laufenden Betrieb aus irgendeinem Grund ändern, mit dem Befehl Uhr. Dieser Befehl akzeptiert ein Argument: der Vorteiler beim Teilen Sie Ihre Taktgeschwindigkeit zu bedienen. Der Befehl clock versteht diese Vorteiler Werte:

          ckdiv2 ckdiv4 ckdiv8 ckdiv16 ckdiv32 ckdiv64 ckdiv128 ckdiv256
          Mit dem Befehl:
            Uhr ckdiv2 
          wenn Ihre CPU-Geschwindigkeit ist 16 MHz würde in Ihrem Taktrate führen, die an 8 MHz geändert. Mit Hilfe eines Vorteiler von ckdiv64 mit einer anfänglichen Taktrate von 16 MHz werden in einem abschließenden Taktrate von 250 kHz zur Folge haben. Warum in aller Welt würden Sie wollen, dass Ihr MCU langsamer zu machen? Nun, zum einen, verbraucht eine niedrigere Taktfrequenz weniger Strom und wenn Sie Ihr MCU Ablaufen einer Batterie in einem Projekt-Gehäuse können Sie nicht brauchen, um auf Hochtouren laufen, und daher, verringern Sie die Geschwindigkeit und reduzieren es ist Stromverbrauch , die Erhöhung der Lebensdauer der Batterie. Auch wenn Sie die Uhr für jede Art von Timing-Probleme mit einer anderen MCU, sagen wir, die Implementierung einer Software-UART oder eine solche Sache, möchten Sie vielleicht, um es auf einen bestimmten Wert, die leicht ist, eine nette sogar Baudrate mit zu setzen geringere Fehlerraten.

          Einschalten und Ausschalten Peripheral Subsysteme
          Auf die gleiche Note wie die Verringerung bereits erwähnt Stromverbrauch, können Sie an die Macht weiter zu reduzieren durch Herunterfahren einige der On-Board-Peripheriegeräte, die Sie nicht verwenden. Die Kommando-Interpreter und Schale kann derzeit Einschalten und Ausschalten folgender Peripherie:

            Analog-Digital-Wandler (ADC). Diese periphere wird verwendet, wenn ein analoges Sensor Bereitstellen von Daten (wie Temperatur, Licht, Beschleunigung, etc.) und müssen es in einen digitalen Wert umzuwandeln. Serial Peripheral Interface (SPI). Der SPI-Bus wird verwendet, um mit anderen SPI-fähige Geräte wie externe Speicher, LED-Treiber, externe ADC usw. Teile der SPI für ISP-Programmieren verwendet zu kommunizieren, oder zumindest die Stifte, also Vorsicht beim Herunter diese nach unten wenn Sie über ISP Programmierung. Zweidrahtschnittstelle. Einige externe Geräte verwenden die I2C-Bus zu kommunizieren, obwohl diese schnell durch SPI-fähige Geräte ersetzt werden, wie SPI einen größeren Durchsatz. USART. Das ist Ihre serielle Schnittstelle. Sie haben wahrscheinlich nicht wollen, dies zu deaktivieren, wenn Sie über die serielle Verbindung mit dem AVR verbunden sind! Allerdings fügte ich diese in hier als Gerüst für die Portierung auf Geräten, die mehrere USART ist wie der ATmega162 oder ATmega644P haben. alle. Das Argument für die Powerup oder Powerdown Befehl schaltet alle genannten Peripheriegeräte oder schaltet sie alle mit einem Befehl. Auch hier verwenden Sie diesen Befehl mit Bedacht aus.
              root @ ATMEGA328P> Powerdown twiPowerdown von twi complete.root@ATmega328p> Powerup twiPowerup von twi abgeschlossen. 

            Starten und Stoppen von Zeiten
            Die Schale hat eine integrierte 16-Bit-Zeitgeber, der für die Verwendung zur Verfügung steht. Sie starten den Timer mit dem Befehl Timer:
              Timer-Start 
            und stoppen Sie den Timer mit der Stop-Argument:
              Timer-Stopp 
            Dieser Zeitgeber wird nicht mit dem internen USART Timer-Konflikt. Sehen Sie den Code für die Details der Implementierung des USART-Timer, wenn diese Art von blutigen Details interessiert.
              root @ ATMEGA328P> Timer startStarted timer.root@ATmega328p> Timer stopElapsed Zeit: ~ 157 Sekunden 

            Beglaubigung
            Die Schale kann ein 8-stelliges Passwort in EEPROM speichern. Dieser Passwort-Mechanismus wurde geschaffen, um die Telnet-Login-Fähigkeiten zu unterstützen, aber könnte erweitert werden, um andere Dinge zu schützen. Zum Beispiel können Sie bestimmte Befehle, wie das Ändern von Registerwerten, durch den Authentifizierungsmechanismus erfordern könnte.
            Stellen Sie das Passwort mit dem Passwort-Befehl:
              root @ ATMEGA328P> passwd blahWrote Root-Passwort, um EEPROM 
            Autorisieren gegen Er Passwort (oder genehmigungspflichtig programatically durch den Code) mit dem Befehl Auth. Beachten Sie, dass, wenn Sie versuchen, das root-Passwort zu ändern und es ist bereits ein Root-Passwort gesetzt, müssen Sie sich gegen das alte Passwort, bevor ihm gestattet, um es zu einem neuen Kennwort ändern genehmigen.
              root @ ATMEGA328P> passwd blinkyYou müssen Sie sich first.root@ATmega328p> auth blahAuthorized.root@ATmega328p> passwd blinkyWrote NEW Root-Passwort in das EEPROM, eine Autorisierung 
            Natürlich, werden Sie brauchen, um die Datei zu laden avrsh.eep, wenn Sie die Firmware auf Ihren alten Werte und Variablen wieder zu löschen. Das Makefile wird die EEPROM-Datei für Sie zu erstellen.

            Variablen
            Die Shell versteht den Begriff der benutzerdefinierten Variablen. Der Code schränkt diese auf 20, aber Sie können das ändern, wenn Sie mögen, indem Sie die definieren MAX_VARIABLES in script.h. Sie können eine beliebige 16-Bit-Wert (65.536 das heißt, eine beliebige Anzahl up) zu einer Variablen speichern und später wieder abgerufen werden. Die Syntax ist ähnlich zu Registern außer einem Dollarzeichen ($) wird verwendet, um Variablen, um die Schale zu bezeichnen. Listen Sie alle Variablen mit dem Befehl Druckvariablen.
              drucken variablesUser definierten Variablen: Index Name -> Wert (01): $ FREE $ -> 0 (02): $ FREE $ -> 0 (03): $ FREE $ -> 0 (04): $ FREE $ -> 0 (05): $ FREE $ -> 0 (06): $ FREE $ -> 0 (07): $ FREE $ -> 0 (08): $ FREE $ -> 0 (09): $ FREE $ -> 0 (10): $ FREE $ -> 0 (11): $ FREE $ -> 0 (12): $ FREE $ -> 0 (13): $ FREE $ -> 0 (14): $ FREE $ -> 0 (15): $ FREE $ -> 0 (16): $ FREE $ -> 0 (17): $ FREE $ -> 0 (18): $ FREE $ -> 0 (19): $ FREE $ -> 0 (20): $ FREE $ -> 0Complete. 
            Stellen Sie eine Variable:
              $ Newvar = 25 $ timeout = 23245 
            Holen Sie sich den Wert einer bestimmten Variablen:
              root @ ATMEGA328P> echo $ newvar $ newvar -> 25 
            Sie können sehen, was alle Variablen, die Sie haben derzeit mit dem Druckbefehl, die Sie bereits wissen, instanziiert.
              Benutzerdefinierte Variablen: Index Name -> Wert (01): newvar -> 25 (02): Timeout -> 23245 (03): $ FREE $ -> 0 (04): $ FREE $ -> 0 (05): $ FREE $ -> 0 (06): $ FREE $ -> 0 (07): $ FREE $ -> 0 (08): $ FREE $ -> 0 (09): $ FREE $ -> 0 (10): $ FREE $ -> 0 (11): $ FREE $ -> 0 (12): $ FREE $ -> 0 (13): $ FREE $ -> 0 (14): $ FREE $ -> 0 (15): $ FREE $ -> 0 (16): $ FREE $ -> 0 (17): $ FREE $ -> 0 (18): $ FREE $ -> 0 (19): $ FREE $ -> 0 (20): $ FREE $ -> 0Complete. 
            Die $ FREE $ name gibt an, dass nur, dass variable Lage ist kostenlos und hat noch keine Variablennamen erhalten.

            Schritt 5: Anpassen der Shell

            AVRSH: Ein Command Interpreter Shell für Arduino / AVR.
            Sie sind frei, den Code zu hacken und passen Sie es an Ihre eigenen Bedürfnisse, wenn Sie möchten. Wenn ich gewusst hätte, würde ich diesen Code Loslassen, hätte ich eine separate Befehlsinterpreter Klasse und Befehlsstruktur gemacht und einfach wiederholt durch diese Aufruf einer Funktion Zeiger. Es würde den Umfang des Codes zu reduzieren, aber, wie es steht die Schale analysiert die Befehlszeile und ruft die entsprechende Shell-Methode.

            Um in Ihre eigenen Befehle hinzufügen, machen Sie folgendes:

            1. Ihr Kommando In den Parse-Liste
            Der Befehl-Parser wird die Kommandozeile zu analysieren und geben Sie den Befehl und Argumente getrennt. Die Argumente werden als Zeiger auf Zeiger oder ein Array von Zeigern übergeben, aber Sie, mit ihnen zu arbeiten. Dies ist in shell.cpp gefunden. Öffnen Sie shell.cpp und finden Sie das ExecCmd Verfahren der AVRShell Klasse.

            Vielleicht möchten Sie den Befehl zum Programmspeicher hinzuzufügen. Wenn Sie dies tun, fügen Sie den Befehl in progmem.h und progmem.cpp. Sie können den Befehl zum Programmspeicher direkt mit dem PSTR () Makro hinzufügen, aber Sie werden eine weitere Warnung der älteren genannten Art zu erzeugen. Auch dies ist ein bekannter Bug der Arbeit mit C ++, aber Sie können dies umgehen, indem Sie den Befehl direkt in der progmem. * Dateien, wie ich getan habe. Wenn Sie nichts dagegen haben, mit denen Sie Ihre Nutzung SRAM, können Sie den Befehl hinzufügen, wie ich mit der "Uhr" Befehl veranschaulicht.

            Angenommen, Sie möchten einen neuen Befehl namens fügen wollte "NewCmd." Zum AVRShell :: ExecCmd und finden Sie einen bequemen Platz, um den folgenden Code ein:
              else if cmdNewCmd (args) (strcmp (c, "NewCmd!")); 
            Dies wird Ihren Befehl hinzufügen und rufen Sie die cmdNewCmd Verfahren, die Sie im nächsten Schritt zu schreiben.

            2. Schreiben Sie eine benutzerdefinierte Befehlscode
            In der gleichen Datei, fügen Sie Ihre kundenspezifische Befehlscode. Dies ist der Methodendefinition. Sie werden immer noch wollen, um die Erklärung zu shell.h hinzuzufügen. Nur hängen Sie ihn an die anderen Befehle. Im vorherigen Beispiel könnte der Code wie folgt aussehen:
              voidAVRShell :: cmdNewCmd (char ** args) {sprintf_P (Buff, PSTR ("Dein Befehl% s \ r \ n", args [0]); WriteRAM (Buff);} 
            Es gibt hier mehrere Dinge. Erstens, "buff" ist eine 40-Zeichen-Array-Puffer in den Code für Ihren Gebrauch zur Verfügung gestellt. Wir verwenden die Programmspeicher-Version von sprintf da wir Übergabe eine PSTR. Sie können die normale Version zu verwenden, wenn du willst, aber stellen Sie sicher, das Format in einem PSTR nicht bestehen. Auch sind die Argumente in der args-Array. Wenn Sie "NewCmd arg1 arg2" getippt können Sie auf diese Argumente mit args [0] und args [1] Indizes zu erhalten. Sie können maximal MAX_ARGS Argumente übergeben, wie im Code definiert. Fühlen Sie sich frei, um diesen Wert zu ändern, wenn Sie neu zu kompilieren, wenn Sie viele weitere Argumente, um auf einmal übergeben werden.

            Die Writeline und WriteRAM sind globale Funktionen, die Methoden mit dem gleichen Namen des UART zurückzukehren. Das 2. Argument an diese Funktion ist implizit. Wenn Sie nichts übergeben, wird eine Eingabeaufforderung darauf geschrieben werden. Wenn yo passieren eine 0 als 2. Argument, wird eine Eingabeaufforderung nicht geschrieben werden. Dies ist nützlich, wenn Sie mehrere getrennte Zeichenfolgen Ausgabe zu schreiben, bevor die Eingabeaufforderung an den Benutzer zurückgegeben werden soll.

            3. Lassen Sie die Shell den Befehl Code
            Sie haben bereits die Schale Testamentsvollstrecker gesagt, um das Verfahren durchzuführen, wenn Sie Setup cmdNewCmd der neue Befehl, aber es auf den shell.h Datei hinzufügen, die von der Shell-Objekt verstanden haben. Fügen Sie einfach es unter der letzten Befehl oder vor dem ersten Befehl, oder irgendwo in dort.

            Und das ist es. Neu übersetzen und laden Sie die Firmware auf das Arduino und Ihre neue Befehl ist verfügbar, von der Schale an der Eingabeaufforderung.
            Schritt 6: Zusammenfassung

            Sie sollten wissen, wie die Installation und eine Verbindung zu Ihrem AVR / Arduino und eine Live-Eingabeaufforderung auf Ihrem laufenden Mikrocontroller. Sie wissen, mehrere Befehle, die Laufzeitdaten von der MCU oder eingestellten Werte in die MCU im Fluge ziehen wird. Sie haben auch gezeigt, wie Sie Ihre eigenen benutzerdefinierten Code hinzufügen, um Ihre eigene einzigartige Befehle an die Shell zu schaffen, um weiter anpassen, sie für Ihre eigenen Bedürfnisse. Sie können sogar Darm den Befehlsinterpreter, um es Ihre benutzerdefinierte Befehle enthalten nur, wenn das Ihren Bedürfnissen entspricht.
            Ich hoffe, dass Sie diese instructable genossen haben und dass der AVR Shell kann nützlich sein, entweder als Echtzeit-Befehlsinterpreter oder als Lernprozess bei der Umsetzung Ihrer eigenen.
            Wie immer, ich freue mich auf Kommentare oder Vorschläge, wie diese instructable verbessert werden!
            Viel Spaß mit Ihrem AVR!