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
voidfehler(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?
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.
auf dem Uno sollte sich eine Lötbrücke befinden welche sich "Reset Enable" o.ä. nennt. Auftrennen.
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
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.
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.
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?
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.
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.
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.
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...
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.
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.
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.
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...
Q wie quit beendet ihn per Watchdog.
Richtiger 0x51 (Q) 0x20 (Satzendezeichen) dann antwortet er noch mit 0x14,0x10 und übergibt sofort ans das Hauptprogramm.