Загрузка данных
###############################################################################
sub generate_lmm
{
my ($outDir, $cfgRef) = @_;
my $fileName = 'config_lmm.h';
my %rpcInst;
my $default = 0;
# Open file
open my $out, '>', $outDir . '/' . $fileName
or die "error: failure to open: $outDir/$fileName, $!";
if ($verbose)
{
my $fn = fileparse($fileName);
printf("Generating $fn ...\n");
}
# Output header
print $out &header('LMM', 'logical machine manager');
print $out '/* Includes */' . "\n\n";
print $out '#include "config_user.h"' . "\n\n";
print $out '/* Defines */' . "\n\n";
# Get list of start/stop */
my @ss = grep(/^LM\d*\b/ || /\bstart=/ || /\bstop=/, @$cfgRef);
# Log ss info
&log_array('LMM start/stop info', \@ss);
# Loop over the start/stop list
my $i = 0;
my $lm_handle = 0;
my @start;
my @stop;
foreach my $s (@ss)
{
# Handle LM
if ($s =~ /^LM(\d*)\b/)
{
$lm_handle = $1;
}
# Handle start
if ($s =~ /\bstart=/)
{
# Loop over protocols
foreach my $proto (@protocols)
{
# Get resources
my $ucProto = uc $proto . '_';
my @words = split(/ /, $s);
my @resources = grep(/^[A-Z]+_SM_$ucProto/, @words);
# Loop over resources
foreach my $rsrc (@resources)
{
# Begin with lm
my $srt = sprintf("%03d", $lm_handle);
my $slist = 'lm=' . $lm_handle;
# Append msel
if ((my $parm = ¶m($s, 'msel')) ne '!')
{
$slist .= ' msel=' . $parm;
}
else
{
$slist .= ' msel=0';
}
# Append start
if ((my $parm = ¶m($s, 'start')) ne '!')
{
my @arg = split(/\|/, $parm);
$srt .= sprintf("%04d", $arg[0]);
$slist .= ' arg=' . $parm;
}
# Append protocol
$slist .= ' ss=LMM_SS_' . uc $proto;
# Append resource
$slist .= ' rsrc=' . $rsrc;
push @start, $srt . ': ' . $slist . ' ';
}
}
}
# Handle stop
if ($s =~ /\bstop=/)
{
# Loop over protocols
foreach my $proto (@protocols)
{
# Get resources
my $ucProto = uc $proto . '_';
my @words = split(/ /, $s);
my @resources = grep(/^[A-Z]+_SM_$ucProto/, @words);
# Loop over resources
foreach my $rsrc (@resources)
{
# Begin with lm
my $srt = sprintf("%03d", $lm_handle);
my $slist = 'lm=' . $lm_handle;
# Append msel
if ((my $parm = ¶m($s, 'msel')) ne '!')
{
$slist .= ' msel=' . $parm;
}
else
{
$slist .= ' msel=0';
}
# Append start
if ((my $parm = ¶m($s, 'stop')) ne '!')
{
my @arg = split(/\|/, $parm);
$arg[0] = sprintf("%04d", $arg[0]);
$srt .= sprintf("%04d", $arg[0]);
$slist .= ' arg=' . $parm;
}
# Append protocol
$slist .= ' ss=LMM_SS_' . uc $proto;
# Append resource
$slist .= ' rsrc=' . $rsrc;
push @stop, $srt . ': ' . $slist . ' ';
}
}
}
}
# Sort results
my @tmp = sort @start;
@start = @tmp;
@tmp = sort @stop;
@stop = @tmp;
# Get list of LM
my @list = grep(/^LM\d*\b/ || /^MODE\b/, @$cfgRef);
# Log LM info
&log_array('LMM info', \@list);
# Loop over the LM list
$i = 0;
my $msel = 0;
my $maxMsel = 0;
foreach my $lm (@list)
{
my $rpcType;
# Handle LM
if ($lm =~ /^(LM\d*)\b/)
{
$msel = 0;
# Close previous LM
if ($i != 0)
{
print $out ' }' . "\n\n";
}
# Output banner
$lm =~ /^LM(\d*)\b/;
my $lm_val = $1;
$lm =~ /^(LM\d*)\b/;
my $lm_handle = $1;
my $line = $1 . ' Config';
if ((my $parm = ¶m($lm, 'name')) ne '!')
{
$parm =~ s/\"//g;
$line .= ' (' . $parm . ')';
}
print $out &banner($line);
# Output LM define
print $out '/*! Config for ' . $lm_handle . ' */' . "\n";
print $out '#define SM_' . $lm_handle . '_CONFIG \\' . "\n";
print $out ' { \\' . "\n";
if ((my $parm = ¶m($lm, 'name')) ne '!')
{
$parm =~ s/\"//g;
print $out ' .name = "' . $parm . '", \\' . "\n";
}
if ((my $parm = ¶m($lm, 'rpc')) ne '!')
{
$rpcType = $parm;
print $out ' .rpcType = SM_RPC_'
. uc $parm . ', \\' . "\n";
$rpcInst{$parm}++;
}
if ($rpcType ne 'none')
{
print $out ' .rpcInst = '
. ($rpcInst{$rpcType} - 1)
. 'U, \\' . "\n";
}
if ((my $parm = ¶m($lm, 'boot')) ne '!')
{
print $out ' .boot[0] = ' . $parm . 'U, \\' . "\n";
$rpcInst{$parm}++;
# Check SM info
if ($lm_handle eq 'LM0')
{
if ($parm ne '1')
{
print STDERR 'error: invalid SM/LM0 boot order (must be 1)' . "\n";
exit;
}
}
}
if ((my $parm = ¶m($lm, 'skip')) ne '!')
{
print $out ' .bootSkip[0] = ' . $parm . 'U, \\' . "\n";
$rpcInst{$parm}++;
}
if ((my $parm = ¶m($lm, 'rtime')) ne '!')
{
print $out ' .rtime = ' . $parm . 'U, \\' . "\n";
}
# Output safety type
if ((my $parm = ¶m($lm, 'safe')) ne '!')
{
print $out ' .safeType = LMM_SAFE_TYPE_' . uc $parm
. ', \\' . "\n";
# Check SM info
if ($lm_handle eq 'LM0')
{
if (uc $parm ne 'FEENV')
{
print STDERR 'error: invalid SM/LM0 safe type (must be feenv)' . "\n";
exit;
}
}
}
# Output group
if ((my $parm = ¶m($lm, 'group')) ne '!')
{
print $out ' .group = ' . $parm . 'U, \\' . "\n";
}
# Output auto boot
if ((my $parm = ¶m($lm, 'auto')) ne '!')
{
print $out ' .autoBoot = LMM_AUTO_' . uc $parm
. ', \\' . "\n";
}
# Output start/stop
my $sidx = first { $start[$_] =~ /lm=$lm_val/ } 0..$#start;
if (defined $sidx)
{
my $n = $sidx + 1;
print $out ' .start = ' . $n . 'U, \\' . "\n";
}
$sidx = first { $stop[$_] =~ /lm=$lm_val/ } 0..$#stop;
if (defined $sidx)
{
my $n = $sidx + 1;
print $out ' .stop = ' . $n . 'U, \\' . "\n";
}
# Save default
if ($lm =~ /default /)
{
$default = $i;
}
# Include in make
$makeInclude{LMM} = 'lmm';
$i++;
}
# Handle MODE
if ($lm =~ /^MODE\b/)
{
if ((my $parm = ¶m($lm, 'msel')) ne '!')
{
$msel = $parm;
if ($msel > $maxMsel)
{
$maxMsel = $msel;
}
}
if ((my $parm = ¶m($lm, 'boot')) ne '!')
{
print $out ' .boot[' . $msel . '] = ' . $parm . 'U, \\' . "\n";
$rpcInst{$parm}++;
}
if ((my $parm = ¶m($lm, 'skip')) ne '!')
{
print $out ' .bootSkip[' . $msel . '] = ' . $parm . 'U, \\' . "\n";
$rpcInst{$parm}++;
}
}
}
# Close previous LM
if ($i != 0)
{
print $out ' }' . "\n\n";
}
# Output collected define
my @lm_list = grep(/^LM\d*\b/, @list);
my $num = @lm_list;
print $out &banner('LM Config');
print $out '/*! Config for number of LM */' . "\n";
print $out '#define SM_NUM_LM ' . $num . 'U' . "\n\n";
# Loop over the LM list
$i = 0;
print $out '/*! Config data array for LM */' . "\n";
print $out '#define SM_LM_CONFIG_DATA';
foreach my $lm (@lm_list)
{
$lm =~ /^(LM\d*)\b/;
my $lm_handle = $1;
if ($i != 0)
{
print $out ',';
}
print $out ' \\' . "\n" . ' SM_' . $lm_handle . '_CONFIG';
$i++;
}
print $out "\n\n";
# Output max msel
print $out '/*! Number of mSel */' . "\n";
print $out '#define SM_LM_NUM_MSEL ' . ($maxMsel + 1) . 'U' . "\n\n";
# Output max num seenv
print $out '/*! Number of S-EENV */' . "\n";
print $out '#define SM_LM_NUM_SEENV ' . ($seenvid) . 'U' . "\n\n";
# Output config name
my ($inName, $inPath, $inSuffix) = fileparse($inputFile, '\.[^\.]*');
print $out '/*! Config name */' . "\n";
print $out '#define SM_LM_CFG_NAME "' . substr($inName, 0, 15)
. '"' . "\n\n";
# Output default monitor LM
print $out '/*! Default LM for monitor */' . "\n";
print $out '#define SM_LM_DEFAULT ' . $default . 'U' . "\n\n";
# Output start
print $out &banner('LM Start/Stop Lists');
my $numStart = @start;
print $out '/*! Config for number of start */' . "\n";
print $out '#define SM_LM_NUM_START ' . $numStart . 'U' . "\n\n";
print $out '/*! LM start list */' . "\n";
print $out '#define SM_LM_START_DATA';
print $out &startstop($numStart, \@start);
print $out "\n";
# Output stop
my $numStop = @stop;
print $out '/*! Config for number of stop */' . "\n";
print $out '#define SM_LM_NUM_STOP ' . $numStop . 'U' . "\n\n";
print $out '/*! LM stop list */' . "\n";
print $out '#define SM_LM_STOP_DATA';
print $out &startstop($numStop, \@stop);
print $out "\n";
# Output fault
print $out &banner('LM Fault Lists');
print $out '/*! LM fault reactions */' . "\n";
print $out '#define SM_LM_FAULT_DATA';
# Get list of faults */
my @fault = grep(/^LM\d*\b/ || /\bDEV_SM_FAULT_/, @$cfgRef);
foreach my $f (@fault)
{
# Handle LM
if ($f =~ /^LM(\d*)\b/)
{
$lm_handle = $1;
}
# Handle fault
if ($f =~ /\bDEV_SM_FAULT_(\w*)\b/)
{
my $faultParm = $lm_handle;
my $fault = 'DEV_SM_FAULT_' . $1;
if ((my $parm = ¶m($f, 'reaction')) ne '!')
{
# Get optional parm
if ((my $arg = ¶m($f, 'lm')) ne '!')
{
$faultParm = $arg;
}
print $out ' \\' ."\n" . ' [' . $fault . '] = {';
print $out '.reaction = LMM_REACT_' . uc $parm . ', ';
print $out '.lm = ' . $faultParm . 'U},';
}
}
}
print $out "\n";
# Output footer
print $out &footer('LMM');
# Close file
close($out);
}