• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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