Skip to content

Commit 756bf64

Browse files
authored
fix: build the FreeRTOS pack at any tick rate (#756)
* fix: build the FreeRTOS pack at any tick rate The sysUpTime adapter carried a static assert requiring a 64-bit TickType_t, or a 32-bit one whose configTICK_RATE_HZ divides 100. The umbrella target compiles that translation unit unconditionally, so an ordinary 1000 Hz configuration cost the integrator the whole pack, the mutex included. Remove the assert. The adapter builds everywhere and its header states where the value wraps early; #755 tracks removing the limit itself. * docs: make the FreeRTOS uptime rollover period rate-specific
1 parent e268841 commit 756bf64

5 files changed

Lines changed: 25 additions & 34 deletions

File tree

Core/Interface/SolidSyslogMetaSd.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ SOLIDSYSLOG_EXTERN_C_BEGIN
1818
struct SolidSyslogAtomicCounter;
1919
struct SolidSyslogStructuredData;
2020

21-
/** Returns system uptime in hundredths of a second (RFC 3418 TimeTicks),
22-
* wrapping on overflow. Feeds the meta element's sysUpTime PARAM. */
21+
/** Returns system uptime in hundredths of a second (RFC 3418 TimeTicks):
22+
* monotonic, and wrapping to zero only at 2^32 hundredths. A source counter
23+
* that rolls over sooner must carry the phase across, or the value steps
24+
* backwards mid-range. Feeds the meta element's sysUpTime PARAM. */
2325
typedef uint32_t (*SolidSyslogSysUpTimeFunction)(void);
2426

2527
/** Wiring for the "meta" SD-ELEMENT (RFC 5424 §7.3). Whatever is provided

Platform/FreeRtos/Interface/SolidSyslogFreeRtosSysUpTime.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,11 @@
1111
SOLIDSYSLOG_EXTERN_C_BEGIN
1212

1313
/** Hundredths of a second of uptime from xTaskGetTickCount, for the meta-SD
14-
* sysUpTime field — a faithful RFC 3418 modulo-2^32 TimeTicks counter. A
15-
* compile-time guard rejects tick configurations whose counter would wrap
16-
* non-continuously mod 2^32. Supported envelope: a 64-bit TickType_t at any
17-
* tick rate (faithful over any realistic uptime — its wrap is millions of
18-
* years out), or a 32-bit TickType_t whose configTICK_RATE_HZ divides 100
19-
* (100/50/25/20/10/5/4/2/1 Hz — faithful for the counter's whole lifetime).
20-
* A 16-bit tick counter, or a 32-bit rate that does not divide 100
21-
* (including any rate above 100 Hz), fails to build (widen the tick type,
22-
* pick a dividing rate, or supply your own SolidSyslogSysUpTimeFunction). */
14+
* sysUpTime field. Meets the SolidSyslogSysUpTimeFunction contract for a
15+
* 64-bit TickType_t at any tick rate, and for a 32-bit one whose
16+
* configTICK_RATE_HZ divides 100. Elsewhere — the 1000 Hz default among
17+
* them — the value wraps to zero early, so supply your own
18+
* SolidSyslogSysUpTimeFunction where uptime matters. */
2319
uint32_t SolidSyslogFreeRtos_GetSysUpTime(void);
2420

2521
SOLIDSYSLOG_EXTERN_C_END

Platform/FreeRtos/Source/SolidSyslogFreeRtosSysUpTime.c

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,17 @@
33
#include "FreeRTOS.h"
44
#include "task.h"
55

6-
#include "SolidSyslogMacros.h"
7-
86
enum
97
{
108
HUNDREDTHS_PER_SECOND = 100
119
};
1210

13-
/* The uint32 result is a faithful RFC 3418 modulo-2^32 hundredths counter only
14-
* while every FreeRTOS tick-counter wrap stays phase-continuous mod 2^32. That
15-
* offset is zero for a 64-bit TickType_t at any tick rate (its wrap is millions
16-
* of years out, beyond any realistic uptime), or a 32-bit TickType_t whose
17-
* configTICK_RATE_HZ divides 100 (100/50/25/20/10/5/4/2/1 Hz) — then each tick
18-
* is an exact whole number of hundredths and the wrap lands cleanly. A 16-bit
19-
* tick counter, or a 32-bit rate that does not divide 100 (including any rate
20-
* above 100 Hz), injects a backwards jump at the wrap — refuse to build it
21-
* rather than ship a subtly wrong value. An integrator outside this envelope
22-
* should widen TickType_t (configTICK_TYPE_WIDTH_IN_BITS = TICK_TYPE_WIDTH_64_BITS),
23-
* pick a rate that divides 100, or supply their own SolidSyslogSysUpTimeFunction. */
24-
SOLIDSYSLOG_STATIC_ASSERT(
25-
(sizeof(TickType_t) >= 8U) || ((sizeof(TickType_t) >= 4U) && ((HUNDREDTHS_PER_SECOND % configTICK_RATE_HZ) == 0U)),
26-
"SolidSyslogFreeRtosSysUpTime needs a 64-bit TickType_t (any tick rate), or a 32-bit TickType_t "
27-
"with a configTICK_RATE_HZ that divides 100 (100/50/25/20/10/5/4/2/1 Hz), for a faithful RFC "
28-
"3418 TimeTicks; widen the tick type, use a dividing rate, or supply your own "
29-
"SolidSyslogSysUpTimeFunction."
30-
);
31-
3211
uint32_t SolidSyslogFreeRtos_GetSysUpTime(void)
3312
{
3413
/* Divide the tick count down before scaling by 100 so the intermediate
3514
* cannot overflow even a 64-bit TickType_t; the whole/remainder split is
36-
* exact floor division, and the uint32 cast wraps per RFC 3418 TimeTicks. */
15+
* exact floor division, and the uint32 cast wraps per RFC 3418 TimeTicks.
16+
* The header states which tick configurations wrap early. */
3717
uint64_t ticks = (uint64_t) xTaskGetTickCount();
3818
uint64_t wholeSecondHundredths = (ticks / configTICK_RATE_HZ) * HUNDREDTHS_PER_SECOND;
3919
uint64_t subSecondHundredths = ((ticks % configTICK_RATE_HZ) * HUNDREDTHS_PER_SECOND) / configTICK_RATE_HZ;

docs/platforms/freertos/index.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,16 @@ nothing at run time and cannot fail for want of heap.
3232
The sysUpTime callback reports kernel ticks since boot. It is not wall-clock
3333
time and carries no timezone or synchronisation quality — the clock callback is
3434
a separate injection point.
35+
36+
> [!WARNING]
37+
> `SolidSyslogFreeRtos_GetSysUpTime` meets the
38+
> [sysUpTime contract](../../api/SolidSyslogMetaSd_8h.md) for a 64-bit
39+
> `TickType_t` at any tick rate, and for a 32-bit one whose `configTICK_RATE_HZ`
40+
> divides 100. At every other rate the tick counter rolls over before 2^32
41+
> hundredths do, and the reported uptime loses phase there and returns to zero:
42+
> after 2^32 / `configTICK_RATE_HZ` seconds rather than RFC 3418's 497 days, so
43+
> roughly 50 days at the 1000 Hz FreeRTOS default and sooner as the rate rises.
44+
> Supply your own `SolidSyslogSysUpTimeFunction` from a time source you already
45+
> have, or move to a dividing rate or a 64-bit tick type. Converting correctly
46+
> at any tick rate is tracked as
47+
> [#755](https://github.com/cososo-ltd/solid-syslog/issues/755).

misra_suppressions.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ misra-c2012-5.7:Core/Source/SolidSyslogCircularBuffer.c:21
173173
misra-c2012-5.7:Core/Source/SolidSyslogCrc16.c:12
174174
misra-c2012-5.7:Core/Source/SolidSyslogCrc16Policy.c:10
175175
misra-c2012-5.7:Core/Source/SolidSyslogOriginSdPrivate.h:13
176-
misra-c2012-5.7:Platform/FreeRtos/Source/SolidSyslogFreeRtosSysUpTime.c:9
176+
misra-c2012-5.7:Platform/FreeRtos/Source/SolidSyslogFreeRtosSysUpTime.c:7
177177
misra-c2012-5.7:Platform/Posix/Source/SolidSyslogPosixHostname.c:10
178178
misra-c2012-5.7:Platform/Posix/Source/SolidSyslogPosixMessageQueueBuffer.c:25
179179
misra-c2012-5.7:Platform/Posix/Source/SolidSyslogPosixMessageQueueBufferPrivate.h:17

0 commit comments

Comments
 (0)