我在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]
使用正确的参数运行显然是有效的。但是,当我使用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()
运行命令之间存在某种权限差异。如果有人能提供一些有关这方面的见解或给我任何解决这个问题的技巧,将不胜感激。先谢谢。
#!/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));
然而,这仍然存在同样的问题。如果Perl system()
调用具有与通过命令行运行相同的权限,那么为什么我可以在命令行中执行该命令,但是当我从Perl调用相同的EXE时,COM4访问受到限制? :S
答案 0 :(得分: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);
请注意,您不需要将变量放在双引号之外。并且您可以使用其他引用方法来避免必须转义引号。 E.g:
"\""
可以用以下任何形式编写:
'"'
qw(")
q(")
qq(")
q#"# # etc
有关详细信息,请参阅perldoc perlop。
答案 1 :(得分: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"
。