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 25typedef 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 34static 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 43static 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 50KalTimerId 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 78KalErrCode 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 99KalErrCode 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 124KalErrCode 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 139KalErrCode 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 150unsigned int KalTimerIsRunning(KalTimerId timerId) 151{ 152 if (timerId == NULL) { 153 return 0; 154 } 155 return ((KalTimer *)timerId)->isRunning; 156}