Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.debian.user > #211115 > unrolled thread

Upgrade to Buster and perl Device::SerialPort

Started by"Martin McCormick" <martin.m@suddenlink.net>
First post2019-07-10 00:20 +0200
Last post2019-07-12 10:10 +0200
Articles 9 — 4 participants

Back to article view | Back to linux.debian.user


Contents

  Upgrade to Buster and perl Device::SerialPort "Martin McCormick" <martin.m@suddenlink.net> - 2019-07-10 00:20 +0200
    Re: Upgrade to Buster and perl Device::SerialPort David Christensen <dpchrist@holgerdanske.com> - 2019-07-10 04:00 +0200
      Re: Upgrade to Buster and perl Device::SerialPort "Martin McCormick" <martin.m@suddenlink.net> - 2019-07-10 19:40 +0200
        Re: Upgrade to Buster and perl Device::SerialPort David Christensen <dpchrist@holgerdanske.com> - 2019-07-11 05:00 +0200
          Re: Upgrade to Buster and perl Device::SerialPort <tomas@tuxteam.de> - 2019-07-11 10:30 +0200
            solved! Upgrade to Buster and perl Device::SerialPort "Martin McCormick" <martin.m@suddenlink.net> - 2019-07-11 21:30 +0200
              Re: solved! Upgrade to Buster and perl Device::SerialPort David <bouncingcats@gmail.com> - 2019-07-12 05:40 +0200
            Re: Upgrade to Buster and perl Device::SerialPort David Christensen <dpchrist@holgerdanske.com> - 2019-07-12 02:40 +0200
              Re: Upgrade to Buster and perl Device::SerialPort <tomas@tuxteam.de> - 2019-07-12 10:10 +0200

#211115 — Upgrade to Buster and perl Device::SerialPort

From"Martin McCormick" <martin.m@suddenlink.net>
Date2019-07-10 00:20 +0200
SubjectUpgrade to Buster and perl Device::SerialPort
Message-ID<yi6CR-xj-1@gated-at.bofh.it>
There is a system here that I upgraded to buster from stretch
which runs a perl program I wrote that accesses a RS-232 dialup
modem over /dev/ttyS0, a native RS-232 port on the mother board.

	It works.  The dialup modem is pretty useless these days
for it's original intended purpose but I wrote a nasty little
program that reads callerID tags and lets telemarketers take a
trip down Memory Lane when they repeatedly call us.

	There is another system whose hard drive crashed a couple
of weeks ago so I put stretch on it from a netinstall disk and
promptly upgraded it to buster before installing cpanplus and
Device::SerialPort as the less software you have, the smoother
the upgrade, generally.

	Interestingly enough, the system that didn't crash and
was upgraded perl and all from stretch to buster is handling the
modem fine, whistling cheerfully at callers who are too big of a
wuss to properly identify themselves.

	On the system that got perl after the new drive, the
complaint is that none of the parameters such as baud rate,
handshake and all other trates throw errors right and left about
uninitiallised variables, the variable being the port that was
previously defined.  It's like the port isn't there.  The first
program I tried that exhibited this behavior was one that
accesses /dev/ttyACM0, a device that shows up if you plug a
Uniden scanner radio in to a usb port.  In stretch days, it
nicely acted as a RS-232 port.  Right now, it shows up as soon as
the cable is connected but the program I wrote in perl to control
it throws the same errors.

	Obviously, the two boxes are separate hardware and the
cable to the radio scanner is not long enough to stretch over to
that same box to see if it works there, but I suspect it might.
I think the difference is that perl was added after the buster
upgrade on the serially-deaf box and neither the virtual usb
serial port nor the actual hardware serial port seem to work any
more even though they show up in /dev and the /dev/ACM0 port goes
away when unplugged.

	Any ideas as to what is going on here?

	I am also a member of a perl discussion list but I
thought I would start here as this problem is directly related to
buster VS stretch.  With stretch, it all worked.

	The only other possibility is that there may be a
recommended syntax for perl and serial ports that I got by with
violating in earlier Linux and now the chickens have come home to
roost and I need to do it differently but much of what I wrote is
stolen from other code examples so I bet it is something in
buster that isn't right yet.

	Any suggestions are much appreciated.

	Martin McCormick WB5AGZ

[toc] | [next] | [standalone]


#211125

FromDavid Christensen <dpchrist@holgerdanske.com>
Date2019-07-10 04:00 +0200
Message-ID<yia3L-2oh-1@gated-at.bofh.it>
In reply to#211115
On 7/9/19 3:01 PM, Martin McCormick wrote:
<snip>
> I put stretch on it from a netinstall disk and
> promptly upgraded it to buster before installing cpanplus and
> Device::SerialPort
<snip>
> the
> complaint is that none of the parameters such as baud rate,
> handshake and all other trates throw errors right and left about
> uninitiallised variables, the variable being the port that was
> previously defined.

Post a console session showing the commands issued and the error 
messages produced.


David

[toc] | [prev] | [next] | [standalone]


#211171

From"Martin McCormick" <martin.m@suddenlink.net>
Date2019-07-10 19:40 +0200
Message-ID<yioJr-2Ut-15@gated-at.bofh.it>
In reply to#211125
David Christensen <dpchrist@holgerdanske.com> writes:
> Post a console session showing the commands issued and the error messages
> produced.

I'll go you one better.  I'll show the code of one of the
programs that dies instantly. It uses /dev/ttyACM0 which is the
device created when a Uniden scanner radio is plugged in to a usb
port.  I also have the program that controls a RS-232 modem and
uses /dev/ttyS0 and gives the same results but contains more
lines so let's go with the scanner program.

	Here's the console session short but not sweet.

Script started on 2019-07-10 12:32:35-05:00 [TERM="linux" TTY="/dev/pts/7" COLUMNS="80" LINES="25"]
1wb5agz martin tmp $ p2 sts
Can't call method "baudrate" on an undefined value at /home/martin/etc/p2 line 37.
2wb5agz martin tmp $ ls -l /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 Jul 10 08:32 /dev/ttyACM0
3wb5agz martin tmp $ exit

Script done on 2019-07-10 12:33:21-05:00 [COMMAND_EXIT_CODE="0"]

	You used to only see that kind of response if /dev/ttyXXX
was missing.  On rare occasions, the scanner radio's tty would go
away and one would need to umplug it and reseat the plug to get
it back and it would then work.

	The rest is 66 lines of code for the scanner control
program.

#!/usr/bin/perl -w
use strict;
use warnings::unused;
use File::Basename;
use File::Copy;
use File::Spec;
use Time::Local;
use Device::SerialPort;

sub waitfor {    #Receive from serial port.

    my $received = "";
    our $port;

    until ( "" ne $received ) {
        $received = $port->lookfor;
    }
    return ($received);
}    #Receive from serial port.

#no more sub routine code past this point

#main global variables
our @dbstrings;

#main local variables
my $response;
my $cmd    = "";
my $ONEARG = "";

#my $counter = 1;

#Setup the comm port.
my $dev = "/dev/ttyACM0";
our $instring = "";
our $port     = Device::SerialPort->new("$dev");
$port->baudrate(115200);
$port->databits(8);
$port->parity("none");
$port->stopbits(1);
$port->handshake("none");
$port->read_const_time(500);    # 500 milliseconds = 0.5 seconds
$port->are_match( "\r", "\n", );    # possible end strings

foreach $ONEARG (@ARGV) {           #each argument
    $ONEARG =~ s/^\s+//;
    $ONEARG =~ s/\s+$//;
    $cmd = $cmd . " " . $ONEARG;
    $cmd =~ s/^\s+//;
    $cmd =~ s/\s+$//;
}    #each argument

$cmd = uc $cmd;
$port->write("$cmd\r");
$instring = waitfor;
my @chars = split( "", $instring );
foreach my $char (@chars) {    #

    #print ord($char);
    if ( $char =~ /[\,\s\.\-\+\_0-9A-Za-z]/ ) {    #printable
        $response = $response . $char;
    }    #printable
}    #
print "$response\n";
$instring = "";
exit(0);

[toc] | [prev] | [next] | [standalone]


#211196

FromDavid Christensen <dpchrist@holgerdanske.com>
Date2019-07-11 05:00 +0200
Message-ID<yixtn-rv-1@gated-at.bofh.it>
In reply to#211171
On 7/10/19 10:39 AM, Martin McCormick wrote:
> David Christensen <dpchrist@holgerdanske.com> writes:
>> Post a console session showing the commands issued and the error messages
>> produced.
> 
> I'll go you one better.  I'll show the code of one of the
> programs that dies instantly. It uses /dev/ttyACM0 which is the
> device created when a Uniden scanner radio is plugged in to a usb
> port.  I also have the program that controls a RS-232 modem and
> uses /dev/ttyS0 and gives the same results but contains more
> lines so let's go with the scanner program.
> 
> 	Here's the console session short but not sweet.
> 
> Script started on 2019-07-10 12:32:35-05:00 [TERM="linux" TTY="/dev/pts/7" COLUMNS="80" LINES="25"]
> 1wb5agz martin tmp $ p2 sts
> Can't call method "baudrate" on an undefined value at /home/martin/etc/p2 line 37.
> 2wb5agz martin tmp $ ls -l /dev/ttyACM0
> crw-rw---- 1 root dialout 166, 0 Jul 10 08:32 /dev/ttyACM0
> 3wb5agz martin tmp $ exit
> 
> Script done on 2019-07-10 12:33:21-05:00 [COMMAND_EXIT_CODE="0"]
> 
> 	You used to only see that kind of response if /dev/ttyXXX
> was missing.  On rare occasions, the scanner radio's tty would go
> away and one would need to umplug it and reseat the plug to get
> it back and it would then work.
> 
> 	The rest is 66 lines of code for the scanner control
> program.
> 
> #!/usr/bin/perl -w
> use strict;
> use warnings::unused;
> use File::Basename;
> use File::Copy;
> use File::Spec;
> use Time::Local;
> use Device::SerialPort;
> 
> sub waitfor {    #Receive from serial port.
> 
>      my $received = "";
>      our $port;
> 
>      until ( "" ne $received ) {
>          $received = $port->lookfor;
>      }
>      return ($received);
> }    #Receive from serial port.
> 
> #no more sub routine code past this point
> 
> #main global variables
> our @dbstrings;
> 
> #main local variables
> my $response;
> my $cmd    = "";
> my $ONEARG = "";
> 
> #my $counter = 1;
> 
> #Setup the comm port.
> my $dev = "/dev/ttyACM0";

I would use single quotes around the device path, as the string should 
not be interpolated.


I would check for existence of the device (-e) and die if not present.


> our $instring = "";
> our $port     = Device::SerialPort->new("$dev");

I would not use quotes around $dev.


Please add error checking of return value of new() and try again:

https://metacpan.org/pod/Device::SerialPort#Constructors

$PortObj = new Device::SerialPort ($PortName, $quiet, $lockfile)
        || die "Can't open $PortName: $!\n";


> $port->baudrate(115200);
> $port->databits(8);
> $port->parity("none");
> $port->stopbits(1);
> $port->handshake("none");
> $port->read_const_time(500);    # 500 milliseconds = 0.5 seconds
> $port->are_match( "\r", "\n", );    # possible end strings
> 
> foreach $ONEARG (@ARGV) {           #each argument
>      $ONEARG =~ s/^\s+//;
>      $ONEARG =~ s/\s+$//;
>      $cmd = $cmd . " " . $ONEARG;
>      $cmd =~ s/^\s+//;
>      $cmd =~ s/\s+$//;
> }    #each argument
> 
> $cmd = uc $cmd;
> $port->write("$cmd\r");
> $instring = waitfor;
> my @chars = split( "", $instring );
> foreach my $char (@chars) {    #
> 
>      #print ord($char);
>      if ( $char =~ /[\,\s\.\-\+\_0-9A-Za-z]/ ) {    #printable
>          $response = $response . $char;
>      }    #printable
> }    #
> print "$response\n";
> $instring = "";
> exit(0);
> 

[toc] | [prev] | [next] | [standalone]


#211207

From<tomas@tuxteam.de>
Date2019-07-11 10:30 +0200
Message-ID<yiCCK-3ER-13@gated-at.bofh.it>
In reply to#211196

[Multipart message — attachments visible in raw view] — view raw

On Wed, Jul 10, 2019 at 07:53:23PM -0700, David Christensen wrote:
> On 7/10/19 10:39 AM, Martin McCormick wrote:
> >David Christensen <dpchrist@holgerdanske.com> writes:

[...]

Good points all around.

> I would check for existence of the device (-e) and die if not present.

Perhaps even check whether the device is character special (-c): ISTR
the code tries to do some stty stuff which will fail otherwise.

OTOH it would preclude you to run the code (e.g. as a test) against a
FIFO: but then the failed attempt at stty should be non-fatal.

Cheers
-- t

[toc] | [prev] | [next] | [standalone]


#211251 — solved! Upgrade to Buster and perl Device::SerialPort

From"Martin McCormick" <martin.m@suddenlink.net>
Date2019-07-11 21:30 +0200
Subjectsolved! Upgrade to Buster and perl Device::SerialPort
Message-ID<yiMVs-1zZ-11@gated-at.bofh.it>
In reply to#211207
	After making an utter ass of myself on this group and
another list, something somebody suggested helped me solve the
problem and the news is good for all.

	I thought it was odd that a serial program I am running
on one buster system was running like the proverbial house on
fire, no trouble at all while that same code blew sky high on
another buster system that I had had to replace the boot drive on
after it crashed.

	We need to be careful when diagnosing trouble not to
think about esoteric issues and be sure the power plug is in the
outlet and the ON/OFF switch is in the On position.

	Well, it wasn't quite that stupid on my part but darn
close.

	For as long as I can remember, debian Linux defaults to
disallowing non-root users in general from accessing the serial
ports.  To access /dev/ttyXx, non-root users need to be added to
the group "dialout" and an upgrade doesn't remove anybody who is
there now from dialout so one doesn't even have to give it a
second thought.

	In this case, this was more like starting from bare metal
and I simply forgot to add me to dialout which is done by

sudo usermod -a -G dialout martin

	One must then log out and back in for the change to take
effect.

	A person on a perl discussion group reminded me that I
should always test for issues like this which is absolutely
correct.  Perl will tell you about the error and kill the program
as it should but you need to be smart enough to put the test in
or you get what I got which is utter confusion because the
program blows right through the bash: /dev/ttyS1: Permission denied
condition and tries to grind on which is impossible since the
port won't work.  There is no reason to continue after that
point.

	The function in perl is called die and it has the ability
to print a string stating what error caused the death but it
doesn't just appear by magic.

	I added the dialout group and that program now also runs
like the blazing house.  Nothing's wrong with buster and serial
ports after all.

	I use the die("cause of death\n") function all the time
but forgot to put it in to a test to see if one could access
/dev/ttyXx and it bit me.

Thanks to all who responded with good suggestions.

Martin McCormick WB5AGZ

[toc] | [prev] | [next] | [standalone]


#211265 — Re: solved! Upgrade to Buster and perl Device::SerialPort

FromDavid <bouncingcats@gmail.com>
Date2019-07-12 05:40 +0200
SubjectRe: solved! Upgrade to Buster and perl Device::SerialPort
Message-ID<yiUzD-6o6-1@gated-at.bofh.it>
In reply to#211251
On Fri, 12 Jul 2019 at 05:23, Martin McCormick <martin.m@suddenlink.net> wrote:
>
> Thanks to all who responded with good suggestions.

And thanks to you too for caring for your readers (present
and future) and resolving the thread with a nicely written,
informative, and useful solution!

[toc] | [prev] | [next] | [standalone]


#211258

FromDavid Christensen <dpchrist@holgerdanske.com>
Date2019-07-12 02:40 +0200
Message-ID<yiRLr-4yA-5@gated-at.bofh.it>
In reply to#211207
On 7/11/19 1:29 AM, tomas@tuxteam.de wrote:
> On Wed, Jul 10, 2019 at 07:53:23PM -0700, David Christensen wrote:
>> On 7/10/19 10:39 AM, Martin McCormick wrote:
>>> David Christensen <dpchrist@holgerdanske.com> writes:
> 
> [...]
> 
> Good points all around.
> 
>> I would check for existence of the device (-e) and die if not present.
> 
> Perhaps even check whether the device is character special (-c): ISTR
> the code tries to do some stty stuff which will fail otherwise.

I have always tried to do thorough error checking.  In the past, I have 
taken argument and/or state checking to the extreme.  Currently, I tend 
to do more moderate argument/ state checking and depend upon the error 
checking code to deal with the advanced and/or corner cases -- e.g. "let 
it crash", but capture all details required for a postmortem analysis.


> OTOH it would preclude you to run the code (e.g. as a test) against a
> FIFO: but then the failed attempt at stty should be non-fatal.

Perl, and its testing infrastructure, are especially amenable to 
designing and coding for testability.


David

[toc] | [prev] | [next] | [standalone]


#211278

From<tomas@tuxteam.de>
Date2019-07-12 10:10 +0200
Message-ID<yiYMV-MB-1@gated-at.bofh.it>
In reply to#211258

[Multipart message — attachments visible in raw view] — view raw

On Thu, Jul 11, 2019 at 05:39:28PM -0700, David Christensen wrote:
> On 7/11/19 1:29 AM, tomas@tuxteam.de wrote:
> >On Wed, Jul 10, 2019 at 07:53:23PM -0700, David Christensen wrote:
> >>On 7/10/19 10:39 AM, Martin McCormick wrote:
> >>>David Christensen <dpchrist@holgerdanske.com> writes:
> >
> >[...]
> >
> >Good points all around.
> >
> >>I would check for existence of the device (-e) and die if not present.
> >
> >Perhaps even check whether the device is character special (-c): ISTR
> >the code tries to do some stty stuff which will fail otherwise.
> 
> I have always tried to do thorough error checking.  In the past, I
> have taken argument and/or state checking to the extreme.

We're in violent agreement here: my "perhaps" was meant seriously (as
"I don't know whether I'd do it: think about it" and not as a polite
way of saying "you definitely gotta do this").

Cheers
-- t

[toc] | [prev] | [standalone]


Back to top | Article view | linux.debian.user


csiph-web