2

我对在 Windows 上运行 Perl 有点陌生,并且在尝试运行avrdude.exe将 HEX 文件上传到 Atmel 微控制器时遇到了一些系统命令问题。这些是我用来执行命令的 Perl 命令:

$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);

现在,我正在打印最终命令以确保它是好的,而且看起来是这样。但是,在实际执行中似乎存在某种权限问题。当我将打印的命令复制并粘贴到 Windows 终端时,结果如下:

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]

这显然是使用正确的参数运行的 avrdude。但是,当我使用 运行此命令时system(),我会收到以下输出:

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.

这让我相信在 CMD 中运行命令和通过system(). 如果有人可以对此提供一些见解或给我任何解决此问题的提示,将不胜感激。预先感谢。

编辑:我编写了一个 Perl 脚本,在向 Atmel 发送硬重置后调用 avrdude.org(基于线程中的一些代码):

#!/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));

但是,这仍然存在同样的问题。如果 Perlsystem()调用和通过命令行运行具有相同的权限,那为什么我可以在命令行中执行命令,但是当我从 Perl 调用相同的 EXE 时,COM4 访问受到限制?:S

4

2 回答 2

1

system可以像你一样接受一个字符串参数,或者一个参数列表。在后一种(推荐的)情况下,shell 会为您处理引用。所以,只需列出参数并传递它。像这样的东西:

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);

请注意,您不需要将变量放在双引号之外。您可以使用其他引用方法来避免转义引号。例如:

"\""

可以写成以下任何一种形式:

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

有关详细信息,请参阅perldoc perlop

于 2012-05-10T17:24:14.677 回答
1

我怀疑您的问题可能在于引用命令行的参数。

我试图模拟您的环境,因为您没有显示所有变量的内容:

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

这是输出:

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

当您将它粘贴到 Cmd 中时,该命令是否有效?

如果不是,您将不得不修复引用。我怀疑这-C"my-conf"可能是错误的。尝试-C "my-conf""-Cmy-conf"

于 2012-05-11T09:15:50.487 回答