Commit 8f3c8d57 authored by Miguel Jimenez Lopez's avatar Miguel Jimenez Lopez

sw: Add comments for irq-demo

parent 4bf95691
...@@ -30,6 +30,21 @@ ...@@ -30,6 +30,21 @@
/* Static data for signal handlers */ /* Static data for signal handlers */
static fmc_dio_device global_fmc_dev = NULL; static fmc_dio_device global_fmc_dev = NULL;
/*
* irq-demo /dev/<fmc-device-file> [<irq period>]
* To exit: Please press 'q' in the keyboard or send a stop signal (CNTR+C)
*
* This DEMO shows the behavior of the interrupts for the FMC DIO device. The basic operation
* is to get all the timestamps generated by the FMC DIO channel and compute a basic statistics
* taking into consideration the system time such as time difference, mean and standard deviation.
*
* In order to work properly, it uses several resources that can be found in under dep folder:
* - loggers: General implementation for logs generation. Two kind of loggers are supported now:
* - printf-log: It uses the stdout for messages.
* - file-log: It uses a specific file for messages.
* - fmc-dio-device: Implementation of FMC DIO device functionalities.
* - stats-engine: Statistics engine code. It contains all the logic to compute the different metrics
*/
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
fmc_dio_device dev; fmc_dio_device dev;
...@@ -42,59 +57,96 @@ int main(int argc, char *argv[]) ...@@ -42,59 +57,96 @@ int main(int argc, char *argv[])
stats_engine sengine; stats_engine sengine;
int ret = 0; int ret = 0;
/* Initialize signal handler for force exit */
signal(SIGINT, exit_abruptly); signal(SIGINT, exit_abruptly);
signal(SIGQUIT, exit_abruptly); signal(SIGQUIT, exit_abruptly);
/* Create the loggers: One for stdout and the other for a specific file */
gen_log = create_printf_log_device(); gen_log = create_printf_log_device();
stats_log = create_file_log_device(STATS_LOG_PATH); stats_log = create_file_log_device(STATS_LOG_PATH);
/* Loggers are stored in array:
* -[0]: General logger for stdout
* -[1]: File logger for stats
*/
logs[0] = gen_log; logs[0] = gen_log;
logs[1] = stats_log; logs[1] = stats_log;
/* Parse user arguments (FMC DIO dev entry path and optionally irq period) */
user_arguments = create_user_arguments(); user_arguments = create_user_arguments();
if(parse_user_arguments(argc, argv, user_arguments)) { if(parse_user_arguments(argc, argv, user_arguments)) {
/* In case of failure, show the help message and exit */
show_help(); show_help();
ret = 1; ret = 1;
goto out_log; goto out_log;
} }
/* Create stats engine to compute timestamps metrics (difference, mean, stdev) */
sengine = create_stats_engine(); sengine = create_stats_engine();
if(check_stats_engine(sengine)) { if(check_stats_engine(sengine)) {
/* In case of failure, exit */
ret = 1; ret = 1;
goto out_user_args; goto out_user_args;
} }
/* Attach loggers to stats engine
* This allows the engine to generate output messages for the stdout and log file
*/
attach_log_devices_to_stats_engine(sengine, logs, n_logs); attach_log_devices_to_stats_engine(sengine, logs, n_logs);
/* Enable log for stats engine (by default is disabled) */
enable_log_for_stats_engine(sengine); enable_log_for_stats_engine(sengine);
/* Create FMC DIO device using user arguments */
dev = create_fmc_dio_device(user_arguments->fmc_dev_path); dev = create_fmc_dio_device(user_arguments->fmc_dev_path);
if(open_fmc_dio_device(dev)) { if(open_fmc_dio_device(dev)) {
/* In case of failure, exit */
ret = 1; ret = 1;
goto out_stats_engine; goto out_stats_engine;
} }
/*
* Attach loggers to FMC DIO device
* This allows the FMC DIO to generate output messages for the stdout and log file
*/
attach_log_devices_to_fmc_dio_device(dev, logs, n_logs); attach_log_devices_to_fmc_dio_device(dev, logs, n_logs);
enable_log_for_fmc_dio_device(dev); enable_log_for_fmc_dio_device(dev);
/* Before starting IRQ demo, Interrupts should be properly configured:
* 1) Disable all interrupts
* 2) Enable the TEST_FMC_DIO_CH interrupt line
* 3) Setup specific information for interrupt line (period from user arguments or default one)
*/
disable_fmc_dio_device_all_irq(dev); disable_fmc_dio_device_all_irq(dev);
enable_fmc_dio_device_irq(dev, TEST_FMC_DIO_CH); enable_fmc_dio_device_irq(dev, TEST_FMC_DIO_CH);
setup_fmc_dio_device_irq(dev, user_arguments->irq_period, TEST_FMC_DIO_COUNT); setup_fmc_dio_device_irq(dev, user_arguments->irq_period, TEST_FMC_DIO_COUNT);
/* Configure stdin as non-blocking. It is required for the user check exit function */
set_stdin_as_nonblocking(); set_stdin_as_nonblocking();
/* Save FMC DIO dev in globals for the signal handlers */
global_fmc_dev = dev; global_fmc_dev = dev;
/* Main loop of IRQ demo (until user requests to exit) */
while(!user_stop) { while(!user_stop) {
/* Main logic funtion (get timestamps and process them in the stats engine) */
demo_irq_process_loop(dev, sengine); demo_irq_process_loop(dev, sengine);
/* Check if user has requested to exit */
user_stop = check_user_stop(); user_stop = check_user_stop();
} }
/* Exit sequence */
/* Disable all interrupts */
disable_fmc_dio_device_all_irq(dev); disable_fmc_dio_device_all_irq(dev);
out_fmc_dio_device: out_fmc_dio_device:
/* Close FMC DIO device */
close_fmc_dio_device(dev); close_fmc_dio_device(dev);
out_stats_engine: out_stats_engine:
/* Close stats engine */
destroy_stats_engine(sengine); destroy_stats_engine(sengine);
out_user_args: out_user_args:
/* Free resources for user arguments */
destroy_user_arguments(user_arguments); destroy_user_arguments(user_arguments);
out_log: out_log:
/* Close loggers */
destroy_log_device(stats_log); destroy_log_device(stats_log);
destroy_log_device(gen_log); destroy_log_device(gen_log);
...@@ -105,6 +157,12 @@ static void demo_irq_process_loop(fmc_dio_device fmc_dev, stats_engine engine) ...@@ -105,6 +157,12 @@ static void demo_irq_process_loop(fmc_dio_device fmc_dev, stats_engine engine)
{ {
struct timespec *ts; struct timespec *ts;
unsigned int nts; unsigned int nts;
/* Process loop:
* - Get timestamps from FMC DIO device (specific channel under testing)
* - Pass them to the stats engine and generate the statistics
* - Sleep for a while to avoid excesive CPU consumption
*/
while(!get_utc_ts_from_fmc_dio_device(fmc_dev, TEST_FMC_DIO_CH, &ts, &nts)) { while(!get_utc_ts_from_fmc_dio_device(fmc_dev, TEST_FMC_DIO_CH, &ts, &nts)) {
process_timestamps_to_engine(engine, ts, nts); process_timestamps_to_engine(engine, ts, nts);
usleep(PROCESS_SLEEP_US); usleep(PROCESS_SLEEP_US);
...@@ -115,9 +173,13 @@ static void process_timestamps_to_engine(stats_engine engine, struct timespec *t ...@@ -115,9 +173,13 @@ static void process_timestamps_to_engine(stats_engine engine, struct timespec *t
unsigned int nts) unsigned int nts)
{ {
for(int i = 0 ; i < nts ; i++) { for(int i = 0 ; i < nts ; i++) {
/* Pass a timestamp to stats engine */
add_usr_timestamp_to_stats_engine(engine, &ts[i]); add_usr_timestamp_to_stats_engine(engine, &ts[i]);
/* Compute stats taking into consideration all the timestamps inside the engine */
run_stats_engine(engine); run_stats_engine(engine);
} }
/* Finally, free memory for timestamps (reserved by FMC DIO device) */
free(ts); free(ts);
} }
......
Markdown is supported
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