GCC Code Coverage Report


Directory: /home/runner/work/fprime/fprime/Svc/RateGroupDriver/
File: RateGroupDriver.cpp
Date: 2026-11-03 22:11:53
Exec Total Coverage
Lines: 22 22 100.0%
Functions: 4 4 100.0%
Branches: 9 12 75.0%

Line Branch Exec Source
1 #include <Fw/FPrimeBasicTypes.hpp>
2 #include <Fw/Types/Assert.hpp>
3 #include <Svc/RateGroupDriver/RateGroupDriver.hpp>
4 #include <Utils/Algorithms.hpp>
5 #include <cstdio>
6 #include <cstring>
7
8 namespace Svc {
9
10 1 RateGroupDriver::RateGroupDriver(const char* compName)
11 1 : RateGroupDriverComponentBase(compName), m_ticks(0), m_rollover(1), m_configured(false) {}
12
13 1 void RateGroupDriver::configure(const DividerSet& dividerSet) {
14 // verify port/table size matches
15 static_assert(FW_NUM_ARRAY_ELEMENTS(m_dividers) == NUM_CYCLEOUT_OUTPUT_PORTS,
16 "Divider table size must match the number of cycle output ports");
17 // reset rollover so a reconfigure does not carry over the prior rollover
18 1 this->m_rollover = 1;
19 // copy provided array of dividers
20
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (FwIndexType entry = 0; entry < RateGroupDriver::DIVIDER_SIZE; entry++) {
21 // A port with an offset equal or bigger than the divisor is not accepted because it would never be called
22 3 FW_ASSERT((dividerSet.dividers[entry].offset == 0) ||
23 (dividerSet.dividers[entry].offset < dividerSet.dividers[entry].divisor),
24 static_cast<FwAssertArgType>(dividerSet.dividers[entry].offset),
25 static_cast<FwAssertArgType>(dividerSet.dividers[entry].divisor));
26 3 this->m_dividers[entry] = dividerSet.dividers[entry];
27 // Rollover value should be the least common multiple of all dividers to make sure integer rollover doesn't jump
28 // cycles. Only use non-zero dividers:
29
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (dividerSet.dividers[entry].divisor != 0) {
30 3 this->m_rollover = Utils::lcm(this->m_rollover, dividerSet.dividers[entry].divisor);
31 }
32 }
33 1 this->m_configured = true;
34 1 }
35
36 2 RateGroupDriver::~RateGroupDriver() {}
37
38 262 void RateGroupDriver::CycleIn_handler(FwIndexType portNum, Os::RawTime& cycleStart) {
39 // Make sure that the dividers have been configured:
40 // If this asserts, add the configure() call to initialization.
41 262 FW_ASSERT(this->m_configured);
42
43 // Loop through each divider. For a given port, the port will be called when the divider value
44 // divides evenly into the number of ticks. For example, if the divider value for a port is 4,
45 // it would be called every fourth invocation of the CycleIn port.
46
2/2
✓ Branch 0 taken 786 times.
✓ Branch 1 taken 262 times.
1048 for (FwIndexType entry = 0; entry < RateGroupDriver::DIVIDER_SIZE; entry++) {
47
1/2
✓ Branch 0 taken 786 times.
✗ Branch 1 not taken.
786 if (this->m_dividers[entry].divisor != 0) {
48
1/2
✓ Branch 1 taken 786 times.
✗ Branch 2 not taken.
786 if (this->isConnected_CycleOut_OutputPort(static_cast<FwIndexType>(entry))) {
49
2/2
✓ Branch 0 taken 459 times.
✓ Branch 1 taken 327 times.
786 if ((this->m_ticks % this->m_dividers[entry].divisor) == this->m_dividers[entry].offset) {
50 459 this->CycleOut_out(static_cast<FwIndexType>(entry), cycleStart);
51 }
52 }
53 }
54 }
55
56 // rollover the tick value when the tick count reaches the rollover value
57 // the rollover value is the least common multiple of all the dividers.
58 262 FW_ASSERT(this->m_rollover > 0);
59 262 this->m_ticks = (this->m_ticks + 1) % this->m_rollover;
60 262 }
61
62 } // namespace Svc
63