1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /**
33 * @defgroup los_tick
34 * @ingroup kernel
35 */
36
37 #ifndef _LOS_TICK_H
38 #define _LOS_TICK_H
39
40 #include "los_error.h"
41 #include "los_timer.h"
42
43 #ifdef __cplusplus
44 #if __cplusplus
45 extern "C" {
46 #endif /* __cplusplus */
47 #endif /* __cplusplus */
48
49 /**
50 * @ingroup los_tick
51 * Tick error code: The Tick configuration is incorrect.
52 *
53 * Value: 0x02000400
54 *
55 * Solution: Change values of the OS_SYS_CLOCK and LOSCFG_BASE_CORE_TICK_PER_SECOND
56 * system time configuration modules in Los_config.h.
57 */
58 #define LOS_ERRNO_TICK_CFG_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x00)
59
60 /**
61 * @ingroup los_tick
62 * Tick error code: The system tick timer uninitialized.
63 *
64 * Value: 0x02000401
65 *
66 * Solution: None.
67 */
68 #define LOS_ERRNO_TICK_NO_HWTIMER LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x01)
69
70 /**
71 * @ingroup los_tick
72 * Tick error code: The number of Ticks is too small.
73 *
74 * Value: 0x02000402
75 *
76 * Solution: Change values of the OS_SYS_CLOCK and LOSCFG_BASE_CORE_TICK_PER_SECOND
77 * system time configuration modules according to the SysTick_Config function.
78 */
79 #define LOS_ERRNO_TICK_PER_SEC_TOO_SMALL LOS_ERRNO_OS_ERROR(LOS_MOD_TICK, 0x02)
80
81 /**
82 * @ingroup los_tick
83 * @brief: System timer cycles get function.
84 *
85 * @par Description:
86 * This API is used to get system timer cycles.
87 *
88 * @attention:
89 * <ul><li>None.</li></ul>
90 *
91 * @param: None.
92 *
93 * @retval: current system cycles.
94 *
95 * @par Dependency:
96 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
97 * @see None.
98 *
99 * */
100 extern UINT64 LOS_SysCycleGet(VOID);
101
102 /**
103 * @ingroup los_tick
104 * Number of milliseconds in one second.
105 */
106 #define OS_SYS_MS_PER_SECOND 1000
107
108 /**
109 * @ingroup los_tick
110 * Ticks per second
111 */
112 extern UINT32 g_ticksPerSec;
113
114 /**
115 * @ingroup los_tick
116 * Cycles per Second
117 */
118 extern UINT32 g_uwCyclePerSec;
119
120 /**
121 * @ingroup los_tick
122 * Cycles per Tick
123 */
124 extern UINT32 g_cyclesPerTick;
125
126 /**
127 * @ingroup los_tick
128 * System Clock
129 */
130 extern UINT32 g_sysClock;
131
132 /**
133 * @ingroup los_tick
134 * Number of microseconds in one second.
135 */
136 #define OS_SYS_US_PER_SECOND 1000000
137
138 #define OS_SYS_NS_PER_SECOND 1000000000
139
140 #define OS_SYS_NS_PER_MS 1000000
141
142 #define OS_SYS_NS_PER_US 1000
143
144 #define OS_CYCLE_PER_TICK (g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND)
145
146 #define OS_NS_PER_CYCLE (OS_SYS_NS_PER_SECOND / g_sysClock)
147
148 #define OS_MS_PER_TICK (OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
149
150 #define OS_US_PER_TICK (OS_SYS_US_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
151
152 #define OS_NS_PER_TICK (OS_SYS_NS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND)
153
154 #define OS_SYS_CYCLE_TO_NS(cycle, freq) ((cycle) / (freq)) * OS_SYS_NS_PER_SECOND + \
155 ((cycle) % (freq) * OS_SYS_NS_PER_SECOND / (freq))
156
157 #define OS_SYS_NS_TO_CYCLE(time, freq) (((time) / OS_SYS_NS_PER_SECOND) * (freq) + \
158 ((time) % OS_SYS_NS_PER_SECOND) * (freq) / OS_SYS_NS_PER_SECOND)
159
160 #define OS_SYS_TICK_TO_CYCLE(ticks) (((UINT64)(ticks) * g_sysClock) / LOSCFG_BASE_CORE_TICK_PER_SECOND)
161
162 #define OS_SYS_CYCLE_TO_TICK(cycle) ((((UINT64)(cycle)) * LOSCFG_BASE_CORE_TICK_PER_SECOND) / g_sysClock)
163
164 /**
165 * @ingroup los_tick
166 * System time basic function error code: Null pointer.
167 *
168 * Value: 0x02000010
169 *
170 * Solution: Check whether the input parameter is null.
171 */
172 #define LOS_ERRNO_SYS_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x10)
173
174 /**
175 * @ingroup los_tick
176 * System time basic function error code: Invalid system clock configuration.
177 *
178 * Value: 0x02000011
179 *
180 * Solution: Configure a valid system clock in los_config.h.
181 */
182 #define LOS_ERRNO_SYS_CLOCK_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x11)
183
184 /**
185 * @ingroup los_tick
186 * System time basic function error code: This error code is not in use temporarily.
187 *
188 * Value: 0x02000012
189 *
190 * Solution: None.
191 */
192 #define LOS_ERRNO_SYS_MAXNUMOFCORES_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x12)
193
194 /**
195 * @ingroup los_tick
196 * System time error code: This error code is not in use temporarily.
197 *
198 * Value: 0x02000013
199 *
200 * Solution: None.
201 */
202 #define LOS_ERRNO_SYS_PERIERRCOREID_IS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x13)
203
204 /**
205 * @ingroup los_tick
206 * System time error code: This error code is not in use temporarily.
207 *
208 * Value: 0x02000014
209 *
210 * Solution: None.
211 */
212 #define LOS_ERRNO_SYS_HOOK_IS_FULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x14)
213
214 /**
215 * @ingroup los_tick
216 * System time error code: The Tick Timer must be registered before kernel initialization.
217 *
218 * Value: 0x02000015
219 *
220 * Solution: None.
221 */
222 #define LOS_ERRNO_SYS_TIMER_IS_RUNNING LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x15)
223
224 /**
225 * @ingroup los_tick
226 * System time error code: The tick timer method is NULL.
227 *
228 * Value: 0x02000016
229 *
230 * Solution: None.
231 */
232 #define LOS_ERRNO_SYS_HOOK_IS_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x16)
233
234 /**
235 * @ingroup los_tick
236 * System time error code: The tick timer addr fault.
237 *
238 * Value: 0x02000017
239 *
240 * Solution: None.
241 */
242 #define LOS_ERRNO_SYS_TIMER_ADDR_FAULT LOS_ERRNO_OS_ERROR(LOS_MOD_SYS, 0x16)
243
244 /**
245 * @ingroup los_tick
246 * system time structure.
247 */
248 typedef struct TagSysTime {
249 UINT16 uwYear; /**< value 1970 ~ 2038 or 1970 ~ 2100 */
250 UINT8 ucMonth; /**< value 1 - 12 */
251 UINT8 ucDay; /**< value 1 - 31 */
252 UINT8 ucHour; /**< value 0 - 23 */
253 UINT8 ucMinute; /**< value 0 - 59 */
254 UINT8 ucSecond; /**< value 0 - 59 */
255 UINT8 ucWeek; /**< value 0 - 6 */
256 } SYS_TIME_S;
257
258 UINT64 OsTickTimerReload(UINT64 period);
259
260 #if (LOSCFG_BASE_CORE_TICK_WTIMER == 0)
261 VOID OsTickTimerBaseReset(UINT64 currTime);
262 #endif
263
264 UINT32 OsTickTimerInit(VOID);
265
266 VOID OsTickSysTimerStartTimeSet(UINT64 currTime);
267
OsTimeConvertFreq(UINT64 time,UINT32 oldFreq,UINT32 newFreq)268 STATIC INLINE UINT64 OsTimeConvertFreq(UINT64 time, UINT32 oldFreq, UINT32 newFreq)
269 {
270 if (oldFreq >= newFreq) {
271 return (time / (oldFreq / newFreq));
272 }
273
274 return (time * (newFreq / oldFreq));
275 }
276
277 /**
278 * @ingroup los_tick
279 * @brief Adjust the system tick timer clock frequency function hooks.
280 *
281 * @par Description:
282 * This API is used to adjust the system tick timer clock frequency.
283 * @attention
284 * <ul>
285 * <li>None</li>
286 * </ul>
287 *
288 * @param param [IN] Function parameters.
289 *
290 * @retval 0: Adjust the system tick timer clock frequency failed.
291 * @retval more than zero: Adjust after the system tick timer clock frequency.
292 * @par Dependency:
293 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
294 * @see None
295 */
296 typedef UINT32 (*SYS_TICK_FREQ_ADJUST_FUNC)(UINTPTR param);
297
298 /**
299 * @ingroup los_tick
300 * @brief Adjust the system tick timer clock frequency.
301 *
302 * @par Description:
303 * This API is used to adjust the system tick timer clock frequency.
304 * @attention
305 * <ul>
306 * <li>This function needs to be invoked only when the clock frequency of the system tick timer adjust as a result of
307 * changing the CPU frequency.</li>
308 * </ul>
309 *
310 * @param handler [IN] Adjust the system tick timer clock frequency function hooks.
311 * @param param [IN] Function parameters.
312 *
313 * @retval LOS_OK or Error code.
314 * @par Dependency:
315 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
316 * @see None
317 */
318 extern UINT32 LOS_SysTickClockFreqAdjust(const SYS_TICK_FREQ_ADJUST_FUNC handler, UINTPTR param);
319
320 /**
321 * @ingroup los_tick
322 * @brief Obtain the number of Ticks.
323 *
324 * @par Description:
325 * This API is used to obtain the number of Ticks.
326 * @attention
327 * <ul>
328 * <li>None</li>
329 * </ul>
330 *
331 * @param None
332 *
333 * @retval UINT64 The number of Ticks.
334 * @par Dependency:
335 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
336 * @see None
337 */
338 extern UINT64 LOS_TickCountGet(VOID);
339
340 /**
341 * @ingroup los_tick
342 * @brief Obtain the number of cycles in one second.
343 *
344 * @par Description:
345 * This API is used to obtain the number of cycles in one second.
346 * @attention
347 * <ul>
348 * <li>None</li>
349 * </ul>
350 *
351 * @param None
352 *
353 * @retval UINT32 Number of cycles obtained in one second.
354 * @par Dependency:
355 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
356 * @see None
357 */
358 extern UINT32 LOS_CyclePerTickGet(VOID);
359
360 /**
361 * @ingroup los_tick
362 * @brief Convert Ticks to milliseconds.
363 *
364 * @par Description:
365 * This API is used to convert Ticks to milliseconds.
366 * @attention
367 * <ul>
368 * <li>The number of milliseconds obtained through the conversion is 32-bit.</li>
369 * </ul>
370 *
371 * @param ticks [IN] Number of Ticks. The value range is (0,OS_SYS_CLOCK).
372 *
373 * @retval UINT32 Number of milliseconds obtained through the conversion. Ticks are successfully converted to
374 * milliseconds.
375 * @par Dependency:
376 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
377 * @see LOS_MS2Tick
378 */
379 extern UINT32 LOS_Tick2MS(UINT32 ticks);
380
381 /**
382 * @ingroup los_tick
383 * @brief Convert milliseconds to Ticks.
384 *
385 * @par Description:
386 * This API is used to convert milliseconds to Ticks.
387 * @attention
388 * <ul>
389 * <li>If the parameter passed in is equal to 0xFFFFFFFF, the retval is 0xFFFFFFFF. Pay attention to the value to be
390 * converted because data possibly overflows.</li>
391 * </ul>
392 *
393 * @param millisec [IN] Number of milliseconds.
394 *
395 * @retval UINT32 Number of Ticks obtained through the conversion.
396 * @par Dependency:
397 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
398 * @see LOS_Tick2MS
399 */
400 extern UINT32 LOS_MS2Tick(UINT32 millisec);
401
402 /**
403 * @ingroup los_tick
404 * @brief Re-initializes the system tick timer.
405 *
406 * @par Description:
407 * This API is used to re-initialize the system Tick timer.
408 * @attention
409 *
410 * @param timer [IN] Specify the tick timer.
411 * @param tickHandler [IN] Tick Interrupts the execution of the hook function.
412 *
413 * @retval LOS_OK or Error code.
414 * @par Dependency:
415 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
416 * @see
417 */
418 extern UINT32 LOS_TickTimerRegister(const ArchTickTimer *timer, const HWI_PROC_FUNC tickHandler);
419
420 /* *
421 * @ingroup los_task
422 * @brief: cpu delay.
423 *
424 * @par Description:
425 * This API is used to cpu delay, no task switching.
426 *
427 * @attention:
428 * <ul><li>None.</li></ul>
429 *
430 * @param UINT64 [IN] delay times, microseconds.
431 *
432 * @retval: None.
433 * @par Dependency:
434 * <ul><li>los_task.h: the header file that contains the API declaration.</li></ul>
435 * @see None.
436 */
437 extern VOID LOS_UDelay(UINT64 microseconds);
438
439 /* *
440 * @ingroup los_task
441 * @brief: cpu delay.
442 *
443 * @par Description:
444 * This API is used to cpu delay, no task switching.
445 *
446 * @attention:
447 * <ul><li>None.</li></ul>
448 *
449 * @param UINT32 [IN] delay times, millisecond.
450 *
451 * @retval: None.
452 * @par Dependency:
453 * <ul><li>los_task.h: the header file that contains the API declaration.</li></ul>
454 * @see None.
455 */
456 extern VOID LOS_MDelay(UINT32 millisec);
457
458 /* *
459 * @ingroup los_task
460 * @brief: cpu nanosecond get.
461 *
462 * @par Description:
463 * This API is used to get the current number of nanoseconds.
464 *
465 * @attention:
466 * <ul><li>None.</li></ul>
467 *
468 * @param none.
469 *
470 * @retval: None.
471 * @par Dependency:
472 * <ul><li>los_task.h: the header file that contains the API declaration.</li></ul>
473 * @see None.
474 */
475 extern UINT64 LOS_CurrNanosec(VOID);
476
477 /**
478 * @ingroup los_tick
479 * @brief Handle the system tick timeout.
480 *
481 * @par Description:
482 * This API is called when the system tick timeout and triggers the interrupt.
483 *
484 * @attention
485 * <ul>
486 * <li>None.</li>
487 * </ul>
488 *
489 * @param none.
490 *
491 * @retval None.
492 * @par Dependency:
493 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
494 * @see None.
495 */
496 extern VOID OsTickHandler(VOID);
497
498 /**
499 * @ingroup los_tick
500 * Define the CPU Tick structure.
501 */
502 typedef struct TagCpuTick {
503 UINT32 cntHi; /* < Upper 32 bits of the tick value */
504 UINT32 cntLo; /* < Lower 32 bits of the tick value */
505 } CpuTick;
506
507 /**
508 * @ingroup los_tick
509 * Number of operable bits of a 32-bit operand
510 */
511 #define OS_SYS_MV_32_BIT 32
512
513 /**
514 * @ingroup los_tick
515 * Number of milliseconds in one second.
516 */
517 #define OS_SYS_MS_PER_SECOND 1000
518
519 /**
520 * @ingroup los_tick
521 * Number of microseconds in one second.
522 */
523 #define OS_SYS_US_PER_SECOND 1000000
524
525 #define OS_SYS_US_PER_MS 1000
526
527 /**
528 * @ingroup los_tick
529 * The maximum length of name.
530 */
531 #define OS_SYS_APPVER_NAME_MAX 64
532
533 /**
534 * @ingroup los_tick
535 * The magic word.
536 */
537 #define OS_SYS_MAGIC_WORD 0xAAAAAAAA
538
539 /**
540 * @ingroup los_tick
541 * The initialization value of stack space.
542 */
543 #define OS_SYS_EMPTY_STACK 0xCACACACA
544
545 /**
546 * @ingroup los_tick
547 * @brief Convert cycles to milliseconds.
548 *
549 * @par Description:
550 * This API is used to convert cycles to milliseconds.
551 * @attention
552 * <ul>
553 * <li>None.</li>
554 * </ul>
555 *
556 * @param cpuTick [IN] Number of CPU cycles.
557 * @param msHi [OUT] Upper 32 bits of the number of milliseconds.
558 * @param msLo [OUT] Lower 32 bits of the number of milliseconds.
559 *
560 * @retval #LOS_ERRNO_SYS_PTR_NULL 0x02000011: Invalid parameter.
561 * @retval #LOS_OK 0: Cycles are successfully converted to microseconds.
562 * @par Dependency:
563 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
564 * @see None.
565 */
566 extern UINT32 OsCpuTick2MS(CpuTick *cpuTick, UINT32 *msHi, UINT32 *msLo);
567
568 /**
569 * @ingroup los_tick
570 * @brief Convert cycles to microseconds.
571 *
572 * @par Description:
573 * This API is used to convert cycles to microseconds.
574 * @attention
575 * <ul>
576 * <li>None.</li>
577 * </ul>
578 *
579 * @param cpuTick [IN] Number of CPU cycles.
580 * @param usHi [OUT] Upper 32 bits of the number of microseconds.
581 * @param usLo [OUT] Lower 32 bits of the number of microseconds.
582 *
583 * @retval #LOS_ERRNO_SYS_PTR_NULL 0x02000011: Invalid parameter.
584 * @retval #LOS_OK 0: Cycles are successfully converted to microseconds.
585 * @par Dependency:
586 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
587 * @see None.
588 */
589 extern UINT32 OsCpuTick2US(CpuTick *cpuTick, UINT32 *usHi, UINT32 *usLo);
590
591 /**
592 * @ingroup los_tick
593 * @brief Convert cycles to milliseconds.
594 *
595 * @par Description:
596 * This API is used to convert cycles to milliseconds.
597 * @attention
598 * <ul>
599 * <li>None.</li>
600 * </ul>
601 *
602 * @param cycle [IN] Number of cycles.
603 *
604 * @retval Number of milliseconds obtained through the conversion. Cycles are successfully converted to milliseconds.
605 * @par Dependency:
606 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
607 * @see None.
608 */
OsCycle2MS(UINT64 cycle)609 STATIC_INLINE UINT64 OsCycle2MS(UINT64 cycle)
610 {
611 return (UINT64)((cycle / (g_sysClock / OS_SYS_MS_PER_SECOND)));
612 }
613
614 /**
615 * @ingroup los_tick
616 * @brief Convert cycles to microseconds.
617 *
618 * @par Description:
619 * This API is used to convert cycles to microseconds.
620 * @attention
621 * <ul>
622 * <li>None.</li>
623 * </ul>
624 *
625 * @param cycle [IN] Number of cycles.
626 *
627 * @retval Number of microseconds obtained through the conversion. Cycles are successfully converted to microseconds.
628 * @par Dependency:
629 * <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
630 * @see None.
631 */
OsCycle2US(UINT64 cycle)632 STATIC_INLINE UINT64 OsCycle2US(UINT64 cycle)
633 {
634 UINT64 tmp = g_sysClock / OS_SYS_US_PER_SECOND;
635 if (tmp == 0) {
636 return 0;
637 }
638 return (UINT64)(cycle / tmp);
639 }
640
641
642 #ifdef __cplusplus
643 #if __cplusplus
644 }
645 #endif /* __cplusplus */
646 #endif /* __cplusplus */
647
648 #endif /* _LOS_TICK_H */
649