Commit a1a90299 authored by Stefan Tauner's avatar Stefan Tauner
Browse files

Refine block_till_ready, wait_for_ready and run variable handling

I.e. fix the chaos that has been growing for a while and the bugs
introduced in the patch
"fiji_ee_gui: allow to abort test runs even during long transfers"
parent 432f5c66
......@@ -185,10 +185,11 @@ sub sanitize_config {
my $prev_t1 = 0;
my $prev_t2 = 0;
## @method public send_config (%$config_ref, $block_till_ready, $wait_for_ready)
## @method public send_config (%$config_ref, $run_ref, $block_till_ready, $wait_for_ready)
# @brief Sends a complete configuration to the FI controller.
#
# \param config_ref a reference to a hash representing a FIJI configuration (see \ref sanitize_config).
# \param run_ref a reference to a boolean indicating that no abort is requested (yet).
# \param block_till_ready (optional) Normally the function immediately starts to transmit the new configuration. If this parameter is defined and non-zero the function first waits for a READY message (up to the timeout).
# \param wait_for_ready (optional) Normally the function returns immediately after the CONF_DONE message is received. If this parameter is defined and non-zero the function additionally waits for a READY/UNDERRUN message.
#
......@@ -196,7 +197,7 @@ sub sanitize_config {
# \returns a hash if any message was received (potentially) containing msg_type, fault_detect, error, underrun_occurred
sub send_config {
my $logger = get_logger("");
my ($self, $config_ref, $block_till_ready, $wait_for_ready) = @_;
my ($self, $config_ref, $run_ref, $block_till_ready, $wait_for_ready) = @_;
my $port = $self->{'port'};
if (ref($config_ref) ne 'HASH') {
......@@ -308,7 +309,6 @@ sub sanitize_config {
#
# Additionally we always add the constant below to be one the safe side.
my $timeout_buffer = 500; # in ms
my $timeout = -1;
my @rcv_buf = ();
my %err;
......@@ -322,7 +322,8 @@ sub sanitize_config {
# Timeout: if we are waiting for the previous READY message instantly after
# CONF_DONE, then (if no trigger was set previously) the timeout should contain
# the t1 duration of the last configuration.
$timeout = (($prev_t1 / $consts_ref->{'FREQUENCY'}) * 1000) + $timeout_buffer;
# FIXME: conform to run_ref and abort earlier if indicated
my $timeout = (($prev_t1 / $consts_ref->{'FREQUENCY'}) * 1000) + $timeout_buffer;
if ((_rcv_bitstream($port, 1, $timeout, \@rcv_buf) != 0) || ((scalar @rcv_buf) != 1)) {
my $msg = "Receiving READY message failed";
$logger->error($msg);
......@@ -386,8 +387,8 @@ sub sanitize_config {
}
# exit early if requested to not wait for another READY message
if (!defined($dryrun) || $dryrun == 1) {
$logger->debug("Returning after successfully receiving CONF_DONE message due to dryrun.");
if ((!defined($dryrun) || $dryrun == 1) || (!defined($wait_for_ready) || $wait_for_ready == 0)) {
$logger->debug("Returning after successfully receiving CONF_DONE message due to dryrun or wait_for_ready.");
return {msg_type => $msg_type, fault_detect => \%fd, error => \%err};
}
......@@ -402,16 +403,16 @@ sub sanitize_config {
@rcv_buf = ();
retry_ready_finish:
if (!defined($run_ref) || $$run_ref == 0) {
$logger->debug("Returning early (before receiving READY message) due to unset run.");
return "Aborted";
}
if (defined($tot_timeout) && ($tot_timeout <= 0)) {
$logger->debug("Timed out during waiting for READY message after transaction.");
return "Timeout";
}
if (!defined($wait_for_ready) || $$wait_for_ready == 0) {
$logger->debug("Returning before receiving READY message due to unset wait_for_ready.");
return "Aborted";
}
# wait for READY message
my $ret = _rcv_bitstream($port, 1, $READY_WAIT_MS, \@rcv_buf);
if ($ret > 0) {
......
......@@ -140,34 +140,11 @@ sub existing_tests {
}
}
## @method private _test_fi_uart ($port, %$payload_ref, $t1_duration, $t2_duration, $trigger_en, $trigger_ext, $reset, %$fiji_consts, $dryrun, $wait_for_ready_ref)
# @brief Wrapper for port->send_config
# Generates a configuration hash from discrete parameters
# @returns the return value from FIJI::Connection->send_config
sub _test_fi_uart {
my $logger = get_logger("");
my ($port, $payload_ref, $t1_duration, $t2_duration, $trigger_en, $trigger_ext, $reset, $fiji_consts, $dryrun, $wait_for_ready_ref) = @_;
$$wait_for_ready_ref = \1 if !ref($wait_for_ready_ref);
# my @payload = map hex($_), $cfg_str =~ /(..)/g; # @TODO: how to do this with unpack?
my %config = (
payload => $payload_ref,
t1_duration => $t1_duration,
t2_duration => $t2_duration,
trigger_en => $trigger_en,
trigger_ext => $trigger_ext,
reset => $reset,
consts => $fiji_consts,
dryrun => $dryrun,
);
return $port->send_config(\%config, 0, $wait_for_ready_ref);
}
## @method public download_auto ($testref, $portname, &$intermediate_cb)
## @method public download_auto ($$run_ref, %$$testref, $portname, &$intermediate_cb)
# @brief Download tests contained in the .cfg file
# @param testref (optional) reference where this function shall put the
#
# @param run_ref a reference to a boolean indicating that no abort is requested (yet).
# @param testref (optional) reference (to a HASH REF) where this function shall put the
# executed tests
# @param portname (optional) serial port to use
# @param intermediate_cb (optional) reference to a function to call after each test
......@@ -176,7 +153,7 @@ sub _test_fi_uart {
sub download_auto ($) {
my $msg;
my $logger = get_logger("");
my ($self, $testref, $portname, $intermediate_cb, $wait_for_ready_ref) = @_;
my ($self, $run_ref, $testref, $portname, $intermediate_cb) = @_;
my $fiji_tests = $self->{'fiji_tests'};
my $fiji_design_consts = $self->{'fiji_settings'}->{'design'};
......@@ -207,7 +184,7 @@ sub download_auto ($) {
$logger->info("Downloading test $ti.");
$recv_msg = $self->_download_test(@{$fiji_tests->{'tests'}}[$ti], $port, 0, $wait_for_ready_ref);
$recv_msg = $self->_download_test($run_ref, @{$fiji_tests->{'tests'}}[$ti], $port, 0);
return $recv_msg if (ref($recv_msg) ne "HASH");
......@@ -253,6 +230,8 @@ sub download_auto ($) {
## @method public download_auto (%$testref, $portname, &$intermediate_cb)
# @brief Download randomly generated tests
#
# \param run_ref a reference to a boolean indicating that no abort is requested (yet).
# @param testref (optional) reference where this function shall put the
# executed tests
# @param portname (optional) serial port to use
......@@ -261,7 +240,7 @@ sub download_auto ($) {
# @returns HASH containing the last received message if successfully sent
sub download_random ($$$;$) {
my $logger = get_logger("");
my ($self, $testref, $portname, $intermediate_cb, $wait_for_ready_ref) = @_;
my ($self, $run_ref, $testref, $portname, $intermediate_cb) = @_;
my $fiji_design_consts = $self->{'fiji_settings'}->{'design'};
my $fiji_tests_consts = $self->{'fiji_tests'}->{'design'};
......@@ -287,7 +266,7 @@ sub download_random ($$$;$) {
return $temp_test if (!ref($temp_test));
$tests[$ti] = $temp_test;
$logger->info("=== Test $ti ===");
$recv_msg = $self->_download_test($tests[$ti++], $port, 0, $wait_for_ready_ref);
$recv_msg = $self->_download_test($run_ref, $tests[$ti++], $port, 0);
return $recv_msg if (ref($recv_msg) ne "HASH");
$check = $self->_check_halt($recv_msg);
$cont = &$intermediate_cb($recv_msg);
......@@ -311,12 +290,14 @@ sub download_random ($$$;$) {
## @method download_manual
# @brief Download manually defined tests prompted from <STDIN>
# @param portname (optional) the serial port to use
#
# @param run_ref a reference to a boolean indicating that no abort is requested (yet).
# @param portname (optional) the serial port to use
sub download_manual ($;$) {
my $msg;
my $logger = get_logger("");
my ($self, $portname, $wait_for_ready_ref) = @_;
my ($self, $run_ref, $portname) = @_;
my $fiji_design_consts = $self->{'fiji_settings'}->{'design'};
my $fiji_tests_consts = $self->{'fiji_tests'}->{'design'};
......@@ -332,7 +313,7 @@ sub download_manual ($;$) {
while (1) {
my $test = $self->_get_test_from_stdin();
my $recv_msg = $self->_download_test($test, $port, 0, $wait_for_ready_ref);
my $recv_msg = $self->_download_test($run_ref, $test, $port, 0);
return $recv_msg if (ref($recv_msg) ne "HASH");
......@@ -438,7 +419,7 @@ sub _get_test_from_stdin {
sub get_fic_status ($$) {
my $logger = get_logger("");
my ($self, $portname, $wait_for_ready_ref) = @_;
my ($self, $run_ref, $portname) = @_;
# generate empty test
my $test = {};
......@@ -447,7 +428,7 @@ sub get_fic_status ($$) {
my $port = FIJI::Connection->init($portname, $self->{'fiji_settings'}->{'design'}->{'BAUDRATE'})
or $logger->fatal("Could not init UART.")
and return "Could not init UART.";
return $self->_download_test($test, $port, 1, $wait_for_ready_ref);
return $self->_download_test($run_ref, $test, $port, 1);
}
## @method public download_test (%$test, $portname)
......@@ -458,13 +439,13 @@ sub get_fic_status ($$) {
# @returns HASH returned by _test_fi_uart() containing the decoded return message
sub download_test ($$) {
my $logger = get_logger("");
my ($self, $test, $portname, $wait_for_ready_ref) = @_;
my ($self, $run_ref, $test, $portname) = @_;
my $port = FIJI::Connection->init($portname, $self->{'fiji_settings'}->{'design'}->{'BAUDRATE'})
or $logger->fatal("Could not init UART.")
and return "Could not init UART.";
return $self->_download_test($test, $port, 0, $wait_for_ready_ref);
return $self->_download_test($run_ref, $test, $port, 0);
}
sub update_dur($) {
......@@ -503,6 +484,8 @@ sub update_prob($) {
## @method private _download_test (%$test, $port)
# @brief Download a single test defined by a test hash
#
# \param run_ref a reference to a boolean indicating that no abort is requested (yet).
# @param test The hash defining the test
# - test->{'TIMER_VALUE_1'}
# - test->{'TIMER_VALUE_2'}
......@@ -512,11 +495,10 @@ sub update_prob($) {
# @param port (optional) serial port to use
sub _download_test {
my $logger = get_logger("");
my ($self, $test, $port, $dryrun, $wait_for_ready_ref) = @_;
my ($self, $run_ref, $test, $port, $dryrun, $block_till_ready, $wait_for_ready) = @_;
$dryrun = 0 if !defined $dryrun;
my $fiji_tests = $self->{'fiji_tests'};
my $fiji_design_consts = $self->{'fiji_settings'}->{'design'};
my @payload;
......@@ -551,9 +533,25 @@ sub _download_test {
$logger->debug(sprintf("reset is %sabled.", $reset == 0 ? "dis" : "en"));
# download test via serial
# Default to NOT block before communication but to wait afterwards
$block_till_ready = 0 if !ref($block_till_ready);
$wait_for_ready = 1 if !ref($wait_for_ready);
$logger->trace("dryrun = $dryrun, block_till_ready = $block_till_ready, wait_for_ready = $wait_for_ready");
# my @payload = map hex($_), $cfg_str =~ /(..)/g; # @TODO: how to do this with unpack?
my %config = (
payload => \@payload,
t1_duration => $t1_duration,
t2_duration => $t2_duration,
trigger_en => $trigger_en,
trigger_ext => $trigger_ext,
reset => $reset,
consts => $fiji_design_consts,
dryrun => $dryrun,
);
my $recv_msg = _test_fi_uart($port, \@payload, $t1_duration, $t2_duration, $trigger_en, $trigger_ext, $reset, $fiji_design_consts, $dryrun, $wait_for_ready_ref);
# Download test via serial
my $recv_msg = $port->send_config(\%config, $run_ref, $block_till_ready, $wait_for_ready);
if (ref($recv_msg) eq "HASH" && defined($recv_msg->{'msg_type'})) {
my $log_msg = "Received " . $recv_msg->{'msg_type'} . " message";
$log_msg .= sprintf(": U=%d, I=%d, C=%d, F1=%d, F2=%d,", $recv_msg->{'error'}->{'U'}, $recv_msg->{'error'}->{'I'}, $recv_msg->{'error'}->{'C'}, $recv_msg->{'fault_detect'}->{'1'}, $recv_msg->{'fault_detect'}->{'2'}) if (defined($recv_msg->{'error'}));
......
......@@ -138,15 +138,15 @@ sub main {
# Check mode and execute tests accordingly
if ($cfg->{'mode'} eq "auto") {
$rv = $fiji_downloader->download_auto(\$new_tests, $cfg->{'portname'});
$rv = $fiji_downloader->download_auto(\1, \$new_tests, $cfg->{'portname'});
} elsif ($cfg->{'mode'} eq "manual") {
$rv = $fiji_downloader->download_manual($cfg->{'portname'});
$rv = $fiji_downloader->download_manual(\1, $cfg->{'portname'});
} elsif ($cfg->{'mode'} eq "random") {
$rv = $fiji_downloader->update_dur($dur);
if (!defined $rv) {
$rv = $fiji_downloader->update_prob($prob);
if(!defined $rv) {
$rv = $fiji_downloader->download_random(\$new_tests, $cfg->{'portname'});
$rv = $fiji_downloader->download_random(\1, \$new_tests, $cfg->{'portname'});
}
}
}
......
......@@ -146,6 +146,7 @@ sub download_worker {
# download tests according to mode
if ($item->{'mode'} eq "auto") {
$worker_msg = $dl->download_auto(
\$cont,
\$testref,
$item->{'uart'},
sub {
......@@ -155,10 +156,10 @@ sub download_worker {
$queue_to_gui->enqueue({'state' => "ongoing", 'rmsg' => $worker_msg});
return $cont;
},
\$cont,
);
} elsif ($item->{'mode'} eq "random") {
$worker_msg = $dl->download_random(
\$cont,
\$testref,
$item->{'uart'},
sub {
......@@ -168,16 +169,15 @@ sub download_worker {
$queue_to_gui->enqueue({'state' => "ongoing", 'rmsg' => $worker_msg});
return $cont;
},
\$cont,
);
} elsif ($item->{'mode'} eq "manual") {
$worker_msg = $dl->download_test(
\$cont,
$item->{'test'},
$item->{'uart'},
\$cont,
);
} elsif ($item->{'mode'} eq "dryrun") {
$worker_msg = $dl->get_fic_status($item->{'uart'}, \$cont);
$worker_msg = $dl->get_fic_status(\$cont, $item->{'uart'});
}
# reply to GUI (last message of current work package)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment