博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Perl处理Excel之DMA映射
阅读量:5009 次
发布时间:2019-06-12

本文共 14057 字,大约阅读时间需要 46 分钟。

使用Perl处理Excel之DMA映射

功能


通道处理,将各个通道的外设映射到通道上

外设ack信号处理

脚本执行情况


847278-20170529164114243-1745131211.png

847278-20170529164124446-1263711615.png

顶层Perl脚本(dma_parse.pl)


将上述两个功能脚本整合,便于调用

#!/usr/bin/perl -wuse strict;my $Has_Help = ""; my $workfile = ""; my $worklist = ""; my $excelfile;my $ipnamelist;if( $#ARGV < 0 ) {  &print_usage;  exit;}my $filename ="";&parse_argv;if( $Has_Help =~ /TRUE/ )  #显示帮助说明    {      &print_usage;      exit;    }if($workfile =~ /TRUE/){   chomp($excelfile);      #格式化输出通道输出部分   system"perl dmaremap_parse.pl   $excelfile";   system"perl dmaack_parse.pl   $excelfile";}else    {      &print_usage;      exit;    }################################################## Sub-routine: print_usage()   帮助说明#################################################sub print_usage {  print "\nUsage: perl dma_parse.pl -f 
\\\n"; print " [-h] \n\n"; print "For example:\n"; print " perl dma_parse.pl -f dma_map.xls\n"; print " perl dma_parse.pl -h \n"; print "\n";}################################################## Sub-routine : parse_argv() 参数读入#################################################sub parse_argv { my $all_arg = "-h|-f"; for(my $i=0; $i<=$#ARGV; $i++) { if( $ARGV[$i] =~ /-f/ ) { $i++; if(!defined $ARGV[$i]) { $Has_Help = "TRUE"; } $workfile = "TRUE"; $excelfile = $ARGV[$i]; } elsif( $ARGV[$i] =~ /-h/ ) { $Has_Help = "TRUE"; } else { ### other options $Has_Help = "TRUE"; } }}

通道映射脚本(dmaremap_parse.pl)


#!/usr/bin/perl -w################################################## 使用方法# perl dma_parse.pl dma_map.xls#################################################    use strict;use Spreadsheet::ParseExcel;use Spreadsheet::ParseExcel::FmtUnicode;my $parser   = Spreadsheet::ParseExcel->new();my $formatter = Spreadsheet::ParseExcel::FmtUnicode->new(Unicode_Map=>"CP936");my $workbook = $parser->parse($ARGV[0], $formatter);    #my $workbook = $parser->parse($ARGV[0]); if ( !defined $workbook ) {    die $parser->error(), ".\n";}for my $worksheet ( $workbook->worksheets() ) {     my ( $row_min, $row_max ) = $worksheet->row_range();    my ( $col_min, $col_max ) = $worksheet->col_range(); ################################################## get DMA1/2坐标#################################################        my %dma;    for my $row ( $row_min .. $row_max ) {        for my $col ( $col_min .. $col_max ) {             my $cell = $worksheet->get_cell( $row, $col );            next unless $cell;        $_ = $cell->value();        if(/DMA\d/){        #print "Row, Col    = ($row, $col)\n\n";        my $rowtmpfmt=(sprintf "%03d", $row);        my $coltmpfmt=(sprintf "%03d", $col);        $dma{$cell->value()} = $rowtmpfmt.$coltmpfmt;        #print "$_\n\n";        }        }    }    #显示DMA坐标    #foreach my $position (sort keys %dma) {    #  print "$position = $dma{$position}\n";    #}    print "\n\n";    ################################################## 分别处理DMA1/DMA2(遍历)各个通道#################################################        foreach my $dma_name (sort keys %dma){    #print "$dma_name\n\n";        my $row = substr($dma{$dma_name},0,3);  #使用substr得到前三位字符串        my $col = substr($dma{$dma_name},3,3);  #使用substr得到后三位字符串        my $loop_row = $row + 2;        my $loop_col = $col + 1;    #print "Row, Col    = ($loop_row, $loop_col)\n";            #################################################        # 取得各个通道映射信息        #################################################       my $channel_num = 0;         for my $col ( $loop_col .. $loop_col+7 ) {        my @channel;        #print "channel_num = $channel_num\n";  #通道channel1/2/3            for my $row ( $loop_row .. $loop_row+31 ) {                 my $cell = $worksheet->get_cell( $row, $col );                next unless $cell;        if(($cell->value() eq ""))                {                   next;                }                $_ = $cell->value();        #print "$_\n";        push(@channel,$cell->value());    #得到通道中的外设,存入数组            }            #################################################            # 格式化处理通道数组元素            #################################################           my @fmtouts;        foreach my $peripheral (@channel){    #格式化出通道数组            my @channel_tmp = split(/\s+/,$peripheral);        #print "channel_tmp = @channel_tmp\n";        push @fmtouts,@channel_tmp;         }        #print "\n\nchannel = @channel\n\n";        #print "fmtouts = @fmtouts\n\n\n";            #################################################            # 输出通道内的映射信息            #################################################           my $periphs_num = @fmtouts;        #print "periphs_num = $periphs_num\n";        my $perph_tmpnum = 0;        my $remap = 0;        my $perph_remap;        foreach my $peripherals (@fmtouts){            $_ = $peripherals;        #print "$_\n";        $remap = 0;                    #清除重映射标记        if(/\(1\)/){                #判断是否有重映射              #print "$` \t $& \t $' \n";            $peripherals = $`;            $remap = 1;            $perph_remap = $peripherals."_dma_remap";         }        if(/\(2\)/){                #判断是否有重映射              #print "$` \t $& \t $' \n";            $peripherals = $`;            $remap = 2;            $perph_remap = $peripherals."_dma_remap";         }                        #my $output = $peripherals;        #$output =~ /(\d)/;                 my $eq_left  = $dma_name."_single"."\[$channel_num\]";        my $eq_right = $peripherals."_dma_req";        if($periphs_num == 1){            if($remap == 2){                    print "assign \L$eq_left = \(\L$perph_remap \? \L$eq_right : 0\);\n";            }            elsif($remap == 1){                    print "assign \L$eq_left = \(\L$perph_remap \? 0 : \L$eq_right\);\n";            }            else{                    print "assign \L$eq_left = \L$eq_right;";            }            }            if($perph_tmpnum == 0){            if($remap == 2){                    print "assign \L$eq_left = \(\L$perph_remap \? \L$eq_right : 0\) ||\n";            }            elsif($remap == 1){                    print "assign \L$eq_left = \(\L$perph_remap \? 0 : \L$eq_right\) ||\n";            }            else{                    print "assign \L$eq_left = \L$eq_right ||\n";            }            }            elsif($perph_tmpnum < $periphs_num-1){            if($remap == 2){                    print "                        \(\L$perph_remap \? \L$eq_right : 0\) ||\n";            }            elsif($remap == 1){                    print "                        \(\L$perph_remap \? 0 : \L$eq_right\) ||\n";            }            else{                    print "                        \L$eq_right ||\n";            }            }            else{            if($remap == 2){                    print "                        \(\L$perph_remap \? \L$eq_right : 0\);\n";            }            elsif($remap = 1){                    print "                        \(\L$perph_remap \? 0 : \L$eq_right\);\n";            }            else{                    print "                        \L$eq_right;\n";            }            }                #print"remp = $remap\n";            $perph_tmpnum++;               #通道中外设映射个数        }        $channel_num = $channel_num + 1;   #表示通道号channel1/channel2/...        print"\n";        }    }}

外设ack信号处理脚本(dmaack_parse.pl)


#!/usr/bin/perl -w################################################## 使用方法# perl dma_parse.pl dma_map.xls#################################################    use strict;use Spreadsheet::ParseExcel;use Spreadsheet::ParseExcel::FmtUnicode;my $parser   = Spreadsheet::ParseExcel->new();my $formatter = Spreadsheet::ParseExcel::FmtUnicode->new(Unicode_Map=>"CP936");my $workbook = $parser->parse($ARGV[0], $formatter);    #my $workbook = $parser->parse($ARGV[0]); if ( !defined $workbook ) {    die $parser->error(), ".\n";}for my $worksheet ( $workbook->worksheets() ) {     my ( $row_min, $row_max ) = $worksheet->row_range();    my ( $col_min, $col_max ) = $worksheet->col_range(); ################################################## get DMA1/2坐标#################################################        my %dma;    for my $row ( $row_min .. $row_max ) {        for my $col ( $col_min .. $col_max ) {             my $cell = $worksheet->get_cell( $row, $col );            next unless $cell;        $_ = $cell->value();        if(/DMA\d/){        #print "Row, Col    = ($row, $col)\n\n";        my $rowtmpfmt=(sprintf "%03d", $row);        my $coltmpfmt=(sprintf "%03d", $col);        $dma{$cell->value()} = $rowtmpfmt.$coltmpfmt;        #print "$_\n\n";        }        }    }    #显示DMA坐标    #foreach my $position (sort keys %dma) {    #  print "$position = $dma{$position}\n";    #}    print "\n\n";    ################################################## 分别处理DMA1/DMA2(遍历)各个外设#################################################        foreach my $dma_name (sort keys %dma){    #print "$dma_name\n\n";        my $dma_row = substr($dma{$dma_name},0,3);  #使用substr得到前三位字符串        my $dma_col = substr($dma{$dma_name},3,3);  #使用substr得到后三位字符串        my $loop_row = $dma_row + 2;        my $loop_col = $dma_col + 1;    #print "Row, Col    = ($loop_row, $loop_col)\n";            #################################################        # 取得各个外设映射信息        #################################################           for my $row ( $loop_row .. $loop_row+31 ) {        my @peripherals;        my $periph_cell = $worksheet->get_cell( $row, $loop_col-1);  #外设行列确定        my $peripherals_name = $periph_cell->value;         #print "peripherals_name = $peripherals_name\n";              #外设名字              for my $col ( $loop_col .. $loop_col+7 ) {                my $cell = $worksheet->get_cell( $row, $col );                next unless $cell;        if(($cell->value() eq ""))                {                   next;                }                $_ = $cell->value();        if(/\w+/)                {           #print "dma_col = $dma_col\n";           my $channel_num = $col - $dma_col - 1;          #计算通道信息               my $coltmpfmt=(sprintf "%03d", $channel_num);   #通道信息           #print "coltmpfmt = $coltmpfmt\n";           my $peripherals_tmp = $coltmpfmt.$cell->value();           push(@peripherals,$peripherals_tmp);            #得到外设映射的信息,存入数组,同时将通道信息也存入其中           #print "$_\n";                }            }        my $peripherals_num = @peripherals;          #确定映射信息是否为空(==0)        if($peripherals_num == 0){                next;                                    #如果为空将不在进行数据分析,进行下一次循环        }        #print "peripherals = @peripherals\n";            #################################################            # 格式化处理外设映射数组元素            #################################################           my @fmtouts;        foreach my $peripheral (@peripherals){             #格式化出通道数组        my $channel_num = substr($peripheral,0,3);     #分离通道信息        #print "channel_num = $channel_num\n";        substr($peripheral,0,3) = "";             my @peripherals_tmp = split(/\s+/,$peripheral);        #print "peripherals_tmp = @peripherals_tmp\n";        my $element_num = @peripherals_tmp;        my $count = 0;        while($count < $element_num){                  #附加通道信息               $peripherals_tmp[$count] = $channel_num.$peripherals_tmp[$count];           #print "peripherals_tmp\[$count\] = $peripherals_tmp[$count]\n";            $count++;        }        push @fmtouts,@peripherals_tmp;         }        #print "\n\nfmtouts = @fmtouts\n";                  #################################################            # 正则处理:格式化输出            # 分析数据:数组1用于查找含(1),数组2用于查找含(2)的外设映射通道信息            #################################################           my $remap_num = @fmtouts;        #print "remap_num = $remap_num\n";            #################################################            # 处理无映射情况               #################################################           foreach my $fmtout (@fmtouts){        $_ = $fmtout;        #print "$_\n";        if(/\(\d\)/){           next;              #去除包含重映射的外设        }        my $channel_num = substr($fmtout,2,1);     #分离通道信息        substr($fmtout,0,3) = "";         my $dma_ack = $dma_name."_ack"."\[".$channel_num."\]";        my $peripherals_ack = $fmtout."_dma_ack";        print "assign \L$peripherals_ack = \L$dma_ack;\n";        }            #################################################            # 处理存在映射的情况               #################################################           my @fmtouts_tmp = @fmtouts;        foreach my $fmtout (@fmtouts){        $_ = $fmtout;        #print "$_\n";        if(/\(2\)/){           my $channel_2 = substr($fmtout,2,1);        #映射通道2信息           my $fmtout = $`;                            #自动,捕获之前的信息           substr($fmtout,0,3) = "";                   #去除通道信息,重新赋值            my $dma_ack2 = $dma_name."_ack"."\[".$channel_2."\]";               foreach my $fmtout_tmp (@fmtouts_tmp){               $_ = $fmtout_tmp;               if(/$fmtout/){              $_ = $fmtout_tmp;              if(/\(2\)/){                             next;              }                  my $channel_1 = substr($fmtout_tmp,2,1);     #映射通道2信息                  substr($fmtout_tmp,0,3) = "";                   my $dma_ack1 = $dma_name."_ack"."\[".$channel_1."\]";                  my $peripherals_ack = $fmtout."_dma_ack";              my $peripherals_remap = $fmtout."_dma_remap";                  print "assign \L$peripherals_ack = \L$peripherals_remap ? \L$dma_ack2 : \L$dma_ack1;\n";               }               }        }        }                print "\n";        }    }}

使用方法


dma_parse.pl 顶层文件||--dmaremap_parse.pl||--dmaack_parse.pl################################################## 使用方法# perl dma_parse.pl dma_map.xls################################################################################################### 子文件使用方法# perl dmaremap_parse.pl dma_map.xls# perl dmaack_parse.pl dma_map.xls#################################################

转载于:https://www.cnblogs.com/OneFri/p/6918333.html

你可能感兴趣的文章
Android应用中通过AIDL机制实现进程间的通讯实例
查看>>
Python爬虫(二十一)_Selenium与PhantomJS
查看>>
Python操作redis
查看>>
异常的处理方式----抛出处理
查看>>
ios放大UILabel
查看>>
github上构建自己的个人网站
查看>>
fiddler介绍
查看>>
在word中粘贴的图片为什么显示不完整
查看>>
SQL Server 数据库的鼠标操作
查看>>
HTML 【表单】
查看>>
poj2354Titanic(两点的球面距离)
查看>>
linux 开机启动脚本或者服务
查看>>
Web分析日志
查看>>
Data Lake Analytics + OSS数据文件格式处理大全
查看>>
SSO ---- 转载
查看>>
关于OnGlobalLayoutListener
查看>>
在winform里建立http链接和反序列化解析数据
查看>>
iOS 获取当前月份的天数(转)、
查看>>
android之自定义ViewGroup和自动换行的布局的实现(支持按钮间隔)
查看>>
Linux hrtimer分析(一)
查看>>