2015-05-17 40 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网站之外,还可以帮助您获取各个模块的文档。