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
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?
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
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?
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.
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.
> 2. 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.
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.
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.
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...
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.
Ungetestet mangels griffbereiter Hardware; alle Angaben ohne Gewähr ;)
Edit: Entschuldigen Sie bitte die Störung, aber evt. hilft es in einem
anderen Fall :(
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.
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
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.
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.