Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2011-08

serial under linux, SerOpen blocks

19 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Armin Diehl

I need some hint regarding opening a serial (ttyUSB) port using the unit serial. Minicom works fine under my user id. When i call SerOpen('/dev/ttyUSB0'), fpopen blocks forever. When i first start minicom on that port, SerOpen and all other functions of serial.pp works fine.

ttyUSB0 is:
crw-rw---- 1 root dialout 188, 0 Aug 18 09:37 /dev/ttyUSB0

changing it to
crw-rw-rw- 1 root dialout 188, 0 Aug 18 09:38 ttyUSB0

makes no difference. (my user id has the supplemental group "dialout" added) SerOpen will always block if minicom is not started on the same port, the same applies if i try it wit root.

stty with minicom started:
speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^A; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 5;
-parenb -parodd cs8 hupcl -cstopb cread clocal crtscts ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke

stty without mnicom started:
speed 19200 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^A; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke

diff
time = 0; -clocal -crtscts -ixon -ixof

Fedora 14, 64 Bit
2.6.35.13-92.fc14.x86_64 #1 SMP Sat May 21 17:26:25 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux

Thx
Armin

Reply by email

Mark Morgan Lloyd
to Armin Diehl
Armin Diehl wrote 50 lines
I need some hint regarding opening a serial (ttyUSB) port using the unit serial. Minicom works fine under my user id. When i call SerOpen('/dev/ttyUSB0'), fpopen blocks forever. When i first start minicom on that port, SerOpen and all other functions of serial.pp works fine. ttyUSB0 is: crw-rw---- 1 root dialout 188, 0 Aug 18 09:37 /dev/ttyUSB0 changing it to crw-rw-rw- 1 root dialout 188, 0 Aug 18 09:38 ttyUSB0 makes no difference. (my user id has the supplemental group "dialout" added) SerOpen will always block if minicom is not started on the same port, the same applies if i try it wit root. stty with minicom started: speed 19200 baud; rows 0; columns 0; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^A; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 5; -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon ixoff -iuclc -ixany -imaxbel -iutf8 -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke stty without mnicom started: speed 19200 baud; rows 0; columns 0; line = 0; intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^A; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0; -parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8 -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke diff time = 0; -clocal -crtscts -ixon -ixof Fedora 14, 64 Bit 2.6.35.13-92.fc14.x86_64 #1 SMP Sat May 21 17:26:25 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux

Assuming that you mean the standard serial.pp, that's not something I've seen here /but/ I'm using a 32-bit kernel. I think that the first thing I'd explore is whether you need the incoming control lines (cts, dsr, cd) to be asserted before the function completes, but quite frankly if I'm reading your

When i first start minicom on that port, SerOpen and all other functions of serial.pp works fine.

correctly then it sounds like a kernel or driver issue.

Anybody: I've modified serial.pp to support Win-32 and fix a couple of issues. Bug http://62.166.198.202/view.php?id=18946

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

peter green
to Armin Diehl: I need some hint regarding opening a serial (ttyUSB) port using the unit serial. Minicom…
Armin Diehl wrote 5 lines
I need some hint regarding opening a serial (ttyUSB) port using the unit serial. Minicom works fine under my user id. When i call SerOpen('/dev/ttyUSB0'), fpopen blocks forever. When i first start minicom on that port, SerOpen and all other functions of serial.pp works fine.

I don't use serial.pp but here is how I open a serial port for basic communication (no flow control, modem control or stuff like that) under linux. I remember this taking some experimentation to get right.

procedure tlserial.open;
var
  fd : longint;
  config : termios;
  baudrateos : longint;
begin
  fd := fpopen(device,O_RDWR or O_NOCTTY);
  if isatty(fd)=0 then begin
    writeln('not a tty');
    halt(1);
  end;
  fillchar(config,sizeof(config),#0);
  config.c_cflag := CLOCAL or CREAD;
  cfmakeraw(config);
  case baudrate of
    50:     baudrateos := B50;
    75:     baudrateos := B75;
    110:    baudrateos := B110;
    134:    baudrateos := B134;
    150:    baudrateos := B150;
    200:    baudrateos := B200;
    300:    baudrateos := B300;
    600:    baudrateos := B600;
    1200:   baudrateos := B1200;
    1800:   baudrateos := B1800;
    2400:   baudrateos := B2400;
    4800:   baudrateos := B4800;
    9600:   baudrateos := B9600;
    19200:  baudrateos := B19200;
    38400:  baudrateos := B38400;
    57600:  baudrateos := B57600;
    115200: baudrateos := B115200;
    230400: baudrateos := B230400;
    else raise exception.create('unrecognised baudrate');
  end;
  cfsetispeed(config,baudrateos);
  cfsetospeed(config,baudrateos);
  config.c_cc[VMIN]  := 1;
  config.c_cc[VTIME] := 0;
  if   tcsetattr(fd,TCSAFLUSH,config) <0 then begin
    writeln('could not set termios attributes');
    halt(3);
  end;
  dup(fd);
  closehandles := true;
end;

Reply by email

Armin Diehl
to peter green

Hi Peter,

that is the same as in the standard serial.pp:

Result := fpopen(DeviceName, O_RDWR or O_NOCTTY);

and this fpopen will block as long as minicom is not started on that device.

peter green wrote 61 lines
Armin Diehl wrote: > I need some hint regarding opening a serial (ttyUSB) port using the > unit serial. Minicom works fine under my user id. When i call > SerOpen('/dev/ttyUSB0'), fpopen blocks forever. When i first start > minicom on that port, SerOpen and all other functions of serial.pp > works fine. I don't use serial.pp but here is how I open a serial port for basic communication (no flow control, modem control or stuff like that) under linux. I remember this taking some experimentation to get right. procedure tlserial.open; var fd : longint; config : termios; baudrateos : longint; begin fd := fpopen(device,O_RDWR or O_NOCTTY); if isatty(fd)=0 then begin writeln('not a tty'); halt(1); end; fillchar(config,sizeof(config),#0); config.c_cflag := CLOCAL or CREAD; cfmakeraw(config); case baudrate of 50: baudrateos := B50; 75: baudrateos := B75; 110: baudrateos := B110; 134: baudrateos := B134; 150: baudrateos := B150; 200: baudrateos := B200; 300: baudrateos := B300; 600: baudrateos := B600; 1200: baudrateos := B1200; 1800: baudrateos := B1800; 2400: baudrateos := B2400; 4800: baudrateos := B4800; 9600: baudrateos := B9600; 19200: baudrateos := B19200; 38400: baudrateos := B38400; 57600: baudrateos := B57600; 115200: baudrateos := B115200; 230400: baudrateos := B230400; else raise exception.create('unrecognised baudrate'); end; cfsetispeed(config,baudrateos); cfsetospeed(config,baudrateos); config.c_cc[VMIN] := 1; config.c_cc[VTIME] := 0; if tcsetattr(fd,TCSAFLUSH,config) <0 then begin writeln('could not set termios attributes'); halt(3); end; dup(fd); closehandles := true; end; _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Marco van de Voort
to Armin Diehl

In our previous episode, Armin Diehl said:

Show quoted text 6 lines
that is the same as in the standard serial.pp: Result := fpopen(DeviceName, O_RDWR or O_NOCTTY); and this fpopen will block as long as minicom is not started on that device.

Yes. And seems that minicom turns of xon/xoff. You could try to verify that by disabling it with stty.

Reply by email

Henry Vermaak
to Armin Diehl: that is the same as in the standard serial.pp: Result := fpopen(DeviceName, O_RDWR or…
Armin Diehl wrote 8 lines
Hi Peter, that is the same as in the standard serial.pp: Result := fpopen(DeviceName, O_RDWR or O_NOCTTY); and this fpopen will block as long as minicom is not started on that device.

Try to add O_NONBLOCK to the flags with fpopen. Then set CLOCAL like Peter suggested. Then disable O_NONBLOCK again with fcntl if you want blocking I/O back.

Henry

Reply by email

Armin Diehl
to Mark Morgan Lloyd: Assuming that you mean the standard serial.pp, that's not something I've seen here /but/…

Just tried it on a 32 bit system (Linux t41.armin.d 2.6.35.13-92.fc14.i686 #1 SMP Sat May 21 17:39:42 UTC 2011 i686 i686 i386 GNU/Linux) as root

uses baseunix;
var handle : longint;
begin
   writeln('Start: fpopen');
   handle := fpopen('/dev/ttyUSB0',O_RDWR or O_NOCTTY);
   writeln ('Result: ',Handle);
   if handle  0 then fpclose(handle);
end.

and exactly the same problem. fpopen blocks if minicom is not started on the same port. I think i have to figure out how minicom (or stty) opens the port.

btw, ttyUSB0 is a Prolific pl2303:

Aug 18 11:47:18 t41 kernel: [ 599.994081] usb 3-2: new full speed USB device using uhci_hcd and address 2
Aug 18 11:47:18 t41 kernel: [ 600.140165] usb 3-2: New USB device found, idVendor=067b, idProduct=2303
Aug 18 11:47:18 t41 kernel: [ 600.140180] usb 3-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Aug 18 11:47:18 t41 kernel: [ 600.140191] usb 3-2: Product: USB-Serial Controller
Aug 18 11:47:18 t41 kernel: [ 600.140200] usb 3-2: Manufacturer: Prolific Technology Inc.
Aug 18 11:47:18 t41 mtp-probe: checking bus 3, device 2: "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2"
Aug 18 11:47:18 t41 mtp-probe: bus: 3, device: 2 was not an MTP device Aug 18 11:47:18 t41 kernel: [ 600.329041] usbcore: registered new interface driver usbserial
Aug 18 11:47:18 t41 kernel: [ 600.329070] USB Serial support registered for generic
Aug 18 11:47:18 t41 kernel: [ 600.329948] usbcore: registered new interface driver usbserial_generic
Aug 18 11:47:18 t41 kernel: [ 600.329953] usbserial: USB Serial Driver core Aug 18 11:47:18 t41 kernel: [ 600.345812] USB Serial support registered for pl2303
Aug 18 11:47:18 t41 kernel: [ 600.346655] pl2303 3-2:1.0: pl2303 converter detected
Aug 18 11:47:18 t41 kernel: [ 600.358507] usb 3-2: pl2303 converter now attached to ttyUSB0
Aug 18 11:47:18 t41 kernel: [ 600.359439] usbcore: registered new interface driver pl2303
Aug 18 11:47:18 t41 kernel: [ 600.359445] pl2303: Prolific PL2303 USB to serial adaptor driver

Mark Morgan Lloyd wrote 66 lines
Armin Diehl wrote: > I need some hint regarding opening a serial (ttyUSB) port using the > unit serial. Minicom works fine under my user id. When i call > SerOpen('/dev/ttyUSB0'), fpopen blocks forever. When i first start > minicom on that port, SerOpen and all other functions of serial.pp > works fine. > > ttyUSB0 is: > crw-rw---- 1 root dialout 188, 0 Aug 18 09:37 /dev/ttyUSB0 > > changing it to > crw-rw-rw- 1 root dialout 188, 0 Aug 18 09:38 ttyUSB0 > > makes no difference. (my user id has the supplemental group "dialout" > added) SerOpen will always block if minicom is not started on the > same port, the same applies if i try it wit root. > > stty with minicom started: > speed 19200 baud; rows 0; columns 0; line = 0; > intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^A; eol = <undef>; > eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; > susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; > time = 5; > -parenb -parodd cs8 hupcl -cstopb cread clocal crtscts > ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl > ixon ixoff -iuclc -ixany -imaxbel -iutf8 > -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 > bs0 vt0 ff0 > -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase > -tostop -echoprt -echoctl -echoke > > stty without mnicom started: > speed 19200 baud; rows 0; columns 0; line = 0; > intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^A; eol = <undef>; > eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; > susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; > time = 0; > -parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts > -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl > -ixon -ixoff -iuclc -ixany -imaxbel -iutf8 > -opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 > bs0 vt0 ff0 > -isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase > -tostop -echoprt -echoctl -echoke > > diff > time = 0; -clocal -crtscts -ixon -ixof > > Fedora 14, 64 Bit > 2.6.35.13-92.fc14.x86_64 #1 SMP Sat May 21 17:26:25 UTC 2011 x86_64 > x86_64 x86_64 GNU/Linux Assuming that you mean the standard serial.pp, that's not something I've seen here /but/ I'm using a 32-bit kernel. I think that the first thing I'd explore is whether you need the incoming control lines (cts, dsr, cd) to be asserted before the function completes, but quite frankly if I'm reading your > When i first start minicom on that port, SerOpen and all other > functions of serial.pp works fine. correctly then it sounds like a kernel or driver issue. Anybody: I've modified serial.pp to support Win-32 and fix a couple of issues. Bug http://62.166.198.202/view.php?id=18946

Reply by email

Armin Diehl
to Henry Vermaak: Try to add O_NONBLOCK to the flags with fpopen. Then set CLOCAL like Peter suggested. …

Yes, found that a few minutes ago (strace is nice), micom does:

open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK) = 3 fcntl(3, F_GETFL) = 0x8802 (flags O_RDWR|O_NONBLOCK|O_LARGEFILE)
fcntl(3, F_SETFL, O_RDWR|O_LARGEFILE) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TIOCMGET, [TIOCM_DTR|TIOCM_RTS]) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TIOCMGET, [TIOCM_DTR|TIOCM_RTS]) = 0
ioctl(3, TIOCMSET, [TIOCM_DTR|TIOCM_RTS]) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_START or SNDRV_TIMER_IOCTL_TREAD or TCSETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(3, TCFLSH, 0x2) = 0

should that be changed in the standard serial.pp ?

Henry Vermaak wrote 18 lines
On 18/08/11 10:34, Armin Diehl wrote: > Hi Peter, > > that is the same as in the standard serial.pp: > > Result := fpopen(DeviceName, O_RDWR or O_NOCTTY); > > and this fpopen will block as long as minicom is not started on that > device. Try to add O_NONBLOCK to the flags with fpopen. Then set CLOCAL like Peter suggested. Then disable O_NONBLOCK again with fcntl if you want blocking I/O back. Henry _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Marco van de Voort
to Armin Diehl

In our previous episode, Armin Diehl said:

should that be changed in the standard serial.pp ?

I'm not sure, since this leaves nonblocking behaviour on by default, moreover serial is pan unix, and non linuxes might react differently.

Btw do you see minicom do a sequence of "opening in nonblock, setting params and reopening without nonblock" ?

Reply by email

Henry Vermaak
to Marco van de Voort
Marco van de Voort wrote 6 lines
In our previous episode, Armin Diehl said: > > should that be changed in the standard serial.pp ? I'm not sure, since this leaves nonblocking behaviour on by default, moreover serial is pan unix, and non linuxes might react differently.

No it doesn't, the fcntl call disables it again.

Henry

Reply by email

Armin Diehl
to Marco van de Voort: In our previous episode, Armin Diehl said: I'm not sure, since this leaves nonblocking…

Hi Marco,

minicom calls open with O_NONBLOCK and resets O_NONBLOCK directly after the open call:

open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK) = 3 fcntl(3, F_GETFL) = 0x8802 (flags O_RDWR|O_NONBLOCK|O_LARGEFILE)
fcntl(3, F_SETFL, O_RDWR|O_LARGEFILE) = 0

doing the same in serial.pp should not change the blocking behaviour of serial.pp.

function SerOpen(const DeviceName: String): TSerialHandle;
begin
   Result := fpopen(DeviceName, O_RDWR or O_NOCTTY or O_NONBLOCK);  //
AD: O_NONBLOCK was missing
   if result > -1 then
     fpfcntl(Result,F_SETFL,O_RDWR or O_NOCTTY);
//AD: non blocking off again
end;
Marco van de Voort wrote 10 lines
In our previous episode, Armin Diehl said: > should that be changed in the standard serial.pp ? I'm not sure, since this leaves nonblocking behaviour on by default, moreover serial is pan unix, and non linuxes might react differently. Btw do you see minicom do a sequence of "opening in nonblock, setting params and reopening without nonblock" ? _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Henry Vermaak
to Armin Diehl
Armin Diehl wrote 18 lines
Hi Marco, minicom calls open with O_NONBLOCK and resets O_NONBLOCK directly after the open call: open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK) = 3 fcntl(3, F_GETFL) = 0x8802 (flags O_RDWR|O_NONBLOCK|O_LARGEFILE) fcntl(3, F_SETFL, O_RDWR|O_LARGEFILE) = 0 doing the same in serial.pp should not change the blocking behaviour of serial.pp. function SerOpen(const DeviceName: String): TSerialHandle; begin Result := fpopen(DeviceName, O_RDWR or O_NOCTTY or O_NONBLOCK); // AD: O_NONBLOCK was missing if result > -1 then fpfcntl(Result,F_SETFL,O_RDWR or O_NOCTTY); //AD: non blocking off again

Better use F_GETFL first, then flags &= ~O_NONBLOCK, like minicom does.

Henry

Reply by email

Armin Diehl
to Henry Vermaak

yes, that is better

function SerOpen(const DeviceName: String): TSerialHandle;
var
   flags : cint;
begin
   Result := fpopen(DeviceName, O_RDWR or O_NOCTTY or O_NONBLOCK);
   if result > -1 then
   begin
     flags := fpfcntl(Result,F_GetFl);
     fpfcntl(Result,F_SETFL,flags and (not O_NONBLOCK));
   end;
end;

results in
open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 10 fcntl(10, F_GETFL) = 0x8802 (flags O_RDWR|O_NONBLOCK|O_LARGEFILE)
fcntl(10, F_SETFL, O_RDWR|O_LARGEFILE) = 0

i think this should be changed in serial.pp

Henry Vermaak wrote 26 lines
On 18/08/11 12:00, Armin Diehl wrote: > Hi Marco, > > minicom calls open with O_NONBLOCK and resets O_NONBLOCK directly after > the open call: > > open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK) = 3 > fcntl(3, F_GETFL) = 0x8802 (flags O_RDWR|O_NONBLOCK|O_LARGEFILE) > fcntl(3, F_SETFL, O_RDWR|O_LARGEFILE) = 0 > > doing the same in serial.pp should not change the blocking behaviour of > serial.pp. > > function SerOpen(const DeviceName: String): TSerialHandle; > begin > Result := fpopen(DeviceName, O_RDWR or O_NOCTTY or O_NONBLOCK); // AD: > O_NONBLOCK was missing > if result > -1 then > fpfcntl(Result,F_SETFL,O_RDWR or O_NOCTTY); //AD: non blocking off again Better use F_GETFL first, then flags &= ~O_NONBLOCK, like minicom does. Henry _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email

Mark Morgan Lloyd
to Armin Diehl
Armin Diehl wrote 22 lines
yes, that is better function SerOpen(const DeviceName: String): TSerialHandle; var flags : cint; begin Result := fpopen(DeviceName, O_RDWR or O_NOCTTY or O_NONBLOCK); if result > -1 then begin flags := fpfcntl(Result,F_GetFl); fpfcntl(Result,F_SETFL,flags and (not O_NONBLOCK)); end; end; results in open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NONBLOCK|O_LARGEFILE) = 10 fcntl(10, F_GETFL) = 0x8802 (flags O_RDWR|O_NONBLOCK|O_LARGEFILE) fcntl(10, F_SETFL, O_RDWR|O_LARGEFILE) = 0 i think this should be changed in serial.pp

But why have I not seen this problem on Debian despite having used this unit extensively? And why have I not seen it when testing the modified unit on Solaris with the SerOpen() function being unchanged?

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Henry Vermaak
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote
But why have I not seen this problem on Debian despite having used this unit extensively? And why have I not seen it when testing the modified unit on Solaris with the SerOpen() function being unchanged?

Some serial ports seem to have clocal unset, for some reason, which causes it to block on open (waiting for the modem status lines). Like you, I've never seen it with any of my serial ports, either.

Henry

Reply by email

Marco van de Voort
to Henry Vermaak

In our previous episode, Henry Vermaak said:

Show quoted text 8 lines
On 18/08/11 14:11, Mark Morgan Lloyd wrote: > But why have I not seen this problem on Debian despite having used this > unit extensively? And why have I not seen it when testing the modified > unit on Solaris with the SerOpen() function being unchanged? Some serial ports seem to have clocal unset, for some reason, which causes it to block on open (waiting for the modem status lines). Like you, I've never seen it with any of my serial ports, either.

Might have to do with the defaulting to autobaud of some usbserial chips.

Reply by email

Ludo Brands
to Marco van de Voort
Show quoted text 7 lines
> Some serial ports seem to have clocal unset, for some reason, which > causes it to block on open (waiting for the modem status lines). Like > you, I've never seen it with any of my serial ports, either. Might have to do with the defaulting to autobaud of some usbserial chips. _______________________________________________

Apparently a bug in a recent usb serial kernel module pl2303:

https://bugs.launchpad.net/ubuntu/+source/linux/+bug/661321

Ludo

Reply by email

Mark Morgan Lloyd
to Ludo Brands
Ludo Brands wrote 11 lines
>> Some serial ports seem to have clocal unset, for some reason, which >> causes it to block on open (waiting for the modem status > lines). Like >> you, I've never seen it with any of my serial ports, either. > Might have to do with the defaulting to autobaud of some > usbserial chips. _______________________________________________ Apparently a bug in a recent usb serial kernel module pl2303: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/661321

Well spotted :-) I was going to speculate that it might be something to do with the Prolific driver- I think that the device I use most is FTDI.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Armin Diehl
to Mark Morgan Lloyd

there must be a reason why minicom uses O_NDELAY (=O_NONBLOCK) in case O_NDELAY ist defined. Now i remember that i had the same problem several years ago with cat file >/dev/ttyUSB0, i think it was Fedora Core 3 or 4. I assume this does not only happen with a pl2303.

#if defined(O_NDELAY) && defined(F_SETFL)

       portfd = open(dial_tty, O_RDWR|O_NDELAY|O_NOCTTY);
       if (portfd >= 0) {
         /* Cancel the O_NDELAY flag. */
         n = fcntl(portfd, F_GETFL, 0);
         fcntl(portfd, F_SETFL, n & ~O_NDELAY);
       }

#else
if (portfd < 0)

         portfd = open(dial_tty, O_RDWR|O_NOCTTY);

#endif

Mark Morgan Lloyd wrote 17 lines
Ludo Brands wrote: >>> Some serial ports seem to have clocal unset, for some reason, which >>> causes it to block on open (waiting for the modem status >> lines). Like >>> you, I've never seen it with any of my serial ports, either. >> Might have to do with the defaulting to autobaud of some usbserial >> chips. _______________________________________________ > > > Apparently a bug in a recent usb serial kernel module pl2303: > > https://bugs.launchpad.net/ubuntu/+source/linux/+bug/661321 Well spotted :-) I was going to speculate that it might be something to do with the Prolific driver- I think that the device I use most is FTDI.

Reply by email