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 でコマンドを実行する場合と .xml を介してコマンドを実行する場合に、何らかの権限の違いがあると思われますsystem()。誰かがこれについて洞察を提供したり、この問題を解決するためのヒントを教えてくれたりすると、大歓迎です. 事前に感謝します。

編集: Atmel にハード リセットを送信した後に avrdude.org を呼び出す Perl スクリプトを作成しました (このスレッドのコードに基づいて):

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

あなたの問題は、コマンドラインの引数を引用することにあると思われます。

すべての変数の内容を表示していないため、環境をシミュレートしようとしました:

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 に答える
1

systemあなたがしたように、文字列引数、または引数のリストのいずれかを取ることができます。後者 (推奨) の場合、シェルが引用を処理します。したがって、引数のリストを作成して渡すだけです。このようなもの:

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 に答える