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