2

I'm kinda new to running Perl on windows, and I'm having some problems with the system command while trying to run avrdude.exe to upload a HEX file to a Atmel Microcontroller. These are the Perl commands I am using to execute the command:

$AVR_CMD = "\"".$AVR_DUDE."\"" . " -C" . "\"".$AVR_DUDE_CONF."\""; 
$AVR_CMD .= " -v -v -v -v -patmega2560 -cstk500v2"; 
$AVR_CMD .= " -P\\\\.\\".$PORT;
$AVR_CMD .= " -b115200 -D -Uflash:w:". "\"".$HEX_FILE."\"". ":i";

system($AVR_CMD);

Now, I am printing the final command to ensure that it is OK, and it seems to be. However, there seems to be some sort of permissions problem in the actual execution. When I copy and paste the printed command into the windows terminal, it results in this:

avrdude.exe: Version 5.11, compiled on Sep  2 2011 at 19:38:36
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is BLOCKED FOR SO

         Using Port                    : \\.\COM4
         Using Programmer              : stk500v2
         Overriding Baud Rate          : 115200
avrdude.exe: Send: . [1b] . [01] . [00] . [01] . [0e] . [01] . [14]

Which is evidently avrdude being run with the correct parameters. However, when I run this command using system(), I receive this output:

avrdude.exe: Version 5.11, compiled on Sep  2 2011 at 19:38:36
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch

         System wide configuration file is BLOCKED FOR SO

         Using Port                    : \\.\COM4
         Using Programmer              : stk500v2
         Overriding Baud Rate          : 115200
avrdude.exe: ser_open(): can't open device "\\.\COM4": Access is denied.
avrdude.exe done.  Thank you.

This leads me to believe that there is some sort of permissions difference between running a command in CMD and running it through system(). If anyone could offer some insight on this or give me any tips to remedy this problem it would be greatly appreciated. Thanks beforehand.

EDIT: I have written a Perl script that calls avrdude.org after sending a hard reset to the Atmel (based on some code in this thread):

#!/usr/bin/perl -w
use Win32::SerialPort qw( :STAT 0.19 );
use FindBin qw($Bin);

#Do port reset
foreach (@ARGV)
{
    if ($_ =~ /-P\\\\\.\\(.*)/)
    {
        print "Found -P argument - ";
        print ("Resetting DTR on " . $1 . "\n");
        $P1 = new Win32::SerialPort ($1);
        $P1->pulse_dtr_on(1000);    
        last;
    }
}

select(undef, undef, undef, 0.1);
print ("Executing avrdude\n");
system($Bin . "/avrdude.org " . join(" ", @ARGV));

However, this still has the same problem. If the Perl system() call has the same permissions as running through the command line, then why can I execute the command in the command line, but COM4 access is restricted when I call the same EXE from Perl? :S

dolmen
  • 8,126
  • 5
  • 40
  • 42
SuperTron
  • 4,203
  • 6
  • 35
  • 62
  • 1
    Re "This leads me to believe that there is some sort of permissions difference between running a command in CMD and running it through `system()`.", No, there isn't. Especially since you told Perl to use `cmd`! – ikegami May 10 '12 at 18:51
  • I'm confused as to why I can access COM4 in avrdude using the command line, but not through perl using the same command... If they have the same permission settings it should work no? – SuperTron May 10 '12 at 19:07
  • 1
    I've already stated the difference is not between Perl and not Perl, and asking me what the difference is between Perl and not Perl isn't productive. – ikegami May 10 '12 at 19:09
  • i.e. Look elsewhere. How was Perl launched? Was the same command actually used? What's the current work directory? etc etc etc – ikegami May 10 '12 at 19:22
  • I'm launching it from the command line with just a `perl upload.pl` – SuperTron May 10 '12 at 19:32
  • You do not show the content of the `$AVR_DUDE`, `$AVR_DUDE_CONF`, `$PORT`, and `$HEX_FILE` variable. That could help to find the issue. – dolmen May 11 '12 at 09:04
  • Let's not dismiss the permission issue just yet. I've ran into a similar issue for the first time, where using system("mkdir -p $dir") didn't work, but mkpath $dir created the path just fine. – ybenjira Nov 20 '20 at 23:14
  • Two comments: 1) As `system` accepts a *LIST*, why taking the efforts to join all the arguments together (BTW: there is a `join` function), also doing quoting (there is a `map` function, too)? 2) If you actually use a *LIST*, try to display it immediately before executing it in the Perl debugger (use `perl -d your_program`). – U. Windl Aug 24 '23 at 06:57

2 Answers2

1

system can take either a string argument, like you did, or a list of arguments. In the latter (recommended) case, the shell handles the quoting for you. So, just make a list of the arguments and pass it. Something like this:

my @args = ($AVR_DUDE, " -C", $AVR_DUDE_CONF, 
           qw(-v -v -v -v -patmega2560 -cstk500v2), "-P\\.\.$PORT", 
           qw(-b115200 -D -Uflash:w:), $HEX_FILE, ":i");
system(@args);

Note that you do not need to put variables outside double quotes. And you can use other quoting methods to avoid having to escape quotes. E.g.:

"\""

Can be written in any of these forms:

'"'
qw(")
q(")
qq(")
q#"#   # etc

See perldoc perlop for more information.

TLP
  • 66,756
  • 10
  • 92
  • 149
1

I suspect that your issue may be in quoting the arguments of the command-line.

I tried to simulate your environnement as you did not show the content of all your variables:

use strict;
use warnings;

my $AVR_DUDE = 'avrdude.exe';
my $AVR_DUDE_CONF = 'my-conf';
my $PORT = 'COM4';
my $HEX_FILE = 'file.hex';

my $AVR_CMD;
$AVR_CMD = "\"".$AVR_DUDE."\"" . " -C" . "\"".$AVR_DUDE_CONF."\""; 
$AVR_CMD .= " -v -v -v -v -patmega2560 -cstk500v2"; 
$AVR_CMD .= " -P\\\\.\\".$PORT;
$AVR_CMD .= " -b115200 -D -Uflash:w:". "\"".$HEX_FILE."\"". ":i";

print "$AVR_CMD\n";

Here is the output:

"avrdude.exe" -C"my-conf" -v -v -v -v -patmega2560 -cstk500v2 -P\\.\COM4 -b115200 -D -Uflash:w:"file.hex":i

Does that command work when you paste it in Cmd?

If not you'll have to fix the quoting. I suspect that -C"my-conf" may be wrong. Try -C "my-conf" or "-Cmy-conf".

dolmen
  • 8,126
  • 5
  • 40
  • 42