Branch data Line data Source code
1 : : /* SPDX-FileCopyrightText: Copyright 2026 Cozens Software Solutions Limited
2 : : * SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0 OR LicenseRef-PolyForm-Internal-Use-1.0.0 OR LicenseRef-COSOSO-Commercial
3 : : */
4 : :
5 : : #include "SolidSyslogCmsisRtosSysUpTime.h"
6 : :
7 : : #include <stdint.h>
8 : :
9 : : #include "cmsis_os2.h"
10 : :
11 : : enum
12 : : {
13 : : CMSISRTOS_SYS_UP_TIME_HUNDREDTHS_PER_SECOND = 100
14 : : };
15 : :
16 : : /* osKernelGetTickCount is 32-bit on every CMSIS-RTOS2 implementation and the
17 : : * counter cannot say how often it has wrapped, so the phase is kept here. */
18 : : static uint32_t CmsisRtosSysUpTime_LastTicks;
19 : : static uint32_t CmsisRtosSysUpTime_Rollovers;
20 : :
21 : : static uint64_t CmsisRtosSysUpTime_Extend(uint32_t nowTicks);
22 : : static uint32_t CmsisRtosSysUpTime_Hundredths(uint64_t ticks, uint32_t tickFreqHz);
23 : :
24 : 11 : uint32_t SolidSyslogCmsisRtos_GetSysUpTime(void)
25 : : {
26 : 11 : int32_t previousLock = osKernelLock();
27 : 11 : uint64_t ticks = CmsisRtosSysUpTime_Extend(osKernelGetTickCount());
28 : 11 : (void) osKernelRestoreLock(previousLock);
29 : :
30 : 11 : return CmsisRtosSysUpTime_Hundredths(ticks, osKernelGetTickFreq());
31 : : }
32 : :
33 : : /* Missing a wrap needs 50 days of silence at 1000 Hz; every message calls in. */
34 : 11 : static uint64_t CmsisRtosSysUpTime_Extend(uint32_t nowTicks)
35 : : {
36 [ + + ]: 11 : if (nowTicks < CmsisRtosSysUpTime_LastTicks)
37 : : {
38 : 1 : CmsisRtosSysUpTime_Rollovers++;
39 : : }
40 : 11 : CmsisRtosSysUpTime_LastTicks = nowTicks;
41 : :
42 : 11 : return ((uint64_t) CmsisRtosSysUpTime_Rollovers << 32U) | (uint64_t) nowTicks;
43 : : }
44 : :
45 : 11 : static uint32_t CmsisRtosSysUpTime_Hundredths(uint64_t ticks, uint32_t tickFreqHz)
46 : : {
47 : : /* Divide before scaling so the intermediate cannot overflow; the uint32
48 : : * cast wraps at 2^32 hundredths, as RFC 3418 TimeTicks does. */
49 : 11 : uint64_t wholeSecondHundredths = (ticks / tickFreqHz) * CMSISRTOS_SYS_UP_TIME_HUNDREDTHS_PER_SECOND;
50 : 11 : uint64_t subSecondHundredths = ((ticks % tickFreqHz) * CMSISRTOS_SYS_UP_TIME_HUNDREDTHS_PER_SECOND) / tickFreqHz;
51 : 11 : return (uint32_t) (wholeSecondHundredths + subSecondHundredths);
52 : : }
|