LCOV - code coverage report
Current view: top level - home/runner/zephyrproject/zephyr/boards/native/native_posix - timer_model.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 28 158 17.7 %
Date: 2024-09-16 20:15:30 Functions: 5 28 17.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 2 22 9.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2017 Oticon A/S
       3                 :            :  *
       4                 :            :  * SPDX-License-Identifier: Apache-2.0
       5                 :            :  */
       6                 :            : 
       7                 :            : /**
       8                 :            :  * This provides a model of:
       9                 :            :  *  - A system tick
      10                 :            :  *  - A real time clock
      11                 :            :  *  - A one shot HW timer which can be used to awake the CPU at a given time
      12                 :            :  *  - The clock source for all of this, and therefore for native_posix
      13                 :            :  *
      14                 :            :  * Please see doc/board.rst for more information, specially sections:
      15                 :            :  *  About time in native_posix
      16                 :            :  *  Peripherals:
      17                 :            :  *      Clock source, system tick and timer
      18                 :            :  *      Real time clock
      19                 :            :  */
      20                 :            : 
      21                 :            : #include <stdint.h>
      22                 :            : #include <time.h>
      23                 :            : #include <stdbool.h>
      24                 :            : #include <math.h>
      25                 :            : #include "hw_models_top.h"
      26                 :            : #include "irq_ctrl.h"
      27                 :            : #include "board_soc.h"
      28                 :            : #include <zephyr/types.h>
      29                 :            : #include <zephyr/arch/posix/posix_trace.h>
      30                 :            : #include <zephyr/sys/util.h>
      31                 :            : #include "cmdline.h"
      32                 :            : #include "posix_native_task.h"
      33                 :            : 
      34                 :            : #define DEBUG_NP_TIMER 0
      35                 :            : 
      36                 :            : #if DEBUG_NP_TIMER
      37                 :            : 
      38                 :            : /**
      39                 :            :  * Helper function to convert a 64 bit time in microseconds into a string.
      40                 :            :  * The format will always be: hh:mm:ss.ssssss\0
      41                 :            :  *
      42                 :            :  * Note: the caller has to allocate the destination buffer (at least 17 chars)
      43                 :            :  */
      44                 :            : #include <stdio.h>
      45                 :            : static char *us_time_to_str(char *dest, uint64_t time)
      46                 :            : {
      47                 :            :         if (time != NEVER) {
      48                 :            :                 unsigned int hour;
      49                 :            :                 unsigned int minute;
      50                 :            :                 unsigned int second;
      51                 :            :                 unsigned int us;
      52                 :            : 
      53                 :            :                 hour   = (time / 3600U / 1000000U) % 24;
      54                 :            :                 minute = (time / 60U / 1000000U) % 60;
      55                 :            :                 second = (time / 1000000U) % 60;
      56                 :            :                 us     = time % 1000000;
      57                 :            : 
      58                 :            :                 sprintf(dest, "%02u:%02u:%02u.%06u", hour, minute, second, us);
      59                 :            :         } else {
      60                 :            :                 sprintf(dest, " NEVER/UNKNOWN ");
      61                 :            : 
      62                 :            :         }
      63                 :            :         return dest;
      64                 :            : }
      65                 :            : #endif
      66                 :            : 
      67                 :            : uint64_t hw_timer_timer;
      68                 :            : 
      69                 :            : uint64_t hw_timer_tick_timer;
      70                 :            : uint64_t hw_timer_awake_timer;
      71                 :            : 
      72                 :            : static uint64_t tick_p; /* Period of the ticker */
      73                 :            : static int64_t silent_ticks;
      74                 :            : 
      75                 :            : static bool real_time_mode =
      76                 :            : #if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME)
      77                 :            :         true;
      78                 :            : #else
      79                 :            :         false;
      80                 :            : #endif
      81                 :            : 
      82                 :            : static bool reset_rtc; /*"Reset" the RTC on boot*/
      83                 :            : 
      84                 :            : /*
      85                 :            :  * When this executable started running, this value shall not be changed after
      86                 :            :  * boot
      87                 :            :  */
      88                 :            : static uint64_t boot_time;
      89                 :            : 
      90                 :            : /*
      91                 :            :  * Ratio of the simulated clock to the real host time
      92                 :            :  * For ex. a clock_ratio = 1+100e-6 means the simulated time is 100ppm faster
      93                 :            :  * than real time
      94                 :            :  */
      95                 :            : static double clock_ratio = 1.0;
      96                 :            : 
      97                 :            : #if DEBUG_NP_TIMER
      98                 :            : /*
      99                 :            :  * Offset of the simulated time vs the real host time due to drift/clock ratio
     100                 :            :  * until "last_radj_*time"
     101                 :            :  *
     102                 :            :  * A positive value means simulated time is ahead of the host time
     103                 :            :  *
     104                 :            :  * This variable is only kept for debugging purposes
     105                 :            :  */
     106                 :            : static int64_t last_drift_offset;
     107                 :            : #endif
     108                 :            : 
     109                 :            : /*
     110                 :            :  * Offsets of the RTC relative to the hardware models simu_time
     111                 :            :  * "simu_time" == simulated time which starts at 0 on boot
     112                 :            :  */
     113                 :            : static int64_t rtc_offset;
     114                 :            : 
     115                 :            : /* Last host/real time when the ratio was adjusted */
     116                 :            : static uint64_t last_radj_rtime;
     117                 :            : /* Last simulated time when the ratio was adjusted */
     118                 :            : static uint64_t last_radj_stime;
     119                 :            : 
     120                 :            : extern uint64_t posix_get_hw_cycle(void);
     121                 :            : 
     122                 :          0 : void hwtimer_set_real_time_mode(bool new_rt)
     123                 :            : {
     124                 :          0 :         real_time_mode = new_rt;
     125                 :          0 : }
     126                 :            : 
     127                 :          2 : static void hwtimer_update_timer(void)
     128                 :            : {
     129                 :          2 :         hw_timer_timer = MIN(hw_timer_tick_timer, hw_timer_awake_timer);
     130                 :          2 : }
     131                 :            : 
     132                 :          0 : static inline void host_clock_gettime(struct timespec *tv)
     133                 :            : {
     134                 :            : #if defined(CLOCK_MONOTONIC_RAW)
     135                 :          0 :         clock_gettime(CLOCK_MONOTONIC_RAW, tv);
     136                 :            : #else
     137                 :            :         clock_gettime(CLOCK_MONOTONIC, tv);
     138                 :            : #endif
     139                 :          0 : }
     140                 :            : 
     141                 :          0 : uint64_t get_host_us_time(void)
     142                 :            : {
     143                 :          0 :         struct timespec tv;
     144                 :            : 
     145                 :          0 :         host_clock_gettime(&tv);
     146                 :          0 :         return (uint64_t)tv.tv_sec * 1e6 + tv.tv_nsec / 1000;
     147                 :            : }
     148                 :            : 
     149                 :          1 : void hwtimer_init(void)
     150                 :            : {
     151                 :          1 :         silent_ticks = 0;
     152                 :          1 :         hw_timer_tick_timer = NEVER;
     153                 :          1 :         hw_timer_awake_timer = NEVER;
     154                 :          1 :         hwtimer_update_timer();
     155         [ -  + ]:          1 :         if (real_time_mode) {
     156                 :          0 :                 boot_time = get_host_us_time();
     157                 :          0 :                 last_radj_rtime = boot_time;
     158                 :          0 :                 last_radj_stime = 0U;
     159                 :            :         }
     160         [ +  - ]:          1 :         if (!reset_rtc) {
     161                 :          1 :                 struct timespec tv;
     162                 :          1 :                 uint64_t realhosttime;
     163                 :            : 
     164                 :          1 :                 clock_gettime(CLOCK_REALTIME, &tv);
     165                 :          1 :                 realhosttime = (uint64_t)tv.tv_sec * 1e6 + tv.tv_nsec / 1000;
     166                 :            : 
     167                 :          1 :                 rtc_offset += realhosttime;
     168                 :            :         }
     169                 :          1 : }
     170                 :            : 
     171                 :          1 : void hwtimer_cleanup(void)
     172                 :            : {
     173                 :            : 
     174                 :          1 : }
     175                 :            : 
     176                 :            : /**
     177                 :            :  * Enable the HW timer tick interrupts with a period <period> in microseconds
     178                 :            :  */
     179                 :          1 : void hwtimer_enable(uint64_t period)
     180                 :            : {
     181                 :          1 :         tick_p = period;
     182                 :          1 :         hw_timer_tick_timer = hwm_get_time() + tick_p;
     183                 :          1 :         hwtimer_update_timer();
     184                 :          1 :         hwm_find_next_timer();
     185                 :          1 : }
     186                 :            : 
     187                 :          0 : static void hwtimer_tick_timer_reached(void)
     188                 :            : {
     189         [ #  # ]:          0 :         if (real_time_mode) {
     190                 :          0 :                 uint64_t expected_rt = (hw_timer_tick_timer - last_radj_stime)
     191                 :          0 :                                     / clock_ratio
     192                 :          0 :                                     + last_radj_rtime;
     193                 :          0 :                 uint64_t real_time = get_host_us_time();
     194                 :            : 
     195                 :          0 :                 int64_t diff = expected_rt - real_time;
     196                 :            : 
     197                 :            : #if DEBUG_NP_TIMER
     198                 :            :                 char es[30];
     199                 :            :                 char rs[30];
     200                 :            : 
     201                 :            :                 us_time_to_str(es, expected_rt - boot_time);
     202                 :            :                 us_time_to_str(rs, real_time - boot_time);
     203                 :            :                 printf("tick @%5llims: diff = expected_rt - real_time = "
     204                 :            :                         "%5lli = %s - %s\n",
     205                 :            :                         hw_timer_tick_timer/1000U, diff, es, rs);
     206                 :            : #endif
     207                 :            : 
     208         [ #  # ]:          0 :                 if (diff > 0) { /* we need to slow down */
     209                 :          0 :                         struct timespec requested_time;
     210                 :          0 :                         struct timespec remaining;
     211                 :            : 
     212                 :          0 :                         requested_time.tv_sec  = diff / 1e6;
     213                 :          0 :                         requested_time.tv_nsec = (diff -
     214                 :          0 :                                                  requested_time.tv_sec*1e6)*1e3;
     215                 :            : 
     216                 :          0 :                         (void) nanosleep(&requested_time, &remaining);
     217                 :            :                 }
     218                 :            :         }
     219                 :            : 
     220                 :          0 :         hw_timer_tick_timer += tick_p;
     221                 :          0 :         hwtimer_update_timer();
     222                 :            : 
     223         [ #  # ]:          0 :         if (silent_ticks > 0) {
     224                 :          0 :                 silent_ticks -= 1;
     225                 :            :         } else {
     226                 :          0 :                 hw_irq_ctrl_set_irq(TIMER_TICK_IRQ);
     227                 :            :         }
     228                 :          0 : }
     229                 :            : 
     230                 :          0 : static void hwtimer_awake_timer_reached(void)
     231                 :            : {
     232                 :          0 :         hw_timer_awake_timer = NEVER;
     233                 :          0 :         hwtimer_update_timer();
     234                 :          0 :         hw_irq_ctrl_set_irq(PHONY_HARD_IRQ);
     235                 :          0 : }
     236                 :            : 
     237                 :          0 : void hwtimer_timer_reached(void)
     238                 :            : {
     239                 :          0 :         uint64_t Now = hw_timer_timer;
     240                 :            : 
     241         [ #  # ]:          0 :         if (hw_timer_awake_timer == Now) {
     242                 :          0 :                 hwtimer_awake_timer_reached();
     243                 :            :         }
     244                 :            : 
     245         [ #  # ]:          0 :         if (hw_timer_tick_timer == Now) {
     246                 :          0 :                 hwtimer_tick_timer_reached();
     247                 :            :         }
     248                 :          0 : }
     249                 :            : 
     250                 :            : /**
     251                 :            :  * The timer HW will awake the CPU (without an interrupt) at least when <time>
     252                 :            :  * comes (it may awake it earlier)
     253                 :            :  *
     254                 :            :  * If there was a previous request for an earlier time, the old one will prevail
     255                 :            :  *
     256                 :            :  * This is meant for k_busy_wait() like functionality
     257                 :            :  */
     258                 :          0 : void hwtimer_wake_in_time(uint64_t time)
     259                 :            : {
     260         [ #  # ]:          0 :         if (hw_timer_awake_timer > time) {
     261                 :          0 :                 hw_timer_awake_timer = time;
     262                 :          0 :                 hwtimer_update_timer();
     263                 :          0 :                 hwm_find_next_timer();
     264                 :            :         }
     265                 :          0 : }
     266                 :            : 
     267                 :            : /**
     268                 :            :  * The kernel wants to skip the next sys_ticks tick interrupts
     269                 :            :  * If sys_ticks == 0, the next interrupt will be raised.
     270                 :            :  */
     271                 :          0 : void hwtimer_set_silent_ticks(int64_t sys_ticks)
     272                 :            : {
     273                 :          0 :         silent_ticks = sys_ticks;
     274                 :          0 : }
     275                 :            : 
     276                 :          0 : int64_t hwtimer_get_pending_silent_ticks(void)
     277                 :            : {
     278                 :          0 :         return silent_ticks;
     279                 :            : }
     280                 :            : 
     281                 :            : 
     282                 :            : /**
     283                 :            :  * During boot set the real time clock simulated time not start
     284                 :            :  * from the real host time
     285                 :            :  */
     286                 :          0 : void hwtimer_reset_rtc(void)
     287                 :            : {
     288                 :          0 :         reset_rtc = true;
     289                 :          0 : }
     290                 :            : 
     291                 :            : /**
     292                 :            :  * Set a time offset (microseconds) of the RTC simulated time
     293                 :            :  * Note: This should not be used after starting
     294                 :            :  */
     295                 :          0 : void hwtimer_set_rtc_offset(int64_t offset)
     296                 :            : {
     297                 :          0 :         rtc_offset = offset;
     298                 :          0 : }
     299                 :            : 
     300                 :            : /**
     301                 :            :  * Set the ratio of the simulated time to host (real) time.
     302                 :            :  * Note: This should not be used after starting
     303                 :            :  */
     304                 :          0 : void hwtimer_set_rt_ratio(double ratio)
     305                 :            : {
     306                 :          0 :         clock_ratio = ratio;
     307                 :          0 : }
     308                 :            : 
     309                 :            : /**
     310                 :            :  * Increase or decrease the RTC simulated time by offset_delta
     311                 :            :  */
     312                 :          0 : void hwtimer_adjust_rtc_offset(int64_t offset_delta)
     313                 :            : {
     314                 :          0 :         rtc_offset += offset_delta;
     315                 :          0 : }
     316                 :            : 
     317                 :            : /**
     318                 :            :  * Adjust the ratio of the simulated time by a factor
     319                 :            :  */
     320                 :          0 : void hwtimer_adjust_rt_ratio(double ratio_correction)
     321                 :            : {
     322                 :          0 :         uint64_t current_stime = hwm_get_time();
     323                 :          0 :         int64_t s_diff = current_stime - last_radj_stime;
     324                 :            :         /* Accumulated real time drift time since last adjustment: */
     325                 :            : 
     326                 :          0 :         last_radj_rtime += s_diff / clock_ratio;
     327                 :          0 :         last_radj_stime = current_stime;
     328                 :            : 
     329                 :            : #if DEBUG_NP_TIMER
     330                 :            :         char ct[30];
     331                 :            :         int64_t r_drift = (long double)(clock_ratio-1.0)/(clock_ratio)*s_diff;
     332                 :            : 
     333                 :            :         last_drift_offset += r_drift;
     334                 :            :         us_time_to_str(ct, current_stime);
     335                 :            : 
     336                 :            :         printf("%s(): @%s, s_diff= %llius after last adjust\n"
     337                 :            :                 " during which we drifted %.3fms\n"
     338                 :            :                 " total acc drift (last_drift_offset) = %.3fms\n"
     339                 :            :                 " last_radj_rtime = %.3fms (+%.3fms )\n"
     340                 :            :                 " Ratio adjusted to %f\n",
     341                 :            :                 __func__, ct, s_diff,
     342                 :            :                 r_drift/1000.0,
     343                 :            :                 last_drift_offset/1000.0,
     344                 :            :                 last_radj_rtime/1000.0,
     345                 :            :                 s_diff/clock_ratio/1000.0,
     346                 :            :                 clock_ratio*ratio_correction);
     347                 :            : #endif
     348                 :            : 
     349                 :          0 :         clock_ratio *= ratio_correction;
     350                 :          0 : }
     351                 :            : 
     352                 :            : /**
     353                 :            :  * Return the current simulated RTC time in microseconds
     354                 :            :  */
     355                 :          0 : int64_t hwtimer_get_simu_rtc_time(void)
     356                 :            : {
     357                 :          0 :         return hwm_get_time() + rtc_offset;
     358                 :            : }
     359                 :            : 
     360                 :            : 
     361                 :            : /**
     362                 :            :  * Return a version of the host time which would have drifted as if the host
     363                 :            :  * real time clock had been running from the native_posix clock, and adjusted
     364                 :            :  * both in rate and in offsets as the native_posix has been.
     365                 :            :  *
     366                 :            :  * Note that this time may be significantly ahead of the simulated time
     367                 :            :  * (the time the Zephyr kernel thinks it is).
     368                 :            :  * This will be the case in general if native_posix is not able to run at or
     369                 :            :  * faster than real time.
     370                 :            :  */
     371                 :          0 : void hwtimer_get_pseudohost_rtc_time(uint32_t *nsec, uint64_t *sec)
     372                 :            : {
     373                 :            :         /*
     374                 :            :          * Note: long double has a 64bits mantissa in x86.
     375                 :            :          * Therefore to avoid loss of precision after 500 odd years into
     376                 :            :          * the epoch, we first calculate the offset from the last adjustment
     377                 :            :          * time split in us and ns. So we keep the full precision for 500 odd
     378                 :            :          * years after the last clock ratio adjustment (or native_posix boot,
     379                 :            :          * whichever is latest).
     380                 :            :          * Meaning, we will still start to loose precision after 500 off
     381                 :            :          * years of runtime without a clock ratio adjustment, but that really
     382                 :            :          * should not be much of a problem, given that the ns lower digits are
     383                 :            :          * pretty much noise anyhow.
     384                 :            :          * (So, all this is a huge overkill)
     385                 :            :          *
     386                 :            :          * The operation below in plain is just:
     387                 :            :          *   st = (rt - last_rt_adj_time)*ratio + last_dt_adj_time
     388                 :            :          * where st = simulated time
     389                 :            :          *       rt = real time
     390                 :            :          *       last_rt_adj_time = time (real) when the last ratio
     391                 :            :          *                          adjustment took place
     392                 :            :          *       last_st_adj_time = time (simulated) when the last ratio
     393                 :            :          *                          adjustment took place
     394                 :            :          *       ratio = ratio between simulated time and real time
     395                 :            :          */
     396                 :          0 :         struct timespec tv;
     397                 :            : 
     398                 :          0 :         host_clock_gettime(&tv);
     399                 :            : 
     400                 :          0 :         uint64_t rt_us = (uint64_t)tv.tv_sec * 1000000ULL + tv.tv_nsec / 1000;
     401                 :          0 :         uint32_t rt_ns = tv.tv_nsec % 1000;
     402                 :            : 
     403                 :          0 :         long double drt_us = (long double)rt_us - last_radj_rtime;
     404                 :          0 :         long double drt_ns = drt_us * 1000.0L + (long double)rt_ns;
     405                 :          0 :         long double st = drt_ns * (long double)clock_ratio +
     406                 :          0 :                          (long double)(last_radj_stime + rtc_offset) * 1000.0L;
     407                 :            : 
     408                 :          0 :         *nsec = fmodl(st, 1e9L);
     409                 :          0 :         *sec = st / 1e9L;
     410                 :          0 : }
     411                 :            : 
     412                 :            : static struct {
     413                 :            :         double stop_at;
     414                 :            :         double rtc_offset;
     415                 :            :         double rt_drift;
     416                 :            :         double rt_ratio;
     417                 :            : } args;
     418                 :            : 
     419                 :          0 : static void cmd_stop_at_found(char *argv, int offset)
     420                 :            : {
     421                 :          0 :         ARG_UNUSED(offset);
     422         [ #  # ]:          0 :         if (args.stop_at < 0) {
     423                 :          0 :                 posix_print_error_and_exit("Error: stop-at must be positive "
     424                 :            :                                            "(%s)\n", argv);
     425                 :            :         }
     426                 :          0 :         hwm_set_end_of_time(args.stop_at*1e6);
     427                 :          0 : }
     428                 :            : 
     429                 :          0 : static void cmd_realtime_found(char *argv, int offset)
     430                 :            : {
     431                 :          0 :         ARG_UNUSED(argv);
     432                 :          0 :         ARG_UNUSED(offset);
     433                 :          0 :         hwtimer_set_real_time_mode(true);
     434                 :          0 : }
     435                 :            : 
     436                 :          0 : static void cmd_no_realtime_found(char *argv, int offset)
     437                 :            : {
     438                 :          0 :         ARG_UNUSED(argv);
     439                 :          0 :         ARG_UNUSED(offset);
     440                 :          0 :         hwtimer_set_real_time_mode(false);
     441                 :          0 : }
     442                 :            : 
     443                 :          0 : static void cmd_rtcoffset_found(char *argv, int offset)
     444                 :            : {
     445                 :          0 :         ARG_UNUSED(argv);
     446                 :          0 :         ARG_UNUSED(offset);
     447                 :          0 :         hwtimer_set_rtc_offset(args.rtc_offset*1e6);
     448                 :          0 : }
     449                 :            : 
     450                 :          0 : static void cmd_rt_drift_found(char *argv, int offset)
     451                 :            : {
     452                 :          0 :         ARG_UNUSED(argv);
     453                 :          0 :         ARG_UNUSED(offset);
     454         [ #  # ]:          0 :         if (!(args.rt_drift > -1)) {
     455                 :          0 :                 posix_print_error_and_exit("The drift needs to be > -1. "
     456                 :            :                                           "Please use --help for more info\n");
     457                 :            :         }
     458                 :          0 :         args.rt_ratio = args.rt_drift + 1;
     459                 :          0 :         hwtimer_set_rt_ratio(args.rt_ratio);
     460                 :          0 : }
     461                 :            : 
     462                 :          0 : static void cmd_rt_ratio_found(char *argv, int offset)
     463                 :            : {
     464                 :          0 :         ARG_UNUSED(argv);
     465                 :          0 :         ARG_UNUSED(offset);
     466         [ #  # ]:          0 :         if ((args.rt_ratio <= 0)) {
     467                 :          0 :                 posix_print_error_and_exit("The ratio needs to be > 0. "
     468                 :            :                                           "Please use --help for more info\n");
     469                 :            :         }
     470                 :          0 :         hwtimer_set_rt_ratio(args.rt_ratio);
     471                 :          0 : }
     472                 :            : 
     473                 :          0 : static void cmd_rtcreset_found(char *argv, int offset)
     474                 :            : {
     475                 :          0 :         ARG_UNUSED(argv);
     476                 :          0 :         ARG_UNUSED(offset);
     477                 :          0 :         hwtimer_reset_rtc();
     478                 :          0 : }
     479                 :            : 
     480                 :          1 : static void native_add_time_options(void)
     481                 :            : {
     482                 :          1 :         static struct args_struct_t timer_options[] = {
     483                 :            :                 /*
     484                 :            :                  * Fields:
     485                 :            :                  * manual, mandatory, switch,
     486                 :            :                  * option_name, var_name ,type,
     487                 :            :                  * destination, callback,
     488                 :            :                  * description
     489                 :            :                  */
     490                 :            :                 {false, false, true,
     491                 :            :                 "rt", "", 'b',
     492                 :            :                 NULL, cmd_realtime_found,
     493                 :            :                 "Slow down the execution to the host real time, "
     494                 :            :                 "or a ratio of it (see --rt-ratio below)"},
     495                 :            : 
     496                 :            :                 {false, false, true,
     497                 :            :                 "no-rt", "", 'b',
     498                 :            :                 NULL, cmd_no_realtime_found,
     499                 :            :                 "Do NOT slow down the execution to real time, but advance "
     500                 :            :                 "Zephyr's time as fast as possible and decoupled from the host "
     501                 :            :                 "time"},
     502                 :            : 
     503                 :            :                 {false, false, false,
     504                 :            :                 "rt-drift", "dratio", 'd',
     505                 :            :                 (void *)&args.rt_drift, cmd_rt_drift_found,
     506                 :            :                 "Drift of the simulated clock relative to the host real time. "
     507                 :            :                 "Normally this would be set to a value of a few ppm (e.g. 50e-6"
     508                 :            :                 ") "
     509                 :            :                 "This option has no effect in non real time mode"
     510                 :            :                 },
     511                 :            : 
     512                 :            :                 {false, false, false,
     513                 :            :                 "rt-ratio", "ratio", 'd',
     514                 :            :                 (void *)&args.rt_ratio, cmd_rt_ratio_found,
     515                 :            :                 "Relative speed of the simulated time vs real time. "
     516                 :            :                 "For ex. set to 2 to have simulated time pass at double the "
     517                 :            :                 "speed of real time. "
     518                 :            :                 "Note that both rt-drift & rt-ratio adjust the same clock "
     519                 :            :                 "speed, and therefore it does not make sense to use them "
     520                 :            :                 "simultaneously. "
     521                 :            :                 "This option has no effect in non real time mode"
     522                 :            :                 },
     523                 :            : 
     524                 :            :                 {false, false, false,
     525                 :            :                 "rtc-offset", "time_offset", 'd',
     526                 :            :                 (void *)&args.rtc_offset, cmd_rtcoffset_found,
     527                 :            :                 "At boot offset the RTC clock by this amount of seconds"
     528                 :            :                 },
     529                 :            : 
     530                 :            :                 {false, false, true,
     531                 :            :                 "rtc-reset", "", 'b',
     532                 :            :                 NULL, cmd_rtcreset_found,
     533                 :            :                 "Start the simulated real time clock at 0. Otherwise it starts "
     534                 :            :                 "matching the value provided by the host real time clock"},
     535                 :            : 
     536                 :            :                 {false, false, false,
     537                 :            :                  "stop_at", "time", 'd',
     538                 :            :                 (void *)&args.stop_at, cmd_stop_at_found,
     539                 :            :                 "In simulated seconds, when to stop automatically"},
     540                 :            : 
     541                 :            :                 ARG_TABLE_ENDMARKER};
     542                 :            : 
     543                 :          1 :         native_add_command_line_opts(timer_options);
     544                 :          1 : }
     545                 :            : 
     546                 :            : NATIVE_TASK(native_add_time_options, PRE_BOOT_1, 1);

Generated by: LCOV version 1.14