diff --git a/arch/posix/CMakeLists.txt b/arch/posix/CMakeLists.txt index fea0100017..9b96b49138 100644 --- a/arch/posix/CMakeLists.txt +++ b/arch/posix/CMakeLists.txt @@ -20,7 +20,7 @@ zephyr_link_libraries_ifdef(CONFIG_COVERAGE -lgcov ) -zephyr_compile_definitions(_POSIX_C_SOURCE=199309) +zephyr_compile_definitions(_POSIX_C_SOURCE=200809) zephyr_ld_options( -ldl diff --git a/boards/posix/native_posix/hw_models_top.c b/boards/posix/native_posix/hw_models_top.c index fe8f571a75..4585dd9187 100644 --- a/boards/posix/native_posix/hw_models_top.c +++ b/boards/posix/native_posix/hw_models_top.c @@ -5,10 +5,13 @@ */ /** - * Barebones HW model sufficient to run some of the sample apps + * Bare-bones HW model sufficient to run some of the sample apps + * and regression tests */ #include +#include +#include #include "hw_models_top.h" #include "timer_model.h" #include "irq_ctrl.h" @@ -33,6 +36,56 @@ static u64_t *Timer_list[NUMBER_OF_TIMERS] = { static u64_t next_timer_time; +/* Have we received a SIGTERM or SIGINT */ +static volatile sig_atomic_t signaled_end; + + +/** + * Handler for SIGTERM and SIGINT + */ +void hwm_signal_end_handler(int sig) +{ + signaled_end = 1; +} + +/** + * Set the handler for SIGTERM and SIGINT which will cause the + * program to exit gracefully when they are received the 1st time + * + * Note that our handler only sets a variable indicating the signal was + * received, and in each iteration of the hw main loop this variable is + * evaluated. + * If for some reason (the program is stuck) we never evaluate it, the program + * would never exit. + * Therefore we set SA_RESETHAND: This way, the 2nd time the signal is received + * the default handler would be called to terminate the program no matter what. + * + * Note that SA_RESETHAND requires either _POSIX_C_SOURCE>=200809 or + * _XOPEN_SOURCE>=500 + */ +void hwm_set_sig_handler(void) +{ + struct sigaction act; + int e; + + act.sa_handler = hwm_signal_end_handler; + e = sigemptyset(&act.sa_mask); + if (e) { + posix_print_error_and_exit("Error on sigemptyset()\n"); + } + + act.sa_flags = SA_RESETHAND; + + e = sigaction(SIGTERM, &act, NULL); + if (e) { + posix_print_error_and_exit("Error on sigaction()\n"); + } + e = sigaction(SIGINT, &act, NULL); + if (e) { + posix_print_error_and_exit("Error on sigaction()\n"); + } +} + static void hwm_sleep_until_next_timer(void) { @@ -46,9 +99,9 @@ static void hwm_sleep_until_next_timer(void) next_timer_index); } - if (device_time >= end_of_time) { - posix_print_trace("\n\n\n\n\n\nAutostopped after %.3Lfs\n", - ((long double)end_of_time)/1.0e6); + if (signaled_end || (device_time >= end_of_time)) { + posix_print_trace("\nStopped after %.3Lfs\n", + ((long double)device_time)/1.0e6); main_clean_up(0); } @@ -120,6 +173,7 @@ u64_t hwm_get_time(void) */ void hwm_init(void) { + hwm_set_sig_handler(); hwtimer_init(); hw_irq_ctrl_init(); diff --git a/boards/posix/native_posix/main.c b/boards/posix/native_posix/main.c index 24d0772591..92ee99d95e 100644 --- a/boards/posix/native_posix/main.c +++ b/boards/posix/native_posix/main.c @@ -6,7 +6,7 @@ /* * The basic principle of operation is: - * No asynchronous behavior, no undeterminism. + * No asynchronous behavior, no indeterminism. * If you run the same thing 20 times, you get exactly the same result 20 * times. * It does not matter if you are running from console, or in a debugger @@ -15,7 +15,7 @@ * This is achieved as follows: * The HW models run in their own simulated time. We do really not attempt * to link ourselves to the actual real time / wall time of the machine as this - * would make execution undeterministic and debugging or instrumentation not + * would make execution indeterministic and debugging or instrumentation not * really possible. Although we may slow the run to real time. */ @@ -42,12 +42,13 @@ void main_clean_up(int exit_code) exit(exit_code); } + /** * This is the actual main for the Linux process, * the Zephyr application main is renamed something else thru a define. * * Note that normally one wants to use this POSIX arch to be part of a - * simulation engine, with some proper HW models and whatnot + * simulation engine, with some proper HW models and what not * * This is just a very simple demo which is able to run some of the sample * apps (hello world, synchronization, philosophers) and run the sanity-check diff --git a/boards/posix/native_posix/timer_model.c b/boards/posix/native_posix/timer_model.c index 3d74b701ce..b41ad96324 100644 --- a/boards/posix/native_posix/timer_model.c +++ b/boards/posix/native_posix/timer_model.c @@ -76,11 +76,7 @@ static void hwtimer_tick_timer_reached(void) requested_time.tv_sec = diff / 1e6; requested_time.tv_nsec = (diff - requested_time.tv_sec*1e6)*1e3; - int s = nanosleep(&requested_time, &remaining); - - if (s == -1) { - posix_print_trace("Interrupted or error\n"); - } + nanosleep(&requested_time, &remaining); } #endif