Arduino Uno R3: Bootloader beenden, Programm starten

#7921406
Lesenswert?

Hallo,

ich habe an einem Linux-System einen Arduino Uno R3 an /dev/ttyUSB0 hängen. Es freut mich sehr, dass ich ihn - auch dank Hilfe von hier - ohne die Arduino-IDE betreiben kann. Zum Aufspielen von Code verwende ich in einem shell script den Befehl "avrdude -F -V -c arduino -p m328p -P /dev/ttyUSB0 -U flash:w:$1.hex". Avrdude resettet den Uno, wodurch der Bootloader startet, der Code runtergeladen, gebrannt und gestartet wird.

Ich ein Programm geschrieben und auf den Uno gebrannt, das nach dem Empfang des Strings "xyz" die LED auf der Platine einschaltet. Ich sende den String mit folgendem Programm vom Linux-System an den Uno:

1
...
2
void fehler (char *s);
3
...
4
if ((fp = fopen ("/dev/ttyUSB0", "w")) == NULL)
5
  fehler ("Die Datei läßt sich nicht anlegen!");
6
fprintf (fp, "%s","xyz\n");
7
fclose (fp);
8
...

Beim Öffnen von ttyUSB0 wird ein Reset generiert, der den Bootloader startet. Ich sende meinen String also an den Bootloader, nicht an mein zuvor in den Uno gebranntes Programm.

Frage:

Gibt es eine Zeichensequenz, die ich via ttyUSB0 an den Bootloader senden kann, die den Bootloader beendet und das bereits zuvor in den Uno gebrannte Programm startet, so dass ich mein "xyz" an mein Programm senden kann?

(Firma: Gast) #7921412
Lesenswert?

Michael schrieb:

Gibt es eine Zeichensequenz, die ich via ttyUSB0 an den Bootloader senden kann, die den Bootloader beendet und das bereits zuvor in den Uno gebrannte Programm startet, so dass ich mein "xyz" an mein Programm senden kann?

Es bieten sich 2 Möglichkeiten an, den Reset zu unterbinden.

  1. auf dem Uno sollte sich eine Lötbrücke befinden welche sich "Reset Enable" o.ä. nennt. Auftrennen.
  2. einen 10µF Kondensator zwischen Reset und GND des Uno platzieren.

Unter Win kann man mit Mode den DTR Reset unterbinden. Ist abhängig vom Anwendungsprogramm und USB-UART Chip ob das klappt.

Auch Linux sollte das Gezappel an DTR unterbinden können, habe aber KA wie

: Bearbeitet durch User
#7921430
Lesenswert?

Michael schrieb:

Gibt es eine Zeichensequenz, die ich via ttyUSB0 an den Bootloader senden kann, die den Bootloader beendet und das bereits zuvor in den Uno gebrannte Programm startet

Ich kenne das meist so dass sich der Bootloader automatisch beendet: Nach dem Powerup wird als erstes der Bootloader angesprungen. Der Bootloader checkt das Applikationsprogramm ob das Konsistent (z.B. CRC) und valide (z.B. richtiges Programm) ist. Ist das nicht der Fall bleibt der Bootloader so lange aktiv bis über ihn ein gültiges Applikationsprogramm geladen wurde. Ist das Applikationsprogramm gültig, so wartet der Bootloader eine Zeit x bis er ins Hauptprogramm springt. Wenn man sich die Zeit sparen möchte oder sehr kurz machen will gibt es da auch Abwandlungen dass Taste x oder auf ein Zeichen in einer Kommunikationsschnittstelle geprüft wird das dann den Sprung ins Applikationsprogramm verhindert.

In deinem Fall oben, würde dann automatisch nach dem Bootloader das Hauptprogramm angesprungen werden. Ohne weiteres zutun.

Michael schrieb:

Beim Öffnen von ttyUSB0 wird ein Reset generiert

Wobei ich das als erstes versuchen würde abzustellen. Finde ich unschön. Nur weil die Kommunikation geöffnet wird springt die Kiste in den Reset?

(Firma: Gast) #7921458
Lesenswert?

N. M. schrieb:

Nur weil die Kommunikation geöffnet wird springt die Kiste in den Reset?

Das Gezappel an "Data Terminal Ready" ist ganz offensichtlich das Standard Verhalten. Unabhängig davon, was man selber darüber denken mag. DTR löst am UNO den Reset aus.

Das Problem ist in der Arduino Welt gut bekannt. Oben habe ich 2 praktikable und zuverlässige Verfahren genannt.

#7921653
Lesenswert?

Michael schrieb:

Beim Öffnen von ttyUSB0 wird ein Reset generiert, der den Bootloader startet. Ich sende meinen String also an den Bootloader, nicht an mein zuvor in den Uno gebranntes Programm.

Es ist keine Option, eine Pause zu machen oder erst zu senden, nachdem sich der Uno gemeldet hat?

Arduino F. schrieb:

  1. auf dem Uno sollte sich eine Lötbrücke befinden welche sich "Reset Enable" o.ä. nennt. Auftrennen.

Könnte beim Original so sein, bei den Chinesen scheinbar nicht.

  1. einen 10µF Kondensator zwischen Reset und GND des Uno platzieren.

Wenn man schon löten will: 3. Den 100n-Kondensator zwischen DTR des 16U2 / CH340 und Reset des AT328 auslöten.

Unter Win kann man mit Mode den DTR Reset unterbinden. Ist abhängig vom Anwendungsprogramm und USB-UART Chip ob das klappt.

Hahaha .. dazu gibt/gab es gerade einen Thread, dessen Ersteller das nicht gelingt.

(Firma: Gast) #7921662
Lesenswert?

Manfred P. schrieb:

Wenn man schon löten will:

Nein, nöö. Beim Uno kann man den auch stecken. Ganz ohne löten.

Hahaha .. dazu gibt/gab es gerade einen Thread, dessen Ersteller das nicht gelingt.

Da sagt im aber nicht was ihm mit mode gemacht hat. Riesig viel Getue um hub4com und com0com. Hat nur nix mit dem eigentlichen Problem zu tun. Nebelkerzen.

#7921821
Lesenswert?

Michael schrieb:

Beim Öffnen von ttyUSB0 wird ein Reset generiert, der den Bootloader startet.

Warum schickst du einen Reset, wenn du das nicht möchtest. Der Reset beim Uno wird durch DTR ausgelöst und wenn diese Leitung beim Öffnen von ttyUSB durch dein fopen() gesetzt wird, bekommt der Uno eben genau den Reset. Avrdude nutzt genau diese Funktion, damit der Code geflasht werden kann. Wenn du die Reset-Leitungen hardwaremäßig unterbrichst, musst du zum Flashen den Reset manuell auslösen.

Arduino F. schrieb:

Das Problem ist in der Arduino Welt gut bekannt.

Das ist nicht ein Problem der "Arduino Welt", sondern eine Frage des Schnittstellen-Handligs auf der PC-Seite. Bei Terminalprogrammen wie z.B. HTerm kann man doch auch einstellen, ob beim Öffnen der Schnittstelle das DTR-Signal gesetzt werden soll oder eben nicht.

: Bearbeitet durch User
#7921865
Lesenswert?

Hallo,

dass das Öffnen von ttyUSB0 einen Reset auslöst, stört mich nicht, im Gegenteil, ich bin ja darauf angewiesen, dass der uC in einem definierten Zustand ist, wenn ich mit ihm kommuniziere.

(Falls es mich stören würde, könnte ich es möglicherweise in einem Terminal-Fenster mit

1
 stty -F /dev/ttyUSB0 -hup

oder in einem C-Programm mit

1
 system ("stty -F /dev/ttyUSB0 -hup");

unterbinden, ich habe das allerdings nicht getestet.)

Ich könnte auch durch Setzen der Fuses, hier des Bootloader Jump Bits, das Ausführen des Bootloaders abschalten, was ich aber ebenfalls nicht möchte.

Mein Problem ist nicht der Reset, sondern der Bootloader. Ich bin noch nicht dazu gekommen, zu untersuchen, ob der nach einer gewissen Zeit das im uC geflashte Programm startet. Wenn das nicht eine Ewigkeit dauern sollte, wäre das durchaus eine Möglichkeit für mich. Am elegantesten wäre natürlich, wenn ich dem Bootloader eine bestimmte Zeichenfolge senden könnte, auf die hin er das bereits zuvor geflashte Programm startet...

: Bearbeitet durch User
#7921867
Lesenswert?

Die Linux-Treiber kennen 2 verdächtige Flags: wenn CLOCAL gesetzt ist und HUPCL nicht, könnte es funktionieren; man termios sagt

1
  HUPCL  Lower modem control lines after last process closes
2
         the device (hang up).
3

4
  CLOCAL Ignore modem control lines.

Alle Flags werden mit einem ioctl() gesetzt, siehe ioctl_tty(2). Im Gegensatz zu vielen Beispielen im Netz mache ich kein TCGETS, sondern setze alle Flags wie ich sie brauche. Nebenbei wird so der "raw mode" benutzt. Damit werden alle Zeichen 1:1 gesendet und empfangen.

1
{
2
  struct termios  comm_params;
3

4
  comm_params.c_iflag = IGNBRK | IGNPAR | strip;
5
  comm_params.c_oflag = 0;
6
  comm_params.c_cflag = CREAD | CLOCAL | bits | parity | stopbits | baud;
7
  comm_params.c_lflag = 0;
8
  comm_params.c_line = 0;
9
  comm_params.c_cc[VMIN] = 1;
10
  comm_params.c_cc[VTIME] = 0;
11
  if (ioctl (port, TCSETS, &comm_params)) {
12
    error (0, errno, "sci_open: ioctl TCSETS '%s'", dev);
13
    return -1;
14
  }
15
  return port;
16
}

Ungetestet mangels griffbereiter Hardware; alle Angaben ohne Gewähr ;)

Edit: Entschuldigen Sie bitte die Störung, aber evt. hilft es in einem anderen Fall :(

: Bearbeitet durch User
#7921871
Lesenswert?

Michael schrieb:

Mein Problem ist nicht der Reset, sondern der Bootloader. Ich bin noch nicht dazu gekommen, zu untersuchen, ob der nach einer gewissen Zeit das im uC geflashte Programm startet. Wenn das nicht eine Ewigkeit dauern sollte, wäre das durchaus eine Möglichkeit für mich.

Da ich gerade mit dem Arduino Uno (nicht mit der Arduino IDE) zu tun habe kann ich dir sagen dass einer der bei der IDE mit- gelieferten Bootloader (optiboot_atmega328.hex) das von dir erwartete Verhalten erfüllt. Ich flashe die Anwendung über die USB-Schnittstelle und benutze dann die gleiche Schnittstelle zum Steuern der Anwendung mittels Terminal-Software. Dabei ergibt sich nach dem Starten des Terminals und Öffnen der Schnittstelle eine kurze Verzögerung (das Bootloader-Delay) bis die Kommunikation mit dem Terminal startet.

(Firma: Gast) #7921881
Lesenswert?

Michael schrieb:

dass das Öffnen von ttyUSB0 einen Reset auslöst, stört mich nicht, im Gegenteil, ich bin ja darauf angewiesen, dass der uC in einem definierten Zustand ist, wenn ich mit ihm kommuniziere.

Wenn dein µC in undefinierte Zustände fällt, hast du ganz andere Probleme, als die mit dem Bootloader.

Ich bin noch nicht dazu gekommen, zu untersuchen, ob der nach einer gewissen Zeit das im uC geflashte Programm startet.

Natürlich tut er das!

Am elegantesten wäre natürlich, wenn ich dem Bootloader eine bestimmte Zeichenfolge senden könnte, auf die hin er das bereits zuvor geflashte Programm startet...

Wenn es sowas gibt findest du das im STK500 Protokoll. Der UNO Bootloader verwendet eine reduzierte Variante davon.

Wastl schrieb:

kann ich dir sagen dass einer der bei der IDE mit- gelieferten Bootloader (optiboot_atmega328.hex) das von dir erwartete Verhalten erfüllt.

Genau der wird auf dem UNO verwendet, und hat von allen Arduino Bootloadern die kürzeste Wartezeit.

Siehe:

uno.bootloader.file=optiboot/optiboot_atmega328.hex

Aus der aktuellen platform.txt

: Bearbeitet durch User
Beitrag #7921897 wurde vom Autor gelöscht.
#7921902
Lesenswert?

Michael schrieb:

Ich bin noch nicht dazu gekommen, zu untersuchen, ob der nach einer gewissen Zeit das im uC geflashte Programm startet.

Tut er

Am elegantesten wäre natürlich, wenn ich dem Bootloader eine bestimmte Zeichenfolge senden könnte, auf die hin er das bereits zuvor geflashte Programm startet...

Dann ändere ihn doch entsprechend.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren