You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

202 lines
5.3 KiB

/*
Copyright Jeroen Vreeken (pe1rxq@amsat.org), 2007 - 2018
Copyright Stichting C.A. Muller Radioastronomiestation, 2007 - 2013
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
dt_ctrl.c
Main loop for the DT controller.
Here the controller network is initialized.
(By loading a .ctrl file supplied on the command line).
After initialization the sample thread is started and this function's
work is done.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <signal.h>
#include "dynarg.h"
#include <controller/controller_bus.h>
#include <controller/controller_block.h>
#include <controller/controller_trace.h>
#include <controller/controller_sample.h>
#include <controller/controller_dumpdot.h>
#include <controller/controller_load.h>
#include <controller/controller_time.h>
#include <controller/controller_mem.h>
#include <shell/shell.h>
#include <log/log.h>
#include <dt_port_numbers.h>
#ifdef HAVE_EMBEDDED
extern char _binary_controller_ctrl_embedded_ctrl_start;
extern char _binary_controller_ctrl_embedded_ctrl_end;
#endif
#ifdef HAVE_SYSTICK
#include <samx70.h>
#include <wdt.h>
#endif
int main(int argc, char **argv)
{
char *ctrl_filename;
char *dot_filename;
sigset_t sigset;
int blocks;
int outputs;
int i;
size_t usage_0, usage_r, usage_w, usage_rw;
#ifdef HAVE_FILEIO
sigemptyset (&sigset);
sigaddset(&sigset, SIGALRM);
sigprocmask(SIG_BLOCK, &sigset, NULL);
if (argc < 2) {
printf("Usage: %s <controllerfile>\n", argv[0]);
printf("\n");
printf("E.g.: %s dt_ctrl.ctrl\n", argv[0]);
goto err_init;
}
#endif
log_server_start(CTRL_LOG_PORT, LOG_T_DEBUG, LOG_T_INFO);
#ifndef HAVE_EMBEDDED
ctrl_filename = argv[1];
controller_load_variable_int_set("trace_server", 1);
/* Create and link blocks */
log_send(LOG_T_DEBUG, "Going to load controller file '%s'",
ctrl_filename);
if (controller_load(ctrl_filename)) {
log_send(LOG_T_ERROR, "Could not load controller file");
goto err_init;
}
#else
log_send(LOG_T_DEBUG, "Going to load embedded controller file");
if (controller_load_mem("ctrl_embedded",
&_binary_controller_ctrl_embedded_ctrl_start,
&_binary_controller_ctrl_embedded_ctrl_end - &_binary_controller_ctrl_embedded_ctrl_start))
goto err_init;
if (controller_block_link())
goto err_init;
#endif
if (controller_time_process() != 0) {
goto err_init;
}
blocks = controller_block_nr();
outputs = 0;
for (i = 0; i < blocks; i++) {
outputs += controller_block_get(i)->outputs;
}
#ifdef HAVE_TCP
if (controller_load_variable_int_get("trace_server"))
controller_trace_server_start(CTRL_TRACE_PORT, outputs);
controller_load_variable_int_set("shell", 0);
controller_load_variable_string_set("shell_intro", shell_intro);
controller_load_variable_string_set("shell_prompt", shell_prompt);
/* Start command shell */
if (controller_load_variable_int_get("shell")) {
controller_sample_shell_add();
controller_load_shell_add();
shell_intro = controller_load_variable_string_get("shell_intro");
shell_prompt = controller_load_variable_string_get("shell_prompt");
shell_server_start(CTRL_SHELL_PORT, 10);
}
#endif
#ifdef HAVE_FILEIO
asprintf(&dot_filename, "%s.dot", ctrl_filename);
controller_dumpdot(dot_filename);
free(dot_filename);
#endif
/* Start 'sample' */
if (controller_block_sample_init()) {
goto err_init;
}
controller_sample_start();
controller_mem_usage(0, &usage_0);
controller_mem_usage(CONTROLLER_MEM_PERIODIC_WRITE, &usage_w);
controller_mem_usage(CONTROLLER_MEM_PERIODIC_READ, &usage_r);
controller_mem_usage(CONTROLLER_MEM_PERIODIC_WRITE | CONTROLLER_MEM_PERIODIC_READ, &usage_rw);
log_send(LOG_T_DEBUG, "Memory usage: %zd bytes unused", usage_0);
log_send(LOG_T_DEBUG, "Memory usage: %zd bytes periodic read", usage_r);
log_send(LOG_T_DEBUG, "Memory usage: %zd bytes periodic write", usage_w);
log_send(LOG_T_DEBUG, "Memory usage: %zd bytes periodic read/write", usage_rw);
log_send(LOG_T_DEBUG, "Entering state polling loop");
int oks_p = 0, errors_p = 0, recoverables_p = 0;
while (1) {
int oks, errors, recoverables;
controller_bus_poll_states(&oks, &errors, &recoverables);
if (oks != oks_p) {
log_send(LOG_T_WARNING,
"Number of OK blocks changed: %d -> %d",
oks_p, oks);
oks_p = oks;
}
if (errors != errors_p) {
log_send(LOG_T_WARNING,
"Number of ERROR blocks changed: %d -> %d",
errors_p, errors);
errors_p = errors;
}
if (recoverables != recoverables_p) {
log_send(LOG_T_WARNING,
"Number of RECOVERABLE blocks changed: %d -> %d",
recoverables_p, recoverables);
recoverables_p = recoverables;
}
if (recoverables) {
controller_bus_recover();
}
#ifdef HAVE_SYSTICK
wdt_restart();
#endif
sleep(1);
}
return 0;
err_init:
log_server_flush();
return 1;
}