1 /*
2 * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3 *
4 * UniProton is licensed under Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 * http://license.coscl.org.cn/MulanPSL2
8 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11 * See the Mulan PSL v2 for more details.
12 * Create: 2009-12-22
13 * Description: 软件定时器模块的C文件
14 */
15 #include "prt_swtmr_internal.h"
16
OsSwTmrGetRemain(struct TagSwTmrCtrl * swtmr)17 OS_SEC_L4_TEXT U32 OsSwTmrGetRemain(struct TagSwTmrCtrl *swtmr)
18 {
19 U32 retValue = 0;
20 U32 temp;
21 struct TagSwTmrCtrl *timer = NULL;
22 struct TagListObject *listObject = NULL;
23
24 temp = UWSORTINDEX(swtmr->idxRollNum);
25 if (temp <= g_tmrSortLink.cursor) {
26 temp = temp + OS_SWTMR_SORTLINK_LEN;
27 }
28 temp -= g_tmrSortLink.cursor;
29
30 listObject = g_tmrSortLink.sortLink + (uintptr_t)UWSORTINDEX(swtmr->idxRollNum);
31
32 timer = swtmr;
33
34 while (timer != (struct TagSwTmrCtrl *)listObject) {
35 retValue += UWROLLNUM(timer->idxRollNum);
36 timer = timer->prev;
37 }
38 retValue = retValue * OS_SWTMR_SORTLINK_LEN;
39 retValue = retValue + temp;
40
41 return retValue;
42 }
43
44 /*
45 * 描述:获取软件定时器剩余Tick数
46 */
OsSwTmrGetRemainTick(struct TagSwTmrCtrl * swtmr)47 OS_SEC_L4_TEXT U32 OsSwTmrGetRemainTick(struct TagSwTmrCtrl *swtmr)
48 {
49 U32 temp;
50 uintptr_t intSave;
51
52 intSave = OsIntLock();
53 switch (swtmr->state & OS_SWTMR_STATUS_MASK) {
54 case OS_TIMER_CREATED:
55 OsIntRestore(intSave);
56 return (swtmr->idxRollNum);
57 case OS_TIMER_EXPIRED:
58 OsIntRestore(intSave);
59 return 0;
60 default:
61 break;
62 }
63
64 temp = OsSwTmrGetRemain(swtmr);
65
66 OsIntRestore(intSave);
67 return temp;
68 }
69
70 /*
71 * 描述:软件定时器的暂停内部接口,定时器由Ticking状态迁移到Created状态
72 */
OsSwTmrStop(struct TagSwTmrCtrl * swtmr,bool reckonOff)73 OS_SEC_L2_TEXT void OsSwTmrStop(struct TagSwTmrCtrl *swtmr, bool reckonOff)
74 {
75 U32 idx;
76 struct TagListObject *listObject = NULL;
77 uintptr_t intSave;
78
79 intSave = OsIntLock();
80 /* if the stoping node have next node ,set its rollnum to the next node's */
81 idx = UWSORTINDEX(swtmr->idxRollNum);
82 listObject = (g_tmrSortLink.sortLink + idx);
83 if (swtmr->next != (struct TagSwTmrCtrl *)listObject) {
84 UWROLLNUMADD(swtmr->next->idxRollNum, swtmr->idxRollNum);
85 }
86
87 if (!reckonOff) {
88 /* 调用获取定时器剩余Tick数内部接口 */
89 swtmr->idxRollNum = OsSwTmrGetRemainTick(swtmr);
90 }
91
92 swtmr->next->prev = swtmr->prev;
93 swtmr->prev->next = swtmr->next;
94 /* 定时器被暂停,修改定时器状态 */
95 swtmr->state = (U8)OS_TIMER_CREATED;
96 swtmr->next = NULL;
97 swtmr->prev = NULL;
98
99 OsIntRestore(intSave);
100 }
101
102 /*
103 * 描述:软件定时器的删除内部接口
104 */
OsSwTmrDelete(struct TagSwTmrCtrl * swtmr)105 OS_SEC_L2_TEXT void OsSwTmrDelete(struct TagSwTmrCtrl *swtmr)
106 {
107 /*
108 * 插入到空闲链表中
109 */
110 swtmr->next = g_tmrFreeList;
111 g_tmrFreeList = swtmr;
112 swtmr->state = (U8)OS_TIMER_FREE;
113 }
114
115 /*
116 * 描述:软件定时器的启动接口
117 */
OsSwTmrStartTimer(TimerHandle tmrHandle)118 OS_SEC_L2_TEXT U32 OsSwTmrStartTimer(TimerHandle tmrHandle)
119 {
120 struct TagSwTmrCtrl *swtmr = NULL;
121 uintptr_t intSave;
122
123 if (OS_TIMER_GET_INDEX(tmrHandle) >= g_swTmrMaxNum) {
124 return OS_ERRNO_TIMER_HANDLE_INVALID;
125 }
126
127 // 转化为软件定时器内部ID号
128 swtmr = g_swtmrCbArray + OS_SWTMR_ID_2_INDEX(tmrHandle);
129 intSave = OsSwtmrIqrSplLock(swtmr);
130
131 switch (swtmr->state & OS_SWTMR_STATUS_MASK) {
132 case OS_TIMER_FREE:
133 OsSwtmrIqrSplUnlock(swtmr, intSave);
134 return OS_ERRNO_SWTMR_NOT_CREATED;
135 case OS_TIMER_EXPIRED:
136 swtmr->state = OS_SWTMR_PRE_RUNNING | (U8)OS_TIMER_EXPIRED;
137 OsSwtmrIqrSplUnlock(swtmr, intSave);
138 return OS_OK;
139 case OS_TIMER_RUNNING:
140 OsSwtmrIqrSplUnlock(swtmr, intSave);
141 return OS_OK;
142 default:
143 break;
144 }
145
146 if (swtmr->idxRollNum == 0) {
147 // ,定时器超时处理后或者在超时处理函数中停止定时器,剩余时间置为0,启动定时器时再赋值swtmr->interval
148 swtmr->idxRollNum = swtmr->interval;
149 }
150
151 OsSwTmrStart(swtmr, swtmr->idxRollNum);
152
153 OsSwtmrIqrSplUnlock(swtmr, intSave);
154
155 return OS_OK;
156 }
157
158 /*
159 * 描述:软件定时器的暂停接口
160 */
OsSwTmrStopTimer(TimerHandle tmrHandle)161 OS_SEC_L2_TEXT U32 OsSwTmrStopTimer(TimerHandle tmrHandle)
162 {
163 struct TagSwTmrCtrl *swtmr = NULL;
164 uintptr_t intSave;
165
166 if (OS_TIMER_GET_INDEX(tmrHandle) >= g_swTmrMaxNum) {
167 return OS_ERRNO_TIMER_HANDLE_INVALID;
168 }
169
170 swtmr = g_swtmrCbArray + OS_SWTMR_ID_2_INDEX(tmrHandle);
171 intSave = OsSwtmrIqrSplLock(swtmr);
172
173 switch (swtmr->state & OS_SWTMR_STATUS_MASK) {
174 case OS_TIMER_FREE:
175 OsSwtmrIqrSplUnlock(swtmr, intSave);
176 return OS_ERRNO_SWTMR_NOT_CREATED;
177 case OS_TIMER_EXPIRED:
178 swtmr->state = OS_SWTMR_PRE_CREATED | (U8)OS_TIMER_EXPIRED;
179 OsSwtmrIqrSplUnlock(swtmr, intSave);
180 return OS_OK;
181 case OS_TIMER_CREATED:
182 OsSwtmrIqrSplUnlock(swtmr, intSave);
183 return OS_ERRNO_SWTMR_UNSTART;
184 default:
185 break;
186 }
187 /*
188 * 调用暂停定时器内部接口,在暂停时计算剩余时间
189 */
190 OsSwTmrStop(swtmr, FALSE);
191
192 OsSwtmrIqrSplUnlock(swtmr, intSave);
193 return OS_OK;
194 }
195
OsSwTmrRestartTimer(TimerHandle tmrHandle)196 OS_SEC_L2_TEXT U32 OsSwTmrRestartTimer(TimerHandle tmrHandle)
197 {
198 struct TagSwTmrCtrl *swtmr = NULL;
199 uintptr_t intSave;
200
201 if (OS_TIMER_GET_INDEX(tmrHandle) >= g_swTmrMaxNum) {
202 return OS_ERRNO_TIMER_HANDLE_INVALID;
203 }
204
205 // 转化为软件定时器内部ID?
206 swtmr = g_swtmrCbArray + OS_SWTMR_ID_2_INDEX(tmrHandle);
207 intSave = OsSwtmrIqrSplLock(swtmr);
208
209 switch (swtmr->state & OS_SWTMR_STATUS_MASK) {
210 case OS_TIMER_FREE:
211 OsSwtmrIqrSplUnlock(swtmr, intSave);
212 return OS_ERRNO_SWTMR_NOT_CREATED;
213 case OS_TIMER_EXPIRED:
214 swtmr->state = OS_SWTMR_PRE_RUNNING | (U8)OS_TIMER_EXPIRED;
215 OsSwtmrIqrSplUnlock(swtmr, intSave);
216 return OS_OK;
217 case OS_TIMER_RUNNING:
218 OsSwTmrStop(swtmr, TRUE);
219 break;
220 default:
221 break;
222 }
223
224 OsSwTmrStart(swtmr, swtmr->interval);
225
226 OsSwtmrIqrSplUnlock(swtmr, intSave);
227
228 return OS_OK;
229 }
230
231 /*
232 * 描述:查询软件定时器剩余超时时间
233 */
OsSwTmrQuery(TimerHandle tmrHandle,U32 * expireTime)234 OS_SEC_L2_TEXT U32 OsSwTmrQuery(TimerHandle tmrHandle, U32 *expireTime)
235 {
236 struct TagSwTmrCtrl *swtmr = NULL;
237 uintptr_t intSave;
238 U32 remainTick;
239 U32 remainMs;
240
241 if (OS_TIMER_GET_INDEX(tmrHandle) >= g_swTmrMaxNum) {
242 return OS_ERRNO_TIMER_HANDLE_INVALID;
243 }
244
245 // 转化为软件定时器内部ID
246 swtmr = g_swtmrCbArray + OS_SWTMR_ID_2_INDEX(tmrHandle);
247 intSave = OsSwtmrIqrSplLock(swtmr);
248
249 if (swtmr->state == (U8)OS_TIMER_FREE) {
250 OsSwtmrIqrSplUnlock(swtmr, intSave);
251 return OS_ERRNO_SWTMR_NOT_CREATED;
252 }
253
254 /* 调用获取定时器剩余Tick数内部接口 */
255 remainTick = OsSwTmrGetRemainTick(swtmr);
256 remainMs = (U32)DIV64(((U64)remainTick * OS_SYS_MS_PER_SECOND), g_tickModInfo.tickPerSecond);
257 if (DIV64_REMAIN((U64)remainTick * OS_SYS_MS_PER_SECOND, g_tickModInfo.tickPerSecond) != 0) { // 若不整除,则+1
258 remainMs++;
259 }
260
261 *expireTime = remainMs;
262
263 OsSwtmrIqrSplUnlock(swtmr, intSave);
264 return OS_OK;
265 }
266