Software-Reset aus dem Arduino Leonardo herauspatchen

19.12.2013 yahe arduino code hardware legacy security

Der Arduino Leonardo, der nun seit etwa einem Jahr auf dem Markt ist, besitzt dank seines ATmega 32u4 direkt die Möglichkeit, eine USB-Verbindung mit dem PC aufzubauen. Auf dem Arduino Uno war dafür ein separater Mikrocontroller zuständig. Durch diese Änderung hat sich jedoch auch die Art, wie Resets über den USB-Anschluss angestoßen werden, geändert. Dieser Reset ist inzwischen eine reine Software-Routine und kann falls nötig herausgepatcht werden.

Der Software-Reset wird ausgeführt, indem vom PC aus eine serielle Verbindung mit 1200 Baud aufgebaut und wieder geschlossen wird. Die auf dem Arduino Leonardo laufende Software interpretiert dies als Wunsch, einen Reset durchzuführen. Dieser Reset kann im Anschluss zum Beispiel genutzt werden, um einen neuen Sketch auf das Gerät zu laden. In Fällen, in denen mit Hilfe der Arduinos jedoch z.B. eine Kleinserie gefertigt wird, kann der Wunsch bestehen, das einfache Aufspielen von neuen Sketches zu unterbinden. Hierfür sollte man bei seinem Arduino-IDE Installationsverzeichnis einmal in die Datei "/hardware/arduino/avr/cores/arduino/CDC.cpp" blicken. In dieser findet sich die Funktion "CDC_Setup()", die folgenden Passus enthält:

if (CDC_SET_LINE_CODING == r || CDC_SET_CONTROL_LINE_STATE == r)
{
  // auto-reset into the bootloader is triggered when the port, already
  // open at 1200 bps, is closed.  this is the signal to start the watchdog
  // with a relatively long period so it can finish housekeeping tasks
  // like servicing endpoints before the sketch ends

  // We check DTR state to determine if host port is open (bit 0 of lineState).
  if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0)
  {
    *(uint16_t *)0x0800 = 0x7777;
    wdt_enable(WDTO_120MS);
  }
  else
  {
    // Most OSs do some intermediate steps when configuring ports and DTR can
    // twiggle more than once before stabilizing.
    // To avoid spurious resets we set the watchdog to 250ms and eventually
    // cancel if DTR goes back high.

    wdt_disable();
    wdt_reset();
    *(uint16_t *)0x0800 = 0x0;
  }
}

Um den Software-Reset zu deaktivieren, muss dieser Code einfach vollständig auskommentiert werden. Anschließend ist ein Reset nur noch durch Betätigung des Reset-Buttons oder durch manuelles Verbinden des RESET-Pins mit einem GND-Pin möglich. Natürlich ist es auch möglich, den Software-Reset später wieder zu aktivieren. Dazu muss der vormals auskommentierte Quelltextblock wieder einkommentiert und einmal ein Sketch durch einen rechtzeitigen manuellen Reset geflasht werden.


Search

Categories

administration (45)
arduino (12)
calcpw (3)
code (38)
hardware (20)
java (2)
legacy (113)
linux (31)
publicity (8)
raspberry (3)
review (2)
security (65)
thoughts (22)
update (11)
windows (17)
wordpress (19)