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 "SolidSyslogFreeRtosSysUpTime.h"
6 : :
7 : : #include "FreeRTOS.h"
8 : : #include "task.h"
9 : :
10 : : #if (configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS)
11 : :
12 : : enum
13 : : {
14 : : HUNDREDTHS_PER_SECOND = 100
15 : : };
16 : :
17 : : static uint64_t FreeRtosSysUpTime_Extend(uint32_t nowTicks);
18 : : static uint32_t FreeRtosSysUpTime_Hundredths(uint64_t ticks);
19 : :
20 : 8 : uint32_t SolidSyslogFreeRtos_GetSysUpTime(void)
21 : : {
22 : : /* Extend touches shared state and runs wherever a message is formatted,
23 : : * which may be more than one task. The scaling is pure and stays out. */
24 : : taskENTER_CRITICAL();
25 : 8 : uint64_t ticks = FreeRtosSysUpTime_Extend((uint32_t) xTaskGetTickCount());
26 : : taskEXIT_CRITICAL();
27 : :
28 : 8 : return FreeRtosSysUpTime_Hundredths(ticks);
29 : : }
30 : :
31 : : /* The counter cannot say how often it has wrapped, so the phase is kept here.
32 : : * Missing a wrap needs 50 days of silence at 1000 Hz; every message calls in. */
33 : 8 : static uint64_t FreeRtosSysUpTime_Extend(uint32_t nowTicks)
34 : : {
35 : : static uint32_t lastTicks;
36 : : static uint32_t rollovers;
37 : :
38 [ + + ]: 8 : if (nowTicks < lastTicks)
39 : : {
40 : 5 : rollovers++;
41 : : }
42 : 8 : lastTicks = nowTicks;
43 : :
44 : 8 : return ((uint64_t) rollovers << 32U) | (uint64_t) nowTicks;
45 : : }
46 : :
47 : 8 : static uint32_t FreeRtosSysUpTime_Hundredths(uint64_t ticks)
48 : : {
49 : : /* Divide before scaling so the intermediate cannot overflow; the uint32
50 : : * cast wraps at 2^32 hundredths, as RFC 3418 TimeTicks does. */
51 : 8 : uint64_t wholeSecondHundredths = (ticks / configTICK_RATE_HZ) * HUNDREDTHS_PER_SECOND;
52 : 8 : uint64_t subSecondHundredths = ((ticks % configTICK_RATE_HZ) * HUNDREDTHS_PER_SECOND) / configTICK_RATE_HZ;
53 : 8 : return (uint32_t) (wholeSecondHundredths + subSecondHundredths);
54 : : }
55 : :
56 : : #endif /* configTICK_TYPE_WIDTH_IN_BITS */
|