Re: Perl problem - COM ports and filehandles
Hi Darren, > i am trying to convert a perl script from *nix to win32. > 1) the unix script opens a filehandle to a device like this: > > open my $pipe, '+<', '/dev/ttyUSB0' or die "Couldn't open pipe for reading > and writing"; When I wanted to use the serial port on Win32, I went another route... Grab the plink.exe program (Google for PuTTY if you don't know it) and get the params for that working so as to connect to the right port and baud etc. Then, wrap this using Perl's IPC::Run module which should do all the buffering etc that you want. Seemed to work well enough for me. hope this helps, oliver.
Re: Perl problem - COM ports and filehandles
> > > Message: 1 > Date: Wed, 1 Feb 2012 11:59:17 -0500 > From: Darren Harwood > Subject: Perl problem - COM ports and filehandles > To: "london.pm@london.pm.org" > Message-ID: > > <1ffef92edf70f14d992f400f4c6f70d8b5969b4...@pbi-namsg-03.mgdpbi.global.pvt > > > > Content-Type: text/plain; charset="us-ascii" > > good afternoon all, > > ... > i am trying to convert a perl script from *nix to win32. > i am having difficulty with a couple of things: > > 1) the unix script opens a filehandle to a device like this: > > open my $pipe, '+<', '/dev/ttyUSB0' or die "Couldn't open pipe for reading > and writing"; > my $mb = myDevice::myObject->new($pipe); > > I am not an expert in serial comms, but this looks like Unix systems programming in Perl, which makes it inherently less portable. There are USB abstractions in CPAN (Device::USB). See www.libusb.org. If you can port your code to the abstraction in Unix *first*, maybe it will be less painful to port to Win32. Ash
Re: Perl problem - COM ports and filehandles
* Darren Harwood (darren.harw...@pb.com) [120201 17:08]: > i am trying to convert a perl script from *nix to win32. > i am having difficulty with a couple of things: > > 1) the unix script opens a filehandle to a device like this: > my ($nfound, $timeleft) = select($rin, undef, undef, $timeDelimiter_s); > thoughts on equivalent code? > my $ob = Win32::SerialPort->new ('COM8') || die; The POSIX select() is supported under Windows, however... in its minimal implementation: only network sockets... afaik. See http://msdn.microsoft.com/en-us/library/ms740141%28v=vs.85%29.aspx I expect the same is true for poll() (WSApoll on Windows) And a COM port is not a socket, is it? Even the UNIXes have different levels of support. They all support pipes and devices, some do support file-io to be in there. (warning: I never use Windows so this knowledge is only from (outdated?) man-pages) -- Regards, MarkOv Mark Overmeer MScMARKOV Solutions m...@overmeer.net soluti...@overmeer.net http://Mark.Overmeer.net http://solutions.overmeer.net
Re: Perl problem - COM ports and filehandles
On Wed, Feb 01, 2012 at 11:59:17AM -0500, Darren Harwood wrote: > good afternoon all, > > me=long time lurker, first time poster! It happens that there's a social meeting tonight near Euston station - you could also come and lurk at that: http://london.pm.org/pipermail/london.pm-announce/2012-January/000266.html (or not lurk, and claim a free beer (or beer-equivalent thing) if it's your first time.) > (warning! there is code in the post below - but as a first time poster i have > no idea how well > that is going to format itself for your consumption...we'll seei > apologise now if its a garbled mess. > i did try to find posting advice on the london.pm website, but no joy) Something like: 1) jobs go to the jobs list at j...@london.pm.org 2) Perl is sometimes considered "Off Topic", as a joking reference to how much other chat is on the list. ? Yes, there's not much advice. > i am trying to convert a perl script from *nix to win32. > i am having difficulty with a couple of things: > > 1) the unix script opens a filehandle to a device like this: > > open my $pipe, '+<', '/dev/ttyUSB0' or die "Couldn't open pipe for reading > and writing"; > my $mb = myDevice::myObject->new($pipe); > > this filehandle is then referenced in the module via a mechanism containing: > my $rin = ''; > vec($rin,fileno($pipe),1) = 1; > my ($nfound, $timeleft) = select($rin, undef, undef, $timeDelimiter_s); > last if($nfound == 0); > my $bytes; > sysread($pipe, $bytes, $nfound); The intent of that code looks to be doing non-blocking reads from the serial port. And just the serial port - it's not using select to multiplex between more than one input device. > my (clearly incorrect) approach was to substitute the "open" for a use > Win32::SerialPort; > (because the device is connected via a virtual serial port over usb) > with the following: > > my $PortObj = tie (*FH, 'Win32::SerialPort', $Configuration_File_Name) || die > "Can't tie: $^E\n"; > > which i would expect to allow me to code: > my $mb = myDevice::myObject->new(FH); > > but perl complains about the FH bareword. > using *FH in the new method allows the script to compile, but i am unsure of > the impact!?! *that* part should be fine, but. > with my (dodgy?) *FH, i then hit the problem: > Can't locate object method "FILENO" via package "Win32::SerialPort" > when it hits the line: > vec($rin,fileno($pipe),1) = 1; > > and i go no further. i clearly dont have a valid filehandle in my FH at this > point - but i'm not sure why > or what alternate approach to use. (aside - how do i know if my "tied" > filehandle is opened for input/output/both in this > context?) > i appreciate that the "vec" and "fileno" commands are quite rare (to me, they > were brand spanky new) and primarily > associated with low level tty operations - so perhaps they dont work the same > on win32 as *nix? > > thoughts on equivalent code? Right. I don't know Win32 at all. But from what I can infer the Unix code is looking to read data from the serial port when data is available, but not block when it is not. It's using file handles and select() as the mechanism to do this. From the code you give I don't think that they are only an implementation detail. The fact that Win32::SerialPort provides a *tied* file handle strongly suggests that it's only emulating a file handle interface for compatibility. I don't think your code needs to use file handles, as I'm guessing that they aren't exposed externally. The documentation for Win32::SerialPort seems, um, big: https://metacpan.org/module/Win32::SerialPort but skimming it I can see that there's reference to non-blocking reads. I think you need to look to see what API Win32::SerialPort provides to do a non-blocking read natively, and use that. I have no idea about the answer to your other question. Nicholas Clark
Perl problem - COM ports and filehandles
good afternoon all, me=long time lurker, first time poster! (warning! there is code in the post below - but as a first time poster i have no idea how well that is going to format itself for your consumption...we'll seei apologise now if its a garbled mess. i did try to find posting advice on the london.pm website, but no joy) i am trying to convert a perl script from *nix to win32. i am having difficulty with a couple of things: 1) the unix script opens a filehandle to a device like this: open my $pipe, '+<', '/dev/ttyUSB0' or die "Couldn't open pipe for reading and writing"; my $mb = myDevice::myObject->new($pipe); this filehandle is then referenced in the module via a mechanism containing: my $rin = ''; vec($rin,fileno($pipe),1) = 1; my ($nfound, $timeleft) = select($rin, undef, undef, $timeDelimiter_s); last if($nfound == 0); my $bytes; sysread($pipe, $bytes, $nfound); my (clearly incorrect) approach was to substitute the "open" for a use Win32::SerialPort; (because the device is connected via a virtual serial port over usb) with the following: my $PortObj = tie (*FH, 'Win32::SerialPort', $Configuration_File_Name) || die "Can't tie: $^E\n"; which i would expect to allow me to code: my $mb = myDevice::myObject->new(FH); but perl complains about the FH bareword. using *FH in the new method allows the script to compile, but i am unsure of the impact!?! with my (dodgy?) *FH, i then hit the problem: Can't locate object method "FILENO" via package "Win32::SerialPort" when it hits the line: vec($rin,fileno($pipe),1) = 1; and i go no further. i clearly dont have a valid filehandle in my FH at this point - but i'm not sure why or what alternate approach to use. (aside - how do i know if my "tied" filehandle is opened for input/output/both in this context?) i appreciate that the "vec" and "fileno" commands are quite rare (to me, they were brand spanky new) and primarily associated with low level tty operations - so perhaps they dont work the same on win32 as *nix? thoughts on equivalent code? 2) when (if) i get problem 1 fixed..i need to open the COM port at a non-standard baud rate of 100. soi have tried the code i normally use for my other (working!) serial communication perl scripts: use strict; use Win32::SerialPort; my $Configuration_File_Name="port_config.ini"; my $ob = Win32::SerialPort->new ('COM8') || die; $ob->user_msg(1); # misc. warnings $ob->error_msg(1); # hardware and data errors $ob->baudrate(100); $ob->parity("none"); $ob->databits(8); $ob->stopbits(1); $ob->stty_icrnl(1)||die"icrnl set fail"; $ob->handshake('none'); #$ob->read_const_time(15000); $ob->write_settings||die"setting failed"; $ob->save($Configuration_File_Name); ... do stuff with $ob exit 0; which gives me the error: Could not set baudrate on COM8 any pointers on custom baud rates? have looked at docs for Win32::SerialPort and (tried to) understand the intricacies of Win32API::CommPort (which Win32::SerialPort uses), but no joy. sorry if i haven't posted quite the right snippets here.once you have been looking at things for so many hours, you can't see the wood through the trees...and what's obvious to me, won't be to others i'm sure.. there is no panic on thisit is "play" rather than "work" (by default it is therefore far more interesting!). thanks for reading! sorry to disturb. hello. goodbye. etc... dch26