guowenxue
2023-07-10 5e9d03d507aad324a803eb8795e0eed6fb671761
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/********************************************************************************
 *      Copyright:  (C) 2020 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  util_time.h
 *    Description:  This head file is system time, timer API
 *
 *        Version:  1.0.0(07/23/2020)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "07/23/2020 07:46:37 AM"
 *
 ********************************************************************************/
#ifndef __UTIL_TIME_H_
#define __UTIL_TIME_H_
 
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
 
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
 
 
typedef struct date_time_s
{
    int year;
    int month;
    int day;
    int hour;
    int minute;
    int second;
    int dayofweek;
} date_time_t;
 
/* sleep for micro second */
static inline void msleep(unsigned long ms)
{
    struct timespec  timeout;
    unsigned long    tmp;
 
    timeout.tv_sec = ms / 1000;
    if (timeout.tv_sec == 0)
    {
        tmp = ms * 10000;
        timeout.tv_nsec = tmp * 100;
    }
    else
    {
        timeout.tv_nsec = 0;
    }
 
    nanosleep(&timeout, 0);
}
 
/* call gettimeofday() to get current micro second */
static inline unsigned long time_now()
{
    struct timeval            now;
 
    gettimeofday(&now, 0);
 
    return (now.tv_sec*1000) + (now.tv_usec/1000);
}
 
/* timep has elapsed since $start, unit as micro second*/
static inline uint32_t time_elapsed(uint32_t start)
{
    uint32_t current = time_now();
 
    if(current >= start)
        return current-start;
    else
        return current+0xFFFFFFFF-start;
}
 
/* call gettimeofday() to get current micro second */
static inline unsigned long time_second()
{
    struct timeval            now;
 
    gettimeofday(&now, 0);
    return now.tv_sec;
}
 
/* timep has elapsed since $start, unit as micro second*/
static inline uint32_t seconds_elapsed(uint32_t start)
{
    uint32_t current = time_second();
 
    if(current >= start)
        return current-start;
    else
        return current+0xFFFFFFFF-start;
}
 
/*
* These inlines deal with timer wrapping correctly. You are
* strongly encouraged to use them
* 1. Because people otherwise forget
* 2. Because if the timer wrap changes in future you won't have to
* alter your driver code.
*
* time_after(a,b) returns true if the time a is after time b.
*
* Do this with "<0" and ">=0" to only test the sign of the result. A
* good compiler would generate better code (and a really good compiler
* wouldn't care). Gcc is currently neither.
*/
 
#define typecheck(type,x) \
({      type __dummy; \
        typeof(x) __dummy2; \
        (void)(&__dummy == &__dummy2); \
        1; \
})
 
#define time_after(a,b) \
(typecheck(unsigned long, a) && typecheck(unsigned long, b) && ((long)(b) - (long)(a) < 0))
#define time_before(a,b) time_after(b,a)
 
#define time_after_eq(a,b) \
(typecheck(unsigned long, a) && typecheck(unsigned long, b) && ((long)(a) - (long)(b) >= 0))
#define time_before_eq(a,b) time_after_eq(b,a)
 
/* Same as above, but does so with platform independent 64bit types.
 * These must be used when utilizing jiffies_64 (i.e. return value of
 * get_jiffies_64() */
#define time_after64(a,b) \
    (typecheck(__u64, a) && typecheck(__u64, b) && ((__s64)(b) - (__s64)(a) < 0))
#define time_before64(a,b)  time_after64(b,a)
 
#define time_after_eq64(a,b) \
    (typecheck(__u64, a) && typecheck(__u64, b) && ((__s64)(a) - (__s64)(b) >= 0))
#define time_before_eq64(a,b)   time_after_eq64(b,a)
 
 
static inline void get_sys_time(date_time_t *date)
{
    time_t now = time(NULL);
    struct tm *tnow = localtime(&now);
 
    memset(date, 0, sizeof(*date));
    date->year = 1900 + tnow->tm_year;
    date->month = 1 + tnow->tm_mon;
    date->day = tnow->tm_mday;
 
    date->hour = tnow->tm_hour;
    date->minute = tnow->tm_min;
    date->second = tnow->tm_sec;
    date->dayofweek = tnow->tm_wday;
    return;
}
 
static inline int get_rtc_time(date_time_t *date)
{
    int                 rv, fd = -1;
    struct rtc_time     rtc_tm;
 
    memset(date, 0, sizeof(*date));
 
    if ((fd=open("/dev/rtc0", O_RDONLY)) < 0)
        return -1;
 
    if((rv=ioctl(fd, RTC_RD_TIME, &rtc_tm)) < 0)
        return -2;
 
    date->year = 1900 + rtc_tm.tm_year;
    date->month = 1 + rtc_tm.tm_mon;
    date->day = rtc_tm.tm_mday;
 
    date->hour = rtc_tm.tm_hour;
    date->minute = rtc_tm.tm_min;
    date->second = rtc_tm.tm_sec;
    date->dayofweek = rtc_tm.tm_wday;
 
    close(fd);
 
    return 0;
}
 
#endif