Ustawianie baudrate dla pl2303 z Openwrt (Linux 2.4)
1. Powód
Problem zaistniał dla mnie przy próbie odczytu danych bezpośrednio z odbiornika GPS (NMEA strings). Mógłbym wykorzystać gpsd który by zapewne zadziałał, lecz po co mi marnować zasoby kiedy mogę wykorzystać wbudowane w busybox awk.
2. Problem
Mój adapter GPS (chipset SKYTRAQ Venus 6), pracuje jedynie na określonym baudrate (według producenta 4800/9600/19200/38400, dla mnie działał tylko z 38400). Także by odczytać dane z niego muszę ustawić to na porcie.
Zazwyczaj można to osiągnąć przy pomocy setserial.
setserial /dev/tts/0 baud_base 38400
Lecz, gdy próbuje przeprowadzić tą operacje otrzymuje błąd
setserial /dev/usb/tts/0 baud_base 38400 Cannot get serial info: Invalid argument
Szukając w sieci odpowiedzi natrafiam na osoby z podobnym problemem, lecz bez pomysłów na rozwiązanie. Problem wynika podobno już z samej natury sterownika, lecz tutaj już bardziej zainteresowany by działało niż rozwiązaniem zagadki napisałem prosty patch zamieszczony poniżej.
3. Rozwiązanie
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -59,6 +59,8 @@
static int debug;
#endif
+static int cbaud = 0;
+
#include "usb-serial.h"
#include "pl2303.h"
@@ -572,7 +574,7 @@
dbg("%s - data bits = %d", __FUNCTION__, buf[6]);
}
- baud = tty_get_baud_rate(port->tty);
+ baud = (cbaud)?cbaud:tty_get_baud_rate(port->tty);
dbg("%s - baud = %d", __FUNCTION__, baud);
if (baud) {
buf[0] = baud & 0xff;
@@ -1254,3 +1256,6 @@
MODULE_PARM(debug, "i");
MODULE_PARM_DESC(debug, "Debug enabled or not");
+MODULE_PARM(cbaud, "i");
+MODULE_PARM_DESC(cbaud, "Set baud rate");
+
Po odpowiednim zaaplikowaniu patcha (dla openwrt będzie to przykładowo umieszczenie go w katalogu target/linux/brcm-2.4/patches/ , i zmiana nazwy na jakaś poprzedzoną dużą liczbą np. target/linux/brcm-2.4/patches/120-pl2303_baudhack.patch, robimy jeszcze make clean && make i gotowe ), już na systemie docelowym przeprowadzamy następujące operacje:
rmmod pl2303 #upewniamy sie ze nie ma już załadowanego modułu insmod pl2303.o cbaud=38400 # gdzie cbaud to baudrate który chcemy mieć, jeśli nie ustawiony będzie zachowywał się jak driver bez patcha
4. Uwagi
Problem występuje na jądrze 2.4 – podczas prób z 2.6 go nie zaobserwowałem. Moje zmiany nie są objęte żadna gwarancją i używa się ich na własną odpowiedzialność. Testowano na jądrze Linux OpenWrt 2.4.37.5 #3 Thu Sep 24 02:10:59 CEST 2009 mips unknown.
Oryginalny plik pl2303.c
EDIT[09.12.2009]
Alternatywna metoda, która „nie psuje” pl2303 to
stty -F /dev/ttyUSB0 raw speed 38400 -clocal cs8 -parenb -cstopb
zdaje się być właściwą. Zazwyczaj też sam program korzystający z tty powinien go ustawić odpowiednio. W prekompilowanym OpenWrt dostępnym na oficjalnej stronie busybox nie zawiera stty, także i ta metoda zmusza nas niestety do kompilacji ze źródeł pakietu.