سؤال

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

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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".

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top