• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  * Description: timer
15  *
16  * Create: 2021-12-16
17  */
18 
19 #include <los_swtmr.h>
20 #include <los_memory.h>
21 #include <los_config.h>
22 #include <time.h>
23 #include <limits.h>
24 #include <linux/hrtimer.h>
25 #include "soc_osal.h"
26 #include "osal_errno.h"
27 #include "osal_inner.h"
28 
29 #define US_TO_NSEC  1000
30 #define MS_TO_USEC  1000
31 
32 #ifdef LOSCFG_COMPAT_LINUX_HRTIMER
33 typedef enum hrtimer_restart (*hrtimer_function)(struct hrtimer *timer);
34 
osal_hrtimer_create(osal_hrtimer * phrtimer)35 int osal_hrtimer_create(osal_hrtimer *phrtimer)
36 {
37     int ret;
38     if (phrtimer == NULL || phrtimer->timer != NULL) {
39         osal_log("parameter invalid!\n");
40         return OSAL_FAILURE;
41     }
42     if (phrtimer->interval > (ULONG_MAX / MS_TO_USEC)) {
43         osal_log("interval is too large!\n");
44         return OSAL_FAILURE;
45     }
46     union ktime stime;
47     stime.tv.sec = 0;
48     stime.tv.usec = (phrtimer->interval) * MS_TO_USEC;
49 
50     phrtimer->timer = (struct hrtimer *)LOS_MemAlloc((void*)m_aucSysMem0, sizeof(struct hrtimer));
51     if (phrtimer->timer == NULL) {
52         osal_log("LOS_MemAlloc failed!\n");
53         return OSAL_FAILURE;
54     }
55     ret = hrtimer_create((struct hrtimer *)phrtimer->timer, stime, (hrtimer_function)phrtimer->handler);
56     if (ret != 0) {
57         osal_log("hrtimer_create failed!\n");
58         LOS_MemFree((void*)m_aucSysMem0, phrtimer->timer);
59         phrtimer->timer = NULL;
60         return OSAL_FAILURE;
61     }
62     return ret;
63 }
64 
osal_hrtimer_start(osal_hrtimer * phrtimer)65 int osal_hrtimer_start(osal_hrtimer *phrtimer)
66 {
67     if (phrtimer == NULL || phrtimer->timer == NULL) {
68         osal_log("parameter invalid!\n");
69         return OSAL_FAILURE;
70     }
71     if (phrtimer->interval > (ULONG_MAX / MS_TO_USEC)) {
72         osal_log("interval is too large!\n");
73         return OSAL_FAILURE;
74     }
75     union ktime stime;
76     stime.tv.sec = 0;
77     stime.tv.usec = (phrtimer->interval) * MS_TO_USEC;
78     return hrtimer_start((struct hrtimer *)phrtimer->timer, stime, HRTIMER_MODE_REL);
79 }
80 
osal_hrtimer_destroy(osal_hrtimer * phrtimer)81 int osal_hrtimer_destroy(osal_hrtimer *phrtimer)
82 {
83     if ((phrtimer == NULL) || (phrtimer->timer == NULL)) {
84         osal_log("parameter invalid!\n");
85         return OSAL_FAILURE;
86     }
87     hrtimer_cancel((struct hrtimer *)phrtimer->timer);
88     LOS_MemFree((void*)m_aucSysMem0, phrtimer->timer);
89     phrtimer->timer = NULL;
90     return OSAL_SUCCESS;
91 }
92 #endif
93 
osal_timer_get_private_data(const void * sys_data)94 unsigned long osal_timer_get_private_data(const void *sys_data)
95 {
96     return (unsigned long)(UINTPTR)sys_data;
97 }
98 
osal_timer_init(osal_timer * timer)99 int osal_timer_init(osal_timer *timer)
100 {
101     int ret;
102     if (timer == NULL || timer->handler == NULL || timer->timer != NULL) {
103         osal_log("parameter invalid!\n");
104         return OSAL_FAILURE;
105     }
106     if (LOS_MS2Tick(timer->interval) <= 0) {
107         osal_log("interval:%d invalid!\n", timer->interval);
108         return OSAL_FAILURE;
109     }
110     // osal_timer.data will be used by osal_timer.handler(osal_timer.data);
111     ret = LOS_SwtmrCreate(LOS_MS2Tick(timer->interval), LOS_SWTMR_MODE_NO_SELFDELETE,
112         (SWTMR_PROC_FUNC)timer->handler, (unsigned short *)(&(timer->timer)), timer->data);
113     if (ret != LOS_OK) {
114         osal_log("LOS_SwtmrCreate failed! ret = %#x.\n", ret);
115         return OSAL_FAILURE;
116     }
117     return OSAL_SUCCESS;
118 }
119 
120 /*
121  * timer will restart after modify.
122  */
osal_timer_mod(osal_timer * timer,unsigned int interval)123 int osal_timer_mod(osal_timer *timer, unsigned int interval)
124 {
125     unsigned int ret;
126 
127     if (timer == NULL || timer->handler == NULL || LOS_MS2Tick(interval) <= 0) {
128         osal_log("interval=%d parameter invalid!\n", interval);
129         return OSAL_FAILURE;
130     }
131     ret = LOS_SwtmrDelete((unsigned short)(UINTPTR)(timer->timer));
132     if (ret != LOS_OK) {
133         osal_log("LOS_SwtmrDelete failed! ret = %#x.\n", ret);
134         return OSAL_FAILURE;
135     }
136     timer->interval = interval;
137     // osal_timer.data will be used by osal_timer.handler(osal_timer.data);
138     ret = LOS_SwtmrCreate(LOS_MS2Tick(timer->interval), LOS_SWTMR_MODE_NO_SELFDELETE,
139         (SWTMR_PROC_FUNC)timer->handler, (unsigned short *)(&(timer->timer)), timer->data);
140     if (ret != LOS_OK) {
141         osal_log("LOS_SwtmrCreate failed! ret = %#x.\n", ret);
142         return OSAL_FAILURE;
143     }
144     ret = LOS_SwtmrStart((unsigned short)(UINTPTR)(timer->timer));
145     if (ret != LOS_OK) {
146         osal_log("LOS_SwtmrStart failed! ret = %#x.\n", ret);
147         return OSAL_FAILURE;
148     }
149     return OSAL_SUCCESS;
150 }
151 
152 /*
153  * if the timer is timing, this function will restart the timer
154  */
osal_timer_start(osal_timer * timer)155 int osal_timer_start(osal_timer *timer)
156 {
157     if (timer == NULL) {
158         osal_log("parameter invalid!\n");
159         return OSAL_FAILURE;
160     }
161 
162     int ret = LOS_SwtmrStart((unsigned short)(UINTPTR)(timer->timer));
163     if (ret != LOS_OK) {
164         osal_log("LOS_SwtmrStart failed! ret = %#x.\n", ret);
165         return OSAL_FAILURE;
166     }
167     return OSAL_SUCCESS;
168 }
169 
osal_timer_stop(osal_timer * timer)170 int osal_timer_stop(osal_timer *timer)
171 {
172     if (timer == NULL) {
173         osal_log("parameter invalid!\n");
174         return OSAL_FAILURE;
175     }
176 
177     int ret = LOS_SwtmrStop((unsigned short)(UINTPTR)(timer->timer));
178     if (ret == LOS_ERRNO_SWTMR_NOT_STARTED) {
179         return OSAL_SUCCESS; // stop success, timer is already stoped, return 0;
180     } else if (ret == LOS_OK) {
181         return 1; // stop success, timer is pengding, return 1;
182     } else {
183         osal_log("LOS_SwtmrStop failed! ret = %#x.\n", ret);
184         return OSAL_FAILURE;
185     }
186 }
187 
osal_timer_destroy(osal_timer * timer)188 int osal_timer_destroy(osal_timer *timer)
189 {
190     if (timer == NULL) {
191         osal_log("parameter invalid!\n");
192         return OSAL_FAILURE;
193     }
194 
195     int ret = LOS_SwtmrDelete((unsigned short)(UINTPTR)(timer->timer));
196     if (ret != LOS_OK) {
197         osal_log("LOS_SwtmrDelete failed! ret = %#x.\n", ret);
198         return OSAL_FAILURE;
199     }
200     return OSAL_SUCCESS;
201 }
202 
osal_sched_clock(void)203 unsigned long long osal_sched_clock(void)
204 {
205     return LOS_CurrNanosec();
206 }
207 
osal_gettimeofday(osal_timeval * tv)208 void osal_gettimeofday(osal_timeval *tv)
209 {
210     if (tv == NULL) {
211         return;
212     }
213 
214     struct timespec tp;
215     if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
216         tv->tv_usec = (unsigned int)(tp.tv_nsec / US_TO_NSEC);
217         tv->tv_sec = tp.tv_sec;
218     } else {
219         osal_log("clock_gettime failed!\n");
220     }
221 }
222 
osal_get_jiffies(void)223 unsigned long long osal_get_jiffies(void)
224 {
225     return LOS_TickCountGet();
226 }
227 
osal_msecs_to_jiffies(const unsigned int m)228 unsigned long osal_msecs_to_jiffies(const unsigned int m)
229 {
230     return (unsigned long)LOS_MS2Tick(m);
231 }
232 
osal_jiffies_to_msecs(const unsigned int n)233 unsigned int osal_jiffies_to_msecs(const unsigned int n)
234 {
235     return LOS_Tick2MS(n);
236 }
237 
osal_get_cycle_per_tick(void)238 unsigned int osal_get_cycle_per_tick(void)
239 {
240     return LOS_CyclePerTickGet();
241 }
242