1 /*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
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 */
15
16 #include "kal.h"
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <time.h>
20
21 #define KAL_TASK_NAME_LEN 32
22 #define LOSCFG_BASE_CORE_MS_PER_SECOND 1000
23 #define OS_SYS_NS_PER_SECOND 1000000000
24
25 typedef struct {
26 timer_t timerPtr;
27 KalTimerType type;
28 unsigned int millisec;
29 KalTimerProc func;
30 union sigval arg;
31 int isRunning;
32 } KalTimer;
33
KalFunction(union sigval kalTimer)34 static void KalFunction(union sigval kalTimer)
35 {
36 KalTimer* tmpPtr = (KalTimer *)(kalTimer.sival_ptr);
37 if (tmpPtr->type == KAL_TIMER_ONCE) {
38 tmpPtr->isRunning = 0;
39 }
40 tmpPtr->func(tmpPtr->arg);
41 }
42
KalMs2TimeSpec(struct timespec * tp,unsigned int ms)43 static void KalMs2TimeSpec(struct timespec* tp, unsigned int ms)
44 {
45 tp->tv_sec = ms / LOSCFG_BASE_CORE_MS_PER_SECOND;
46 ms -= tp->tv_sec * LOSCFG_BASE_CORE_MS_PER_SECOND;
47 tp->tv_nsec = (long)(((unsigned long long)ms * OS_SYS_NS_PER_SECOND) / LOSCFG_BASE_CORE_MS_PER_SECOND);
48 }
49
KalTimerCreate(KalTimerProc func,KalTimerType type,void * arg,unsigned int millisec)50 KalTimerId KalTimerCreate(KalTimerProc func, KalTimerType type, void* arg, unsigned int millisec)
51 {
52 struct sigevent evp = {0};
53 timer_t timer;
54 if ((func == NULL) || ((type != KAL_TIMER_ONCE) && (type != KAL_TIMER_PERIODIC))) {
55 return NULL;
56 }
57 KalTimer* kalTimer = (KalTimer *)malloc(sizeof(KalTimer));
58 if (kalTimer == NULL) {
59 return NULL;
60 }
61 kalTimer->func = func;
62 kalTimer->arg.sival_ptr = arg;
63 kalTimer->type = type;
64 evp.sigev_notify = SIGEV_THREAD;
65 evp.sigev_notify_function = KalFunction;
66 evp.sigev_value.sival_ptr = kalTimer;
67 int ret = timer_create(CLOCK_REALTIME, &evp, &timer);
68 if (ret != 0) {
69 free(kalTimer);
70 return NULL;
71 }
72 kalTimer->timerPtr = timer;
73 kalTimer->millisec = millisec;
74 kalTimer->isRunning = 0;
75 return (KalTimerId)kalTimer;
76 }
77
KalTimerStart(KalTimerId timerId)78 KalErrCode KalTimerStart(KalTimerId timerId)
79 {
80 if (timerId == NULL) {
81 return KAL_ERR_PARA;
82 }
83 struct itimerspec ts = {0};
84 KalTimer* tmpPtr = (KalTimer *)timerId;
85 KalMs2TimeSpec(&ts.it_value, tmpPtr->millisec);
86 if (tmpPtr->type == KAL_TIMER_PERIODIC) {
87 KalMs2TimeSpec(&ts.it_interval, tmpPtr->millisec);
88 }
89 int ret = timer_settime(tmpPtr->timerPtr, 0, &ts, NULL);
90 if (ret != 0) {
91 return KAL_ERR_PARA;
92 }
93 if (tmpPtr->millisec != 0) {
94 tmpPtr->isRunning = 1;
95 }
96 return KAL_OK;
97 }
98
KalTimerChange(KalTimerId timerId,unsigned int millisec)99 KalErrCode KalTimerChange(KalTimerId timerId, unsigned int millisec)
100 {
101 if (timerId == NULL) {
102 return KAL_ERR_PARA;
103 }
104 KalTimer* tmpPtr = (KalTimer *)timerId;
105 struct itimerspec ts = {0};
106 tmpPtr->millisec = millisec;
107 if (tmpPtr->isRunning == 1) {
108 KalMs2TimeSpec(&ts.it_value, millisec);
109 if (tmpPtr->type == KAL_TIMER_PERIODIC) {
110 KalMs2TimeSpec(&ts.it_interval, millisec);
111 }
112 int ret = timer_settime(tmpPtr->timerPtr, 0, &ts, NULL);
113 if (ret != 0) {
114 tmpPtr->isRunning = 0;
115 return KAL_ERR_INNER;
116 }
117 if (millisec == 0) {
118 tmpPtr->isRunning = 0;
119 }
120 }
121 return KAL_OK;
122 }
123
KalTimerStop(KalTimerId timerId)124 KalErrCode KalTimerStop(KalTimerId timerId)
125 {
126 if (timerId == NULL) {
127 return KAL_ERR_PARA;
128 }
129 KalTimer* tmpPtr = (KalTimer *)timerId;
130 struct itimerspec ts = {0};
131 int ret = timer_settime(tmpPtr->timerPtr, 0, &ts, NULL);
132 if (ret != 0) {
133 return KAL_ERR_INNER;
134 }
135 tmpPtr->isRunning = 0;
136 return KAL_OK;
137 }
138
KalTimerDelete(KalTimerId timerId)139 KalErrCode KalTimerDelete(KalTimerId timerId)
140 {
141 if (timerId == NULL) {
142 return KAL_ERR_PARA;
143 }
144 KalTimer* tmpPtr = (KalTimer *)timerId;
145 int ret = timer_delete(tmpPtr->timerPtr);
146 free(timerId);
147 return (ret != 0) ? KAL_ERR_INNER : KAL_OK;
148 }
149
KalTimerIsRunning(KalTimerId timerId)150 unsigned int KalTimerIsRunning(KalTimerId timerId)
151 {
152 if (timerId == NULL) {
153 return 0;
154 }
155 return ((KalTimer *)timerId)->isRunning;
156 }