Paparazzi UAS  v7.0_unstable
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 
180 {
181  /* get current time */
182  struct timespec now;
183  clock_gettime(CLOCK_MONOTONIC, &now);
184 
185  /* time difference to startup */
186  time_t d_sec = now.tv_sec - startup_time.tv_sec;
187  long d_nsec = now.tv_nsec - startup_time.tv_nsec;
188 
189  /* wrap if negative nanoseconds */
190  if (d_nsec < 0) {
191  d_sec -= 1;
192  d_nsec += 1000000000L;
193  }
194  return d_sec * 10000 + d_nsec / 100000;
195 }
196 
202 {
203  /* get current time */
204  struct timespec now;
205  clock_gettime(CLOCK_MONOTONIC, &now);
206 
207  /* time difference to startup */
208  time_t d_sec = now.tv_sec - startup_time.tv_sec;
209  long d_nsec = now.tv_nsec - startup_time.tv_nsec;
210 
211  /* wrap if negative nanoseconds */
212  if (d_nsec < 0) {
213  d_sec -= 1;
214  d_nsec += 1000000000L;
215  }
216  return d_sec * 1000 + d_nsec / 1000000;
217 }
#define LED_TOGGLE(i)
Definition: led_hw.h:53
uint32_t get_sys_time_usec100(void)
Get the time in microseconds divided by 100 since startup.
Definition: sys_time_arch.c:87
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:71
void sys_time_arch_init(void)
Definition: sys_time_arch.c:52
uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
Definition: sys_time_arch.c:98
arch independent LED (Light Emitting Diodes) API
#define SYS_TIME_THREAD_PRIO
Definition: sys_time_arch.c:39
void * sys_time_thread_main(void *data)
Definition: sys_time_arch.c:49
static struct timespec startup_time
Definition: sys_time_arch.c:42
static void sys_tick_handler(void)
#define NSEC_OF_SEC(sec)
Definition: sys_time_arch.c:47
Functions to obtain rt priority or set the nice level.
static int get_rt_prio(int prio)
Definition: rt_priority.h:32
int fd
Definition: serial.c:26
Architecture independent timing functions.
volatile uint32_t nb_tick
SYS_TIME_TICKS since startup.
Definition: sys_time.h:74
static uint32_t sys_time_ticks_of_sec(float seconds)
Definition: sys_time.h:147
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:72
uint32_t cpu_ticks_per_sec
cpu ticks per second
Definition: sys_time.h:80
uint32_t duration
in SYS_TIME_TICKS
Definition: sys_time.h:68
static uint32_t sys_time_ticks_of_usec(uint32_t usec)
Definition: sys_time.h:157
uint32_t resolution_cpu_ticks
sys_time_timer resolution in cpu ticks
Definition: sys_time.h:79
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:73
float resolution
sys_time_timer resolution in seconds
Definition: sys_time.h:77
sys_time_cb cb
Definition: sys_time.h:65
#define SYS_TIME_NB_TIMER
Definition: sys_time.h:44
static uint32_t cpu_ticks_of_nsec(uint32_t nsec)
Definition: sys_time.h:197
uint32_t end_time
in SYS_TIME_TICKS
Definition: sys_time.h:67
struct sys_time_timer timer[SYS_TIME_NB_TIMER]
Definition: sys_time.h:75
volatile bool elapsed
Definition: sys_time.h:66
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78