Paparazzi UAS  v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
sys_time_arch.c
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (C) 2009-2013 The Paparazzi Team
4  *
5  * This file is part of paparazzi.
6  *
7  * paparazzi is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * paparazzi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with paparazzi; see the file COPYING. If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 
27 #include "mcu_periph/sys_time.h"
28 #include <stdio.h>
29 #include <pthread.h>
30 #include <sys/timerfd.h>
31 #include <time.h>
32 #include "rt_priority.h"
33 
34 #ifdef SYS_TIME_LED
35 #include "led.h"
36 #endif
37 
38 #ifndef SYS_TIME_THREAD_PRIO
39 #define SYS_TIME_THREAD_PRIO 29
40 #endif
41 
42 static struct timespec startup_time;
43 
44 static void sys_tick_handler(void);
45 void *sys_time_thread_main(void *data);
46 
47 #define NSEC_OF_SEC(sec) ((sec) * 1e9)
48 
49 void *sys_time_thread_main(void *data)
50 {
51  int fd;
52 
53  /* Create the timer */
54  fd = timerfd_create(CLOCK_MONOTONIC, 0);
55  if (fd == -1) {
56  perror("Could not set up timer.");
57  return NULL;
58  }
59 
61 
62  /* Make the timer periodic */
63  struct itimerspec timer;
64  /* timer expires after sys_time.resolution sec */
65  timer.it_value.tv_sec = 0;
66  timer.it_value.tv_nsec = NSEC_OF_SEC(sys_time.resolution);
67  /* and every SYS_TIME_RESOLUTION sec after that */
68  timer.it_interval.tv_sec = 0;
69  timer.it_interval.tv_nsec = NSEC_OF_SEC(sys_time.resolution);
70 
71  if (timerfd_settime(fd, 0, &timer, NULL) == -1) {
72  perror("Could not set up timer.");
73  return NULL;
74  }
75 
76  while (1) {
77  unsigned long long missed;
78  /* Wait for the next timer event. If we have missed any the
79  number is written to "missed" */
80  int r = read(fd, &missed, sizeof(missed));
81  if (r == -1) {
82  perror("Couldn't read timer!");
83  }
84  if (missed > 1) {
85  fprintf(stderr, "Missed %lld timer events!\n", missed);
86  }
87  /* set current sys_time */
89  }
90  return NULL;
91 }
92 
94 {
97 
98  clock_gettime(CLOCK_MONOTONIC, &startup_time);
99 
100  pthread_t tid;
101  int ret = pthread_create(&tid, NULL, sys_time_thread_main, NULL);
102  if (ret) {
103  perror("Could not setup sys_time_thread");
104  return;
105  }
106 #ifndef __APPLE__
107  pthread_setname_np(tid, "sys_time");
108 #endif
109 }
110 
111 static void sys_tick_handler(void)
112 {
113  /* get current time */
114  struct timespec now;
115  clock_gettime(CLOCK_MONOTONIC, &now);
116 
117  /* time difference to startup */
118  time_t d_sec = now.tv_sec - startup_time.tv_sec;
119  long d_nsec = now.tv_nsec - startup_time.tv_nsec;
120 
121  /* wrap if negative nanoseconds */
122  if (d_nsec < 0) {
123  d_sec -= 1;
124  d_nsec += 1000000000L;
125  }
126 
127 #ifdef SYS_TIME_LED
128  if (d_sec > sys_time.nb_sec) {
129  LED_TOGGLE(SYS_TIME_LED);
130  }
131 #endif
132 
133  sys_time.nb_sec = d_sec;
136 
137  /* advance virtual timers */
138  for (unsigned int i = 0; i < SYS_TIME_NB_TIMER; i++) {
139  if (sys_time.timer[i].in_use &&
142  sys_time.timer[i].elapsed = true;
143  /* call registered callbacks, WARNING: they will be executed in the sys_time thread! */
144  if (sys_time.timer[i].cb) {
145  sys_time.timer[i].cb(i);
146  }
147  }
148  }
149 }
150 
157 {
158  /* get current time */
159  struct timespec now;
160  clock_gettime(CLOCK_MONOTONIC, &now);
161 
162  /* time difference to startup */
163  time_t d_sec = now.tv_sec - startup_time.tv_sec;
164  long d_nsec = now.tv_nsec - startup_time.tv_nsec;
165 
166  /* wrap if negative nanoseconds */
167  if (d_nsec < 0) {
168  d_sec -= 1;
169  d_nsec += 1000000000L;
170  }
171  return d_sec * 1000000 + d_nsec / 1000;
172 }
173 
179 {
180  /* get current time */
181  struct timespec now;
182  clock_gettime(CLOCK_MONOTONIC, &now);
183 
184  /* time difference to startup */
185  time_t d_sec = now.tv_sec - startup_time.tv_sec;
186  long d_nsec = now.tv_nsec - startup_time.tv_nsec;
187 
188  /* wrap if negative nanoseconds */
189  if (d_nsec < 0) {
190  d_sec -= 1;
191  d_nsec += 1000000000L;
192  }
193  return d_sec * 1000 + d_nsec / 1000000;
194 }
sys_time::cpu_ticks_per_sec
uint32_t cpu_ticks_per_sec
cpu ticks per second
Definition: sys_time.h:80
sys_time::timer
struct sys_time_timer timer[SYS_TIME_NB_TIMER]
Definition: sys_time.h:75
rt_priority.h
sys_time_timer::elapsed
volatile bool elapsed
Definition: sys_time.h:66
sys_time::resolution_cpu_ticks
uint32_t resolution_cpu_ticks
sys_time_timer resolution in cpu ticks
Definition: sys_time.h:79
sys_time_timer::duration
uint32_t duration
in SYS_TIME_TICKS
Definition: sys_time.h:68
sys_time_ticks_of_usec
static uint32_t sys_time_ticks_of_usec(uint32_t usec)
Definition: sys_time.h:148
startup_time
static struct timespec startup_time
Definition: sys_time_arch.c:42
uint32_t
unsigned long uint32_t
Definition: types.h:18
LED_TOGGLE
#define LED_TOGGLE(i)
Definition: led_hw.h:53
get_sys_time_usec
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:68
sys_time::nb_tick
volatile uint32_t nb_tick
SYS_TIME_TICKS since startup.
Definition: sys_time.h:74
sys_time_timer::in_use
bool in_use
Definition: sys_time.h:64
sys_time.h
Architecture independent timing functions.
get_sys_time_msec
uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
Definition: sys_time_arch.c:78
led.h
arch independent LED (Light Emitting Diodes) API
sys_time_timer::cb
sys_time_cb cb
Definition: sys_time.h:65
fd
int fd
Definition: serial.c:26
get_rt_prio
static int get_rt_prio(int prio)
Definition: rt_priority.h:32
sys_time_arch_init
void sys_time_arch_init(void)
Definition: sys_time_arch.c:49
sys_time
Definition: sys_time.h:71
SYS_TIME_NB_TIMER
#define SYS_TIME_NB_TIMER
Definition: sys_time.h:40
sys_time::nb_sec_rem
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:73
sys_time_timer::end_time
uint32_t end_time
in SYS_TIME_TICKS
Definition: sys_time.h:67
SYS_TIME_THREAD_PRIO
#define SYS_TIME_THREAD_PRIO
Definition: sys_time_arch.c:39
sys_time::nb_sec
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:72
sys_tick_handler
static void sys_tick_handler(void)
Definition: sys_time_arch.c:111
sys_time_ticks_of_sec
static uint32_t sys_time_ticks_of_sec(float seconds)
Definition: sys_time.h:138
sys_time_thread_main
void * sys_time_thread_main(void *data)
Definition: sys_time_arch.c:49
NSEC_OF_SEC
#define NSEC_OF_SEC(sec)
Definition: sys_time_arch.c:47
cpu_ticks_of_nsec
static uint32_t cpu_ticks_of_nsec(uint32_t nsec)
Definition: sys_time.h:188
sys_time::resolution
float resolution
sys_time_timer resolution in seconds
Definition: sys_time.h:77