Svc::RateGroupDriver Component
1. Introduction
The RateGroupDriver Component is used to take a single system tick and distribute it to multiple rate groups in a system.
It takes the input Svc::Sched port, then divides down the tick rate based on arguments to the constructor.
Typically, the output ports would be connected to the asynchronous inputs of an ActiveRateGroup.
2. Requirements
The requirements for RateGroupDriver are as follows:
| Requirement | Description | Verification Method |
|---|---|---|
| RGD-001 | The 'Svc::RateGroupDriver' component shall divide a primary system tick into the needed rate groups | Unit Test |
| RCD-002 | The 'Svc::RateGroupDriver' component shall be able to run in ISR context | Inspection |
3. Design
3.1 Context
3.1.1 Component Diagram
The Svc::RateGroupDriver component has the following component diagram:

3.1.2 Ports
The Svc::RateGroupDriver component uses the following port types:
| Port Data Type | Name | Direction | Kind | Usage |
|---|---|---|---|---|
Svc::Cycle |
CycleIn | Input | Synchronous | Receive the system tick |
Svc::Cycle |
CycleOut | Output | n/a | Used to drive rate groups |
3.2 Functional Description
The Svc::RateGroupDriver component has one input port that receives a system tick.
The configure() function is passed a divider set that specifies the divisors and offsets for each output port. This should be called after the constructor but before any port calls are made. The contents of the structure are copied during the call, so the array can be a temporary variable.
DividerSet holds one Divider{divisor, offset} entry per CycleOut port, indexed by output port number. The divider contract is:
- The component keeps a tick counter that starts at zero and increments on every
CycleIncall. - Output port
nis called on a tick whenticks % dividers[n].divisor == dividers[n].offset, so the input rate is divided down bydivisorand the output is shifted byoffsetticks. Different offsets let rate groups with the same divisor run on different ticks. - A
divisorof0disables the output port; it is never called. This is the default for an entry that is not set. - The
offsetmust be0or less than thedivisor;configure()asserts otherwise because such a port would never be called. - The tick counter rolls over at the product of all non-zero divisors, so every port keeps its cadence across the rollover.
configure()asserts if this product would overflow.
The implementation will be ISR compliant by avoiding the following:
- Floating point calculations
- Taking mutexes
- Calling libraries with unknown side effects
- Long implementation
For instance,
CycleIn Rate |
dividers[0] |
CycleOut[0] |
dividers[1] |
CycleOut[1] |
dividers[2] |
CycleOut[2] |
|---|---|---|---|---|---|---|
| 1Hz | {1, 0} | 1Hz (every tick) | {2, 0} | 0.5Hz (ticks 0, 2, 4, ...) | {2, 1} | 0.5Hz (ticks 1, 3, 5, ...) |
3.3 Scenarios
3.3.1 System Tick Port Call
As described in the Functional Description section, the RateGroupDriver component accepts calls to CycleIn and divides them down to the CycleOut ports:
3.4 State
RateGroupDriver has no state machines.
3.5 Algorithms
RateGroupDriver has no significant algorithms.
4. Dictionary
No dictionary for this module
5. Module Checklists
| Checklist |
|---|
| Design |
| Code |
| Unit Test |
6. Unit Testing
To see unit test coverage run fprime-util check --coverage
7. Change Log
| Date | Description |
|---|---|
| 6/19/2015 | Design review edits |
| 7/22/2015 | Design review actions |
| 9/2/2015 | Unit test updates |