Skip to content

Commit ec0b087

Browse files
authored
rate-group.md: replaced the hardcoded example with a redirect from the core libraries
1 parent a7b437e commit ec0b087

File tree

1 file changed

+3
-29
lines changed

1 file changed

+3
-29
lines changed

docs/user-manual/design-patterns/rate-group.md

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,15 @@ system clock and the port call to rate group driver's `CycleIn` port.
2525
The reference application calls the `CycleIn` port followed by a sleep for the system clock time within a while loop to
2626
simulate a system-driven clock.
2727

28-
**_Example_**: Recall a crystal oscillator running at 1000 HZ (or 1 MHZ), then a system clock source would sample each 1MHZ. Recall that a `RateGroupDriver` is registered to this system clock source sampler that requires to be updated at a rate of 100HZ; therefore the following applies:
28+
**_Example_**: Consider a crystal oscillator running at 1000 HZ (or 1 MHZ), then a system clock source would sample each 1MHZ. Recall that a `RateGroupDriver` is registered to this system clock source sampler that requires to be updated at a rate of 100HZ; therefore the following applies:
2929
* On the API layers level, both drivers; the `SystemSourceDriver`, and the `RateGroupDriver` shall be implementations of F' components; thus they could only communicate via ports (e.g., commands, events, and telemetry channels). In this case, the implementation could be taken towards commanding.
3030
* On the hardware level, the `SystemSourceDriver` shall use a clock divider that drives the `RateGroupDriver` each $$\frac{100HZ}{1MHZ}$$ of the system source sampler (i.e., at a rate of $$\frac{1}{10}$$ of the system source sampler).
3131
* On the hardware implementation level, this could be done via many approaches; a counter algorithm (that triggers an interrupt when reaching 100 cycles resetting the `numberOfCycles` each second) can suffice or a more complex modular arithmetics algorithm could be used (e.g., $$((ticks\ mod\ rate)\ ==\ offset) \implies CycleOut$$; where `ticks` represents the current system virtual clocks, `rate` represents the `RateGroupDriver` required frequency, and `offset` represents the remainder of the value at which sampling shall occur when the system clock `ticks` reaches the requested `rate`; Zero `offset` means that the system source sampler will sample this driver when it reaches an integer multiple of its requested `rate`).
3232

3333
> [!NOTE]
3434
> **Linking with the `Svc` core module:**
35-
> * Here is an optimized simple algorithm utilized internally by `Svc::RateGroupDriver`; where values captured from this algorithm can be encapsulated further in a `Divider` structure.
36-
> * This is essentially a variant of rate-controlled publish-subscriber pattern that samples the registered `RateGroupDriver` components by their requested sampling rate via their port channels:
37-
> ```cpp
38-
> ...
39-
> void RateGroupDriver::CycleIn_handler(FwIndexType portNum, Os::RawTime& cycleStart) {
40-
> // Make sure that the dividers have been configured:
41-
> // If this asserts, add the configure() call to initialization.
42-
> FW_ASSERT(this->m_configured);
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-
> for (FwIndexType entry = 0; entry < RateGroupDriver::DIVIDER_SIZE; entry++) {
47-
> // 1) Input Validation (Divisor and Port connection validation).
48-
> if (0 == this->m_dividers[entry].divisor ||
49-
> !(this->isConnected_CycleOut_OutputPort(static_cast<FwIndexType>(entry)))) {
50-
> continue;
51-
> }
52-
> // 2) Perform a virtual clock prescaling using an integer division arithmetics and test against the required sampling rate.
53-
> if ((this->m_ticks % this->m_dividers[entry].divisor) == this->m_dividers[entry].offset) {
54-
> this->CycleOut_out(static_cast<FwIndexType>(entry),cycleStart);
55-
> }
56-
> }
57-
> // rollover the tick value when the tick count reaches the rollover value
58-
> // the rollover value is the product of all the dividers. See comment in constructor.
59-
> this->m_ticks = (this->m_ticks + 1) % this->m_rollover;
60-
> }
61-
> ...
62-
> ```
35+
> * Here is the simple algorithm of `Svc::RateGroupDriver` implemented by the core libraries; where values captured from this algorithm can be encapsulated further in a `Divider` structure.
36+
> * This is essentially a variant of rate-controlled publish-subscriber pattern that samples the registered `RateGroupDriver` components by their requested sampling rate via their port channels: See [the Core Implementation `RateGroupDriver::CycleIn_handler(...)`](https://github.com/nasa/fprime/blob/devel/Svc/RateGroupDriver/RateGroupDriver.cpp).
6337
> * The algorithm utilized here provides a software-based analogous activity to [the clock prescaler digital circuits](https://en.wikipedia.org/wiki/Prescaler).
6438
>
6539

0 commit comments

Comments
 (0)