Paparazzi UAS  v5.12_stable-4-g9b43e9b
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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 pthread_t sys_time_thread;
43 static struct timespec startup_time;
44 
45 static void sys_tick_handler(void);
46 void *sys_time_thread_main(void *data);
47 
48 #define NSEC_OF_SEC(sec) ((sec) * 1e9)
49 
50 void *sys_time_thread_main(void *data)
51 {
52  int fd;
53 
54  /* Create the timer */
55  fd = timerfd_create(CLOCK_MONOTONIC, 0);
56  if (fd == -1) {
57  perror("Could not set up timer.");
58  return NULL;
59  }
60 
62 
63  /* Make the timer periodic */
64  struct itimerspec timer;
65  /* timer expires after sys_time.resolution sec */
66  timer.it_value.tv_sec = 0;
67  timer.it_value.tv_nsec = NSEC_OF_SEC(sys_time.resolution);
68  /* and every SYS_TIME_RESOLUTION sec after that */
69  timer.it_interval.tv_sec = 0;
70  timer.it_interval.tv_nsec = NSEC_OF_SEC(sys_time.resolution);
71 
72  if (timerfd_settime(fd, 0, &timer, NULL) == -1) {
73  perror("Could not set up timer.");
74  return NULL;
75  }
76 
77  while (1) {
78  unsigned long long missed;
79  /* Wait for the next timer event. If we have missed any the
80  number is written to "missed" */
81  int r = read(fd, &missed, sizeof(missed));
82  if (r == -1) {
83  perror("Couldn't read timer!");
84  }
85  if (missed > 1) {
86  fprintf(stderr, "Missed %lld timer events!\n", missed);
87  }
88  /* set current sys_time */
90  }
91  return NULL;
92 }
93 
95 {
98 
99  clock_gettime(CLOCK_MONOTONIC, &startup_time);
100 
101  int ret = pthread_create(&sys_time_thread, NULL, sys_time_thread_main, NULL);
102  if (ret) {
103  perror("Could not setup sys_time_thread");
104  return;
105  }
106 }
107 
108 static void sys_tick_handler(void)
109 {
110  /* get current time */
111  struct timespec now;
112  clock_gettime(CLOCK_MONOTONIC, &now);
113 
114  /* time difference to startup */
115  time_t d_sec = now.tv_sec - startup_time.tv_sec;
116  long d_nsec = now.tv_nsec - startup_time.tv_nsec;
117 
118  /* wrap if negative nanoseconds */
119  if (d_nsec < 0) {
120  d_sec -= 1;
121  d_nsec += 1000000000L;
122  }
123 
124 #ifdef SYS_TIME_LED
125  if (d_sec > sys_time.nb_sec) {
126  LED_TOGGLE(SYS_TIME_LED);
127  }
128 #endif
129 
130  sys_time.nb_sec = d_sec;
133 
134  /* advance virtual timers */
135  for (unsigned int i = 0; i < SYS_TIME_NB_TIMER; i++) {
136  if (sys_time.timer[i].in_use &&
139  sys_time.timer[i].elapsed = true;
140  /* call registered callbacks, WARNING: they will be executed in the sys_time thread! */
141  if (sys_time.timer[i].cb) {
142  sys_time.timer[i].cb(i);
143  }
144  }
145  }
146 }
147 
154 {
155  /* get current time */
156  struct timespec now;
157  clock_gettime(CLOCK_MONOTONIC, &now);
158 
159  /* time difference to startup */
160  time_t d_sec = now.tv_sec - startup_time.tv_sec;
161  long d_nsec = now.tv_nsec - startup_time.tv_nsec;
162 
163  /* wrap if negative nanoseconds */
164  if (d_nsec < 0) {
165  d_sec -= 1;
166  d_nsec += 1000000000L;
167  }
168  return d_sec * 1000000 + d_nsec/1000;
169 }
170 
176 {
177  /* get current time */
178  struct timespec now;
179  clock_gettime(CLOCK_MONOTONIC, &now);
180 
181  /* time difference to startup */
182  time_t d_sec = now.tv_sec - startup_time.tv_sec;
183  long d_nsec = now.tv_nsec - startup_time.tv_nsec;
184 
185  /* wrap if negative nanoseconds */
186  if (d_nsec < 0) {
187  d_sec -= 1;
188  d_nsec += 1000000000L;
189  }
190  return d_sec * 1000 + d_nsec/1000000;
191 }
static void sys_tick_handler(void)
static uint32_t cpu_ticks_of_nsec(uint32_t nsec)
Definition: sys_time.h:188
float resolution
sys_time_timer resolution in seconds
Definition: sys_time.h:77
uint32_t get_sys_time_msec(void)
Get the time in milliseconds since startup.
Definition: sys_time_arch.c:78
uint32_t cpu_ticks_per_sec
cpu ticks per second
Definition: sys_time.h:80
#define NSEC_OF_SEC(sec)
Definition: sys_time_arch.c:48
void * sys_time_thread_main(void *data)
Definition: sys_time_arch.c:50
volatile uint32_t nb_tick
SYS_TIME_TICKS since startup.
Definition: sys_time.h:74
Functions to obtain rt priority or set the nice level.
volatile bool elapsed
Definition: sys_time.h:66
pthread_t sys_time_thread
Definition: sys_time_arch.c:42
Architecture independent timing functions.
unsigned long uint32_t
Definition: types.h:18
uint32_t end_time
in SYS_TIME_TICKS
Definition: sys_time.h:67
volatile uint32_t nb_sec_rem
remainder of seconds since startup in CPU_TICKS
Definition: sys_time.h:73
#define LED_TOGGLE(i)
Definition: led_hw.h:52
struct sys_time_timer timer[SYS_TIME_NB_TIMER]
Definition: sys_time.h:75
static uint32_t sys_time_ticks_of_sec(float seconds)
Definition: sys_time.h:138
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:72
static struct timespec startup_time
Definition: sys_time_arch.c:43
int fd
Definition: serial.c:26
#define SYS_TIME_THREAD_PRIO
Definition: sys_time_arch.c:39
sys_time_cb cb
Definition: sys_time.h:65
arch independent LED (Light Emitting Diodes) API
#define SYS_TIME_NB_TIMER
Definition: sys_time.h:40
static int get_rt_prio(int prio)
Definition: rt_priority.h:32
uint32_t duration
in SYS_TIME_TICKS
Definition: sys_time.h:68
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:68
static uint32_t sys_time_ticks_of_usec(uint32_t usec)
Definition: sys_time.h:148
void sys_time_arch_init(void)
Definition: sys_time_arch.c:49
uint32_t resolution_cpu_ticks
sys_time_timer resolution in cpu ticks
Definition: sys_time.h:79