2015-05-17 37 views
-4

我是Perl的新手,但瞭解C和C++和。我想下面的URL下轉換Perl腳本Shell或bash: https://code.google.com/p/busware/source/browse/trunk/SD0/Firmware_VZ/vzfeeder/vzfeeder.pl將Perl轉換爲shell或bash以通過gpio進行通信

下面是代碼:

#!/usr/bin/perl 

use warnings; 
use strict; 
use Time::HiRes qw/ gettimeofday /;; 
use POE; 
use POE::Wheel::ReadWrite; 
use POE::Wheel::ReadLine; 
use POE::Component::Client::HTTP; 
use POE::Component::DBIAgent; 
use Symbol qw(gensym); 
use Device::SerialPort; 
use POE::Filter::Line; 
use HTTP::Request; 
use Data::Dumper; 
use DateTime; 

sub DB_NAME() { "volkszaehler" } 
sub DB_USER() { "vz" } 
sub DB_PASS() { "demo" } 

use Log::Log4perl qw/:easy/; 
Log::Log4perl->easy_init({ 
          level => $INFO, 
          layout => '[%d] %p %c - %m%n', 
          }); 

INFO('starting logger process'); 

POE::Session->create(
    inline_states => { 
    _start  => \&setup_device, 
    open_serial => \&open_serial, 
    program_serial => \&program_serial, 
    got_serial => \&got_serial, 
    got_error => \&handle_errors, 
    cmd_V  => \&got_version, 
    cmd_L  => \&got_portbits, 
    queue_cmd => \&queue_cmd, 

    mod_reset => \&mod_reset, 
    mod_bl  => \&mod_bl, 

    query_all_channels_done => \&handle_query_all_channels_response, 
    finish_query_all_channels => \&finish_query_all_channels, 
    }, 
)->option(trace => 1); 

POE::Kernel->run(); 
exit 0; 

sub setup_device { 
    my ($kernel, $heap, $session) = @_[KERNEL, HEAP, SESSION]; 

    POE::Component::Client::HTTP->spawn(
             Alias  => 'ua', 
             Timeout => 10, 
            ); 

    INFO('opening database link'); 
    my $dbi = $heap->{dbi_helper} = POE::Component::DBIAgent->new(
    DSN  => ['dbi:mysql:dbname=' . DB_NAME, DB_USER, DB_PASS], 
    Count => 3, 
    Queries => { 
     query_all_channels => 'select * from entities', 
     insert_tickdata  => 'insert into data (timestamp,channel_id,value) values (?, ?, ?)', 
#  update => "update test set value = ? where name = ?", 
#  delete => "delete from test where name = ?", 
    }, 
); 

    $heap->{CHANNELS} = []; 
    $dbi->query(query_all_channels => $session->ID => 'query_all_channels_done'); 

    $kernel->yield('open_serial'); 
} 

# open serial Port 
sub open_serial { 
    my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0]; 

    INFO('opening serial port'); 

    qx^if test ! -d /sys/class/gpio/gpio27; then echo 27 > /sys/class/gpio/export; fi^; 
    qx^echo out > /sys/class/gpio/gpio27/direction^; 
    qx^echo 1 > /sys/class/gpio/gpio27/value^; 
    qx^if test ! -d /sys/class/gpio/gpio17; then echo 17 > /sys/class/gpio/export; fi^; 
    qx^echo out > /sys/class/gpio/gpio17/direction^; 
    qx^echo 0 > /sys/class/gpio/gpio17/value^; 
    qx^echo 1 > /sys/class/gpio/gpio17/value^; 

    # Open a serial port, and tie it to a file handle for POE. 
    my $handle = gensym(); 
    my $port = tie(*$handle, "Device::SerialPort", "/dev/ttyAMA0"); 
    die "can't open port: $!" unless $port; 

    $port->datatype('raw'); 
    $port->reset_error(); 
    $port->baudrate(38400); 
    $port->databits(8); 
    $port->parity('none'); 
    $port->stopbits(1); 
    $port->handshake('none'); 

    $port->write_settings(); 

    $port->lookclear(); 

    # Start interacting with the GPS. 
    $heap->{port}  = $port; 
    $heap->{port_wheel} = POE::Wheel::ReadWrite->new(
    Handle => $handle, 
    Filter => POE::Filter::Line->new(
     InputLiteral => "\x0D\x0A", # Received line endings. 
     OutputLiteral => "\x0D",  # Sent line endings. 
    ), 
    InputEvent => "got_serial", 
    ErrorEvent => "got_error", 
); 

    $kernel->delay_add(queue_cmd => 2 => 'v'); 
    $kernel->delay(program_serial => 5); 
} 

# programming via serial Port 
sub program_serial { 
    my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0]; 

    INFO('flashing module @ serial port'); 

    delete $heap->{port_wheel}; 
    untie($heap->{port}) if $heap->{port}; 
    delete ($heap->{port}); 

    qx^if test ! -d /sys/class/gpio/gpio17; then echo 17 > /sys/class/gpio/export; fi^; 
    qx^echo out > /sys/class/gpio/gpio17/direction^; 
    qx^echo 0 > /sys/class/gpio/gpio17/value^; 
    qx^if test ! -d /sys/class/gpio/gpio27; then echo 27 > /sys/class/gpio/export; fi^; 
    qx^echo out > /sys/class/gpio/gpio27/direction^; 
    qx^echo 0 > /sys/class/gpio/gpio27/value^; 
    qx^echo 1 > /sys/class/gpio/gpio17/value^; 
    qx^sleep 1^; 
    qx^echo 1 > /sys/class/gpio/gpio27/value^; 
    qx^avrdude -p atmega1284p -P /dev/ttyAMA0 -b 38400 -c avr109 -U flash:w:main.hex^; 

    $kernel->yield('open_serial'); 
} 


# Port data (lines, separated by CRLF) are displayed on the console. 
sub got_serial { 
    my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0]; 
    INFO('got_serial: ' . $data); 
    my @v = split(/\s+/, $data); 

    # Channel ticks? 
    if ($v[0] =~ /^([ABCD])$/) { 
    my $ch = $1; 
    INFO('Tick @ ' . $ch); 
    my ($seconds, $microseconds) = gettimeofday; 
    my $sec = sprintf('%d%03d', $seconds, $microseconds/1000); 

    $heap->{dbi_helper}->query(insert_tickdata => $session->ID => undef => ($sec, ord($ch)-64, 1)); 

    return; 
    } 

    my $cmd = sprintf 'cmd_%s', shift @v; 
    $kernel->yield($cmd => [@v]); 
} 

# Error on the serial port. Shut down. 
sub handle_errors { 
    my $heap = $_[HEAP]; 
    ERROR('received error!'); 
    delete $heap->{port_wheel}; 
} 

sub got_version { 
    my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0]; 
    INFO('VERSION: ' . $data->[0]); 
    $heap->{VERSION} = $data->[0]; 

    $kernel->delay('program_serial'); 
} 

sub got_portbits { 
    my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0]; 
    INFO('Portbits: ' . $data->[0]); 
    $heap->{PORTBITS} = $data->[0]; 
} 

sub queue_cmd { 
    my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0]; 
    $heap->{port_wheel}->put($data); 
} 

# 
# DATABASE work 
# 

sub handle_query_all_channels_response { 
    my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0]; 

    if (ref($data) eq 'ARRAY') { 
    push $heap->{CHANNELS}, $data; 
    } elsif ($data eq 'EOF') { 
    $kernel->yield(finish_query_all_channels => $heap->{CHANNELS}); 
    } 

} 

sub finish_query_all_channels { 
    my ($kernel, $heap, $data) = @_[KERNEL, HEAP, ARG0]; 
    INFO(Dumper($heap->{CHANNELS})); 
} 

這裏是perl腳本作爲外殼/慶典的一部分:

#!/usr/bin/sh 

function setup_device() {{ 

} 
function open_Serial(){ 
    echo "opening serial port; Resetting\\Booting the SD0" 

    if test ! -d /sys/class/gpio/gpio27; then echo 27 > /sys/class/gpio/export; fi 
    echo out > /sys/class/gpio/gpio27/direction 
    echo 1 > /sys/class/gpio/gpio27/value 
    if test ! -d /sys/class/gpio/gpio17; then echo 17 > /sys/class/gpio/export; fi 
    echo out > /sys/class/gpio/gpio17/direction 
    echo 0 > /sys/class/gpio/gpio17/value 
    echo 1 > /sys/class/gpio/gpio17/value 
    minicom -b 38400 -o -D /dev/ttyAMA0 
} 

function program_Serial(){ 
    echo "flashing module @ serial port" 
    echo calling co-processor bootloader ... 

    if test ! -d /sys/class/gpio/gpio17; then echo 17 > /sys/class/gpio/export; fi 
    echo out > /sys/class/gpio/gpio17/direction 
    echo 0 > /sys/class/gpio/gpio17/value 
    if test ! -d /sys/class/gpio/gpio27; then echo 27 > /sys/class/gpio/export; fi 
    echo out > /sys/class/gpio/gpio27/direction 
    echo 0 > /sys/class/gpio/gpio27/value 
    echo 1 > /sys/class/gpio/gpio17/value 
    sleep 1 
    echo 1 > /sys/class/gpio/gpio27/value 

    avrdude -p atmega1284p -P /dev/ttyAMA0 -b 38400 -c avr109 -U flash:w:SD0.hex 
} 

爲例

什麼
my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0]; 

是什麼意思?我會爲函數(?)的參數進行猜測,但是如何轉換ARG? 或者下面的代碼在做什麼?

my $handle = gensym(); 

是否有一個將perl腳本轉換爲shell的工具?還是一個可以幫助翻譯的(好文件)?

+0

如果您的聲望得分爲75,則可以開始[賞金](http://stackoverflow.com/help/bounty )。 – Cyrus

+1

您似乎已經完成的所有操作都是從使用腳本的部分周圍移除'qx',這不應該在第一個位置寫入。這是一項大量的工作,我不知道你在這裏會得到什麼幫助。沒有任何東西可以將Perl轉換成任何其他語言,並且由於其交織和同時編譯和執行能力而不能一般。運行Perl程序時出現什麼問題? – Borodin

回答

5

您的Perl程序是圍繞POE (the Perl Object Environment)構建的,它是一個事件循環機制,允許多個獨立任務並行執行以響應事件,消息或經過的時間。它是一個綜合組在其他語言中對應的模塊,但不是直接複製任何地方

爲例

什麼
my ($kernel, $heap, $session, $data) = @_[KERNEL, HEAP, SESSION, ARG0]; 

是什麼意思?我會爲函數(?)的參數進行猜測,但是如何轉換ARG?

這是POE調用機制的一部分。參數傳遞給@_數組中的Perl子例程,而POE有一個約定,即相同的參數總是以相同的順序傳遞給其成員子例程。值KERNELHEAP等僅僅是用於將索引標記到參數列表中的數字常量。例如,SESSION,KERNELHEAP分別是1,2和3。 ARG0是10,所以它挑選了@_的第11個元素。其他值定義爲

或者下面的代碼在做什麼?

my $handle = gensym(); 

這是Perl中的一個非常深奧的角落。 gensymSymbol module提供的,而在這種情況下,沒有給它一個特定的標識

有其轉換perl腳本殼一個工具創建的文件句柄的一種方式?還是一個可以幫助翻譯的(好文件)?

沒有什麼,因爲會,正如我在我的上述評論暗示一般的Perl程序轉換成其他語言,Perl有相互交織的編譯和執行階段,沒有其他語言股份的獨特方式。有可能是周圍的東西會轉化非常基本的Perl,但我還沒有碰到過它來了,反正你的代碼沒有資格作爲基本

爲Perl本身最好的文檔是perldocmetacpan會除了以上鍊接的POE網站之外,還可以幫助您獲取各個模塊的文檔。