Finish code formatting (#4134)

This commit is contained in:
Thomas Boyer-Chammard 2025-09-10 15:02:07 -07:00 committed by GitHub
parent c8e2d44877
commit ba65039fff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
80 changed files with 2514 additions and 3120 deletions

View File

@ -31,11 +31,16 @@ jobs:
env: env:
# Svc is currently listing all but Svc/FpySequencer # Svc is currently listing all but Svc/FpySequencer
CHECKED_DIRS: >- CHECKED_DIRS: >-
CFDP
default
Drv Drv
FppTestProject FppTestProject
Fw Fw
Os Os
Ref
Svc Svc
TestUtils
Utils
run: | run: |
fprime-util format --check --dirs $CHECKED_DIRS fprime-util format --check --dirs $CHECKED_DIRS

View File

@ -14,133 +14,83 @@
#include "Fw/Types/Assert.hpp" #include "Fw/Types/Assert.hpp"
static U32 min(const U32 a, const U32 b) { static U32 min(const U32 a, const U32 b) {
return (a < b) ? a : b; return (a < b) ? a : b;
} }
namespace CFDP { namespace CFDP {
Checksum :: Checksum ::Checksum() : m_value(0) {}
Checksum() : m_value(0)
{
} Checksum ::Checksum(const U32 value) : m_value(value) {}
Checksum :: Checksum ::Checksum(const Checksum& original) {
Checksum(const U32 value) : m_value(value)
{
}
Checksum ::
Checksum(const Checksum &original)
{
this->m_value = original.getValue(); this->m_value = original.getValue();
} }
Checksum :: Checksum ::~Checksum() {}
~Checksum()
{
} Checksum& Checksum ::operator=(const Checksum& checksum) {
Checksum& Checksum ::
operator=(const Checksum& checksum)
{
this->m_value = checksum.m_value; this->m_value = checksum.m_value;
return *this; return *this;
} }
bool Checksum :: bool Checksum ::operator==(const Checksum& checksum) const {
operator==(const Checksum& checksum) const
{
return this->m_value == checksum.m_value; return this->m_value == checksum.m_value;
} }
bool Checksum :: bool Checksum ::operator!=(const Checksum& checksum) const {
operator!=(const Checksum& checksum) const return not(*this == checksum);
{ }
return not (*this == checksum);
}
U32 Checksum :: U32 Checksum ::getValue() const {
getValue() const
{
return this->m_value; return this->m_value;
} }
void Checksum :: void Checksum ::update(const U8* const data, const U32 offset, const U32 length) {
update(
const U8 *const data,
const U32 offset,
const U32 length
)
{
U32 index = 0; U32 index = 0;
// Add the first word unaligned if necessary // Add the first word unaligned if necessary
const U32 offsetMod4 = offset % 4; const U32 offsetMod4 = offset % 4;
if (offsetMod4 != 0) { if (offsetMod4 != 0) {
const U8 wordLength = static_cast<U8>(min(length, 4 - offsetMod4)); const U8 wordLength = static_cast<U8>(min(length, 4 - offsetMod4));
this->addWordUnaligned( this->addWordUnaligned(&data[index], static_cast<U8>(offset + index), wordLength);
&data[index], index += wordLength;
static_cast<U8>(offset + index),
wordLength
);
index += wordLength;
} }
// Add the middle words aligned // Add the middle words aligned
for ( ; index + 4 <= length; index += 4) { for (; index + 4 <= length; index += 4) {
addWordAligned(&data[index]); addWordAligned(&data[index]);
} }
// Add the last word unaligned if necessary // Add the last word unaligned if necessary
if (index < length) { if (index < length) {
const U8 wordLength = static_cast<U8>(length - index); const U8 wordLength = static_cast<U8>(length - index);
this->addWordUnaligned( this->addWordUnaligned(&data[index], static_cast<U8>(offset + index), wordLength);
&data[index],
static_cast<U8>(offset + index),
wordLength
);
} }
}
} void Checksum ::addWordAligned(const U8* const word) {
void Checksum ::
addWordAligned(const U8 *const word)
{
for (U8 i = 0; i < 4; ++i) { for (U8 i = 0; i < 4; ++i) {
addByteAtOffset(word[i], i); addByteAtOffset(word[i], i);
} }
} }
void Checksum :: void Checksum ::addWordUnaligned(const U8* word, const U8 position, const U8 length) {
addWordUnaligned(
const U8 *word,
const U8 position,
const U8 length
)
{
FW_ASSERT(length < 4); FW_ASSERT(length < 4);
U8 offset = position % 4; U8 offset = position % 4;
for (U8 i = 0; i < length; ++i) { for (U8 i = 0; i < length; ++i) {
addByteAtOffset(word[i], offset); addByteAtOffset(word[i], offset);
++offset; ++offset;
if (offset == 4) { if (offset == 4) {
offset = 0; offset = 0;
} }
} }
}
void Checksum ::
addByteAtOffset(
const U8 byte,
const U8 offset
)
{
FW_ASSERT(offset < 4);
const U32 addend = static_cast<U32>(byte) << (8*(3-offset));
this->m_value += addend;
}
} }
void Checksum ::addByteAtOffset(const U8 byte, const U8 offset) {
FW_ASSERT(offset < 4);
const U32 addend = static_cast<U32>(byte) << (8 * (3 - offset));
this->m_value += addend;
}
} // namespace CFDP

View File

@ -17,130 +17,120 @@
namespace CFDP { namespace CFDP {
//! \class Checksum //! \class Checksum
//! \brief Class representing a 32-bit checksum as mandated by the CCSDS File //! \brief Class representing a 32-bit checksum as mandated by the CCSDS File
//! Delivery Protocol. //! Delivery Protocol.
//! //!
//! This checksum is calculated by update of an existing 32-bit value //! This checksum is calculated by update of an existing 32-bit value
//! with the "next" 32-bit string drawn from the file data. Beginning //! with the "next" 32-bit string drawn from the file data. Beginning
//! at the start of the file, a 4-byte window moves up the file by four //! at the start of the file, a 4-byte window moves up the file by four
//! bytes per update. The update itself replaces the existing checksum //! bytes per update. The update itself replaces the existing checksum
//! with the byte-wise sum of the existing checksum and the file data //! with the byte-wise sum of the existing checksum and the file data
//! contained in the window. Overflows in the addition are permitted //! contained in the window. Overflows in the addition are permitted
//! and the carry discarded. //! and the carry discarded.
//! //!
//! If an update is to be made beginning at an offset into the file //! If an update is to be made beginning at an offset into the file
//! which is not aligned to a 4-byte boundary, the window is treated //! which is not aligned to a 4-byte boundary, the window is treated
//! as beginning at the last 4-byte boundary, but is left-zero-padded. //! as beginning at the last 4-byte boundary, but is left-zero-padded.
//! Similarly, where the file data for an update ends on an unaligned //! Similarly, where the file data for an update ends on an unaligned
//! byte, the window extends up to the next boundary and is //! byte, the window extends up to the next boundary and is
//! right-zero-padded. //! right-zero-padded.
//! //!
//! ## Example //! ## Example
//! //!
//! For buffer 0xDE 0xAD 0xBE 0xEF 0xCA 0xFE and initial zero checksum: //! For buffer 0xDE 0xAD 0xBE 0xEF 0xCA 0xFE and initial zero checksum:
//! //!
//! ------------------------------------ Update 1 //! ------------------------------------ Update 1
//! Window 0xDE 0xAD 0xBE 0xEF //! Window 0xDE 0xAD 0xBE 0xEF
//! Checksum 0xDEADBEEF //! Checksum 0xDEADBEEF
//! //!
//! ------------------------------------ Update 2 //! ------------------------------------ Update 2
//! Window 0xCA 0xFE //! Window 0xCA 0xFE
//! Checksum 0xDEADBEEF+ //! Checksum 0xDEADBEEF+
//! 0xCAFE0000 //! 0xCAFE0000
//! ---------- //! ----------
//! 0xA8ABBEEF <- Final value //! 0xA8ABBEEF <- Final value
class Checksum { class Checksum {
public:
// ----------------------------------------------------------------------
// Types
// ----------------------------------------------------------------------
public: public:
// ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- //! Construct a fresh Checksum object.
// Types Checksum();
// ----------------------------------------------------------------------
public: //! Construct a Checksum object and initialize it with a value.
Checksum(const U32 value);
// ---------------------------------------------------------------------- //! Copy a Checksum object.
// Construction and destruction Checksum(const Checksum& original);
// ----------------------------------------------------------------------
//! Construct a fresh Checksum object. //! Destroy a Checksum object.
Checksum(); ~Checksum();
//! Construct a Checksum object and initialize it with a value. public:
Checksum(const U32 value); // ----------------------------------------------------------------------
// Public instance methods
// ----------------------------------------------------------------------
//! Copy a Checksum object. //! Assign checksum to this.
Checksum(const Checksum &original); Checksum& operator=(const Checksum& checksum);
//! Destroy a Checksum object. //! Compare checksum and this for equality.
~Checksum(); bool operator==(const Checksum& checksum) const;
public: //! Compare checksum and this for inequality.
bool operator!=(const Checksum& checksum) const;
// ---------------------------------------------------------------------- //! Update the checksum value by accumulating words in the given data.
// Public instance methods //!
// ---------------------------------------------------------------------- //! \important The data and data-length passed to this method are specifically
//! those over which the update is made, rather than the entire
//! file. Typically, therefore, `data` will be a pointer to the
//! byte given by the offset, e.g. `&file_buffer[offset]`.
//!
void update(const U8* const data, //!< Beginning of the data over which to update.
const U32 offset, //!< Offset into the file at which the data begins.
const U32 length //!< Length of the update data in bytes.
);
//! Assign checksum to this. //! Get the checksum value
Checksum& operator=(const Checksum& checksum); U32 getValue() const;
//! Compare checksum and this for equality. private:
bool operator==(const Checksum& checksum) const; // ----------------------------------------------------------------------
// Private instance methods
// ----------------------------------------------------------------------
//! Compare checksum and this for inequality. //! Add a four-byte aligned word to the checksum value
bool operator!=(const Checksum& checksum) const; void addWordAligned(const U8* const word //! The word
);
//! Update the checksum value by accumulating words in the given data. //! Add a four-byte unaligned word to the checksum value
//! void addWordUnaligned(const U8* const word, //! The word
//! \important The data and data-length passed to this method are specifically const U8 position, //! The position of the word relative to the start of the file
//! those over which the update is made, rather than the entire const U8 length //! The number of valid bytes in the word
//! file. Typically, therefore, `data` will be a pointer to the );
//! byte given by the offset, e.g. `&file_buffer[offset]`.
//!
void update(const U8* const data, //!< Beginning of the data over which to update.
const U32 offset, //!< Offset into the file at which the data begins.
const U32 length //!< Length of the update data in bytes.
);
//! Get the checksum value //! Add byte to value at offset in word
U32 getValue() const; void addByteAtOffset(const U8 byte, //! The byte
const U8 offset //! The offset
);
private: private:
// ----------------------------------------------------------------------
// Private member variables
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- //! The accumulated checksum value
// Private instance methods U32 m_value;
// ---------------------------------------------------------------------- };
//! Add a four-byte aligned word to the checksum value } // namespace CFDP
void addWordAligned(
const U8 *const word //! The word
);
//! Add a four-byte unaligned word to the checksum value
void addWordUnaligned(
const U8 *const word, //! The word
const U8 position, //! The position of the word relative to the start of the file
const U8 length //! The number of valid bytes in the word
);
//! Add byte to value at offset in word
void addByteAtOffset(
const U8 byte, //! The byte
const U8 offset //! The offset
);
private:
// ----------------------------------------------------------------------
// Private member variables
// ----------------------------------------------------------------------
//! The accumulated checksum value
U32 m_value;
};
}
#endif #endif

View File

@ -14,19 +14,14 @@
namespace CFDP { namespace CFDP {
namespace GTest { namespace GTest {
void Checksums ::
compare(
const CFDP::Checksum& expected,
const CFDP::Checksum& actual
)
{
const U32 expectedValue = expected.getValue();
const U32 actualValue = actual.getValue();
ASSERT_EQ(expectedValue, actualValue);
}
}
void Checksums ::compare(const CFDP::Checksum& expected, const CFDP::Checksum& actual) {
const U32 expectedValue = expected.getValue();
const U32 actualValue = actual.getValue();
ASSERT_EQ(expectedValue, actualValue);
} }
} // namespace GTest
} // namespace CFDP

View File

@ -19,21 +19,20 @@
namespace CFDP { namespace CFDP {
namespace GTest { namespace GTest {
//! Utilities for testing Checksum operations //! Utilities for testing Checksum operations
//! //!
namespace Checksums { namespace Checksums {
void compare( void compare(const CFDP::Checksum& expected, //!< Expected value
const CFDP::Checksum& expected, //!< Expected value const CFDP::Checksum& actual //!< Actual value
const CFDP::Checksum& actual //!< Actual value );
);
}
}
} }
} // namespace GTest
} // namespace CFDP
#endif #endif

View File

@ -8,49 +8,47 @@
using namespace CFDP; using namespace CFDP;
const U8 data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; const U8 data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
const U32 expectedValue = const U32 expectedValue = (data[0] << 3 * 8) + (data[1] << 2 * 8) + (data[2] << 1 * 8) + data[3] + (data[4] << 3 * 8) +
(data[0] << 3*8) + (data[1] << 2*8) + (data[2] << 1*8) + data[3] + (data[5] << 2 * 8) + (data[6] << 1 * 8) + data[7];
(data[4] << 3*8) + (data[5] << 2*8) + (data[6] << 1*8) + data[7];
TEST(Checksum, OnePacket) { TEST(Checksum, OnePacket) {
Checksum checksum; Checksum checksum;
checksum.update(data, 0, 8); checksum.update(data, 0, 8);
ASSERT_EQ(expectedValue, checksum.getValue()); ASSERT_EQ(expectedValue, checksum.getValue());
} }
TEST(Checksum, TwoPacketsAligned) { TEST(Checksum, TwoPacketsAligned) {
Checksum checksum; Checksum checksum;
checksum.update(&data[0], 0, 4); checksum.update(&data[0], 0, 4);
checksum.update(&data[4], 4, 4); checksum.update(&data[4], 4, 4);
ASSERT_EQ(expectedValue, checksum.getValue()); ASSERT_EQ(expectedValue, checksum.getValue());
} }
TEST(Checksum, TwoPacketsUnaligned1) { TEST(Checksum, TwoPacketsUnaligned1) {
Checksum checksum; Checksum checksum;
checksum.update(&data[0], 0, 3); checksum.update(&data[0], 0, 3);
checksum.update(&data[3], 3, 5); checksum.update(&data[3], 3, 5);
ASSERT_EQ(expectedValue, checksum.getValue()); ASSERT_EQ(expectedValue, checksum.getValue());
} }
TEST(Checksum, TwoPacketsUnaligned2) { TEST(Checksum, TwoPacketsUnaligned2) {
Checksum checksum; Checksum checksum;
checksum.update(&data[0], 0, 5); checksum.update(&data[0], 0, 5);
checksum.update(&data[5], 5, 3); checksum.update(&data[5], 5, 3);
ASSERT_EQ(expectedValue, checksum.getValue()); ASSERT_EQ(expectedValue, checksum.getValue());
} }
TEST(Checksum, ThreePackets) { TEST(Checksum, ThreePackets) {
Checksum checksum; Checksum checksum;
checksum.update(&data[0], 0, 2); checksum.update(&data[0], 0, 2);
checksum.update(&data[2], 2, 3); checksum.update(&data[2], 2, 3);
checksum.update(&data[5], 5, 3); checksum.update(&data[5], 5, 3);
ASSERT_EQ(expectedValue, checksum.getValue()); ASSERT_EQ(expectedValue, checksum.getValue());
} }
int main(int argc, char **argv) { int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View File

@ -1,31 +1,25 @@
#include <Ref/BlockDriver/BlockDriver.hpp>
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
#include <Fw/Types/Assert.hpp> #include <Fw/Types/Assert.hpp>
#include <Ref/BlockDriver/BlockDriver.hpp>
namespace Ref { namespace Ref {
BlockDriver::BlockDriver(const char* compName) : BlockDriver::BlockDriver(const char* compName) : BlockDriverComponentBase(compName), m_cycles(0) {}
BlockDriverComponentBase(compName), m_cycles(0)
{}
BlockDriver::~BlockDriver() {} BlockDriver::~BlockDriver() {}
void BlockDriver::BufferIn_handler(FwIndexType portNum, Drv::DataBuffer& buffer) {
// just a pass-through
this->BufferOut_out(0,buffer);
}
void BlockDriver::Sched_handler(FwIndexType portNum, U32 context) {
this->tlmWrite_BD_Cycles(this->m_cycles++);
}
void BlockDriver::PingIn_handler(
const FwIndexType portNum,
U32 key
)
{
// call ping output port
this->PingOut_out(0,key);
}
void BlockDriver::BufferIn_handler(FwIndexType portNum, Drv::DataBuffer& buffer) {
// just a pass-through
this->BufferOut_out(0, buffer);
} }
void BlockDriver::Sched_handler(FwIndexType portNum, U32 context) {
this->tlmWrite_BD_Cycles(this->m_cycles++);
}
void BlockDriver::PingIn_handler(const FwIndexType portNum, U32 key) {
// call ping output port
this->PingOut_out(0, key);
}
} // namespace Ref

View File

@ -5,31 +5,26 @@
namespace Ref { namespace Ref {
class BlockDriver final : public BlockDriverComponentBase { class BlockDriver final : public BlockDriverComponentBase {
public:
// Only called by derived class
BlockDriver(const char* compName);
public: ~BlockDriver();
// Only called by derived class private:
BlockDriver(const char* compName); // downcalls for input ports
void BufferIn_handler(FwIndexType portNum, Drv::DataBuffer& buffer);
void Sched_handler(FwIndexType portNum, U32 context);
//! Handler implementation for PingIn
//!
void PingIn_handler(const FwIndexType portNum, /*!< The port number*/
U32 key /*!< Value to return to pinger*/
);
~BlockDriver(); // cycle count
U32 m_cycles;
private: };
} // namespace Ref
// downcalls for input ports
void BufferIn_handler(FwIndexType portNum, Drv::DataBuffer& buffer);
void Sched_handler(FwIndexType portNum, U32 context);
//! Handler implementation for PingIn
//!
void PingIn_handler(
const FwIndexType portNum, /*!< The port number*/
U32 key /*!< Value to return to pinger*/
);
// cycle count
U32 m_cycles;
};
}
#endif #endif

View File

@ -7,21 +7,21 @@
#include "BlockDriverTester.hpp" #include "BlockDriverTester.hpp"
TEST(Nominal, testDataLoopBack) { TEST(Nominal, testDataLoopBack) {
Ref::BlockDriverTester tester; Ref::BlockDriverTester tester;
tester.testDataLoopBack(); tester.testDataLoopBack();
} }
TEST(Nominal, testPing) { TEST(Nominal, testPing) {
Ref::BlockDriverTester tester; Ref::BlockDriverTester tester;
tester.testPing(); tester.testPing();
} }
TEST(Nominal, testCycleIncrement) { TEST(Nominal, testCycleIncrement) {
Ref::BlockDriverTester tester; Ref::BlockDriverTester tester;
tester.testCycleIncrement(); tester.testCycleIncrement();
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View File

@ -8,32 +8,23 @@
namespace Ref { namespace Ref {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Construction and destruction // Construction and destruction
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
BlockDriverTester :: BlockDriverTester ::BlockDriverTester()
BlockDriverTester() : : BlockDriverGTestBase("BlockDriverTester", BlockDriverTester::MAX_HISTORY_SIZE), component("BlockDriver") {
BlockDriverGTestBase("BlockDriverTester", BlockDriverTester::MAX_HISTORY_SIZE),
component("BlockDriver")
{
this->initComponents(); this->initComponents();
this->connectPorts(); this->connectPorts();
} }
BlockDriverTester :: BlockDriverTester ::~BlockDriverTester() {}
~BlockDriverTester()
{
} // ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- void BlockDriverTester ::testDataLoopBack() {
// Tests
// ----------------------------------------------------------------------
void BlockDriverTester ::
testDataLoopBack()
{
const U8 data[] = {1, 2, 3, 4, 5, 6, 7}; const U8 data[] = {1, 2, 3, 4, 5, 6, 7};
Drv::DataBuffer dataBuffer(data, 7); Drv::DataBuffer dataBuffer(data, 7);
@ -47,11 +38,9 @@ namespace Ref {
// verify data output // verify data output
ASSERT_from_BufferOut_SIZE(1); ASSERT_from_BufferOut_SIZE(1);
ASSERT_from_BufferOut(0, dataBuffer); ASSERT_from_BufferOut(0, dataBuffer);
} }
void BlockDriverTester :: void BlockDriverTester ::testPing() {
testPing()
{
const U32 key = 42; const U32 key = 42;
this->clearHistory(); this->clearHistory();
@ -64,15 +53,13 @@ namespace Ref {
// verify Ping output // verify Ping output
ASSERT_from_PingOut_SIZE(1); ASSERT_from_PingOut_SIZE(1);
ASSERT_from_PingOut(0, key); ASSERT_from_PingOut(0, key);
} }
void BlockDriverTester :: void BlockDriverTester ::testCycleIncrement() {
testCycleIncrement()
{
this->clearHistory(); this->clearHistory();
// call ISR // call ISR
this->invoke_to_Sched(0,0); this->invoke_to_Sched(0, 0);
this->component.doDispatch(); this->component.doDispatch();
// there shall be one report with 0 cycle // there shall be one report with 0 cycle
@ -81,13 +68,13 @@ namespace Ref {
ASSERT_TLM_BD_Cycles(0, 0); ASSERT_TLM_BD_Cycles(0, 0);
// call ISR once again // call ISR once again
this->invoke_to_Sched(0,0); this->invoke_to_Sched(0, 0);
this->component.doDispatch(); this->component.doDispatch();
// there shall be one more report with 1 cycle // there shall be one more report with 1 cycle
ASSERT_TLM_SIZE(2); ASSERT_TLM_SIZE(2);
ASSERT_TLM_BD_Cycles_SIZE(2); ASSERT_TLM_BD_Cycles_SIZE(2);
ASSERT_TLM_BD_Cycles(1, 1); ASSERT_TLM_BD_Cycles(1, 1);
}
} }
} // namespace Ref

View File

@ -7,80 +7,71 @@
#ifndef Ref_BlockDriverTester_HPP #ifndef Ref_BlockDriverTester_HPP
#define Ref_BlockDriverTester_HPP #define Ref_BlockDriverTester_HPP
#include "Ref/BlockDriver/BlockDriverGTestBase.hpp"
#include "Ref/BlockDriver/BlockDriver.hpp" #include "Ref/BlockDriver/BlockDriver.hpp"
#include "Ref/BlockDriver/BlockDriverGTestBase.hpp"
namespace Ref { namespace Ref {
class BlockDriverTester final : class BlockDriverTester final : public BlockDriverGTestBase {
public BlockDriverGTestBase public:
{ // ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------
public: // Maximum size of histories storing events, telemetry, and port outputs
static const FwSizeType MAX_HISTORY_SIZE = 10;
// ---------------------------------------------------------------------- // Instance ID supplied to the component instance under test
// Constants static const FwEnumStoreType TEST_INSTANCE_ID = 0;
// ----------------------------------------------------------------------
// Maximum size of histories storing events, telemetry, and port outputs // Queue depth supplied to the component instance under test
static const FwSizeType MAX_HISTORY_SIZE = 10; static const FwSizeType TEST_INSTANCE_QUEUE_DEPTH = 10;
// Instance ID supplied to the component instance under test public:
static const FwEnumStoreType TEST_INSTANCE_ID = 0; // ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------
// Queue depth supplied to the component instance under test //! Construct object BlockDriverTester
static const FwSizeType TEST_INSTANCE_QUEUE_DEPTH = 10; BlockDriverTester();
public: //! Destroy object BlockDriverTester
~BlockDriverTester();
// ---------------------------------------------------------------------- public:
// Construction and destruction // ----------------------------------------------------------------------
// ---------------------------------------------------------------------- // Tests
// ----------------------------------------------------------------------
//! Construct object BlockDriverTester //! Test data loop back port
BlockDriverTester(); void testDataLoopBack();
//! Destroy object BlockDriverTester //! Test Ping port
~BlockDriverTester(); void testPing();
public: //! Test ISR cycle increment
void testCycleIncrement();
// ---------------------------------------------------------------------- private:
// Tests // ----------------------------------------------------------------------
// ---------------------------------------------------------------------- // Helper functions
// ----------------------------------------------------------------------
//! Test data loop back port //! Connect ports
void testDataLoopBack(); void connectPorts();
//! Test Ping port //! Initialize components
void testPing(); void initComponents();
//! Test ISR cycle increment private:
void testCycleIncrement(); // ----------------------------------------------------------------------
// Member variables
// ----------------------------------------------------------------------
private: //! The component under test
BlockDriver component;
};
// ---------------------------------------------------------------------- } // namespace Ref
// Helper functions
// ----------------------------------------------------------------------
//! Connect ports
void connectPorts();
//! Initialize components
void initComponents();
private:
// ----------------------------------------------------------------------
// Member variables
// ----------------------------------------------------------------------
//! The component under test
BlockDriver component;
};
}
#endif #endif

View File

@ -8,239 +8,166 @@
namespace Ref { namespace Ref {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Component construction and destruction // Component construction and destruction
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
DpDemo ::DpDemo(const char* const compName) : DpDemoComponentBase(compName) { DpDemo ::DpDemo(const char* const compName) : DpDemoComponentBase(compName) {
this->selectedColor = DpDemo_ColorEnum::RED; this->selectedColor = DpDemo_ColorEnum::RED;
this->numRecords = 0; this->numRecords = 0;
this->dpPriority = 0; this->dpPriority = 0;
}
DpDemo ::~DpDemo() {}
// ----------------------------------------------------------------------
// Handler implementations for typed input ports
// ----------------------------------------------------------------------
void DpDemo ::run_handler(FwIndexType portNum, U32 context) {
// If a Data product is being generated, store records
if (this->dpInProgress) {
this->dpContainer.serializeRecord_StringRecord(Fw::String("Test string"));
this->dpContainer.serializeRecord_BooleanRecord(true);
this->dpContainer.serializeRecord_I32Record(-100);
this->dpContainer.serializeRecord_F64Record(1.25);
this->dpContainer.serializeRecord_U32ArrayRecord(DpDemo_U32Array({1, 2, 3, 4, 5}));
this->dpContainer.serializeRecord_F32ArrayRecord(DpDemo_F32Array({1.1f, 2.2f, 3.3f}));
this->dpContainer.serializeRecord_BooleanArrayRecord(DpDemo_BooleanArray({true, false}));
// Array Records
// Array record of strings
Fw::String str0("String array element 0");
Fw::String str1("String array element 1");
Fw::String str2("String array element 2");
const Fw::StringBase* strings[3] = {&str0, &str1, &str2};
this->dpContainer.serializeRecord_StringArrayRecord(strings, 3);
// Array record of arrays
const DpDemo_StringArray arrayArray[1] = {DpDemo_StringArray(
{Fw::String("0 - String array record element 0"), Fw::String("0 - String array record element 1")})};
this->dpContainer.serializeRecord_ArrayArrayRecord(arrayArray, 1);
// Array record of structs
const DpDemo_StructWithStringMembers structArray[2] = {
DpDemo_StructWithStringMembers(Fw::String("0 - String member"),
DpDemo_StringArray({Fw::String("0 - String array element 0"),
Fw::String("0 - String array element 1")})),
DpDemo_StructWithStringMembers(Fw::String("1 - String member"),
DpDemo_StringArray({Fw::String("1 - String array element 0"),
Fw::String("1 - String array element 1")}))};
this->dpContainer.serializeRecord_StructArrayRecord(structArray, 2);
this->dpContainer.serializeRecord_ArrayOfStringArrayRecord(DpDemo_ArrayOfStringArray(
{DpDemo_StringArray({Fw::String("0 - String array element 0"), Fw::String("0 - String array element 1")}),
DpDemo_StringArray({Fw::String("1 - String array element 0"), Fw::String("1 - String array element 1")}),
DpDemo_StringArray(
{Fw::String("2 - String array element 0"), Fw::String("2 - String array element 1")})}));
this->dpContainer.serializeRecord_ArrayOfStructsRecord(DpDemo_ArrayOfStructs(
{DpDemo_StructWithStringMembers(Fw::String("0 - String member"),
DpDemo_StringArray({Fw::String("0 - String array element 0"),
Fw::String("0 - String array element 1")})),
DpDemo_StructWithStringMembers(Fw::String("1 - String member"),
DpDemo_StringArray({Fw::String("1 - String array element 0"),
Fw::String("1 - String array element 1")})),
DpDemo_StructWithStringMembers(Fw::String("2 - String member"),
DpDemo_StringArray({Fw::String("2 - String array element 0"),
Fw::String("2 - String array element 1")}))}));
this->dpContainer.serializeRecord_EnumArrayRecord(
DpDemo_EnumArray({DpDemo_ColorEnum::RED, DpDemo_ColorEnum::GREEN, DpDemo_ColorEnum::BLUE}));
this->dpContainer.serializeRecord_StructWithEverythingRecord(DpDemo_StructWithEverything(
-1, 2.5, Fw::String("String Member"), false, this->selectedColor,
{DpDemo_U32Array({1, 2, 3, 4, 5}), DpDemo_U32Array({6, 7, 8, 9, 10})}, DpDemo_F32Array({4.4f, 5.5f, 6.6f}),
DpDemo_U32Array({6, 7, 8, 9, 10}),
DpDemo_EnumArray({DpDemo_ColorEnum::RED, DpDemo_ColorEnum::GREEN, DpDemo_ColorEnum::BLUE}),
DpDemo_StringArray({Fw::String("String array element 0"), Fw::String("String array element 1")}),
DpDemo_BooleanArray({true, false}),
DpDemo_StructWithStringMembers(
Fw::String("String member"),
DpDemo_StringArray({Fw::String("String array element 0"), Fw::String("String array element 1")})),
DpDemo_ArrayOfStringArray({DpDemo_StringArray({Fw::String("0 - String array element 0"),
Fw::String("0 - String array element 1")}),
DpDemo_StringArray({Fw::String("1 - String array element 0"),
Fw::String("1 - String array element 1")}),
DpDemo_StringArray({Fw::String("2 - String array element 0"),
Fw::String("2 - String array element 1")})})));
this->log_ACTIVITY_LO_DpComplete(this->numRecords);
this->cleanupAndSendDp();
}
}
// ----------------------------------------------------------------------
// Handler implementations for commands
// ----------------------------------------------------------------------
void DpDemo ::SelectColor_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Ref::DpDemo_ColorEnum color) {
this->selectedColor = color;
log_ACTIVITY_HI_ColorSelected(color);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
void DpDemo ::Dp_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, DpDemo_DpReqType reqType, U32 priority) {
// make sure DPs are available
if (!this->isConnected_productGetOut_OutputPort(0) || !this->isConnected_productRequestOut_OutputPort(0)) {
this->log_WARNING_HI_DpsNotConnected();
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
return;
} }
DpDemo ::~DpDemo() {} this->numRecords = 15; // 15 records in current demo
FwSizeType dpSize = DpDemo_StringAlias::SERIALIZED_SIZE + sizeof(DpDemo_BoolAlias) + sizeof(DpDemo_I32Alias) +
sizeof(DpDemo_F64Alias) + DpDemo_U32Array::SERIALIZED_SIZE + DpDemo_F32Array::SERIALIZED_SIZE +
DpDemo_BooleanArray::SERIALIZED_SIZE + DpDemo_EnumArray::SERIALIZED_SIZE +
DpDemo_StringArray::SERIALIZED_SIZE + DpDemo_StructWithEverything::SERIALIZED_SIZE +
DpDemo_StructWithStringMembers::SERIALIZED_SIZE + (DpDemo_StringArray::SERIALIZED_SIZE * 3) +
(DpDemo_StringArray::SERIALIZED_SIZE * 1) +
(DpDemo_StructWithStringMembers::SERIALIZED_SIZE * 2) +
DpDemo_ArrayOfStringArray::SERIALIZED_SIZE + (numRecords * sizeof(FwDpIdType));
// ---------------------------------------------------------------------- this->dpPriority = static_cast<FwDpPriorityType>(priority);
// Handler implementations for typed input ports this->log_ACTIVITY_LO_DpMemRequested(dpSize);
// ---------------------------------------------------------------------- if (reqType == DpDemo_DpReqType::IMMEDIATE) {
Fw::Success stat = this->dpGet_DpDemoContainer(dpSize, this->dpContainer);
void DpDemo ::run_handler(FwIndexType portNum, U32 context) { // make sure we got the memory we wanted
// If a Data product is being generated, store records if (Fw::Success::FAILURE == stat) {
if (this->dpInProgress) {
this->dpContainer.serializeRecord_StringRecord(Fw::String("Test string"));
this->dpContainer.serializeRecord_BooleanRecord(true);
this->dpContainer.serializeRecord_I32Record(-100);
this->dpContainer.serializeRecord_F64Record(1.25);
this->dpContainer.serializeRecord_U32ArrayRecord(DpDemo_U32Array({1, 2, 3, 4, 5}));
this->dpContainer.serializeRecord_F32ArrayRecord(DpDemo_F32Array({1.1f, 2.2f, 3.3f}));
this->dpContainer.serializeRecord_BooleanArrayRecord(DpDemo_BooleanArray({true, false}));
// Array Records
// Array record of strings
Fw::String str0("String array element 0");
Fw::String str1("String array element 1");
Fw::String str2("String array element 2");
const Fw::StringBase* strings[3] = { &str0, &str1, &str2 };
this->dpContainer.serializeRecord_StringArrayRecord(strings, 3);
// Array record of arrays
const DpDemo_StringArray arrayArray[1] = {
DpDemo_StringArray({
Fw::String("0 - String array record element 0"),
Fw::String("0 - String array record element 1")
})
};
this->dpContainer.serializeRecord_ArrayArrayRecord(arrayArray, 1);
// Array record of structs
const DpDemo_StructWithStringMembers structArray[2] = {
DpDemo_StructWithStringMembers(
Fw::String("0 - String member"),
DpDemo_StringArray({
Fw::String("0 - String array element 0"),
Fw::String("0 - String array element 1")
})
),
DpDemo_StructWithStringMembers(
Fw::String("1 - String member"),
DpDemo_StringArray({
Fw::String("1 - String array element 0"),
Fw::String("1 - String array element 1")
})
)
};
this->dpContainer.serializeRecord_StructArrayRecord(structArray, 2);
this->dpContainer.serializeRecord_ArrayOfStringArrayRecord(
DpDemo_ArrayOfStringArray({
DpDemo_StringArray({
Fw::String("0 - String array element 0"),
Fw::String("0 - String array element 1")
}),
DpDemo_StringArray({
Fw::String("1 - String array element 0"),
Fw::String("1 - String array element 1")
}),
DpDemo_StringArray({
Fw::String("2 - String array element 0"),
Fw::String("2 - String array element 1")
})
})
);
this->dpContainer.serializeRecord_ArrayOfStructsRecord(
DpDemo_ArrayOfStructs({
DpDemo_StructWithStringMembers(
Fw::String("0 - String member"),
DpDemo_StringArray({
Fw::String("0 - String array element 0"),
Fw::String("0 - String array element 1")
})
),
DpDemo_StructWithStringMembers(
Fw::String("1 - String member"),
DpDemo_StringArray({
Fw::String("1 - String array element 0"),
Fw::String("1 - String array element 1")
})
),
DpDemo_StructWithStringMembers(
Fw::String("2 - String member"),
DpDemo_StringArray({
Fw::String("2 - String array element 0"),
Fw::String("2 - String array element 1")
})
)
})
);
this->dpContainer.serializeRecord_EnumArrayRecord(DpDemo_EnumArray({DpDemo_ColorEnum::RED, DpDemo_ColorEnum::GREEN, DpDemo_ColorEnum::BLUE}));
this->dpContainer.serializeRecord_StructWithEverythingRecord(DpDemo_StructWithEverything(
-1,
2.5,
Fw::String("String Member"),
false,
this->selectedColor,
{
DpDemo_U32Array({1, 2, 3, 4, 5}),
DpDemo_U32Array({6, 7, 8, 9, 10})
},
DpDemo_F32Array({4.4f, 5.5f, 6.6f}),
DpDemo_U32Array({6, 7, 8, 9, 10}),
DpDemo_EnumArray({DpDemo_ColorEnum::RED, DpDemo_ColorEnum::GREEN, DpDemo_ColorEnum::BLUE}),
DpDemo_StringArray({
Fw::String("String array element 0"),
Fw::String("String array element 1")
}),
DpDemo_BooleanArray({true, false}),
DpDemo_StructWithStringMembers(
Fw::String("String member"),
DpDemo_StringArray({
Fw::String("String array element 0"),
Fw::String("String array element 1")
})
),
DpDemo_ArrayOfStringArray({
DpDemo_StringArray({
Fw::String("0 - String array element 0"),
Fw::String("0 - String array element 1")
}),
DpDemo_StringArray({
Fw::String("1 - String array element 0"),
Fw::String("1 - String array element 1")
}),
DpDemo_StringArray({
Fw::String("2 - String array element 0"),
Fw::String("2 - String array element 1")
})
})
));
this->log_ACTIVITY_LO_DpComplete(this->numRecords);
this->cleanupAndSendDp();
}
}
// ----------------------------------------------------------------------
// Handler implementations for commands
// ----------------------------------------------------------------------
void DpDemo ::SelectColor_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Ref::DpDemo_ColorEnum color) {
this->selectedColor = color;
log_ACTIVITY_HI_ColorSelected(color);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
void DpDemo ::Dp_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, DpDemo_DpReqType reqType, U32 priority) {
// make sure DPs are available
if (!this->isConnected_productGetOut_OutputPort(0) || !this->isConnected_productRequestOut_OutputPort(0)) {
this->log_WARNING_HI_DpsNotConnected();
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
return;
}
this->numRecords = 15; // 15 records in current demo
FwSizeType dpSize = DpDemo_StringAlias::SERIALIZED_SIZE +
sizeof(DpDemo_BoolAlias) +
sizeof(DpDemo_I32Alias) +
sizeof(DpDemo_F64Alias) +
DpDemo_U32Array::SERIALIZED_SIZE +
DpDemo_F32Array::SERIALIZED_SIZE +
DpDemo_BooleanArray::SERIALIZED_SIZE +
DpDemo_EnumArray::SERIALIZED_SIZE +
DpDemo_StringArray::SERIALIZED_SIZE +
DpDemo_StructWithEverything::SERIALIZED_SIZE +
DpDemo_StructWithStringMembers::SERIALIZED_SIZE +
(DpDemo_StringArray::SERIALIZED_SIZE * 3) +
(DpDemo_StringArray::SERIALIZED_SIZE * 1) +
(DpDemo_StructWithStringMembers::SERIALIZED_SIZE * 2) +
DpDemo_ArrayOfStringArray::SERIALIZED_SIZE +
(numRecords * sizeof(FwDpIdType));
this->dpPriority = static_cast<FwDpPriorityType>(priority);
this->log_ACTIVITY_LO_DpMemRequested(dpSize);
if(reqType == DpDemo_DpReqType::IMMEDIATE) {
Fw::Success stat = this->dpGet_DpDemoContainer(dpSize, this->dpContainer);
// make sure we got the memory we wanted
if (Fw::Success::FAILURE == stat) {
this->log_WARNING_HI_DpMemoryFail();
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
} else {
this->dpInProgress = true;
this->log_ACTIVITY_LO_DpStarted(numRecords);
this->log_ACTIVITY_LO_DpMemReceived(this->dpContainer.getBuffer().getSize());
// override priority with requested priority
this->dpContainer.setPriority(priority);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
}
else if (reqType == DpDemo_DpReqType::ASYNC) {
this->dpRequest_DpDemoContainer(dpSize);
}
else {
// should never get here
FW_ASSERT(0, reqType.e);
}
}
// ----------------------------------------------------------------------
// Handler implementations for data products
// ----------------------------------------------------------------------
void DpDemo ::dpRecv_DpDemoContainer_handler(DpContainer& container, Fw::Success::T status) {
// Make sure we got the buffer we wanted or quit
if (Fw::Success::SUCCESS == status) {
this->dpContainer = container;
this->dpInProgress = true;
// set previously requested priority
this->dpContainer.setPriority(this->dpPriority);
this->log_ACTIVITY_LO_DpStarted(this->numRecords);
} else {
this->log_WARNING_HI_DpMemoryFail(); this->log_WARNING_HI_DpMemoryFail();
// cleanup this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
this->dpInProgress = false; } else {
this->numRecords = 0; this->dpInProgress = true;
this->log_ACTIVITY_LO_DpStarted(numRecords);
this->log_ACTIVITY_LO_DpMemReceived(this->dpContainer.getBuffer().getSize());
// override priority with requested priority
this->dpContainer.setPriority(priority);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
} }
} else if (reqType == DpDemo_DpReqType::ASYNC) {
this->dpRequest_DpDemoContainer(dpSize);
} else {
// should never get here
FW_ASSERT(0, reqType.e);
} }
}
void DpDemo ::cleanupAndSendDp() { // ----------------------------------------------------------------------
this->dpSend(this->dpContainer); // Handler implementations for data products
// ----------------------------------------------------------------------
void DpDemo ::dpRecv_DpDemoContainer_handler(DpContainer& container, Fw::Success::T status) {
// Make sure we got the buffer we wanted or quit
if (Fw::Success::SUCCESS == status) {
this->dpContainer = container;
this->dpInProgress = true;
// set previously requested priority
this->dpContainer.setPriority(this->dpPriority);
this->log_ACTIVITY_LO_DpStarted(this->numRecords);
} else {
this->log_WARNING_HI_DpMemoryFail();
// cleanup
this->dpInProgress = false; this->dpInProgress = false;
this->numRecords = 0; this->numRecords = 0;
} }
}
void DpDemo ::cleanupAndSendDp() {
this->dpSend(this->dpContainer);
this->dpInProgress = false;
this->numRecords = 0;
}
} // namespace Ref } // namespace Ref

View File

@ -19,7 +19,6 @@
// Used to get the Os::Console // Used to get the Os::Console
#include <Os/Os.hpp> #include <Os/Os.hpp>
/** /**
* \brief print commandline help message * \brief print commandline help message
* *

View File

@ -10,7 +10,7 @@
namespace Ref { namespace Ref {
typedef PingReceiverComponentImpl PingReceiver; typedef PingReceiverComponentImpl PingReceiver;
} }

View File

@ -10,53 +10,37 @@
// //
// ====================================================================== // ======================================================================
#include <Ref/PingReceiver/PingReceiverComponentImpl.hpp>
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
#include <Ref/PingReceiver/PingReceiverComponentImpl.hpp>
namespace Ref { namespace Ref {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Construction, initialization, and destruction // Construction, initialization, and destruction
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
PingReceiverComponentImpl :: PingReceiverComponentImpl ::PingReceiverComponentImpl(const char* const compName)
PingReceiverComponentImpl( : PingReceiverComponentBase(compName), m_inhibitPings(false), m_pingsRecvd(0) {}
const char *const compName
) : PingReceiverComponentBase(compName), m_inhibitPings(false), m_pingsRecvd(0)
{
} PingReceiverComponentImpl ::~PingReceiverComponentImpl() {}
PingReceiverComponentImpl :: // ----------------------------------------------------------------------
~PingReceiverComponentImpl() // Handler implementations for user-defined typed input ports
{ // ----------------------------------------------------------------------
} void PingReceiverComponentImpl ::PingIn_handler(const FwIndexType portNum, U32 key) {
// this->log_DIAGNOSTIC_PR_PingReceived(key);
// ----------------------------------------------------------------------
// Handler implementations for user-defined typed input ports
// ----------------------------------------------------------------------
void PingReceiverComponentImpl ::
PingIn_handler(
const FwIndexType portNum,
U32 key
)
{
//this->log_DIAGNOSTIC_PR_PingReceived(key);
this->tlmWrite_PR_NumPings(this->m_pingsRecvd++); this->tlmWrite_PR_NumPings(this->m_pingsRecvd++);
if (not this->m_inhibitPings) { if (not this->m_inhibitPings) {
PingOut_out(0,key); PingOut_out(0, key);
} }
} }
void PingReceiverComponentImpl::PR_StopPings_cmdHandler( void PingReceiverComponentImpl::PR_StopPings_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
FwOpcodeType opCode, /*!< The opcode*/ U32 cmdSeq /*!< The command sequence number*/
U32 cmdSeq /*!< The command sequence number*/ ) {
) { this->m_inhibitPings = true;
this->m_inhibitPings = true; this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK); }
}
} // end namespace Ref } // end namespace Ref

View File

@ -17,50 +17,40 @@
namespace Ref { namespace Ref {
class PingReceiverComponentImpl final : class PingReceiverComponentImpl final : public PingReceiverComponentBase {
public PingReceiverComponentBase public:
{ // ----------------------------------------------------------------------
// Construction, initialization, and destruction
// ----------------------------------------------------------------------
public: //! Construct object PingReceiver
//!
PingReceiverComponentImpl(const char* const compName /*!< The component name*/
);
// ---------------------------------------------------------------------- //! Destroy object PingReceiver
// Construction, initialization, and destruction //!
// ---------------------------------------------------------------------- ~PingReceiverComponentImpl();
//! Construct object PingReceiver private:
//! // ----------------------------------------------------------------------
PingReceiverComponentImpl( // Handler implementations for user-defined typed input ports
const char *const compName /*!< The component name*/ // ----------------------------------------------------------------------
);
//! Destroy object PingReceiver //! Handler implementation for PingIn
//! //!
~PingReceiverComponentImpl(); void PingIn_handler(const FwIndexType portNum, /*!< The port number*/
U32 key /*!< Value to return to pinger*/
);
private: void PR_StopPings_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq /*!< The command sequence number*/
);
// ---------------------------------------------------------------------- bool m_inhibitPings;
// Handler implementations for user-defined typed input ports U32 m_pingsRecvd;
// ---------------------------------------------------------------------- };
//! Handler implementation for PingIn } // end namespace Ref
//!
void PingIn_handler(
const FwIndexType portNum, /*!< The port number*/
U32 key /*!< Value to return to pinger*/
);
void PR_StopPings_cmdHandler(
FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq /*!< The command sequence number*/
);
bool m_inhibitPings;
U32 m_pingsRecvd;
};
} // end namespace Ref
#endif #endif

View File

@ -10,7 +10,7 @@
namespace Ref { namespace Ref {
typedef RecvBuffImpl RecvBuff; typedef RecvBuffImpl RecvBuff;
} }

View File

@ -1,7 +1,7 @@
#include <Ref/RecvBuffApp/RecvBuffComponentImpl.hpp>
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
#include <Os/Console.hpp>
#include <Fw/Types/Assert.hpp> #include <Fw/Types/Assert.hpp>
#include <Os/Console.hpp>
#include <Ref/RecvBuffApp/RecvBuffComponentImpl.hpp>
#include <cstdio> #include <cstdio>
@ -9,87 +9,82 @@
namespace Ref { namespace Ref {
RecvBuffImpl::RecvBuffImpl(const char* compName) : RecvBuffImpl::RecvBuffImpl(const char* compName) : RecvBuffComponentBase(compName) {
RecvBuffComponentBase(compName) { this->m_firstBuffReceived = 0;
this->m_firstBuffReceived = 0; this->m_sensor1 = 1000.0;
this->m_sensor1 = 1000.0; this->m_sensor2 = 10.0;
this->m_sensor2 = 10.0; this->m_stats.set_BuffRecv(0);
this->m_stats.set_BuffRecv(0); this->m_stats.set_BuffErr(0);
this->m_stats.set_BuffErr(0); this->m_stats.set_PacketStatus(PacketRecvStatus::PACKET_STATE_NO_PACKETS);
this->m_stats.set_PacketStatus(PacketRecvStatus::PACKET_STATE_NO_PACKETS);
}
RecvBuffImpl::~RecvBuffImpl() {
}
void RecvBuffImpl::Data_handler(FwIndexType portNum, Drv::DataBuffer &buff) {
this->m_stats.set_BuffRecv(++this->m_buffsReceived);
// reset deserialization of buffer
buff.resetDeser();
// deserialize packet ID
U32 id = 0;
Fw::SerializeStatus stat = buff.deserializeTo(id);
FW_ASSERT(stat == Fw::FW_SERIALIZE_OK,static_cast<FwAssertArgType>(stat));
// deserialize data
U8 testData[24] = {0};
FwSizeType size = sizeof(testData);
stat = buff.deserializeTo(testData,size);
FW_ASSERT(stat == Fw::FW_SERIALIZE_OK,static_cast<FwAssertArgType>(stat));
// deserialize checksum
U32 csum = 0;
stat = buff.deserializeTo(csum);
FW_ASSERT(stat == Fw::FW_SERIALIZE_OK,static_cast<FwAssertArgType>(stat));
// if first packet, send event
if (not this->m_firstBuffReceived) {
this->log_ACTIVITY_LO_FirstPacketReceived(id);
this->m_stats.set_PacketStatus(PacketRecvStatus::PACKET_STATE_OK);
this->m_firstBuffReceived = true;
}
// compute checksum
U32 sum = 0;
for (U32 byte = 0; byte < size; byte++) {
sum += testData[byte];
}
// check checksum
if (sum != csum) {
// increment error count
this->m_stats.set_BuffErr(++this->m_errBuffs);
// send error event
this->log_WARNING_HI_PacketChecksumError(id);
// update stats
this->m_stats.set_PacketStatus(PacketRecvStatus::PACKET_STATE_ERRORS);
}
// update sensor values
this->m_sensor1 += 5.0;
this->m_sensor2 += 1.2;
// update channels
this->tlmWrite_Sensor1(this->m_sensor1);
this->tlmWrite_Sensor2(this->m_sensor2);
this->tlmWrite_PktState(this->m_stats);
}
void RecvBuffImpl::parameterUpdated(FwPrmIdType id) {
this->log_ACTIVITY_LO_BuffRecvParameterUpdated(id);
Fw::ParamValid valid;
switch(id) {
case PARAMID_PARAMETER1: {
U32 val = this->paramGet_parameter1(valid);
this->tlmWrite_Parameter1(val);
break;
}
case PARAMID_PARAMETER2: {
I16 val = this->paramGet_parameter2(valid);
this->tlmWrite_Parameter2(val);
break;
}
default:
FW_ASSERT(0,id);
break;
}
}
} }
RecvBuffImpl::~RecvBuffImpl() {}
void RecvBuffImpl::Data_handler(FwIndexType portNum, Drv::DataBuffer& buff) {
this->m_stats.set_BuffRecv(++this->m_buffsReceived);
// reset deserialization of buffer
buff.resetDeser();
// deserialize packet ID
U32 id = 0;
Fw::SerializeStatus stat = buff.deserializeTo(id);
FW_ASSERT(stat == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
// deserialize data
U8 testData[24] = {0};
FwSizeType size = sizeof(testData);
stat = buff.deserializeTo(testData, size);
FW_ASSERT(stat == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
// deserialize checksum
U32 csum = 0;
stat = buff.deserializeTo(csum);
FW_ASSERT(stat == Fw::FW_SERIALIZE_OK, static_cast<FwAssertArgType>(stat));
// if first packet, send event
if (not this->m_firstBuffReceived) {
this->log_ACTIVITY_LO_FirstPacketReceived(id);
this->m_stats.set_PacketStatus(PacketRecvStatus::PACKET_STATE_OK);
this->m_firstBuffReceived = true;
}
// compute checksum
U32 sum = 0;
for (U32 byte = 0; byte < size; byte++) {
sum += testData[byte];
}
// check checksum
if (sum != csum) {
// increment error count
this->m_stats.set_BuffErr(++this->m_errBuffs);
// send error event
this->log_WARNING_HI_PacketChecksumError(id);
// update stats
this->m_stats.set_PacketStatus(PacketRecvStatus::PACKET_STATE_ERRORS);
}
// update sensor values
this->m_sensor1 += 5.0;
this->m_sensor2 += 1.2;
// update channels
this->tlmWrite_Sensor1(this->m_sensor1);
this->tlmWrite_Sensor2(this->m_sensor2);
this->tlmWrite_PktState(this->m_stats);
}
void RecvBuffImpl::parameterUpdated(FwPrmIdType id) {
this->log_ACTIVITY_LO_BuffRecvParameterUpdated(id);
Fw::ParamValid valid;
switch (id) {
case PARAMID_PARAMETER1: {
U32 val = this->paramGet_parameter1(valid);
this->tlmWrite_Parameter1(val);
break;
}
case PARAMID_PARAMETER2: {
I16 val = this->paramGet_parameter2(valid);
this->tlmWrite_Parameter2(val);
break;
}
default:
FW_ASSERT(0, id);
break;
}
}
} // namespace Ref

View File

@ -5,30 +5,27 @@
namespace Ref { namespace Ref {
class RecvBuffImpl final : public RecvBuffComponentBase { class RecvBuffImpl final : public RecvBuffComponentBase {
public: public:
// Only called by derived class
RecvBuffImpl(const char* compName);
// Only called by derived class ~RecvBuffImpl();
RecvBuffImpl(const char* compName);
~RecvBuffImpl(); private:
// downcall for input port
void Data_handler(FwIndexType portNum, Drv::DataBuffer& buff);
Ref::PacketStat m_stats;
U32 m_buffsReceived; // !< number of buffers received
bool m_firstBuffReceived; // !< first buffer received or not
U32 m_errBuffs; // !< number of buffers with errors received
F32 m_sensor1;
F32 m_sensor2;
private: // parameter update notification
void parameterUpdated(FwPrmIdType id);
};
// downcall for input port } // namespace Ref
void Data_handler(FwIndexType portNum, Drv::DataBuffer &buff);
Ref::PacketStat m_stats;
U32 m_buffsReceived; // !< number of buffers received
bool m_firstBuffReceived; // !< first buffer received or not
U32 m_errBuffs; // !< number of buffers with errors received
F32 m_sensor1;
F32 m_sensor2;
// parameter update notification
void parameterUpdated(FwPrmIdType id);
};
}
#endif #endif

View File

@ -10,7 +10,7 @@
namespace Ref { namespace Ref {
typedef SendBuffImpl SendBuff; typedef SendBuffImpl SendBuff;
} }

View File

@ -1,7 +1,7 @@
#include <Ref/SendBuffApp/SendBuffComponentImpl.hpp>
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
#include <Fw/Types/Assert.hpp> #include <Fw/Types/Assert.hpp>
#include <Os/Console.hpp> #include <Os/Console.hpp>
#include <Ref/SendBuffApp/SendBuffComponentImpl.hpp>
#include <cstring> #include <cstring>
#include <cstdio> #include <cstdio>
@ -10,138 +10,131 @@
namespace Ref { namespace Ref {
SendBuffImpl::SendBuffImpl(const char* compName) : SendBuffImpl::SendBuffImpl(const char* compName) : SendBuffComponentBase(compName) {
SendBuffComponentBase(compName) { this->m_currPacketId = 0;
this->m_currPacketId = 0; this->m_invocations = 0;
this->m_invocations = 0; this->m_buffsSent = 0;
this->m_buffsSent = 0; this->m_errorsInjected = 0;
this->m_errorsInjected = 0; this->m_injectError = false;
this->m_injectError = false; this->m_sendPackets = false;
this->m_sendPackets = false; this->m_currPacketId = 0;
this->m_currPacketId = 0; this->m_firstPacketSent = false;
this->m_firstPacketSent = false; this->m_state = SendBuff_ActiveState::SEND_IDLE;
this->m_state = SendBuff_ActiveState::SEND_IDLE; }
SendBuffImpl::~SendBuffImpl() {}
void SendBuffImpl::SchedIn_handler(FwIndexType portNum, U32 context) {
// first, dequeue any messages
MsgDispatchStatus stat = MSG_DISPATCH_OK;
while (MSG_DISPATCH_OK == stat) {
stat = this->doDispatch();
FW_ASSERT(stat != MSG_DISPATCH_ERROR);
} }
SendBuffImpl::~SendBuffImpl() { if (this->m_sendPackets) {
// check to see if first
} if (this->m_firstPacketSent) {
this->m_firstPacketSent = false;
void SendBuffImpl::SchedIn_handler(FwIndexType portNum, U32 context) { this->log_ACTIVITY_HI_FirstPacketSent(this->m_currPacketId);
this->tlmWrite_NumErrorsInjected(this->m_errorsInjected);
// first, dequeue any messages
MsgDispatchStatus stat = MSG_DISPATCH_OK;
while (MSG_DISPATCH_OK == stat) {
stat = this->doDispatch();
FW_ASSERT(stat != MSG_DISPATCH_ERROR);
} }
// reset buffer
if (this->m_sendPackets) { this->m_testBuff.resetSer();
// check to see if first // serialize packet id
if (this->m_firstPacketSent) { Fw::SerializeStatus serStat = this->m_testBuff.serialize(this->m_currPacketId);
this->m_firstPacketSent = false; FW_ASSERT(serStat == Fw::FW_SERIALIZE_OK);
this->log_ACTIVITY_HI_FirstPacketSent(this->m_currPacketId); // increment packet id
this->tlmWrite_NumErrorsInjected(this->m_errorsInjected); this->m_currPacketId++;
} this->m_buffsSent++;
// reset buffer // set telemetry
this->m_testBuff.resetSer(); this->tlmWrite_PacketsSent(this->m_buffsSent);
// serialize packet id // write data
Fw::SerializeStatus serStat = this->m_testBuff.serialize(this->m_currPacketId); U8 testData[24];
FW_ASSERT(serStat == Fw::FW_SERIALIZE_OK); FwSizeType dataSize = static_cast<FwSizeType>(sizeof(testData));
// increment packet id memset(testData, 0xFF, static_cast<size_t>(dataSize));
this->m_currPacketId++; // compute checksum
this->m_buffsSent++; U32 csum = 0;
// set telemetry for (U32 byte = 0; byte < dataSize; byte++) {
this->tlmWrite_PacketsSent(this->m_buffsSent); csum += testData[byte];
// write data
U8 testData[24];
FwSizeType dataSize = static_cast<FwSizeType>(sizeof(testData));
memset(testData,0xFF,static_cast<size_t>(dataSize));
// compute checksum
U32 csum = 0;
for (U32 byte = 0; byte < dataSize; byte++) {
csum += testData[byte];
}
// inject error, if requested
if (this->m_injectError) {
this->m_injectError = false;
this->m_errorsInjected++;
testData[5] = 0;
this->log_WARNING_HI_PacketErrorInserted(this->m_currPacketId-1);
}
// serialize data
serStat = this->m_testBuff.serialize(testData,dataSize);
FW_ASSERT(serStat == Fw::FW_SERIALIZE_OK);
// serialize checksum
serStat = this->m_testBuff.serialize(csum);
FW_ASSERT(serStat == Fw::FW_SERIALIZE_OK);
// send data
this->Data_out(0,this->m_testBuff);
} }
// inject error, if requested
this->m_invocations++; if (this->m_injectError) {
this->m_injectError = false;
this->tlmWrite_SendState(this->m_state); this->m_errorsInjected++;
} testData[5] = 0;
this->log_WARNING_HI_PacketErrorInserted(this->m_currPacketId - 1);
void SendBuffImpl::SB_START_PKTS_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
this->m_sendPackets = true;
this->m_state = SendBuff_ActiveState::SEND_ACTIVE;
this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK);
}
void SendBuffImpl::SB_INJECT_PKT_ERROR_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
this->m_injectError = true;
this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK);
}
void SendBuffImpl::SB_GEN_FATAL_cmdHandler(
FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 arg1, /*!< First FATAL Argument*/
U32 arg2, /*!< Second FATAL Argument*/
U32 arg3 /*!< Third FATAL Argument*/
) {
this->log_FATAL_SendBuffFatal(arg1,arg2,arg3);
this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK);
}
//! Handler for command SB_GEN_ASSERT
/* Generate an ASSERT */
void SendBuffImpl::SB_GEN_ASSERT_cmdHandler(
FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 arg1, /*!< First ASSERT Argument*/
U32 arg2, /*!< Second ASSERT Argument*/
U32 arg3, /*!< Third ASSERT Argument*/
U32 arg4, /*!< Fourth ASSERT Argument*/
U32 arg5, /*!< Fifth ASSERT Argument*/
U32 arg6 /*!< Sixth ASSERT Argument*/
) {
FW_ASSERT(0,arg1,arg2,arg3,arg4,arg5,arg6);
this->cmdResponse_out(opCode,cmdSeq,Fw::CmdResponse::OK);
}
void SendBuffImpl::parameterUpdated(FwPrmIdType id) {
this->log_ACTIVITY_LO_BuffSendParameterUpdated(id);
Fw::ParamValid valid;
switch(id) {
case PARAMID_PARAMETER3: {
U8 val = this->paramGet_parameter3(valid);
this->tlmWrite_Parameter3(val);
break;
}
case PARAMID_PARAMETER4: {
F32 val = this->paramGet_parameter4(valid);
this->tlmWrite_Parameter4(val);
break;
}
default:
FW_ASSERT(0,id);
break;
} }
// serialize data
serStat = this->m_testBuff.serialize(testData, dataSize);
FW_ASSERT(serStat == Fw::FW_SERIALIZE_OK);
// serialize checksum
serStat = this->m_testBuff.serialize(csum);
FW_ASSERT(serStat == Fw::FW_SERIALIZE_OK);
// send data
this->Data_out(0, this->m_testBuff);
}
this->m_invocations++;
this->tlmWrite_SendState(this->m_state);
}
void SendBuffImpl::SB_START_PKTS_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
this->m_sendPackets = true;
this->m_state = SendBuff_ActiveState::SEND_ACTIVE;
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
void SendBuffImpl::SB_INJECT_PKT_ERROR_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
this->m_injectError = true;
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
void SendBuffImpl::SB_GEN_FATAL_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 arg1, /*!< First FATAL Argument*/
U32 arg2, /*!< Second FATAL Argument*/
U32 arg3 /*!< Third FATAL Argument*/
) {
this->log_FATAL_SendBuffFatal(arg1, arg2, arg3);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
//! Handler for command SB_GEN_ASSERT
/* Generate an ASSERT */
void SendBuffImpl::SB_GEN_ASSERT_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 arg1, /*!< First ASSERT Argument*/
U32 arg2, /*!< Second ASSERT Argument*/
U32 arg3, /*!< Third ASSERT Argument*/
U32 arg4, /*!< Fourth ASSERT Argument*/
U32 arg5, /*!< Fifth ASSERT Argument*/
U32 arg6 /*!< Sixth ASSERT Argument*/
) {
FW_ASSERT(0, arg1, arg2, arg3, arg4, arg5, arg6);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
void SendBuffImpl::parameterUpdated(FwPrmIdType id) {
this->log_ACTIVITY_LO_BuffSendParameterUpdated(id);
Fw::ParamValid valid;
switch (id) {
case PARAMID_PARAMETER3: {
U8 val = this->paramGet_parameter3(valid);
this->tlmWrite_Parameter3(val);
break;
}
case PARAMID_PARAMETER4: {
F32 val = this->paramGet_parameter4(valid);
this->tlmWrite_Parameter4(val);
break;
}
default:
FW_ASSERT(0, id);
break;
} }
} }
} // namespace Ref

View File

@ -5,58 +5,54 @@
namespace Ref { namespace Ref {
/// This component sends a data buffer to a driver each time it is invoked by a scheduler /// This component sends a data buffer to a driver each time it is invoked by a scheduler
class SendBuffImpl final : public SendBuffComponentBase { class SendBuffImpl final : public SendBuffComponentBase {
public: public:
// Only called by derived class
SendBuffImpl(const char* compName); //!< constructor
~SendBuffImpl(); //!< destructor
// Only called by derived class private:
SendBuffImpl(const char* compName); //!< constructor void SchedIn_handler(FwIndexType portNum, U32 context); //!< downcall for input port
~SendBuffImpl(); //!< destructor void SB_START_PKTS_cmdHandler(FwOpcodeType opcode, U32 cmdSeq); //!< START_PKTS command handler
void SB_INJECT_PKT_ERROR_cmdHandler(FwOpcodeType opcode, U32 cmdSeq); //!< START_PKTS command handler
void SB_GEN_FATAL_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 arg1, /*!< First FATAL Argument*/
U32 arg2, /*!< Second FATAL Argument*/
U32 arg3 /*!< Third FATAL Argument*/
);
private: //! Handler for command SB_GEN_ASSERT
/* Generate an ASSERT */
void SB_GEN_ASSERT_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 arg1, /*!< First ASSERT Argument*/
U32 arg2, /*!< Second ASSERT Argument*/
U32 arg3, /*!< Third ASSERT Argument*/
U32 arg4, /*!< Fourth ASSERT Argument*/
U32 arg5, /*!< Fifth ASSERT Argument*/
U32 arg6 /*!< Sixth ASSERT Argument*/
);
U32 m_invocations; //!< number of times component has been called by the scheduler
U32 m_buffsSent; //!< number of buffers sent
U32 m_errorsInjected; //!< number of errors injected
bool m_injectError; //!< flag to inject error on next packet
bool m_sendPackets; //!< If true, send packets
U32 m_currPacketId; //!< current packet ID to be sent
bool m_firstPacketSent; //!< set if first packet
void SchedIn_handler(FwIndexType portNum, U32 context); //!< downcall for input port // buffer data
void SB_START_PKTS_cmdHandler(FwOpcodeType opcode, U32 cmdSeq); //!< START_PKTS command handler Drv::DataBuffer m_testBuff; //!< data buffer to send
void SB_INJECT_PKT_ERROR_cmdHandler(FwOpcodeType opcode, U32 cmdSeq); //!< START_PKTS command handler
void SB_GEN_FATAL_cmdHandler(
FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 arg1, /*!< First FATAL Argument*/
U32 arg2, /*!< Second FATAL Argument*/
U32 arg3 /*!< Third FATAL Argument*/
);
//! Handler for command SB_GEN_ASSERT // parameter update notification
/* Generate an ASSERT */ void parameterUpdated(FwPrmIdType id); //!< Notification function for changed parameters
void SB_GEN_ASSERT_cmdHandler(
FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 arg1, /*!< First ASSERT Argument*/
U32 arg2, /*!< Second ASSERT Argument*/
U32 arg3, /*!< Third ASSERT Argument*/
U32 arg4, /*!< Fourth ASSERT Argument*/
U32 arg5, /*!< Fifth ASSERT Argument*/
U32 arg6 /*!< Sixth ASSERT Argument*/
);
U32 m_invocations; //!< number of times component has been called by the scheduler
U32 m_buffsSent; //!< number of buffers sent
U32 m_errorsInjected; //!< number of errors injected
bool m_injectError; //!< flag to inject error on next packet
bool m_sendPackets; //!< If true, send packets
U32 m_currPacketId; //!< current packet ID to be sent
bool m_firstPacketSent; //!< set if first packet
// buffer data // send state
Drv::DataBuffer m_testBuff; //!< data buffer to send SendBuff_ActiveState m_state;
// parameter update notification
void parameterUpdated(FwPrmIdType id); //!< Notification function for changed parameters
// send state
SendBuff_ActiveState m_state;
}; };
} } // namespace Ref
#endif #endif

View File

@ -17,280 +17,252 @@
// TKC - don't know why it's undefined in VxWorks // TKC - don't know why it's undefined in VxWorks
#ifdef TGT_OS_TYPE_VXWORKS #ifdef TGT_OS_TYPE_VXWORKS
#define M_PI (22.0/7.0) #define M_PI (22.0 / 7.0)
#endif #endif
namespace Ref { namespace Ref {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Construction, initialization, and destruction // Construction, initialization, and destruction
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
SignalGen :: SignalGen ::SignalGen(const char* name)
SignalGen(const char* name) : : SignalGenComponentBase(name),
SignalGenComponentBase(name), sampleFrequency(25),
sampleFrequency(25), signalFrequency(1),
signalFrequency(1), signalAmplitude(0.0f),
signalAmplitude(0.0f), signalPhase(0.0f),
signalPhase(0.0f), ticks(0),
ticks(0), sigType(SignalType::SINE),
sigType(SignalType::SINE), sigHistory(),
sigHistory(), sigPairHistory(),
sigPairHistory(), running(false),
running(false), skipOne(false),
skipOne(false), m_dpInProgress(false),
m_dpInProgress(false), m_numDps(0),
m_numDps(0), m_currDp(0),
m_currDp(0), m_dpPriority(0) {}
m_dpPriority(0)
{}
SignalGen ::~SignalGen() {}
SignalGen :: ~SignalGen() { } // ----------------------------------------------------------------------
// Handler implementations
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- F32 SignalGen::generateSample(U32 ticks) {
// Handler implementations F32 val = 0.0f;
// ---------------------------------------------------------------------- if (this->skipOne) {
return val;
F32 SignalGen::generateSample(U32 ticks) { }
F32 val = 0.0f; // Samples per period
if (this->skipOne) { F32 samplesPerPeriod = static_cast<F32>(this->sampleFrequency) / static_cast<F32>(this->signalFrequency);
return val; U32 halfSamplesPerPeriod = samplesPerPeriod / 2;
} /* Signals courtesy of the open source Aquila DSP Library */
// Samples per period switch (this->sigType.e) {
F32 samplesPerPeriod = static_cast<F32>(this->sampleFrequency) / static_cast<F32>(this->signalFrequency); case SignalType::TRIANGLE: {
U32 halfSamplesPerPeriod = samplesPerPeriod / 2;
/* Signals courtesy of the open source Aquila DSP Library */
switch (this->sigType.e) {
case SignalType::TRIANGLE:
{
F32 m = this->signalAmplitude / static_cast<F32>(halfSamplesPerPeriod); F32 m = this->signalAmplitude / static_cast<F32>(halfSamplesPerPeriod);
val = m * static_cast<F32>(ticks % halfSamplesPerPeriod); val = m * static_cast<F32>(ticks % halfSamplesPerPeriod);
break; break;
} }
case SignalType::SINE: case SignalType::SINE: {
{
F32 normalizedFrequency = 1.0f / samplesPerPeriod; F32 normalizedFrequency = 1.0f / samplesPerPeriod;
val = this->signalAmplitude * std::sin((2.0 * M_PI * normalizedFrequency * val = this->signalAmplitude * std::sin((2.0 * M_PI * normalizedFrequency * static_cast<F32>(ticks)) +
static_cast<F32>(ticks)) + (this->signalPhase * 2.0 * M_PI)); (this->signalPhase * 2.0 * M_PI));
break; break;
} }
case SignalType::SQUARE: case SignalType::SQUARE: {
{ val = this->signalAmplitude *
val = this->signalAmplitude * ((ticks % static_cast<U32>(samplesPerPeriod) < halfSamplesPerPeriod) ? 1.0f : -1.0f); ((ticks % static_cast<U32>(samplesPerPeriod) < halfSamplesPerPeriod) ? 1.0f : -1.0f);
break; break;
} }
case SignalType::NOISE: case SignalType::NOISE: {
{
val = this->signalAmplitude * (std::rand() / static_cast<double>(RAND_MAX)); val = this->signalAmplitude * (std::rand() / static_cast<double>(RAND_MAX));
break; break;
} }
default: default:
FW_ASSERT(0); // Should never happen FW_ASSERT(0); // Should never happen
}
return val;
}
void SignalGen::schedIn_handler(FwIndexType portNum, /*!< The port number*/
U32 context /*!< The call order*/
) {
F32 value = 0.0f;
// This is a queued component, so it must intentionally run the dispatch of commands and queue processing on this
// synchronous scheduled call
this->doDispatch();
// This short-circuits when the signal generator is not running
if (not this->running) {
return;
}
// Allows for skipping a single reading of the signal
if (not this->skipOne) {
value = this->generateSample(this->ticks);
}
this->skipOne = false;
// Build our new types
SignalPair pair = SignalPair(this->ticks, value);
// Shift and assign our array types
for (U32 i = 1; i < this->sigHistory.SIZE; i++) {
this->sigHistory[i - 1] = this->sigHistory[i];
this->sigPairHistory[i - 1] = this->sigPairHistory[i];
}
this->sigHistory[this->sigHistory.SIZE - 1] = value;
this->sigPairHistory[this->sigPairHistory.SIZE - 1] = pair;
// Composite structure
SignalInfo sigInfo(this->sigType, this->sigHistory, this->sigPairHistory);
// Write all signals
this->tlmWrite_Type(this->sigType);
this->tlmWrite_Output(value);
this->tlmWrite_PairOutput(pair);
this->tlmWrite_History(this->sigHistory);
this->tlmWrite_PairHistory(this->sigPairHistory);
this->tlmWrite_Info(sigInfo);
// if a Data product is being generated, store a record
if (this->m_dpInProgress) {
Fw::SerializeStatus stat = this->m_dpContainer.serializeRecord_DataRecord(sigInfo);
this->m_currDp++;
this->m_dpBytes += SignalInfo::SERIALIZED_SIZE;
// check for full data product
if (Fw::SerializeStatus::FW_SERIALIZE_NO_ROOM_LEFT == stat) {
this->log_WARNING_LO_DpRecordFull(this->m_currDp, this->m_dpBytes);
this->cleanupAndSendDp();
} else if (this->m_currDp == this->m_numDps) { // if we reached the target number of DPs
this->log_ACTIVITY_LO_DpComplete(this->m_numDps, this->m_dpBytes);
this->cleanupAndSendDp();
} }
return val;
this->tlmWrite_DpBytes(this->m_dpBytes);
this->tlmWrite_DpRecords(this->m_currDp);
} }
void SignalGen::schedIn_handler( this->ticks += 1;
FwIndexType portNum, /*!< The port number*/ }
U32 context /*!< The call order*/
)
{
F32 value = 0.0f;
// This is a queued component, so it must intentionally run the dispatch of commands and queue processing on this
// synchronous scheduled call
this->doDispatch();
// This short-circuits when the signal generator is not running void SignalGen::Settings_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
if (not this->running) { U32 cmdSeq, /*!< The command sequence number*/
return; U32 Frequency,
} F32 Amplitude,
// Allows for skipping a single reading of the signal F32 Phase,
if (not this->skipOne) { Ref::SignalType SigType) {
value = this->generateSample(this->ticks); this->signalFrequency = Frequency;
} this->signalAmplitude = Amplitude;
this->skipOne = false; this->signalPhase = Phase;
this->sigType = SigType;
// Build our new types // When the settings change, reset the history values
SignalPair pair = SignalPair(this->ticks, value); for (U32 i = 0; i < SignalSet::SIZE; i++) {
this->sigHistory[i] = 0.0f;
}
for (U32 i = 0; i < SignalPairSet::SIZE; i++) {
this->sigPairHistory[i].set_time(0.0f);
this->sigPairHistory[i].set_value(0.0f);
}
this->log_ACTIVITY_LO_SettingsChanged(this->signalFrequency, this->signalAmplitude, this->signalPhase,
this->sigType);
this->tlmWrite_Type(SigType);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
// Shift and assign our array types void SignalGen::Toggle_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
for (U32 i = 1; i < this->sigHistory.SIZE; i++) { U32 cmdSeq /*!< The command sequence number*/
this->sigHistory[i - 1] = this->sigHistory[i]; ) {
this->sigPairHistory[i - 1] = this->sigPairHistory[i]; this->running = !this->running;
} this->ticks = 0;
this->sigHistory[this->sigHistory.SIZE - 1] = value; this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
this->sigPairHistory[this->sigPairHistory.SIZE - 1] = pair; }
// Composite structure void SignalGen::Skip_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
SignalInfo sigInfo(this->sigType, this->sigHistory, this->sigPairHistory); U32 cmdSeq /*!< The command sequence number*/
) {
this->skipOne = true;
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
// Write all signals void SignalGen::Dp_cmdHandler(FwOpcodeType opCode,
this->tlmWrite_Type(this->sigType); U32 cmdSeq,
this->tlmWrite_Output(value); Ref::SignalGen_DpReqType reqType,
this->tlmWrite_PairOutput(pair); U32 records,
this->tlmWrite_History(this->sigHistory); U32 priority) {
this->tlmWrite_PairHistory(this->sigPairHistory); // at least one record
this->tlmWrite_Info(sigInfo); if (0 == records) {
this->log_WARNING_HI_InSufficientDpRecords();
// if a Data product is being generated, store a record this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
if (this->m_dpInProgress) { return;
Fw::SerializeStatus stat = this->m_dpContainer.serializeRecord_DataRecord(sigInfo);
this->m_currDp++;
this->m_dpBytes += SignalInfo::SERIALIZED_SIZE;
// check for full data product
if (Fw::SerializeStatus::FW_SERIALIZE_NO_ROOM_LEFT == stat) {
this->log_WARNING_LO_DpRecordFull(this->m_currDp,this->m_dpBytes);
this->cleanupAndSendDp();
} else if (this->m_currDp == this->m_numDps) { // if we reached the target number of DPs
this->log_ACTIVITY_LO_DpComplete(this->m_numDps,this->m_dpBytes);
this->cleanupAndSendDp();
}
this->tlmWrite_DpBytes(this->m_dpBytes);
this->tlmWrite_DpRecords(this->m_currDp);
}
this->ticks += 1;
} }
void SignalGen::Settings_cmdHandler( // make sure DPs are available
FwOpcodeType opCode, /*!< The opcode*/ if (not this->isConnected_productGetOut_OutputPort(0)) {
U32 cmdSeq, /*!< The command sequence number*/ this->log_WARNING_HI_DpsNotConnected();
U32 Frequency, this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
F32 Amplitude, return;
F32 Phase,
Ref::SignalType SigType
)
{
this->signalFrequency = Frequency;
this->signalAmplitude = Amplitude;
this->signalPhase = Phase;
this->sigType = SigType;
// When the settings change, reset the history values
for (U32 i = 0; i < SignalSet::SIZE; i++) {
this->sigHistory[i] = 0.0f;
}
for (U32 i = 0; i < SignalPairSet::SIZE; i++) {
this->sigPairHistory[i].set_time(0.0f);
this->sigPairHistory[i].set_value(0.0f);
}
this->log_ACTIVITY_LO_SettingsChanged(this->signalFrequency, this->signalAmplitude, this->signalPhase, this->sigType);
this->tlmWrite_Type(SigType);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
} }
void SignalGen::Toggle_cmdHandler( // get DP buffer. Use sync or async request depending on
FwOpcodeType opCode, /*!< The opcode*/ // requested type
U32 cmdSeq /*!< The command sequence number*/ FwSizeType dpSize = records * (SignalInfo::SERIALIZED_SIZE + sizeof(FwDpIdType));
) this->m_numDps = records;
{ this->m_currDp = 0;
this->running = !this->running; this->m_dpPriority = static_cast<FwDpPriorityType>(priority);
this->ticks = 0; this->log_ACTIVITY_LO_DpMemRequested(dpSize);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); if (Ref::SignalGen_DpReqType::IMMEDIATE == reqType) {
} Fw::Success stat = this->dpGet_DataContainer(dpSize, this->m_dpContainer);
// make sure we got the memory we wanted
void SignalGen::Skip_cmdHandler( if (Fw::Success::FAILURE == stat) {
FwOpcodeType opCode, /*!< The opcode*/ this->log_WARNING_HI_DpMemoryFail();
U32 cmdSeq /*!< The command sequence number*/
)
{
this->skipOne = true;
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}
void SignalGen::Dp_cmdHandler(
FwOpcodeType opCode,
U32 cmdSeq,
Ref::SignalGen_DpReqType reqType,
U32 records,
U32 priority
)
{
// at least one record
if (0 == records) {
this->log_WARNING_HI_InSufficientDpRecords();
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR);
return;
}
// make sure DPs are available
if (
not this->isConnected_productGetOut_OutputPort(0)
) {
this->log_WARNING_HI_DpsNotConnected();
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
return;
}
// get DP buffer. Use sync or async request depending on
// requested type
FwSizeType dpSize = records*(SignalInfo::SERIALIZED_SIZE + sizeof(FwDpIdType));
this->m_numDps = records;
this->m_currDp = 0;
this->m_dpPriority = static_cast<FwDpPriorityType>(priority);
this->log_ACTIVITY_LO_DpMemRequested(dpSize);
if (Ref::SignalGen_DpReqType::IMMEDIATE == reqType) {
Fw::Success stat = this->dpGet_DataContainer(dpSize,this->m_dpContainer);
// make sure we got the memory we wanted
if (Fw::Success::FAILURE == stat) {
this->log_WARNING_HI_DpMemoryFail();
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
} else {
this->m_dpInProgress = true;
this->log_ACTIVITY_LO_DpStarted(records);
this->log_ACTIVITY_LO_DpMemReceived(this->m_dpContainer.getBuffer().getSize());
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
// override priority with requested priority
this->m_dpContainer.setPriority(this->m_dpPriority);
}
} else if (Ref::SignalGen_DpReqType::ASYNC == reqType) {
this->dpRequest_DataContainer(dpSize);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
} else { } else {
// should never get here this->m_dpInProgress = true;
FW_ASSERT(0,reqType.e); this->log_ACTIVITY_LO_DpStarted(records);
this->log_ACTIVITY_LO_DpMemReceived(this->m_dpContainer.getBuffer().getSize());
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
// override priority with requested priority
this->m_dpContainer.setPriority(this->m_dpPriority);
} }
} else if (Ref::SignalGen_DpReqType::ASYNC == reqType) {
this->dpRequest_DataContainer(dpSize);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
} else {
// should never get here
FW_ASSERT(0, reqType.e);
} }
}
void SignalGen::cleanupAndSendDp() { void SignalGen::cleanupAndSendDp() {
this->dpSend(this->m_dpContainer); this->dpSend(this->m_dpContainer);
this->m_dpInProgress = false;
this->m_dpBytes = 0;
this->m_numDps = 0;
this->m_currDp = 0;
}
// ----------------------------------------------------------------------
// Handler implementations for data products
// ----------------------------------------------------------------------
void SignalGen ::dpRecv_DataContainer_handler(DpContainer& container, Fw::Success::T status) {
// Make sure we got the buffer we wanted or quit
if (Fw::Success::SUCCESS == status) {
this->m_dpContainer = container;
this->m_dpInProgress = true;
// set previously requested priority
this->m_dpContainer.setPriority(this->m_dpPriority);
this->log_ACTIVITY_LO_DpStarted(this->m_numDps);
} else {
this->log_WARNING_HI_DpMemoryFail();
// cleanup
this->m_dpInProgress = false; this->m_dpInProgress = false;
this->m_dpBytes = 0; this->m_dpBytes = 0;
this->m_numDps = 0; this->m_numDps = 0;
this->m_currDp = 0; this->m_currDp = 0;
} }
// ----------------------------------------------------------------------
// Handler implementations for data products
// ----------------------------------------------------------------------
void SignalGen ::
dpRecv_DataContainer_handler(
DpContainer& container,
Fw::Success::T status
)
{
// Make sure we got the buffer we wanted or quit
if (Fw::Success::SUCCESS == status) {
this->m_dpContainer = container;
this->m_dpInProgress = true;
// set previously requested priority
this->m_dpContainer.setPriority(this->m_dpPriority);
this->log_ACTIVITY_LO_DpStarted(this->m_numDps);
} else {
this->log_WARNING_HI_DpMemoryFail();
// cleanup
this->m_dpInProgress = false;
this->m_dpBytes = 0;
this->m_numDps = 0;
this->m_currDp = 0;
}
}
} }
} // namespace Ref

View File

@ -22,92 +22,77 @@
namespace Ref { namespace Ref {
class SignalGen final : class SignalGen final : public SignalGenComponentBase {
public SignalGenComponentBase private:
{ void schedIn_handler(FwIndexType portNum, /*!< The port number*/
U32 context /*!< The call order*/
) final;
private: void Settings_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
U32 cmdSeq, /*!< The command sequence number*/
U32 Frequency,
F32 Amplitude,
F32 Phase,
Ref::SignalType SigType) final;
void schedIn_handler( void Toggle_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
FwIndexType portNum, /*!< The port number*/ U32 cmdSeq /*!< The command sequence number*/
U32 context /*!< The call order*/ ) final;
) final;
void Settings_cmdHandler( void Skip_cmdHandler(FwOpcodeType opCode, /*!< The opcode*/
FwOpcodeType opCode, /*!< The opcode*/ U32 cmdSeq /*!< The command sequence number*/
U32 cmdSeq, /*!< The command sequence number*/ ) final;
U32 Frequency,
F32 Amplitude,
F32 Phase,
Ref::SignalType SigType
) final;
void Toggle_cmdHandler( //! Handler implementation for command Dp
FwOpcodeType opCode, /*!< The opcode*/ //!
U32 cmdSeq /*!< The command sequence number*/ //! Signal Generator Settings
) final; void Dp_cmdHandler(FwOpcodeType opCode, //!< The opcode
U32 cmdSeq, //!< The command sequence number
Ref::SignalGen_DpReqType reqType,
U32 records,
U32 priority) final;
void Skip_cmdHandler( // ----------------------------------------------------------------------
FwOpcodeType opCode, /*!< The opcode*/ // Handler implementations for data products
U32 cmdSeq /*!< The command sequence number*/ // ----------------------------------------------------------------------
) final;
//! Handler implementation for command Dp //! Receive a container of type DataContainer
//! void dpRecv_DataContainer_handler(DpContainer& container, //!< The container
//! Signal Generator Settings Fw::Success::T status //!< The container status
void Dp_cmdHandler( ) final;
FwOpcodeType opCode, //!< The opcode
U32 cmdSeq, //!< The command sequence number
Ref::SignalGen_DpReqType reqType,
U32 records,
U32 priority
) final;
// ---------------------------------------------------------------------- public:
// Handler implementations for data products //! Construct a SignalGen
// ---------------------------------------------------------------------- SignalGen(const char* compName //!< The component name
);
//! Receive a container of type DataContainer //! Destroy a SignalGen
void dpRecv_DataContainer_handler( ~SignalGen();
DpContainer& container, //!< The container
Fw::Success::T status //!< The container status
) final;
private:
// Generate the next sample internal helper
F32 generateSample(U32 ticks);
public: // DP cleanup helper
//! Construct a SignalGen void cleanupAndSendDp();
SignalGen(
const char* compName //!< The component name
);
//! Destroy a SignalGen // Member variables
~SignalGen(); U32 sampleFrequency;
U32 signalFrequency;
private: F32 signalAmplitude;
// Generate the next sample internal helper F32 signalPhase;
F32 generateSample(U32 ticks); U32 ticks;
SignalType sigType;
// DP cleanup helper SignalSet sigHistory;
void cleanupAndSendDp(); SignalPairSet sigPairHistory;
bool running;
// Member variables bool skipOne;
U32 sampleFrequency; DpContainer m_dpContainer;
U32 signalFrequency; bool m_dpInProgress; //!< flag to indicate data products are being generated
F32 signalAmplitude; U32 m_numDps; //!< number of DPs to store
F32 signalPhase; U32 m_currDp; //!< current DP number
U32 ticks; U32 m_dpBytes; //!< currently serialized records
SignalType sigType; FwDpPriorityType m_dpPriority; //!< stored priority for current DP
SignalSet sigHistory; };
SignalPairSet sigPairHistory; } // namespace Ref
bool running;
bool skipOne;
DpContainer m_dpContainer;
bool m_dpInProgress; //!< flag to indicate data products are being generated
U32 m_numDps; //!< number of DPs to store
U32 m_currDp; //!< current DP number
U32 m_dpBytes; //!< currently serialized records
FwDpPriorityType m_dpPriority; //!< stored priority for current DP
};
}
#endif #endif

View File

@ -9,7 +9,7 @@ TEST(Nominal, TestStart) {
tester.test_start(); tester.test_start();
} }
int main(int argc, char **argv) { int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View File

@ -14,74 +14,54 @@
namespace Ref { namespace Ref {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Construction and destruction // Construction and destruction
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
SignalGenTester :: SignalGenTester ::SignalGenTester() : SignalGenGTestBase("Tester", MAX_HISTORY_SIZE), component("SignalGen") {
SignalGenTester() :
SignalGenGTestBase("Tester", MAX_HISTORY_SIZE),
component("SignalGen")
{
this->initComponents(); this->initComponents();
this->connectPorts(); this->connectPorts();
this->m_reqDpBuff.set(this->m_dpBuff,sizeof(this->m_dpBuff)); this->m_reqDpBuff.set(this->m_dpBuff, sizeof(this->m_dpBuff));
} }
SignalGenTester :: SignalGenTester ::~SignalGenTester() {}
~SignalGenTester()
{
} // ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- void SignalGenTester ::test_start() {
// Tests ASSERT_TLM_Output_SIZE(0);
// ---------------------------------------------------------------------- sendCmd_Toggle(0, 0);
component.doDispatch();
invoke_to_schedIn(0, 0);
component.doDispatch();
ASSERT_TLM_Output_SIZE(1);
sendCmd_Dp(0, 10, Ref::SignalGen_DpReqType::IMMEDIATE, 1, 1);
component.doDispatch();
// verify request for data product buffer
ASSERT_PRODUCT_GET_SIZE(1);
// run 2 cycles, should output data product on second
invoke_to_schedIn(0, 0);
ASSERT_PRODUCT_SEND_SIZE(1);
}
void SignalGenTester :: //! Handle a text event
test_start() void SignalGenTester::textLogIn(FwEventIdType id, //!< The event ID
{ const Fw::Time& timeTag, //!< The time
ASSERT_TLM_Output_SIZE(0); const Fw::LogSeverity severity, //!< The severity
sendCmd_Toggle(0, 0); const Fw::TextLogString& text //!< The event string
component.doDispatch(); ) {
invoke_to_schedIn(0, 0); TextLogEntry e = {id, timeTag, severity, text};
component.doDispatch();
ASSERT_TLM_Output_SIZE(1);
sendCmd_Dp(0,10,Ref::SignalGen_DpReqType::IMMEDIATE,1,1);
component.doDispatch();
// verify request for data product buffer
ASSERT_PRODUCT_GET_SIZE(1);
// run 2 cycles, should output data product on second
invoke_to_schedIn(0, 0);
ASSERT_PRODUCT_SEND_SIZE(1);
} printTextLogHistoryEntry(e, stdout);
}
//! Handle a text event Fw::Success::T SignalGenTester ::productGet_handler(FwDpIdType id, FwSizeType dataSize, Fw::Buffer& buffer) {
void SignalGenTester::textLogIn( printf("Component requested %" PRI_FwSizeType " bytes.\n", dataSize);
FwEventIdType id, //!< The event ID buffer.set(this->m_dpBuff, dataSize);
const Fw::Time& timeTag, //!< The time
const Fw::LogSeverity severity, //!< The severity
const Fw::TextLogString& text //!< The event string
) {
TextLogEntry e = { id, timeTag, severity, text };
printTextLogHistoryEntry(e, stdout);
}
Fw::Success::T SignalGenTester ::
productGet_handler(
FwDpIdType id,
FwSizeType dataSize,
Fw::Buffer& buffer
)
{
printf ("Component requested %" PRI_FwSizeType " bytes.\n",dataSize);
buffer.set(this->m_dpBuff,dataSize);
this->pushProductGetEntry(id, dataSize); this->pushProductGetEntry(id, dataSize);
return Fw::Success::SUCCESS; return Fw::Success::SUCCESS;
} }
} // end namespace Ref
} // end namespace Ref

View File

@ -13,92 +13,83 @@
#ifndef TESTER_HPP #ifndef TESTER_HPP
#define TESTER_HPP #define TESTER_HPP
#include "SignalGenGTestBase.hpp"
#include "Ref/SignalGen/SignalGen.hpp" #include "Ref/SignalGen/SignalGen.hpp"
#include "SignalGenGTestBase.hpp"
namespace Ref { namespace Ref {
class SignalGenTester : class SignalGenTester : public SignalGenGTestBase {
public SignalGenGTestBase // ----------------------------------------------------------------------
{ // Construction and destruction
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------
public: public:
// Maximum size of histories storing events, telemetry, and port outputs // Maximum size of histories storing events, telemetry, and port outputs
static const U32 MAX_HISTORY_SIZE = 10; static const U32 MAX_HISTORY_SIZE = 10;
// Instance ID supplied to the component instance under test // Instance ID supplied to the component instance under test
static const FwEnumStoreType TEST_INSTANCE_ID = 0; static const FwEnumStoreType TEST_INSTANCE_ID = 0;
// Queue depth supplied to component instance under test // Queue depth supplied to component instance under test
static const FwSizeType TEST_INSTANCE_QUEUE_DEPTH = 10; static const FwSizeType TEST_INSTANCE_QUEUE_DEPTH = 10;
//! Construct object SignalGenTester //! Construct object SignalGenTester
//! //!
SignalGenTester(); SignalGenTester();
//! Destroy object SignalGenTester //! Destroy object SignalGenTester
//! //!
~SignalGenTester(); ~SignalGenTester();
public: public:
// ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- //! To do
// Tests //!
// ---------------------------------------------------------------------- void test_start();
//! To do private:
//! // ----------------------------------------------------------------------
void test_start(); // Helper methods
// ----------------------------------------------------------------------
private: //! Connect ports
//!
void connectPorts();
// ---------------------------------------------------------------------- //! Initialize components
// Helper methods //!
// ---------------------------------------------------------------------- void initComponents();
//! Connect ports private:
//! //! Handle a data product get from the component under test
void connectPorts(); //!
//! By default, (1) call pushProductGetEntry; (2) do not allocate a buffer
//! and return FAILURE. You can override this behavior, e.g., to call
//! pushProductGetEntry, allocate a buffer and return SUCCESS.
Fw::Success::T productGet_handler(FwDpIdType id, //!< The container ID (input)
FwSizeType dataSize, //!< The data size of the requested buffer (input)
Fw::Buffer& buffer //!< The buffer (output)
) override;
//! Initialize components // ----------------------------------------------------------------------
//! // Variables
void initComponents(); // ----------------------------------------------------------------------
private: //! The component under test
//!
SignalGen component;
//! Handle a data product get from the component under test void textLogIn(FwEventIdType id, //!< The event ID
//! const Fw::Time& timeTag, //!< The time
//! By default, (1) call pushProductGetEntry; (2) do not allocate a buffer const Fw::LogSeverity severity, //!< The severity
//! and return FAILURE. You can override this behavior, e.g., to call const Fw::TextLogString& text //!< The event string
//! pushProductGetEntry, allocate a buffer and return SUCCESS. ) override;
Fw::Success::T productGet_handler (
FwDpIdType id, //!< The container ID (input)
FwSizeType dataSize, //!< The data size of the requested buffer (input)
Fw::Buffer& buffer //!< The buffer (output)
) override;
U8 m_dpBuff[1024];
Fw::Buffer m_reqDpBuff;
};
// ---------------------------------------------------------------------- } // end namespace Ref
// Variables
// ----------------------------------------------------------------------
//! The component under test
//!
SignalGen component;
void textLogIn(
FwEventIdType id, //!< The event ID
const Fw::Time& timeTag, //!< The time
const Fw::LogSeverity severity, //!< The severity
const Fw::TextLogString& text //!< The event string
) override;
U8 m_dpBuff[1024];
Fw::Buffer m_reqDpBuff;
};
} // end namespace Ref
#endif #endif

View File

@ -15,7 +15,6 @@
// Necessary project-specified types // Necessary project-specified types
#include <Fw/Types/MallocAllocator.hpp> #include <Fw/Types/MallocAllocator.hpp>
// Allows easy reference to objects in FPP/autocoder required namespaces // Allows easy reference to objects in FPP/autocoder required namespaces
using namespace Ref; using namespace Ref;
@ -78,7 +77,7 @@ void setupTopology(const TopologyState& state) {
loadParameters(); loadParameters();
// Autocoded task kick-off (active components). Function provided by autocoder. // Autocoded task kick-off (active components). Function provided by autocoder.
startTasks(state); startTasks(state);
//Initialize socket client communication if and only if there is a valid specification // Initialize socket client communication if and only if there is a valid specification
if (state.hostname != nullptr && state.port != 0) { if (state.hostname != nullptr && state.port != 0) {
Os::TaskString name("ReceiveTask"); Os::TaskString name("ReceiveTask");
comDriver.start(name, COMM_PRIORITY, Default::STACK_SIZE); comDriver.start(name, COMM_PRIORITY, Default::STACK_SIZE);
@ -102,7 +101,7 @@ void teardownTopology(const TopologyState& state) {
stopTasks(state); stopTasks(state);
freeThreads(state); freeThreads(state);
//Stop the comDriver component, free thread // Stop the comDriver component, free thread
comDriver.stop(); comDriver.stop();
(void)comDriver.join(); (void)comDriver.join();

View File

@ -67,12 +67,13 @@ void teardownTopology(const TopologyState& state);
/** /**
* \brief cycle the rate group driver based in a system timer * \brief cycle the rate group driver based in a system timer
* *
* In order to be a portable demonstration, the reference topology does not have a direct hardware timer that is typically used * In order to be a portable demonstration, the reference topology does not have a direct hardware timer that is
* in embedded applications. Instead, a linux system timer is used to drive the rate groups at 1Hz. The slower rate groups are * typically used in embedded applications. Instead, a linux system timer is used to drive the rate groups at 1Hz. The
* derived from this fundamental rate using the RateGroupDriver component to divide the rate down to slower rates. * slower rate groups are derived from this fundamental rate using the RateGroupDriver component to divide the rate down
* to slower rates.
* *
* For embedded Linux, this could be used to drive the system rate groups. For other embedded systems, projects should write components * For embedded Linux, this could be used to drive the system rate groups. For other embedded systems, projects should
* that implement whatever timers are available for that platform in place of Svc/LinuxTimer. * write components that implement whatever timers are available for that platform in place of Svc/LinuxTimer.
* *
* This loop is stopped via a stopRateGroups call. * This loop is stopped via a stopRateGroups call.
* *
@ -86,5 +87,5 @@ void startRateGroups(const Fw::TimeInterval& interval);
*/ */
void stopRateGroups(); void stopRateGroups();
} // namespace Ref } // namespace Ref
#endif #endif

View File

@ -10,19 +10,18 @@
// ====================================================================== // ======================================================================
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
#include <Utils/CRCChecker.hpp>
#include <Fw/Types/Assert.hpp> #include <Fw/Types/Assert.hpp>
#include <Fw/Types/FileNameString.hpp>
#include <Os/File.hpp> #include <Os/File.hpp>
#include <Os/FileSystem.hpp> #include <Os/FileSystem.hpp>
#include <Utils/CRCChecker.hpp>
#include <Utils/Hash/Hash.hpp> #include <Utils/Hash/Hash.hpp>
#include <Fw/Types/FileNameString.hpp>
namespace Utils { namespace Utils {
static_assert(FW_USE_PRINTF_FAMILY_FUNCTIONS_IN_STRING_FORMATTING, static_assert(FW_USE_PRINTF_FAMILY_FUNCTIONS_IN_STRING_FORMATTING,
"Cannot use CRC checker without full string formatting"); "Cannot use CRC checker without full string formatting");
crc_stat_t create_checksum_file(const char* const fname) crc_stat_t create_checksum_file(const char* const fname) {
{
FW_ASSERT(fname != nullptr); FW_ASSERT(fname != nullptr);
FwSizeType i; FwSizeType i;
@ -40,45 +39,39 @@ static_assert(FW_USE_PRINTF_FAMILY_FUNCTIONS_IN_STRING_FORMATTING,
U8 block_data[CRC_FILE_READ_BLOCK]; U8 block_data[CRC_FILE_READ_BLOCK];
fs_stat = Os::FileSystem::getFileSize(fname, filesize); fs_stat = Os::FileSystem::getFileSize(fname, filesize);
if(fs_stat != Os::FileSystem::OP_OK) if (fs_stat != Os::FileSystem::OP_OK) {
{ return FAILED_FILE_SIZE;
return FAILED_FILE_SIZE;
} }
// Open file // Open file
stat = f.open(fname, Os::File::OPEN_READ); stat = f.open(fname, Os::File::OPEN_READ);
if(stat != Os::File::OP_OK) if (stat != Os::File::OP_OK) {
{ return FAILED_FILE_OPEN;
return FAILED_FILE_OPEN;
} }
// Read file // Read file
bytes_to_read = CRC_FILE_READ_BLOCK; bytes_to_read = CRC_FILE_READ_BLOCK;
blocks = filesize / CRC_FILE_READ_BLOCK; blocks = filesize / CRC_FILE_READ_BLOCK;
for(i = 0; i < blocks; i++) for (i = 0; i < blocks; i++) {
{ stat = f.read(block_data, bytes_to_read);
stat = f.read(block_data, bytes_to_read); if (stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK) {
if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK) f.close();
{ return FAILED_FILE_READ;
f.close(); }
return FAILED_FILE_READ;
}
hash.update(block_data, bytes_to_read); hash.update(block_data, bytes_to_read);
} }
remaining_bytes = filesize % CRC_FILE_READ_BLOCK; remaining_bytes = filesize % CRC_FILE_READ_BLOCK;
bytes_to_read = remaining_bytes; bytes_to_read = remaining_bytes;
if(remaining_bytes > 0) if (remaining_bytes > 0) {
{ stat = f.read(block_data, bytes_to_read);
stat = f.read(block_data, bytes_to_read); if (stat != Os::File::OP_OK || bytes_to_read != remaining_bytes) {
if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes) f.close();
{ return FAILED_FILE_READ;
f.close(); }
return FAILED_FILE_READ;
}
hash.update(block_data, remaining_bytes); hash.update(block_data, remaining_bytes);
} }
// close file // close file
@ -92,57 +85,52 @@ static_assert(FW_USE_PRINTF_FAMILY_FUNCTIONS_IN_STRING_FORMATTING,
FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS); FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS);
stat = f.open(hashFilename.toChar(), Os::File::OPEN_WRITE); stat = f.open(hashFilename.toChar(), Os::File::OPEN_WRITE);
if(stat != Os::File::OP_OK) if (stat != Os::File::OP_OK) {
{ return FAILED_FILE_CRC_OPEN;
return FAILED_FILE_CRC_OPEN;
} }
// Write checksum file // Write checksum file
bytes_to_write = sizeof(checksum); bytes_to_write = sizeof(checksum);
stat = f.write(reinterpret_cast<U8*>(&checksum), bytes_to_write); stat = f.write(reinterpret_cast<U8*>(&checksum), bytes_to_write);
if(stat != Os::File::OP_OK || sizeof(checksum) != bytes_to_write) if (stat != Os::File::OP_OK || sizeof(checksum) != bytes_to_write) {
{ f.close();
f.close(); return FAILED_FILE_CRC_WRITE;
return FAILED_FILE_CRC_WRITE;
} }
// close checksum file // close checksum file
f.close(); f.close();
return PASSED_FILE_CRC_WRITE; return PASSED_FILE_CRC_WRITE;
} }
crc_stat_t read_crc32_from_file(const char* const fname, U32 &checksum_from_file) { crc_stat_t read_crc32_from_file(const char* const fname, U32& checksum_from_file) {
Os::File f; Os::File f;
Os::File::Status stat; Os::File::Status stat;
Fw::FileNameString hashFilename; Fw::FileNameString hashFilename;
FW_ASSERT(fname != nullptr); FW_ASSERT(fname != nullptr);
// open checksum file // open checksum file
Fw::FormatStatus formatStatus = hashFilename.format("%s%s", fname, HASH_EXTENSION_STRING); Fw::FormatStatus formatStatus = hashFilename.format("%s%s", fname, HASH_EXTENSION_STRING);
FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS); FW_ASSERT(formatStatus == Fw::FormatStatus::SUCCESS);
stat = f.open(hashFilename.toChar(), Os::File::OPEN_READ); stat = f.open(hashFilename.toChar(), Os::File::OPEN_READ);
if(stat != Os::File::OP_OK) if (stat != Os::File::OP_OK) {
{
return FAILED_FILE_CRC_OPEN; return FAILED_FILE_CRC_OPEN;
} }
// Read checksum file // Read checksum file
FwSizeType checksum_from_file_size = static_cast<FwSizeType>(sizeof(checksum_from_file)); FwSizeType checksum_from_file_size = static_cast<FwSizeType>(sizeof(checksum_from_file));
stat = f.read(reinterpret_cast<U8*>(&checksum_from_file), checksum_from_file_size); stat = f.read(reinterpret_cast<U8*>(&checksum_from_file), checksum_from_file_size);
if(stat != Os::File::OP_OK || checksum_from_file_size != sizeof(checksum_from_file)) if (stat != Os::File::OP_OK || checksum_from_file_size != sizeof(checksum_from_file)) {
{
f.close(); f.close();
return FAILED_FILE_CRC_READ; return FAILED_FILE_CRC_READ;
} }
// close checksum file // close checksum file
f.close(); f.close();
return PASSED_FILE_CRC_CHECK; return PASSED_FILE_CRC_CHECK;
} }
crc_stat_t verify_checksum(const char* const fname, U32 &expected, U32 &actual) crc_stat_t verify_checksum(const char* const fname, U32& expected, U32& actual) {
{
FW_ASSERT(fname != nullptr); FW_ASSERT(fname != nullptr);
FwSizeType i; FwSizeType i;
@ -159,45 +147,39 @@ static_assert(FW_USE_PRINTF_FAMILY_FUNCTIONS_IN_STRING_FORMATTING,
U8 block_data[CRC_FILE_READ_BLOCK]; U8 block_data[CRC_FILE_READ_BLOCK];
fs_stat = Os::FileSystem::getFileSize(fname, filesize); fs_stat = Os::FileSystem::getFileSize(fname, filesize);
if(fs_stat != Os::FileSystem::OP_OK) if (fs_stat != Os::FileSystem::OP_OK) {
{ return FAILED_FILE_SIZE;
return FAILED_FILE_SIZE;
} }
// Open file // Open file
stat = f.open(fname, Os::File::OPEN_READ); stat = f.open(fname, Os::File::OPEN_READ);
if(stat != Os::File::OP_OK) if (stat != Os::File::OP_OK) {
{ return FAILED_FILE_OPEN;
return FAILED_FILE_OPEN;
} }
// Read file // Read file
bytes_to_read = CRC_FILE_READ_BLOCK; bytes_to_read = CRC_FILE_READ_BLOCK;
blocks = filesize / CRC_FILE_READ_BLOCK; blocks = filesize / CRC_FILE_READ_BLOCK;
for(i = 0; i < blocks; i++) for (i = 0; i < blocks; i++) {
{ stat = f.read(block_data, bytes_to_read);
stat = f.read(block_data, bytes_to_read); if (stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK) {
if(stat != Os::File::OP_OK || bytes_to_read != CRC_FILE_READ_BLOCK) f.close();
{ return FAILED_FILE_READ;
f.close(); }
return FAILED_FILE_READ;
}
hash.update(block_data, static_cast<FwSizeType>(bytes_to_read)); hash.update(block_data, static_cast<FwSizeType>(bytes_to_read));
} }
remaining_bytes = filesize % CRC_FILE_READ_BLOCK; remaining_bytes = filesize % CRC_FILE_READ_BLOCK;
bytes_to_read = remaining_bytes; bytes_to_read = remaining_bytes;
if(remaining_bytes > 0) if (remaining_bytes > 0) {
{ stat = f.read(block_data, bytes_to_read);
stat = f.read(block_data, bytes_to_read); if (stat != Os::File::OP_OK || bytes_to_read != remaining_bytes) {
if(stat != Os::File::OP_OK || bytes_to_read != remaining_bytes) f.close();
{ return FAILED_FILE_READ;
f.close(); }
return FAILED_FILE_READ;
}
hash.update(block_data, remaining_bytes); hash.update(block_data, remaining_bytes);
} }
// close file // close file
@ -211,16 +193,15 @@ static_assert(FW_USE_PRINTF_FAMILY_FUNCTIONS_IN_STRING_FORMATTING,
} }
// compare checksums // compare checksums
if(checksum != checksum_from_file) if (checksum != checksum_from_file) {
{ expected = checksum_from_file;
expected = checksum_from_file; actual = checksum;
actual = checksum; return FAILED_FILE_CRC_CHECK;
return FAILED_FILE_CRC_CHECK;
} }
expected = checksum_from_file; expected = checksum_from_file;
actual = checksum; actual = checksum;
return PASSED_FILE_CRC_CHECK; return PASSED_FILE_CRC_CHECK;
}
} }
} // namespace Utils

View File

@ -17,11 +17,9 @@
namespace Utils { namespace Utils {
static const FwSignedSizeType CRC_FILE_READ_BLOCK = CONFIG_CRC_FILE_READ_BLOCK ; static const FwSignedSizeType CRC_FILE_READ_BLOCK = CONFIG_CRC_FILE_READ_BLOCK;
typedef enum {
typedef enum
{
PASSED_FILE_CRC_CHECK = 0, PASSED_FILE_CRC_CHECK = 0,
PASSED_FILE_CRC_WRITE, PASSED_FILE_CRC_WRITE,
FAILED_FILE_SIZE, FAILED_FILE_SIZE,
@ -32,12 +30,12 @@ namespace Utils {
FAILED_FILE_CRC_READ, FAILED_FILE_CRC_READ,
FAILED_FILE_CRC_WRITE, FAILED_FILE_CRC_WRITE,
FAILED_FILE_CRC_CHECK FAILED_FILE_CRC_CHECK
} crc_stat_t; } crc_stat_t;
crc_stat_t create_checksum_file(const char* const filename); crc_stat_t create_checksum_file(const char* const filename);
crc_stat_t read_crc32_from_file(const char* const fname, U32 &checksum_from_file); crc_stat_t read_crc32_from_file(const char* const fname, U32& checksum_from_file);
crc_stat_t verify_checksum(const char* const filename, U32 &expected, U32 &actual); crc_stat_t verify_checksum(const char* const filename, U32& expected, U32& actual);
} } // namespace Utils
#endif #endif

View File

@ -13,113 +13,96 @@
#ifndef UTILS_HASH_HPP #ifndef UTILS_HASH_HPP
#define UTILS_HASH_HPP #define UTILS_HASH_HPP
#include "Fw/Types/StringType.hpp"
#include <Utils/Hash/HashBuffer.hpp> #include <Utils/Hash/HashBuffer.hpp>
#include "Fw/Types/StringType.hpp"
namespace Utils { namespace Utils {
//! \class Hash //! \class Hash
//! \brief A generic interface for creating and comparing hash values //! \brief A generic interface for creating and comparing hash values
//! //!
class Hash { class Hash {
public:
// ----------------------------------------------------------------------
// Types
// ----------------------------------------------------------------------
public:
// ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------
public: //! Construct a Hash object
//!
Hash();
// ---------------------------------------------------------------------- //! Destroy a Hash object
// Types //!
// ---------------------------------------------------------------------- ~Hash();
public:
// ---------------------------------------------------------------------- public:
// Construction and destruction // ----------------------------------------------------------------------
// ---------------------------------------------------------------------- // Public static methods
// ----------------------------------------------------------------------
//! Construct a Hash object //! Create a hash value all at once from raw data
//! //! \param data: pointer to start of data
Hash(); //! \param len: length of the data
//! \param buffer: filled with resulting hash value
static void hash(const void* data, const FwSizeType len, HashBuffer& buffer);
//! Destroy a Hash object public:
//! // ----------------------------------------------------------------------
~Hash(); // Public instance methods
// ----------------------------------------------------------------------
public: //! Initialize a Hash object for incremental hash computation
//!
void init();
// ---------------------------------------------------------------------- //! Set hash value to specified value
// Public static methods //!
// ---------------------------------------------------------------------- void setHashValue(HashBuffer& value //! Hash value
);
//! Create a hash value all at once from raw data //! Update an incremental computation with new data
//! \param data: pointer to start of data //! \param data: pointer to start of data to add to hash calculation
//! \param len: length of the data //! \param len: length of data to add to hash calculation
//! \param buffer: filled with resulting hash value void update(const void* const data, const FwSizeType len);
static void hash(
const void *data,
const FwSizeType len,
HashBuffer& buffer
);
public: //! Finalize an incremental computation and return the result
//!
void final(HashBuffer& buffer //! The result
);
// ---------------------------------------------------------------------- //! Finalize an incremental computation and return the result
// Public instance methods //!
// ---------------------------------------------------------------------- void final(U32& hashvalue);
//! Initialize a Hash object for incremental hash computation //! Get the file extension for the supported hash type
//! //! E.g., could return "SHA256"
void init(); //!
static const char* getFileExtensionString();
//! Set hash value to specified value //! Add the extension for the supported hash type
//! //!
void setHashValue( static void addFileExtension(const Fw::StringBase& baseName, //!< The base name
HashBuffer &value //! Hash value Fw::StringBase& extendedName //!< The extended name
); );
//! Update an incremental computation with new data //! Get the length of the file extension string
//! \param data: pointer to start of data to add to hash calculation //!
//! \param len: length of data to add to hash calculation static FwSizeType getFileExtensionLength();
void update(
const void *const data,
const FwSizeType len
);
//! Finalize an incremental computation and return the result private:
//! // ----------------------------------------------------------------------
void final( // Private member variables
HashBuffer& buffer //! The result // ----------------------------------------------------------------------
);
//! Finalize an incremental computation and return the result //! The hash handle
//! //!
void final(U32 &hashvalue); HASH_HANDLE_TYPE hash_handle;
};
//! Get the file extension for the supported hash type } // namespace Utils
//! E.g., could return "SHA256"
//!
static const char* getFileExtensionString();
//! Add the extension for the supported hash type
//!
static void addFileExtension(
const Fw::StringBase& baseName, //!< The base name
Fw::StringBase& extendedName //!< The extended name
);
//! Get the length of the file extension string
//!
static FwSizeType getFileExtensionLength();
private:
// ----------------------------------------------------------------------
// Private member variables
// ----------------------------------------------------------------------
//! The hash handle
//!
HASH_HANDLE_TYPE hash_handle;
};
}
#endif #endif

View File

@ -2,26 +2,18 @@
namespace Utils { namespace Utils {
const char* Hash :: const char* Hash ::getFileExtensionString() {
getFileExtensionString() return HASH_EXTENSION_STRING;
{
return HASH_EXTENSION_STRING;
}
void Hash ::
addFileExtension(
const Fw::StringBase& baseName,
Fw::StringBase& extendedName
) {
extendedName.format("%s%s", baseName.toChar(), HASH_EXTENSION_STRING);
}
FwSizeType Hash ::
getFileExtensionLength()
{
// Size of returns the size including the '\0' character.
// We want to return just the size of the string.
return sizeof(HASH_EXTENSION_STRING) - 1;
}
} }
void Hash ::addFileExtension(const Fw::StringBase& baseName, Fw::StringBase& extendedName) {
extendedName.format("%s%s", baseName.toChar(), HASH_EXTENSION_STRING);
}
FwSizeType Hash ::getFileExtensionLength() {
// Size of returns the size including the '\0' character.
// We want to return just the size of the string.
return sizeof(HASH_EXTENSION_STRING) - 1;
}
} // namespace Utils

View File

@ -14,80 +14,62 @@
static_assert(sizeof(unsigned long) >= sizeof(U32), "CRC32 cannot fit in CRC32 library chosen types"); static_assert(sizeof(unsigned long) >= sizeof(U32), "CRC32 cannot fit in CRC32 library chosen types");
namespace Utils { namespace Utils {
Hash :: Hash ::Hash() {
Hash() this->init();
{ }
this->init();
}
Hash :: Hash ::~Hash() {}
~Hash()
{
}
void Hash :: void Hash ::hash(const void* const data, const FwSizeType len, HashBuffer& buffer) {
hash(const void *const data, const FwSizeType len, HashBuffer& buffer) HASH_HANDLE_TYPE local_hash_handle;
{ local_hash_handle = 0xffffffffL;
HASH_HANDLE_TYPE local_hash_handle; FW_ASSERT(data);
local_hash_handle = 0xffffffffL; char c;
FW_ASSERT(data); for (FwSizeType index = 0; index < len; index++) {
char c; c = static_cast<const char*>(data)[index];
for(FwSizeType index = 0; index < len; index++) { local_hash_handle = static_cast<HASH_HANDLE_TYPE>(update_crc_32(local_hash_handle, c));
c = static_cast<const char*>(data)[index];
local_hash_handle = static_cast<HASH_HANDLE_TYPE>(update_crc_32(local_hash_handle, c));
}
HashBuffer bufferOut;
// For CRC32 we need to return the one's complement of the result:
Fw::SerializeStatus status = bufferOut.serialize(~(local_hash_handle));
FW_ASSERT( Fw::FW_SERIALIZE_OK == status );
buffer = bufferOut;
} }
HashBuffer bufferOut;
// For CRC32 we need to return the one's complement of the result:
Fw::SerializeStatus status = bufferOut.serialize(~(local_hash_handle));
FW_ASSERT(Fw::FW_SERIALIZE_OK == status);
buffer = bufferOut;
}
void Hash :: void Hash ::init() {
init() this->hash_handle = 0xffffffffL;
{ }
this->hash_handle = 0xffffffffL;
}
void Hash :: void Hash ::update(const void* const data, FwSizeType len) {
update(const void *const data, FwSizeType len) FW_ASSERT(data);
{ char c;
FW_ASSERT(data); for (FwSizeType index = 0; index < len; index++) {
char c; c = static_cast<const char*>(data)[index];
for(FwSizeType index = 0; index < len; index++) { this->hash_handle = static_cast<HASH_HANDLE_TYPE>(update_crc_32(this->hash_handle, c));
c = static_cast<const char*>(data)[index];
this->hash_handle = static_cast<HASH_HANDLE_TYPE>(update_crc_32(this->hash_handle, c));
}
}
void Hash ::
final(HashBuffer& buffer)
{
HashBuffer bufferOut;
// For CRC32 we need to return the one's complement of the result:
Fw::SerializeStatus status = bufferOut.serialize(~(this->hash_handle));
FW_ASSERT( Fw::FW_SERIALIZE_OK == status );
buffer = bufferOut;
}
void Hash ::
final(U32 &hashvalue)
{
FW_ASSERT(sizeof(this->hash_handle) == sizeof(U32));
// For CRC32 we need to return the one's complement of the result:
hashvalue = ~(this->hash_handle);
}
void Hash ::
setHashValue(HashBuffer &value)
{
Fw::SerializeStatus status = value.deserialize(this->hash_handle);
FW_ASSERT( Fw::FW_SERIALIZE_OK == status );
// Expecting `value` to already be one's complement; so doing one's complement
// here for correct hash updates
this->hash_handle = ~this->hash_handle;
} }
} }
void Hash ::final(HashBuffer& buffer) {
HashBuffer bufferOut;
// For CRC32 we need to return the one's complement of the result:
Fw::SerializeStatus status = bufferOut.serialize(~(this->hash_handle));
FW_ASSERT(Fw::FW_SERIALIZE_OK == status);
buffer = bufferOut;
}
void Hash ::final(U32& hashvalue) {
FW_ASSERT(sizeof(this->hash_handle) == sizeof(U32));
// For CRC32 we need to return the one's complement of the result:
hashvalue = ~(this->hash_handle);
}
void Hash ::setHashValue(HashBuffer& value) {
Fw::SerializeStatus status = value.deserialize(this->hash_handle);
FW_ASSERT(Fw::FW_SERIALIZE_OK == status);
// Expecting `value` to already be one's complement; so doing one's complement
// here for correct hash updates
this->hash_handle = ~this->hash_handle;
}
} // namespace Utils

View File

@ -3,7 +3,7 @@
// Include the lic crc c library: // Include the lic crc c library:
extern "C" { extern "C" {
#include <Utils/Hash/libcrc/lib_crc.h> #include <Utils/Hash/libcrc/lib_crc.h>
} }
//! Define the hash handle type for this //! Define the hash handle type for this

View File

@ -1,3 +1,4 @@
// clang-format off
#include "lib_crc.h" #include "lib_crc.h"

View File

@ -1,3 +1,4 @@
// clang-format off
/*******************************************************************\ /*******************************************************************\
* * * *
* Library : lib_crc * * Library : lib_crc *

View File

@ -1,3 +1,4 @@
// clang-format off
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -14,49 +14,36 @@
namespace Utils { namespace Utils {
Hash :: Hash ::Hash() {
Hash() this->init();
{
this->init();
}
Hash ::
~Hash()
{
}
void Hash ::
hash(const void *const data, const FwSizeType len, HashBuffer& buffer)
{
U8 out[SHA256_DIGEST_LENGTH];
U8* ret = SHA256(static_cast<const U8*>(data), len, out);
FW_ASSERT(ret != nullptr);
HashBuffer bufferOut(out, sizeof(out));
buffer = bufferOut;
}
void Hash ::
init()
{
int ret = SHA256_Init(&this->hash_handle);
FW_ASSERT(ret == 1);
}
void Hash ::
update(const void *const data, FwSizeType len)
{
int ret = SHA256_Update(&this->hash_handle, static_cast<const U8*>(data), len);
FW_ASSERT(ret == 1);
}
void Hash ::
final(HashBuffer& buffer)
{
U8 out[SHA256_DIGEST_LENGTH];
int ret = SHA256_Final(out, &this->hash_handle);
FW_ASSERT(ret == 1);
HashBuffer bufferOut(out, sizeof(out));
buffer = bufferOut;
}
} }
Hash ::~Hash() {}
void Hash ::hash(const void* const data, const FwSizeType len, HashBuffer& buffer) {
U8 out[SHA256_DIGEST_LENGTH];
U8* ret = SHA256(static_cast<const U8*>(data), len, out);
FW_ASSERT(ret != nullptr);
HashBuffer bufferOut(out, sizeof(out));
buffer = bufferOut;
}
void Hash ::init() {
int ret = SHA256_Init(&this->hash_handle);
FW_ASSERT(ret == 1);
}
void Hash ::update(const void* const data, FwSizeType len) {
int ret = SHA256_Update(&this->hash_handle, static_cast<const U8*>(data), len);
FW_ASSERT(ret == 1);
}
void Hash ::final(HashBuffer& buffer) {
U8 out[SHA256_DIGEST_LENGTH];
int ret = SHA256_Final(out, &this->hash_handle);
FW_ASSERT(ret == 1);
HashBuffer bufferOut(out, sizeof(out));
buffer = bufferOut;
}
} // namespace Utils

View File

@ -1,3 +1,4 @@
// clang-format off
/* crypto/sha/sha.h */ /* crypto/sha/sha.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.

View File

@ -13,83 +13,46 @@
namespace Utils { namespace Utils {
RateLimiter :: RateLimiter ::RateLimiter(U32 counterCycle, U32 timeCycle) : m_counterCycle(counterCycle), m_timeCycle(timeCycle) {
RateLimiter (
U32 counterCycle,
U32 timeCycle
) :
m_counterCycle(counterCycle),
m_timeCycle(timeCycle)
{
this->reset(); this->reset();
} }
RateLimiter :: RateLimiter ::RateLimiter() : m_counterCycle(0), m_timeCycle(0) {
RateLimiter () :
m_counterCycle(0),
m_timeCycle(0)
{
this->reset(); this->reset();
} }
void RateLimiter :: void RateLimiter ::setCounterCycle(U32 counterCycle) {
setCounterCycle(
U32 counterCycle
)
{
this->m_counterCycle = counterCycle; this->m_counterCycle = counterCycle;
} }
void RateLimiter :: void RateLimiter ::setTimeCycle(U32 timeCycle) {
setTimeCycle(
U32 timeCycle
)
{
this->m_timeCycle = timeCycle; this->m_timeCycle = timeCycle;
} }
void RateLimiter :: void RateLimiter ::reset() {
reset()
{
this->resetCounter(); this->resetCounter();
this->resetTime(); this->resetTime();
} }
void RateLimiter :: void RateLimiter ::resetCounter() {
resetCounter()
{
this->m_counter = 0; this->m_counter = 0;
} }
void RateLimiter :: void RateLimiter ::resetTime() {
resetTime()
{
this->m_time = Fw::Time(); this->m_time = Fw::Time();
this->m_timeAtNegativeInfinity = true; this->m_timeAtNegativeInfinity = true;
} }
void RateLimiter :: void RateLimiter ::setCounter(U32 counter) {
setCounter(
U32 counter
)
{
this->m_counter = counter; this->m_counter = counter;
} }
void RateLimiter :: void RateLimiter ::setTime(Fw::Time time) {
setTime(
Fw::Time time
)
{
this->m_time = time; this->m_time = time;
this->m_timeAtNegativeInfinity = false; this->m_timeAtNegativeInfinity = false;
} }
bool RateLimiter :: bool RateLimiter ::trigger(Fw::Time time) {
trigger(
Fw::Time time
)
{
// NB: this implements a 4-bit decision, logically equivalent to this pseudo-code // NB: this implements a 4-bit decision, logically equivalent to this pseudo-code
// //
// A = HAS_COUNTER, B = HAS_TIME, C = COUNTER_TRIGGER, D = TIME_TRIGGER // A = HAS_COUNTER, B = HAS_TIME, C = COUNTER_TRIGGER, D = TIME_TRIGGER
@ -101,50 +64,44 @@ namespace Utils {
// false // false
// //
if (this->m_counterCycle == 0 && this->m_timeCycle == 0) { if (this->m_counterCycle == 0 && this->m_timeCycle == 0) {
return true; return true;
} }
// evaluate trigger criteria // evaluate trigger criteria
bool shouldTrigger = false; bool shouldTrigger = false;
if (this->m_counterCycle > 0) { if (this->m_counterCycle > 0) {
shouldTrigger = shouldTrigger || this->shouldCounterTrigger(); shouldTrigger = shouldTrigger || this->shouldCounterTrigger();
} }
if (this->m_timeCycle > 0) { if (this->m_timeCycle > 0) {
shouldTrigger = shouldTrigger || this->shouldTimeTrigger(time); shouldTrigger = shouldTrigger || this->shouldTimeTrigger(time);
} }
// update states // update states
if (this->m_counterCycle > 0) { if (this->m_counterCycle > 0) {
this->updateCounter(shouldTrigger); this->updateCounter(shouldTrigger);
} }
if (this->m_timeCycle > 0) { if (this->m_timeCycle > 0) {
this->updateTime(shouldTrigger, time); this->updateTime(shouldTrigger, time);
} }
return shouldTrigger; return shouldTrigger;
} }
bool RateLimiter :: bool RateLimiter ::trigger() {
trigger()
{
FW_ASSERT(this->m_timeCycle == 0); FW_ASSERT(this->m_timeCycle == 0);
return trigger(Fw::Time::zero()); return trigger(Fw::Time::zero());
} }
bool RateLimiter :: bool RateLimiter ::shouldCounterTrigger() {
shouldCounterTrigger()
{
FW_ASSERT(this->m_counterCycle > 0); FW_ASSERT(this->m_counterCycle > 0);
// trigger at 0 // trigger at 0
bool shouldTrigger = (this->m_counter == 0); bool shouldTrigger = (this->m_counter == 0);
return shouldTrigger; return shouldTrigger;
} }
bool RateLimiter :: bool RateLimiter ::shouldTimeTrigger(Fw::Time time) {
shouldTimeTrigger(Fw::Time time)
{
FW_ASSERT(this->m_timeCycle > 0); FW_ASSERT(this->m_timeCycle > 0);
// trigger at prev trigger time + time cycle seconds OR when time is at negative infinity // trigger at prev trigger time + time cycle seconds OR when time is at negative infinity
@ -153,35 +110,31 @@ namespace Utils {
bool shouldTrigger = (time >= nextTrigger) || this->m_timeAtNegativeInfinity; bool shouldTrigger = (time >= nextTrigger) || this->m_timeAtNegativeInfinity;
return shouldTrigger; return shouldTrigger;
} }
void RateLimiter :: void RateLimiter ::updateCounter(bool triggered) {
updateCounter(bool triggered)
{
FW_ASSERT(this->m_counterCycle > 0); FW_ASSERT(this->m_counterCycle > 0);
if (triggered) { if (triggered) {
// triggered, set to next state // triggered, set to next state
this->m_counter = 1; this->m_counter = 1;
} else { } else {
// otherwise, just increment and maybe wrap // otherwise, just increment and maybe wrap
if (++this->m_counter >= this->m_counterCycle) { if (++this->m_counter >= this->m_counterCycle) {
this->m_counter = 0; this->m_counter = 0;
} }
} }
} }
void RateLimiter :: void RateLimiter ::updateTime(bool triggered, Fw::Time time) {
updateTime(bool triggered, Fw::Time time)
{
FW_ASSERT(this->m_timeCycle > 0); FW_ASSERT(this->m_timeCycle > 0);
if (triggered) { if (triggered) {
// mark time of trigger // mark time of trigger
this->m_time = time; this->m_time = time;
} }
this->m_timeAtNegativeInfinity = false; this->m_timeAtNegativeInfinity = false;
} }
} // end namespace Utils } // end namespace Utils

View File

@ -18,65 +18,59 @@
namespace Utils { namespace Utils {
class RateLimiter class RateLimiter {
{ public:
// Construct with defined cycles
RateLimiter(U32 counterCycle, U32 timeCycle);
public: // Construct with cycles set to 0
RateLimiter();
// Construct with defined cycles public:
RateLimiter(U32 counterCycle, U32 timeCycle); // Adjust cycles at run-time
void setCounterCycle(U32 counterCycle);
void setTimeCycle(U32 timeCycle);
// Construct with cycles set to 0 // Main point of entry
RateLimiter(); //
// It will only factor in counter or time, whichever one has a cycle defined
//
// If both are defined, then satisfying _either_ one will work
// e.g. I want to trigger only once every X times or once every Y
// seconds, whichever comes first
//
// The argument-less version is a shorthand for counter-only RateLimiters
// If a time cycle is defined but the argument-less version is called,
// RateLimiter assumes the client forgot to supply a time, and asserts
//
bool trigger(Fw::Time time);
bool trigger();
public: // Manual state adjustments, if necessary
void reset();
void resetCounter();
void resetTime();
void setCounter(U32);
void setTime(Fw::Time time);
// Adjust cycles at run-time private:
void setCounterCycle(U32 counterCycle); // Helper functions to update each independently
void setTimeCycle(U32 timeCycle); bool shouldCounterTrigger();
bool shouldTimeTrigger(Fw::Time time);
void updateCounter(bool triggered);
void updateTime(bool triggered, Fw::Time time);
// Main point of entry private:
// // parameters
// It will only factor in counter or time, whichever one has a cycle defined U32 m_counterCycle;
// U32 m_timeCycle;
// If both are defined, then satisfying _either_ one will work
// e.g. I want to trigger only once every X times or once every Y
// seconds, whichever comes first
//
// The argument-less version is a shorthand for counter-only RateLimiters
// If a time cycle is defined but the argument-less version is called,
// RateLimiter assumes the client forgot to supply a time, and asserts
//
bool trigger(Fw::Time time);
bool trigger();
// Manual state adjustments, if necessary // state
void reset(); U32 m_counter;
void resetCounter(); Fw::Time m_time;
void resetTime(); bool m_timeAtNegativeInfinity;
void setCounter(U32); };
void setTime(Fw::Time time);
private: } // end namespace Utils
// Helper functions to update each independently
bool shouldCounterTrigger();
bool shouldTimeTrigger(Fw::Time time);
void updateCounter(bool triggered);
void updateTime(bool triggered, Fw::Time time);
private:
// parameters
U32 m_counterCycle;
U32 m_timeCycle;
// state
U32 m_counter;
Fw::Time m_time;
bool m_timeAtNegativeInfinity;
};
} // end namespace Utils
#endif #endif

View File

@ -36,7 +36,6 @@
// //
// See below for detailed descriptions // See below for detailed descriptions
// SEND_CMD // SEND_CMD
// //
// Send a command and expect a response status. This command essentially calls // Send a command and expect a response status. This command essentially calls
@ -50,13 +49,12 @@
// SEND_CMD(PWR_SW_MGR_SET_DUTY_CYCLE, Fw::CmdResponse::OK, channel, dutyCycle); // SEND_CMD(PWR_SW_MGR_SET_DUTY_CYCLE, Fw::CmdResponse::OK, channel, dutyCycle);
// SEND_CMD(PWR_SW_MGR_PWR_ON, Fw::COMMAND_EXECUTION_ERROR, illegalChannel); // SEND_CMD(PWR_SW_MGR_PWR_ON, Fw::COMMAND_EXECUTION_ERROR, illegalChannel);
// //
#define SEND_CMD(cmd, status, ...) \ #define SEND_CMD(cmd, status, ...) SEND_CMD_COMP(TEST_COMP, cmd, status, ##__VA_ARGS__)
SEND_CMD_COMP(TEST_COMP, cmd, status, ## __VA_ARGS__)
#define SEND_CMD_COMP(comp, cmd, status, ...) \ #define SEND_CMD_COMP(comp, cmd, status, ...) \
this->sendCmd_ ## cmd(INSTANCE, CMD_SEQ, ## __VA_ARGS__); \ this->sendCmd_##cmd(INSTANCE, CMD_SEQ, ##__VA_ARGS__); \
this->component.doDispatch(); \ this->component.doDispatch(); \
ASSERT_LAST_CMD(cmd, status); ASSERT_LAST_CMD(cmd, status);
// SEND_CMD_NO_EXPECT // SEND_CMD_NO_EXPECT
// //
@ -67,12 +65,11 @@
// SEND_CMD_NO_EXPECT(FILE_DWN_SEND_APID, 100, 0, 0, 0); // SEND_CMD_NO_EXPECT(FILE_DWN_SEND_APID, 100, 0, 0, 0);
// // ... // // ...
// //
#define SEND_CMD_NO_EXPECT(cmd, ...) \ #define SEND_CMD_NO_EXPECT(cmd, ...) SEND_CMD_COMP_NO_EXPECT(TEST_COMP, cmd, ##__VA_ARGS__)
SEND_CMD_COMP_NO_EXPECT(TEST_COMP, cmd, ## __VA_ARGS__)
#define SEND_CMD_COMP_NO_EXPECT(comp, cmd, ...) \ #define SEND_CMD_COMP_NO_EXPECT(comp, cmd, ...) \
this->sendCmd_ ## cmd(INSTANCE, CMD_SEQ, ## __VA_ARGS__); \ this->sendCmd_##cmd(INSTANCE, CMD_SEQ, ##__VA_ARGS__); \
this->component.doDispatch(); this->component.doDispatch();
// ASSERT_LAST_CMD // ASSERT_LAST_CMD
// //
@ -86,12 +83,11 @@
// // ... // // ...
// ASSERT_LAST_CMD(FILE_DWN_SEND_APID, Fw::CmdResponse::OK); // ASSERT_LAST_CMD(FILE_DWN_SEND_APID, Fw::CmdResponse::OK);
// //
#define ASSERT_LAST_CMD(cmd, status) \ #define ASSERT_LAST_CMD(cmd, status) ASSERT_LAST_CMD_COMP(TEST_COMP, cmd, status)
ASSERT_LAST_CMD_COMP(TEST_COMP, cmd, status)
#define ASSERT_LAST_CMD_COMP(comp, cmd, status) \ #define ASSERT_LAST_CMD_COMP(comp, cmd, status) \
ASSERT_GT(this->cmdResponseHistory->size(), 0); \ ASSERT_GT(this->cmdResponseHistory->size(), 0); \
ASSERT_CMD_RESPONSE(this->cmdResponseHistory->size()-1, comp::OPCODE_ ## cmd, CMD_SEQ, status); ASSERT_CMD_RESPONSE(this->cmdResponseHistory->size() - 1, comp::OPCODE_##cmd, CMD_SEQ, status);
// ASSERT_LAST_TLM // ASSERT_LAST_TLM
// //
@ -102,9 +98,9 @@
// ASSERT_LAST_TLM(NeaCamManager_ImageDataSize, dataSize); // ASSERT_LAST_TLM(NeaCamManager_ImageDataSize, dataSize);
// ASSERT_LAST_TLM(NeaCamManager_PatternDataSize, 0); // ASSERT_LAST_TLM(NeaCamManager_PatternDataSize, 0);
// //
#define ASSERT_LAST_TLM(name, value) \ #define ASSERT_LAST_TLM(name, value) \
ASSERT_GT(this->tlmHistory_ ## name->size(), 0); \ ASSERT_GT(this->tlmHistory_##name->size(), 0); \
ASSERT_TLM_ ## name(this->tlmHistory_ ## name->size()-1, value); ASSERT_TLM_##name(this->tlmHistory_##name->size() - 1, value);
// ASSERT_LAST_EVENT // ASSERT_LAST_EVENT
// //
@ -115,9 +111,9 @@
// SEND_CMD(PWR_SW_MGR_SET_DUTY_CYCLE, Fw::COMMAND_VALIDATION_ERROR, 0, 0); // SEND_CMD(PWR_SW_MGR_SET_DUTY_CYCLE, Fw::COMMAND_VALIDATION_ERROR, 0, 0);
// ASSERT_LAST_EVENT(PwrSwitchManager_DutyCyclingNotEnabled, i); // ASSERT_LAST_EVENT(PwrSwitchManager_DutyCyclingNotEnabled, i);
// //
#define ASSERT_LAST_EVENT(name, ...) \ #define ASSERT_LAST_EVENT(name, ...) \
ASSERT_GT(this->eventHistory_ ## name->size(), 0); \ ASSERT_GT(this->eventHistory_##name->size(), 0); \
ASSERT_EVENTS_ ## name(this->eventHistory_ ## name->size()-1, ## __VA_ARGS__); ASSERT_EVENTS_##name(this->eventHistory_##name->size() - 1, ##__VA_ARGS__);
// ASSERT_LAST_PORT_OUT // ASSERT_LAST_PORT_OUT
// //
@ -129,9 +125,8 @@
// this->component.doDispatch(); // this->component.doDispatch();
// ASSERT_LAST_PORT_OUT(PingResponse, 0, 0xDEADBEEF); // ASSERT_LAST_PORT_OUT(PingResponse, 0, 0xDEADBEEF);
// //
#define ASSERT_LAST_PORT_OUT(port, ...) \ #define ASSERT_LAST_PORT_OUT(port, ...) \
ASSERT_GT(this->fromPortHistory_ ## port->size(), 0); \ ASSERT_GT(this->fromPortHistory_##port->size(), 0); \
ASSERT_from_ ## port(__VA_ARGS__); ASSERT_from_##port(__VA_ARGS__);
#endif #endif

View File

@ -15,120 +15,80 @@
namespace Utils { namespace Utils {
TokenBucket :: TokenBucket ::TokenBucket(U32 replenishInterval, U32 maxTokens, U32 replenishRate, U32 startTokens, Fw::Time startTime)
TokenBucket ( : m_replenishInterval(replenishInterval),
U32 replenishInterval,
U32 maxTokens,
U32 replenishRate,
U32 startTokens,
Fw::Time startTime
) :
m_replenishInterval(replenishInterval),
m_maxTokens(maxTokens), m_maxTokens(maxTokens),
m_replenishRate(replenishRate), m_replenishRate(replenishRate),
m_tokens(startTokens), m_tokens(startTokens),
m_time(startTime) m_time(startTime) {}
{
}
TokenBucket :: TokenBucket ::TokenBucket(U32 replenishInterval, U32 maxTokens)
TokenBucket ( : m_replenishInterval(replenishInterval),
U32 replenishInterval,
U32 maxTokens
) :
m_replenishInterval(replenishInterval),
m_maxTokens(maxTokens), m_maxTokens(maxTokens),
m_replenishRate(1), m_replenishRate(1),
m_tokens(maxTokens), m_tokens(maxTokens),
m_time(0, 0) m_time(0, 0) {
{
FW_ASSERT(this->m_maxTokens <= MAX_TOKEN_BUCKET_TOKENS, static_cast<FwAssertArgType>(this->m_maxTokens)); FW_ASSERT(this->m_maxTokens <= MAX_TOKEN_BUCKET_TOKENS, static_cast<FwAssertArgType>(this->m_maxTokens));
} }
void TokenBucket :: void TokenBucket ::setReplenishInterval(U32 replenishInterval) {
setReplenishInterval(
U32 replenishInterval
)
{
this->m_replenishInterval = replenishInterval; this->m_replenishInterval = replenishInterval;
} }
void TokenBucket :: void TokenBucket ::setMaxTokens(U32 maxTokens) {
setMaxTokens(
U32 maxTokens
)
{
this->m_maxTokens = maxTokens; this->m_maxTokens = maxTokens;
} }
void TokenBucket :: void TokenBucket ::setReplenishRate(U32 replenishRate) {
setReplenishRate(
U32 replenishRate
)
{
this->m_replenishRate = replenishRate; this->m_replenishRate = replenishRate;
} }
void TokenBucket :: void TokenBucket ::replenish() {
replenish()
{
if (this->m_tokens < this->m_maxTokens) { if (this->m_tokens < this->m_maxTokens) {
this->m_tokens = this->m_maxTokens; this->m_tokens = this->m_maxTokens;
} }
} }
U32 TokenBucket :: U32 TokenBucket ::getReplenishInterval() const {
getReplenishInterval() const
{
return this->m_replenishInterval; return this->m_replenishInterval;
} }
U32 TokenBucket :: U32 TokenBucket ::getMaxTokens() const {
getMaxTokens() const
{
return this->m_maxTokens; return this->m_maxTokens;
} }
U32 TokenBucket :: U32 TokenBucket ::getReplenishRate() const {
getReplenishRate() const
{
return this->m_replenishRate; return this->m_replenishRate;
} }
U32 TokenBucket :: U32 TokenBucket ::getTokens() const {
getTokens() const
{
return this->m_tokens; return this->m_tokens;
} }
bool TokenBucket :: bool TokenBucket ::trigger(const Fw::Time time) {
trigger(
const Fw::Time time
)
{
// attempt replenishing // attempt replenishing
if (this->m_replenishRate > 0) { if (this->m_replenishRate > 0) {
Fw::Time replenishInterval = Fw::Time(this->m_replenishInterval / 1000000, this->m_replenishInterval % 1000000); Fw::Time replenishInterval = Fw::Time(this->m_replenishInterval / 1000000, this->m_replenishInterval % 1000000);
Fw::Time nextTime = Fw::Time::add(this->m_time, replenishInterval); Fw::Time nextTime = Fw::Time::add(this->m_time, replenishInterval);
while (this->m_tokens < this->m_maxTokens && nextTime <= time) { while (this->m_tokens < this->m_maxTokens && nextTime <= time) {
// replenish by replenish rate, or up to maxTokens // replenish by replenish rate, or up to maxTokens
this->m_tokens += FW_MIN(this->m_replenishRate, this->m_maxTokens - this->m_tokens); this->m_tokens += FW_MIN(this->m_replenishRate, this->m_maxTokens - this->m_tokens);
this->m_time = nextTime; this->m_time = nextTime;
nextTime = Fw::Time::add(this->m_time, replenishInterval); nextTime = Fw::Time::add(this->m_time, replenishInterval);
} }
if (this->m_tokens >= this->m_maxTokens && this->m_time < time) { if (this->m_tokens >= this->m_maxTokens && this->m_time < time) {
this->m_time = time; this->m_time = time;
} }
} }
// attempt consuming token // attempt consuming token
if (this->m_tokens > 0) { if (this->m_tokens > 0) {
this->m_tokens--; this->m_tokens--;
return true; return true;
} else { } else {
return false; return false;
} }
} }
} // end namespace Utils } // end namespace Utils

View File

@ -21,57 +21,52 @@
namespace Utils { namespace Utils {
class TokenBucket class TokenBucket {
{ public:
// Full constructor
//
// replenishInterval is in microseconds
//
TokenBucket(U32 replenishInterval, U32 maxTokens, U32 replenishRate, U32 startTokens, Fw::Time startTime);
public: // replenishRate=1, startTokens=maxTokens, startTime=0
TokenBucket(U32 replenishInterval, U32 maxTokens);
// Full constructor public:
// // Adjust settings at runtime
// replenishInterval is in microseconds void setMaxTokens(U32 maxTokens);
// void setReplenishInterval(U32 replenishInterval);
TokenBucket(U32 replenishInterval, U32 maxTokens, U32 replenishRate, U32 startTokens, Fw::Time startTime); void setReplenishRate(U32 replenishRate);
// replenishRate=1, startTokens=maxTokens, startTime=0 U32 getMaxTokens() const;
TokenBucket(U32 replenishInterval, U32 maxTokens); U32 getReplenishInterval() const;
U32 getReplenishRate() const;
U32 getTokens() const;
public: // Manual replenish
void replenish();
// Adjust settings at runtime // Main point of entry
void setMaxTokens(U32 maxTokens); //
void setReplenishInterval(U32 replenishInterval); // Evaluates time since last trigger to determine number of tokens to
void setReplenishRate(U32 replenishRate); // replenish. If time moved backwards, always returns false.
//
// If number of tokens is not zero, consumes one and returns true.
// Otherwise, returns false.
//
bool trigger(const Fw::Time time);
U32 getMaxTokens() const; private:
U32 getReplenishInterval() const; // parameters
U32 getReplenishRate() const; U32 m_replenishInterval;
U32 getTokens() const; U32 m_maxTokens;
U32 m_replenishRate;
// Manual replenish // state
void replenish(); U32 m_tokens;
Fw::Time m_time;
};
// Main point of entry } // end namespace Utils
//
// Evaluates time since last trigger to determine number of tokens to
// replenish. If time moved backwards, always returns false.
//
// If number of tokens is not zero, consumes one and returns true.
// Otherwise, returns false.
//
bool trigger(const Fw::Time time);
private:
// parameters
U32 m_replenishInterval;
U32 m_maxTokens;
U32 m_replenishRate;
// state
U32 m_tokens;
Fw::Time m_time;
};
} // end namespace Utils
#endif #endif

View File

@ -18,30 +18,18 @@
namespace Types { namespace Types {
CircularBuffer :: CircularBuffer() : CircularBuffer ::CircularBuffer()
m_store(nullptr), : m_store(nullptr), m_store_size(0), m_head_idx(0), m_allocated_size(0), m_high_water_mark(0) {}
m_store_size(0),
m_head_idx(0),
m_allocated_size(0),
m_high_water_mark(0)
{
} CircularBuffer ::CircularBuffer(U8* const buffer, const FwSizeType size)
: m_store(nullptr), m_store_size(0), m_head_idx(0), m_allocated_size(0), m_high_water_mark(0) {
CircularBuffer :: CircularBuffer(U8* const buffer, const FwSizeType size) :
m_store(nullptr),
m_store_size(0),
m_head_idx(0),
m_allocated_size(0),
m_high_water_mark(0)
{
setup(buffer, size); setup(buffer, size);
} }
void CircularBuffer :: setup(U8* const buffer, const FwSizeType size) { void CircularBuffer ::setup(U8* const buffer, const FwSizeType size) {
FW_ASSERT(size > 0); FW_ASSERT(size > 0);
FW_ASSERT(buffer != nullptr); FW_ASSERT(buffer != nullptr);
FW_ASSERT(m_store == nullptr && m_store_size == 0); // Not already setup FW_ASSERT(m_store == nullptr && m_store_size == 0); // Not already setup
// Initialize buffer data // Initialize buffer data
m_store = buffer; m_store = buffer;
@ -51,23 +39,23 @@ void CircularBuffer :: setup(U8* const buffer, const FwSizeType size) {
m_high_water_mark = 0; m_high_water_mark = 0;
} }
FwSizeType CircularBuffer :: get_allocated_size() const { FwSizeType CircularBuffer ::get_allocated_size() const {
return m_allocated_size; return m_allocated_size;
} }
FwSizeType CircularBuffer :: get_free_size() const { FwSizeType CircularBuffer ::get_free_size() const {
FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
FW_ASSERT(m_allocated_size <= m_store_size, static_cast<FwAssertArgType>(m_allocated_size)); FW_ASSERT(m_allocated_size <= m_store_size, static_cast<FwAssertArgType>(m_allocated_size));
return m_store_size - m_allocated_size; return m_store_size - m_allocated_size;
} }
FwSizeType CircularBuffer :: advance_idx(FwSizeType idx, FwSizeType amount) const { FwSizeType CircularBuffer ::advance_idx(FwSizeType idx, FwSizeType amount) const {
FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx)); FW_ASSERT(idx < m_store_size, static_cast<FwAssertArgType>(idx));
return (idx + amount) % m_store_size; return (idx + amount) % m_store_size;
} }
Fw::SerializeStatus CircularBuffer :: serialize(const U8* const buffer, const FwSizeType size) { Fw::SerializeStatus CircularBuffer ::serialize(const U8* const buffer, const FwSizeType size) {
FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
FW_ASSERT(buffer != nullptr); FW_ASSERT(buffer != nullptr);
// Check there is sufficient space // Check there is sufficient space
if (size > get_free_size()) { if (size > get_free_size()) {
@ -86,13 +74,13 @@ Fw::SerializeStatus CircularBuffer :: serialize(const U8* const buffer, const Fw
return Fw::FW_SERIALIZE_OK; return Fw::FW_SERIALIZE_OK;
} }
Fw::SerializeStatus CircularBuffer :: peek(char& value, FwSizeType offset) const { Fw::SerializeStatus CircularBuffer ::peek(char& value, FwSizeType offset) const {
FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
return peek(reinterpret_cast<U8&>(value), offset); return peek(reinterpret_cast<U8&>(value), offset);
} }
Fw::SerializeStatus CircularBuffer :: peek(U8& value, FwSizeType offset) const { Fw::SerializeStatus CircularBuffer ::peek(U8& value, FwSizeType offset) const {
FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
// Check there is sufficient data // Check there is sufficient data
if ((sizeof(U8) + offset) > m_allocated_size) { if ((sizeof(U8) + offset) > m_allocated_size) {
return Fw::FW_DESERIALIZE_BUFFER_EMPTY; return Fw::FW_DESERIALIZE_BUFFER_EMPTY;
@ -103,8 +91,8 @@ Fw::SerializeStatus CircularBuffer :: peek(U8& value, FwSizeType offset) const {
return Fw::FW_SERIALIZE_OK; return Fw::FW_SERIALIZE_OK;
} }
Fw::SerializeStatus CircularBuffer :: peek(U32& value, FwSizeType offset) const { Fw::SerializeStatus CircularBuffer ::peek(U32& value, FwSizeType offset) const {
FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
// Check there is sufficient data // Check there is sufficient data
if ((sizeof(U32) + offset) > m_allocated_size) { if ((sizeof(U32) + offset) > m_allocated_size) {
return Fw::FW_DESERIALIZE_BUFFER_EMPTY; return Fw::FW_DESERIALIZE_BUFFER_EMPTY;
@ -121,8 +109,8 @@ Fw::SerializeStatus CircularBuffer :: peek(U32& value, FwSizeType offset) const
return Fw::FW_SERIALIZE_OK; return Fw::FW_SERIALIZE_OK;
} }
Fw::SerializeStatus CircularBuffer :: peek(U8* buffer, FwSizeType size, FwSizeType offset) const { Fw::SerializeStatus CircularBuffer ::peek(U8* buffer, FwSizeType size, FwSizeType offset) const {
FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
FW_ASSERT(buffer != nullptr); FW_ASSERT(buffer != nullptr);
// Check there is sufficient data // Check there is sufficient data
if ((size + offset) > m_allocated_size) { if ((size + offset) > m_allocated_size) {
@ -138,8 +126,8 @@ Fw::SerializeStatus CircularBuffer :: peek(U8* buffer, FwSizeType size, FwSizeTy
return Fw::FW_SERIALIZE_OK; return Fw::FW_SERIALIZE_OK;
} }
Fw::SerializeStatus CircularBuffer :: rotate(FwSizeType amount) { Fw::SerializeStatus CircularBuffer ::rotate(FwSizeType amount) {
FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
// Check there is sufficient data // Check there is sufficient data
if (amount > m_allocated_size) { if (amount > m_allocated_size) {
return Fw::FW_DESERIALIZE_BUFFER_EMPTY; return Fw::FW_DESERIALIZE_BUFFER_EMPTY;
@ -150,7 +138,7 @@ Fw::SerializeStatus CircularBuffer :: rotate(FwSizeType amount) {
} }
FwSizeType CircularBuffer ::get_capacity() const { FwSizeType CircularBuffer ::get_capacity() const {
FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called FW_ASSERT(m_store != nullptr && m_store_size != 0); // setup method was called
return m_store_size; return m_store_size;
} }
@ -162,4 +150,4 @@ void CircularBuffer ::clear_high_water_mark() {
m_high_water_mark = 0; m_high_water_mark = 0;
} }
} //End Namespace Types } // End Namespace Types

View File

@ -23,138 +23,136 @@
namespace Types { namespace Types {
class CircularBuffer { class CircularBuffer {
friend class CircularBufferTester; friend class CircularBufferTester;
public: public:
/** /**
* Circular buffer constructor. Wraps the supplied buffer as the new data store. Buffer * Circular buffer constructor. Wraps the supplied buffer as the new data store. Buffer
* size is supplied in the 'size' argument. * size is supplied in the 'size' argument.
* *
* Note: specification of storage buffer must be done using `setup` before use. * Note: specification of storage buffer must be done using `setup` before use.
*/ */
CircularBuffer(); CircularBuffer();
/** /**
* Circular buffer constructor. Wraps the supplied buffer as the new data store. Buffer * Circular buffer constructor. Wraps the supplied buffer as the new data store. Buffer
* size is supplied in the 'size' argument. This is equivalent to calling the no-argument constructor followed * size is supplied in the 'size' argument. This is equivalent to calling the no-argument constructor followed
* by setup(buffer, size). * by setup(buffer, size).
* *
* Note: ownership of the supplied buffer is held until the circular buffer is deallocated * Note: ownership of the supplied buffer is held until the circular buffer is deallocated
* *
* \param buffer: supplied buffer used as a data store. * \param buffer: supplied buffer used as a data store.
* \param size: the of the supplied data store. * \param size: the of the supplied data store.
*/ */
CircularBuffer(U8* const buffer, const FwSizeType size); CircularBuffer(U8* const buffer, const FwSizeType size);
/** /**
* Wraps the supplied buffer as the new data store. Buffer size is supplied in the 'size' argument. Cannot be * Wraps the supplied buffer as the new data store. Buffer size is supplied in the 'size' argument. Cannot be
* called after successful setup. * called after successful setup.
* *
* Note: ownership of the supplied buffer is held until the circular buffer is deallocated * Note: ownership of the supplied buffer is held until the circular buffer is deallocated
* *
* \param buffer: supplied buffer used as a data store. * \param buffer: supplied buffer used as a data store.
* \param size: the of the supplied data store. * \param size: the of the supplied data store.
*/ */
void setup(U8* const buffer, const FwSizeType size); void setup(U8* const buffer, const FwSizeType size);
/** /**
* Serialize a given buffer into this circular buffer. Will not accept more data than * Serialize a given buffer into this circular buffer. Will not accept more data than
* space available. This means it will not overwrite existing data. * space available. This means it will not overwrite existing data.
* \param buffer: supplied buffer to be serialized. * \param buffer: supplied buffer to be serialized.
* \param size: size of the supplied buffer. * \param size: size of the supplied buffer.
* \return Fw::FW_SERIALIZE_OK on success or something else on error * \return Fw::FW_SERIALIZE_OK on success or something else on error
*/ */
Fw::SerializeStatus serialize(const U8* const buffer, const FwSizeType size); Fw::SerializeStatus serialize(const U8* const buffer, const FwSizeType size);
/** /**
* Deserialize data into the given variable without moving the head index * Deserialize data into the given variable without moving the head index
* \param value: value to fill * \param value: value to fill
* \param offset: offset from head to start peak. Default: 0 * \param offset: offset from head to start peak. Default: 0
* \return Fw::FW_SERIALIZE_OK on success or something else on error * \return Fw::FW_SERIALIZE_OK on success or something else on error
*/ */
Fw::SerializeStatus peek(char& value, FwSizeType offset = 0) const; Fw::SerializeStatus peek(char& value, FwSizeType offset = 0) const;
/** /**
* Deserialize data into the given variable without moving the head index * Deserialize data into the given variable without moving the head index
* \param value: value to fill * \param value: value to fill
* \param offset: offset from head to start peak. Default: 0 * \param offset: offset from head to start peak. Default: 0
* \return Fw::FW_SERIALIZE_OK on success or something else on error * \return Fw::FW_SERIALIZE_OK on success or something else on error
*/ */
Fw::SerializeStatus peek(U8& value, FwSizeType offset = 0) const; Fw::SerializeStatus peek(U8& value, FwSizeType offset = 0) const;
/** /**
* Deserialize data into the given variable without moving the head index * Deserialize data into the given variable without moving the head index
* \param value: value to fill * \param value: value to fill
* \param offset: offset from head to start peak. Default: 0 * \param offset: offset from head to start peak. Default: 0
* \return Fw::FW_SERIALIZE_OK on success or something else on error * \return Fw::FW_SERIALIZE_OK on success or something else on error
*/ */
Fw::SerializeStatus peek(U32& value, FwSizeType offset = 0) const; Fw::SerializeStatus peek(U32& value, FwSizeType offset = 0) const;
/** /**
* Deserialize data into the given buffer without moving the head variable. * Deserialize data into the given buffer without moving the head variable.
* \param buffer: buffer to fill with data of the peek * \param buffer: buffer to fill with data of the peek
* \param size: size in bytes to peek at * \param size: size in bytes to peek at
* \param offset: offset from head to start peak. Default: 0 * \param offset: offset from head to start peak. Default: 0
* \return Fw::FW_SERIALIZE_OK on success or something else on error * \return Fw::FW_SERIALIZE_OK on success or something else on error
*/ */
Fw::SerializeStatus peek(U8* buffer, FwSizeType size, FwSizeType offset = 0) const; Fw::SerializeStatus peek(U8* buffer, FwSizeType size, FwSizeType offset = 0) const;
/** /**
* Rotate the head index, deleting data from the circular buffer and making * Rotate the head index, deleting data from the circular buffer and making
* space. Cannot rotate more than the available space. * space. Cannot rotate more than the available space.
* \param amount: amount to rotate by (in bytes) * \param amount: amount to rotate by (in bytes)
* \return Fw::FW_SERIALIZE_OK on success or something else on error * \return Fw::FW_SERIALIZE_OK on success or something else on error
*/ */
Fw::SerializeStatus rotate(FwSizeType amount); Fw::SerializeStatus rotate(FwSizeType amount);
/** /**
* Get the number of bytes allocated in the buffer * Get the number of bytes allocated in the buffer
* \return number of bytes * \return number of bytes
*/ */
FwSizeType get_allocated_size() const; FwSizeType get_allocated_size() const;
/** /**
* Get the number of free bytes, i.e., the number * Get the number of free bytes, i.e., the number
* of bytes that may be stored in the buffer without * of bytes that may be stored in the buffer without
* deleting data and without exceeding the buffer capacity * deleting data and without exceeding the buffer capacity
*/ */
FwSizeType get_free_size() const; FwSizeType get_free_size() const;
/** /**
* Get the logical capacity of the buffer, i.e., the number of available * Get the logical capacity of the buffer, i.e., the number of available
* bytes when the buffer is empty * bytes when the buffer is empty
*/ */
FwSizeType get_capacity() const; FwSizeType get_capacity() const;
/** /**
* Return the largest tracked allocated size * Return the largest tracked allocated size
*/ */
FwSizeType get_high_water_mark() const; FwSizeType get_high_water_mark() const;
/** /**
* Clear tracking of the largest allocated size * Clear tracking of the largest allocated size
*/ */
void clear_high_water_mark(); void clear_high_water_mark();
private: private:
/** /**
* Returns a wrap-advanced index into the store. * Returns a wrap-advanced index into the store.
* \param idx: index to advance and wrap. * \param idx: index to advance and wrap.
* \param amount: amount to advance * \param amount: amount to advance
* \return: new index value * \return: new index value
*/ */
FwSizeType advance_idx(FwSizeType idx, FwSizeType amount = 1) const; FwSizeType advance_idx(FwSizeType idx, FwSizeType amount = 1) const;
//! Physical store backing this circular buffer //! Physical store backing this circular buffer
U8* m_store; U8* m_store;
//! Size of the physical store //! Size of the physical store
FwSizeType m_store_size; FwSizeType m_store_size;
//! Index into m_store of byte zero in the logical store. //! Index into m_store of byte zero in the logical store.
//! When memory is deallocated, this index moves forward and wraps around. //! When memory is deallocated, this index moves forward and wraps around.
FwSizeType m_head_idx; FwSizeType m_head_idx;
//! Allocated size (size of the logical store) //! Allocated size (size of the logical store)
FwSizeType m_allocated_size; FwSizeType m_allocated_size;
//! Maximum allocated size //! Maximum allocated size
FwSizeType m_high_water_mark; FwSizeType m_high_water_mark;
}; };
} //End Namespace Types } // End Namespace Types
#endif #endif

View File

@ -14,33 +14,29 @@ namespace Types {
Queue::Queue() : m_internal(), m_message_size(0) {} Queue::Queue() : m_internal(), m_message_size(0) {}
void Queue::setup(U8* const storage, const FwSizeType storage_size, const FwSizeType depth, const FwSizeType message_size) { void Queue::setup(U8* const storage,
const FwSizeType storage_size,
const FwSizeType depth,
const FwSizeType message_size) {
// Ensure that enough storage was supplied // Ensure that enough storage was supplied
const FwSizeType total_needed_size = depth * message_size; const FwSizeType total_needed_size = depth * message_size;
FW_ASSERT( FW_ASSERT(storage_size >= total_needed_size, static_cast<FwAssertArgType>(storage_size),
storage_size >= total_needed_size, static_cast<FwAssertArgType>(depth), static_cast<FwAssertArgType>(message_size));
static_cast<FwAssertArgType>(storage_size),
static_cast<FwAssertArgType>(depth),
static_cast<FwAssertArgType>(message_size));
m_internal.setup(storage, total_needed_size); m_internal.setup(storage, total_needed_size);
m_message_size = message_size; m_message_size = message_size;
} }
Fw::SerializeStatus Queue::enqueue(const U8* const message, const FwSizeType size) { Fw::SerializeStatus Queue::enqueue(const U8* const message, const FwSizeType size) {
FW_ASSERT(m_message_size > 0, static_cast<FwAssertArgType>(m_message_size)); // Ensure initialization FW_ASSERT(m_message_size > 0, static_cast<FwAssertArgType>(m_message_size)); // Ensure initialization
FW_ASSERT( FW_ASSERT(m_message_size == size, static_cast<FwAssertArgType>(size),
m_message_size == size, static_cast<FwAssertArgType>(m_message_size)); // Message size is as expected
static_cast<FwAssertArgType>(size),
static_cast<FwAssertArgType>(m_message_size)); // Message size is as expected
return m_internal.serialize(message, m_message_size); return m_internal.serialize(message, m_message_size);
} }
Fw::SerializeStatus Queue::dequeue(U8* const message, const FwSizeType size) { Fw::SerializeStatus Queue::dequeue(U8* const message, const FwSizeType size) {
FW_ASSERT(m_message_size > 0); // Ensure initialization FW_ASSERT(m_message_size > 0); // Ensure initialization
FW_ASSERT( FW_ASSERT(m_message_size <= size, static_cast<FwAssertArgType>(size),
m_message_size <= size, static_cast<FwAssertArgType>(m_message_size)); // Sufficient storage space for read message
static_cast<FwAssertArgType>(size),
static_cast<FwAssertArgType>(m_message_size)); // Sufficient storage space for read message
Fw::SerializeStatus result = m_internal.peek(message, m_message_size, 0); Fw::SerializeStatus result = m_internal.peek(message, m_message_size, 0);
if (result != Fw::FW_SERIALIZE_OK) { if (result != Fw::FW_SERIALIZE_OK) {
return result; return result;
@ -62,5 +58,4 @@ FwSizeType Queue::getQueueSize() const {
return m_internal.get_allocated_size() / m_message_size; return m_internal.get_allocated_size() / m_message_size;
} }
} // namespace Types } // namespace Types

View File

@ -6,7 +6,4 @@
#include "CircularBufferTester.hpp" #include "CircularBufferTester.hpp"
namespace Types {}
namespace Types {
}

View File

@ -11,20 +11,17 @@
namespace Types { namespace Types {
class CircularBufferTester{ class CircularBufferTester {
public:
static void tester_m_allocated_size_decrement(Types::CircularBuffer& circular_buffer) {
circular_buffer.m_allocated_size--;
}
public: static FwSizeType tester_get_m_head_idx(Types::CircularBuffer& circular_buffer) {
return circular_buffer.m_head_idx;
}
};
static void tester_m_allocated_size_decrement(Types::CircularBuffer &circular_buffer){ } // namespace Types
circular_buffer.m_allocated_size--;
}
static FwSizeType tester_get_m_head_idx(Types::CircularBuffer &circular_buffer){
return circular_buffer.m_head_idx;
}
};
}
#endif #endif

View File

@ -9,201 +9,161 @@
*/ */
#include "CircularRules.hpp" #include "CircularRules.hpp"
#include <cstdlib>
#include <cmath> #include <cmath>
#include <cstdlib>
namespace Types { namespace Types {
RandomizeRule::RandomizeRule(const char* const name) : STest::Rule<MockTypes::CircularState>(name) {}
RandomizeRule::RandomizeRule(const char *const name) bool RandomizeRule::precondition(const MockTypes::CircularState& state) {
: STest::Rule<MockTypes::CircularState>(name) {} return true;
}
void RandomizeRule::action(MockTypes::CircularState& truth) {
(void)truth.generateRandomBuffer();
}
bool RandomizeRule::precondition(const MockTypes::CircularState& state) { SerializeOkRule::SerializeOkRule(const char* const name) : STest::Rule<MockTypes::CircularState>(name) {}
return true;
bool SerializeOkRule::precondition(const MockTypes::CircularState& state) {
return state.getRemainingSize() >= state.getRandomSize();
}
void SerializeOkRule::action(MockTypes::CircularState& state) {
state.checkSizes();
Fw::SerializeStatus status = state.getTestBuffer().serialize(state.getBuffer(), state.getRandomSize());
state.setRemainingSize(state.getRemainingSize() - state.getRandomSize());
ASSERT_TRUE(state.addInfinite(state.getBuffer(), state.getRandomSize()));
ASSERT_EQ(status, Fw::FW_SERIALIZE_OK);
state.checkSizes();
}
SerializeOverflowRule::SerializeOverflowRule(const char* const name) : STest::Rule<MockTypes::CircularState>(name) {}
bool SerializeOverflowRule::precondition(const MockTypes::CircularState& state) {
return state.getRemainingSize() < state.getRandomSize();
}
void SerializeOverflowRule::action(MockTypes::CircularState& state) {
Fw::SerializeStatus status = state.getTestBuffer().serialize(state.getBuffer(), state.getRandomSize());
ASSERT_EQ(status, Fw::FW_SERIALIZE_NO_ROOM_LEFT);
}
PeekOkRule::PeekOkRule(const char* const name) : STest::Rule<MockTypes::CircularState>(name) {}
bool PeekOkRule::precondition(const MockTypes::CircularState& state) {
FwSizeType peek_available = (MAX_BUFFER_SIZE - state.getRemainingSize());
if (state.getPeekType() == 0) {
return peek_available >= sizeof(I8) + state.getPeekOffset();
} else if (state.getPeekType() == 1) {
return peek_available >= sizeof(U8) + state.getPeekOffset();
} else if (state.getPeekType() == 2) {
return peek_available >= sizeof(U32) + state.getPeekOffset();
} else if (state.getPeekType() == 3) {
return peek_available >= state.getRandomSize() + state.getPeekOffset();
} }
return false;
}
void PeekOkRule::action(MockTypes::CircularState& state) {
void RandomizeRule::action(MockTypes::CircularState& truth) { U8* buffer = nullptr;
(void) truth.generateRandomBuffer(); char peek_char = 0;
} U8 peek_u8 = 0;
U32 peek_u32 = 0;
U8 peek_buffer[MAX_BUFFER_SIZE];
// Handle all cases for deserialization
SerializeOkRule::SerializeOkRule(const char *const name) if (state.getPeekType() == 0) {
: STest::Rule<MockTypes::CircularState>(name) {} ASSERT_TRUE(state.peek(buffer, sizeof(I8), state.getPeekOffset()));
peek_char = static_cast<char>(buffer[0]);
ASSERT_EQ(state.getTestBuffer().peek(peek_char, state.getPeekOffset()), Fw::FW_SERIALIZE_OK);
bool SerializeOkRule::precondition(const MockTypes::CircularState& state) { ASSERT_EQ(static_cast<char>(buffer[0]), peek_char);
return state.getRemainingSize() >= state.getRandomSize(); } else if (state.getPeekType() == 1) {
} ASSERT_TRUE(state.peek(buffer, sizeof(U8), state.getPeekOffset()));
peek_u8 = static_cast<U8>(buffer[0]);
ASSERT_EQ(state.getTestBuffer().peek(peek_u8, state.getPeekOffset()), Fw::FW_SERIALIZE_OK);
void SerializeOkRule::action(MockTypes::CircularState& state) { ASSERT_EQ(buffer[0], peek_u8);
state.checkSizes(); } else if (state.getPeekType() == 2) {
Fw::SerializeStatus status = state.getTestBuffer().serialize(state.getBuffer(), state.getRandomSize()); ASSERT_TRUE(state.peek(buffer, sizeof(U32), state.getPeekOffset()));
state.setRemainingSize(state.getRemainingSize() - state.getRandomSize()); ASSERT_EQ(state.getTestBuffer().peek(peek_u32, state.getPeekOffset()), Fw::FW_SERIALIZE_OK);
ASSERT_TRUE(state.addInfinite(state.getBuffer(), state.getRandomSize())); // Big-endian U32
ASSERT_EQ(status, Fw::FW_SERIALIZE_OK); U32 value = 0;
state.checkSizes(); value |= (buffer[0] << 24);
} value |= (buffer[1] << 16);
value |= (buffer[2] << 8);
value |= (buffer[3] << 0);
ASSERT_EQ(value, peek_u32);
SerializeOverflowRule::SerializeOverflowRule(const char *const name) } else if (state.getPeekType() == 3) {
: STest::Rule<MockTypes::CircularState>(name) {} ASSERT_TRUE(state.peek(buffer, state.getRandomSize(), state.getPeekOffset()));
ASSERT_EQ(state.getTestBuffer().peek(peek_buffer, state.getRandomSize(), state.getPeekOffset()),
Fw::FW_SERIALIZE_OK);
bool SerializeOverflowRule::precondition(const MockTypes::CircularState& state) { for (FwSizeType i = 0; i < state.getRandomSize(); i++) {
return state.getRemainingSize() < state.getRandomSize(); ASSERT_EQ(buffer[i], peek_buffer[i]);
}
void SerializeOverflowRule::action(MockTypes::CircularState& state) {
Fw::SerializeStatus status = state.getTestBuffer().serialize(state.getBuffer(), state.getRandomSize());
ASSERT_EQ(status, Fw::FW_SERIALIZE_NO_ROOM_LEFT);
}
PeekOkRule::PeekOkRule(const char *const name)
: STest::Rule<MockTypes::CircularState>(name) {}
bool PeekOkRule::precondition(const MockTypes::CircularState& state) {
FwSizeType peek_available = (MAX_BUFFER_SIZE - state.getRemainingSize());
if (state.getPeekType() == 0 ) {
return peek_available >= sizeof(I8) + state.getPeekOffset();
} }
else if (state.getPeekType() == 1) { } else {
return peek_available >= sizeof(U8) + state.getPeekOffset(); ASSERT_TRUE(false); // Fail the test, bad type
}
else if (state.getPeekType() == 2) {
return peek_available >= sizeof(U32) + state.getPeekOffset();
}
else if (state.getPeekType() == 3) {
return peek_available >= state.getRandomSize() + state.getPeekOffset();
}
return false;
}
void PeekOkRule::action(MockTypes::CircularState& state) {
U8* buffer = nullptr;
char peek_char = 0;
U8 peek_u8 = 0;
U32 peek_u32 = 0;
U8 peek_buffer[MAX_BUFFER_SIZE];
// Handle all cases for deserialization
if (state.getPeekType() == 0) {
ASSERT_TRUE(state.peek(buffer, sizeof(I8), state.getPeekOffset()));
peek_char = static_cast<char>(buffer[0]);
ASSERT_EQ(state.getTestBuffer().peek(peek_char, state.getPeekOffset()), Fw::FW_SERIALIZE_OK);
ASSERT_EQ(static_cast<char>(buffer[0]), peek_char);
}
else if (state.getPeekType() == 1) {
ASSERT_TRUE(state.peek(buffer, sizeof(U8), state.getPeekOffset()));
peek_u8 = static_cast<U8>(buffer[0]);
ASSERT_EQ(state.getTestBuffer().peek(peek_u8, state.getPeekOffset()), Fw::FW_SERIALIZE_OK);
ASSERT_EQ(buffer[0], peek_u8);
}
else if (state.getPeekType() == 2) {
ASSERT_TRUE(state.peek(buffer, sizeof(U32), state.getPeekOffset()));
ASSERT_EQ(state.getTestBuffer().peek(peek_u32, state.getPeekOffset()), Fw::FW_SERIALIZE_OK);
// Big-endian U32
U32 value = 0;
value |= (buffer[0] << 24);
value |= (buffer[1] << 16);
value |= (buffer[2] << 8);
value |= (buffer[3] << 0);
ASSERT_EQ(value, peek_u32);
}
else if (state.getPeekType() == 3) {
ASSERT_TRUE(state.peek(buffer, state.getRandomSize(), state.getPeekOffset()));
ASSERT_EQ(state.getTestBuffer().peek(peek_buffer, state.getRandomSize(), state.getPeekOffset()),
Fw::FW_SERIALIZE_OK);
for (FwSizeType i = 0; i < state.getRandomSize(); i++) {
ASSERT_EQ(buffer[i], peek_buffer[i]);
}
}
else {
ASSERT_TRUE(false); // Fail the test, bad type
}
}
PeekBadRule::PeekBadRule(const char *const name)
: STest::Rule<MockTypes::CircularState>(name) {}
bool PeekBadRule::precondition(const MockTypes::CircularState& state) {
FwSizeType peek_available = (MAX_BUFFER_SIZE - state.getRemainingSize());
if (state.getPeekType() == 0 ) {
return peek_available < sizeof(I8) + state.getPeekOffset();
}
else if (state.getPeekType() == 1) {
return peek_available < sizeof(U8) + state.getPeekOffset();
}
else if (state.getPeekType() == 2) {
return peek_available < sizeof(U32) + state.getPeekOffset();
}
else if (state.getPeekType() == 3) {
return peek_available < state.getRandomSize() + state.getPeekOffset();
}
return false;
}
void PeekBadRule::action(MockTypes::CircularState& state) {
char peek_char = 0;
U8 peek_u8 = 0;
U32 peek_u32 = 0;
U8 peek_buffer[MAX_BUFFER_SIZE];
// Handle all cases for deserialization
if (state.getPeekType() == 0) {
ASSERT_EQ(state.getTestBuffer().peek(peek_char, state.getPeekOffset()), Fw::FW_DESERIALIZE_BUFFER_EMPTY);
}
else if (state.getPeekType() == 1) {
ASSERT_EQ(state.getTestBuffer().peek(peek_u8, state.getPeekOffset()), Fw::FW_DESERIALIZE_BUFFER_EMPTY);
}
else if (state.getPeekType() == 2) {
ASSERT_EQ(state.getTestBuffer().peek(peek_u32, state.getPeekOffset()), Fw::FW_DESERIALIZE_BUFFER_EMPTY);
}
else if (state.getPeekType() == 3) {
ASSERT_EQ(state.getTestBuffer().peek(peek_buffer, state.getRandomSize(), state.getPeekOffset()),
Fw::FW_DESERIALIZE_BUFFER_EMPTY);
}
else {
ASSERT_TRUE(false); // Fail the test, bad type
}
}
RotateOkRule::RotateOkRule(const char *const name)
: STest::Rule<MockTypes::CircularState>(name) {}
bool RotateOkRule::precondition(const MockTypes::CircularState& state) {
FwSizeType rotate_available = (MAX_BUFFER_SIZE - state.getRemainingSize());
return rotate_available >= state.getRandomSize();
}
void RotateOkRule::action(MockTypes::CircularState& state) {
state.checkSizes();
ASSERT_EQ(state.getTestBuffer().rotate(state.getRandomSize()), Fw::FW_SERIALIZE_OK);
ASSERT_TRUE(state.rotate(state.getRandomSize()));
state.setRemainingSize(state.getRemainingSize() + state.getRandomSize());
state.checkSizes();
}
RotateBadRule::RotateBadRule(const char *const name)
: STest::Rule<MockTypes::CircularState>(name) {}
bool RotateBadRule::precondition(const MockTypes::CircularState& state) {
FwSizeType rotate_available = (MAX_BUFFER_SIZE - state.getRemainingSize());
return rotate_available < state.getRandomSize();
}
void RotateBadRule::action(MockTypes::CircularState& state) {
ASSERT_EQ(state.getTestBuffer().rotate(state.getRandomSize()), Fw::FW_DESERIALIZE_BUFFER_EMPTY);
} }
} }
PeekBadRule::PeekBadRule(const char* const name) : STest::Rule<MockTypes::CircularState>(name) {}
bool PeekBadRule::precondition(const MockTypes::CircularState& state) {
FwSizeType peek_available = (MAX_BUFFER_SIZE - state.getRemainingSize());
if (state.getPeekType() == 0) {
return peek_available < sizeof(I8) + state.getPeekOffset();
} else if (state.getPeekType() == 1) {
return peek_available < sizeof(U8) + state.getPeekOffset();
} else if (state.getPeekType() == 2) {
return peek_available < sizeof(U32) + state.getPeekOffset();
} else if (state.getPeekType() == 3) {
return peek_available < state.getRandomSize() + state.getPeekOffset();
}
return false;
}
void PeekBadRule::action(MockTypes::CircularState& state) {
char peek_char = 0;
U8 peek_u8 = 0;
U32 peek_u32 = 0;
U8 peek_buffer[MAX_BUFFER_SIZE];
// Handle all cases for deserialization
if (state.getPeekType() == 0) {
ASSERT_EQ(state.getTestBuffer().peek(peek_char, state.getPeekOffset()), Fw::FW_DESERIALIZE_BUFFER_EMPTY);
} else if (state.getPeekType() == 1) {
ASSERT_EQ(state.getTestBuffer().peek(peek_u8, state.getPeekOffset()), Fw::FW_DESERIALIZE_BUFFER_EMPTY);
} else if (state.getPeekType() == 2) {
ASSERT_EQ(state.getTestBuffer().peek(peek_u32, state.getPeekOffset()), Fw::FW_DESERIALIZE_BUFFER_EMPTY);
} else if (state.getPeekType() == 3) {
ASSERT_EQ(state.getTestBuffer().peek(peek_buffer, state.getRandomSize(), state.getPeekOffset()),
Fw::FW_DESERIALIZE_BUFFER_EMPTY);
} else {
ASSERT_TRUE(false); // Fail the test, bad type
}
}
RotateOkRule::RotateOkRule(const char* const name) : STest::Rule<MockTypes::CircularState>(name) {}
bool RotateOkRule::precondition(const MockTypes::CircularState& state) {
FwSizeType rotate_available = (MAX_BUFFER_SIZE - state.getRemainingSize());
return rotate_available >= state.getRandomSize();
}
void RotateOkRule::action(MockTypes::CircularState& state) {
state.checkSizes();
ASSERT_EQ(state.getTestBuffer().rotate(state.getRandomSize()), Fw::FW_SERIALIZE_OK);
ASSERT_TRUE(state.rotate(state.getRandomSize()));
state.setRemainingSize(state.getRemainingSize() + state.getRandomSize());
state.checkSizes();
}
RotateBadRule::RotateBadRule(const char* const name) : STest::Rule<MockTypes::CircularState>(name) {}
bool RotateBadRule::precondition(const MockTypes::CircularState& state) {
FwSizeType rotate_available = (MAX_BUFFER_SIZE - state.getRemainingSize());
return rotate_available < state.getRandomSize();
}
void RotateBadRule::action(MockTypes::CircularState& state) {
ASSERT_EQ(state.getTestBuffer().rotate(state.getRandomSize()), Fw::FW_DESERIALIZE_BUFFER_EMPTY);
}
} // namespace Types

View File

@ -21,123 +21,122 @@
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
#include <Fw/Types/String.hpp> #include <Fw/Types/String.hpp>
#include <Utils/Types/test/ut/CircularBuffer/CircularState.hpp>
#include <STest/STest/Rule/Rule.hpp>
#include <STest/STest/Pick/Pick.hpp> #include <STest/STest/Pick/Pick.hpp>
#include <STest/STest/Rule/Rule.hpp>
#include <Utils/Types/test/ut/CircularBuffer/CircularState.hpp>
namespace Types { namespace Types {
/** /**
* SetupRandomBufferRule: * SetupRandomBufferRule:
* *
* This rule sets up a random buffer, and other random state. * This rule sets up a random buffer, and other random state.
*/ */
struct RandomizeRule : public STest::Rule<MockTypes::CircularState> { struct RandomizeRule : public STest::Rule<MockTypes::CircularState> {
// Constructor // Constructor
RandomizeRule(const char *const name); RandomizeRule(const char* const name);
// Always valid // Always valid
bool precondition(const MockTypes::CircularState& state); bool precondition(const MockTypes::CircularState& state);
// Will randomize the test state // Will randomize the test state
void action(MockTypes::CircularState& truth); void action(MockTypes::CircularState& truth);
}; };
/** /**
* SerializeOkRule: * SerializeOkRule:
* *
* This rule tests that the circular buffer can accept data when it is valid for the buffer to accept data. * This rule tests that the circular buffer can accept data when it is valid for the buffer to accept data.
*/ */
struct SerializeOkRule : public STest::Rule<MockTypes::CircularState> { struct SerializeOkRule : public STest::Rule<MockTypes::CircularState> {
// Constructor // Constructor
SerializeOkRule(const char *const name); SerializeOkRule(const char* const name);
// Valid precondition for when the buffer should accept data // Valid precondition for when the buffer should accept data
bool precondition(const MockTypes::CircularState& state); bool precondition(const MockTypes::CircularState& state);
// Action that tests the buffer accepting data // Action that tests the buffer accepting data
void action(MockTypes::CircularState& state); void action(MockTypes::CircularState& state);
}; };
/** /**
* SerializeOverflowRule: * SerializeOverflowRule:
* *
* This rule tests that the circular buffer cannot accept data when it is full. * This rule tests that the circular buffer cannot accept data when it is full.
*/ */
struct SerializeOverflowRule : public STest::Rule<MockTypes::CircularState> { struct SerializeOverflowRule : public STest::Rule<MockTypes::CircularState> {
// Constructor // Constructor
SerializeOverflowRule(const char *const name); SerializeOverflowRule(const char* const name);
// Valid precondition for when the buffer should reject data // Valid precondition for when the buffer should reject data
bool precondition(const MockTypes::CircularState& state); bool precondition(const MockTypes::CircularState& state);
// Action that tests the buffer overflowing with an error // Action that tests the buffer overflowing with an error
void action(MockTypes::CircularState& state); void action(MockTypes::CircularState& state);
}; };
/** /**
* PeekOkRule: * PeekOkRule:
* *
* This rule tests that the circular buffer can peek correctly. * This rule tests that the circular buffer can peek correctly.
*/ */
struct PeekOkRule : public STest::Rule<MockTypes::CircularState> { struct PeekOkRule : public STest::Rule<MockTypes::CircularState> {
// Constructor // Constructor
PeekOkRule(const char *const name); PeekOkRule(const char* const name);
// Peek ok available for when buffer size - remaining size <= peek size // Peek ok available for when buffer size - remaining size <= peek size
bool precondition(const MockTypes::CircularState& state); bool precondition(const MockTypes::CircularState& state);
// Action that tests the buffer's ability to peek // Action that tests the buffer's ability to peek
void action(MockTypes::CircularState& state); void action(MockTypes::CircularState& state);
}; };
/** /**
* PeekOkRule: * PeekOkRule:
* *
* This rule tests that the circular buffer cannot peek when it should not peek. * This rule tests that the circular buffer cannot peek when it should not peek.
*/ */
struct PeekBadRule : public STest::Rule<MockTypes::CircularState> { struct PeekBadRule : public STest::Rule<MockTypes::CircularState> {
// Constructor // Constructor
PeekBadRule(const char *const name); PeekBadRule(const char* const name);
// Peek bad available for when buffer size - remaining size > peek size // Peek bad available for when buffer size - remaining size > peek size
bool precondition(const MockTypes::CircularState& state); bool precondition(const MockTypes::CircularState& state);
// Action that tests the buffer's ability to peek with a fail // Action that tests the buffer's ability to peek with a fail
void action(MockTypes::CircularState& state); void action(MockTypes::CircularState& state);
}; };
/** /**
* RotateOkRule: * RotateOkRule:
* *
* This rule tests that the circular buffer can rotate correctly. * This rule tests that the circular buffer can rotate correctly.
*/ */
struct RotateOkRule : public STest::Rule<MockTypes::CircularState> { struct RotateOkRule : public STest::Rule<MockTypes::CircularState> {
// Constructor // Constructor
RotateOkRule(const char *const name); RotateOkRule(const char* const name);
// Rotate is ok when there is more data then rotational size // Rotate is ok when there is more data then rotational size
bool precondition(const MockTypes::CircularState& state); bool precondition(const MockTypes::CircularState& state);
// Action that tests the buffer's ability to rotate // Action that tests the buffer's ability to rotate
void action(MockTypes::CircularState& state); void action(MockTypes::CircularState& state);
}; };
/** /**
* RotateOkRule: * RotateOkRule:
* *
* This rule tests that the circular buffer cannot rotate when it should not rotate. * This rule tests that the circular buffer cannot rotate when it should not rotate.
*/ */
struct RotateBadRule : public STest::Rule<MockTypes::CircularState> { struct RotateBadRule : public STest::Rule<MockTypes::CircularState> {
// Constructor // Constructor
RotateBadRule(const char *const name); RotateBadRule(const char* const name);
// Rotate is bad when there is less data then rotational size // Rotate is bad when there is less data then rotational size
bool precondition(const MockTypes::CircularState& state); bool precondition(const MockTypes::CircularState& state);
// Action that tests the buffer's ability to rotate // Action that tests the buffer's ability to rotate
void action(MockTypes::CircularState& state); void action(MockTypes::CircularState& state);
}; };
} } // namespace Types
#endif //FPRIME_GROUNDINTERFACERULES_HPP #endif // FPRIME_GROUNDINTERFACERULES_HPP

View File

@ -9,115 +9,114 @@
#include <STest/Pick/Pick.hpp> #include <STest/Pick/Pick.hpp>
#include <Utils/Types/test/ut/CircularBuffer/CircularState.hpp> #include <Utils/Types/test/ut/CircularBuffer/CircularState.hpp>
#include <gtest/gtest.h>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <gtest/gtest.h>
U8 CIRCULAR_BUFFER_MEMORY[MAX_BUFFER_SIZE]; U8 CIRCULAR_BUFFER_MEMORY[MAX_BUFFER_SIZE];
namespace MockTypes { namespace MockTypes {
CircularState::CircularState() : CircularState::CircularState()
m_remaining_size(static_cast<FwSizeType>(sizeof(CIRCULAR_BUFFER_MEMORY))), : m_remaining_size(static_cast<FwSizeType>(sizeof(CIRCULAR_BUFFER_MEMORY))),
m_random_size(MAX_BUFFER_SIZE), m_random_size(MAX_BUFFER_SIZE),
m_peek_offset(0), m_peek_offset(0),
m_peek_type(0), m_peek_type(0),
m_infinite_store(nullptr), m_infinite_store(nullptr),
m_infinite_read(0), m_infinite_read(0),
m_infinite_write(0), m_infinite_write(0),
m_infinite_size(0), m_infinite_size(0),
m_test_buffer(CIRCULAR_BUFFER_MEMORY, static_cast<FwSizeType>(sizeof(CIRCULAR_BUFFER_MEMORY))) m_test_buffer(CIRCULAR_BUFFER_MEMORY, static_cast<FwSizeType>(sizeof(CIRCULAR_BUFFER_MEMORY))) {
{ memset(m_buffer, 0, sizeof m_buffer);
memset(m_buffer, 0, sizeof m_buffer); }
}
CircularState::~CircularState() { CircularState::~CircularState() {
if (m_infinite_size != 0) { if (m_infinite_size != 0) {
std::free(m_infinite_store); std::free(m_infinite_store);
}
}
// Generates a random buffer
FwSizeType CircularState::generateRandomBuffer() {
m_peek_offset = static_cast<FwSizeType>(STest::Pick::lowerUpper(0, sizeof(m_buffer)));
m_peek_type = static_cast<FwSizeType>(STest::Pick::lowerUpper(0, 4));
FwSizeType random_size = static_cast<FwSizeType>(STest::Pick::lowerUpper(0, sizeof(m_buffer)));
for (U32 i = 0; i < random_size; i++) {
m_buffer[i] = static_cast<U8>(STest::Pick::lowerUpper(0, 256));
}
this->m_random_size = random_size;
return random_size;
}
void CircularState::setRandom(FwSizeType random, FwSizeType peek_type, FwSizeType peek_offset) {
m_random_size = random;
m_peek_type = peek_type;
m_peek_offset = peek_offset;
}
FwSizeType CircularState::getPeekOffset() const {
return m_peek_offset;
}
FwSizeType CircularState::getPeekType() const {
return m_peek_type;
}
bool CircularState::addInfinite(const U8* buffer, FwSizeType size) {
// If we are out of "infinite space" add another MB, and check allocation
if ((m_infinite_write + size) > m_infinite_size) {
void* new_pointer = std::realloc(m_infinite_store, m_infinite_size + 1048576);
if (new_pointer == nullptr) {
return false;
}
m_infinite_store = static_cast<U8*>(new_pointer);
m_infinite_size += 1048576;
}
std::memcpy(m_infinite_store + m_infinite_write, buffer, size);
m_infinite_write += size;
return true;
}
bool CircularState::peek(U8*& buffer, FwSizeType size, FwSizeType offset) {
FwSizeType final_offset = m_infinite_read + offset;
if ((final_offset + size) > m_infinite_write) {
return false;
}
buffer = m_infinite_store + final_offset;
return true;
}
bool CircularState::rotate(FwSizeType size) {
// Fail if we try to rotate too far
if ((m_infinite_read + size) > m_infinite_write) {
return false;
}
m_infinite_read += size;
return true;
}
FwSizeType CircularState::getRandomSize() const {
return m_random_size;
}
const U8 *CircularState::getBuffer() const {
return m_buffer;
}
FwSizeType CircularState::getRemainingSize() const {
return m_remaining_size;
}
void CircularState::setRemainingSize(FwSizeType mRemainingSize) {
m_remaining_size = mRemainingSize;
}
Types::CircularBuffer& CircularState::getTestBuffer() {
return m_test_buffer;
}
void CircularState::checkSizes() const {
const FwSizeType allocated_size = (MAX_BUFFER_SIZE - m_remaining_size);
ASSERT_EQ(m_test_buffer.get_free_size(), m_remaining_size);
ASSERT_EQ(m_test_buffer.get_allocated_size(), allocated_size);
} }
} }
// Generates a random buffer
FwSizeType CircularState::generateRandomBuffer() {
m_peek_offset = static_cast<FwSizeType>(STest::Pick::lowerUpper(0, sizeof(m_buffer)));
m_peek_type = static_cast<FwSizeType>(STest::Pick::lowerUpper(0, 4));
FwSizeType random_size = static_cast<FwSizeType>(STest::Pick::lowerUpper(0, sizeof(m_buffer)));
for (U32 i = 0; i < random_size; i++) {
m_buffer[i] = static_cast<U8>(STest::Pick::lowerUpper(0, 256));
}
this->m_random_size = random_size;
return random_size;
}
void CircularState::setRandom(FwSizeType random, FwSizeType peek_type, FwSizeType peek_offset) {
m_random_size = random;
m_peek_type = peek_type;
m_peek_offset = peek_offset;
}
FwSizeType CircularState::getPeekOffset() const {
return m_peek_offset;
}
FwSizeType CircularState::getPeekType() const {
return m_peek_type;
}
bool CircularState::addInfinite(const U8* buffer, FwSizeType size) {
// If we are out of "infinite space" add another MB, and check allocation
if ((m_infinite_write + size) > m_infinite_size) {
void* new_pointer = std::realloc(m_infinite_store, m_infinite_size + 1048576);
if (new_pointer == nullptr) {
return false;
}
m_infinite_store = static_cast<U8*>(new_pointer);
m_infinite_size += 1048576;
}
std::memcpy(m_infinite_store + m_infinite_write, buffer, size);
m_infinite_write += size;
return true;
}
bool CircularState::peek(U8*& buffer, FwSizeType size, FwSizeType offset) {
FwSizeType final_offset = m_infinite_read + offset;
if ((final_offset + size) > m_infinite_write) {
return false;
}
buffer = m_infinite_store + final_offset;
return true;
}
bool CircularState::rotate(FwSizeType size) {
// Fail if we try to rotate too far
if ((m_infinite_read + size) > m_infinite_write) {
return false;
}
m_infinite_read += size;
return true;
}
FwSizeType CircularState::getRandomSize() const {
return m_random_size;
}
const U8* CircularState::getBuffer() const {
return m_buffer;
}
FwSizeType CircularState::getRemainingSize() const {
return m_remaining_size;
}
void CircularState::setRemainingSize(FwSizeType mRemainingSize) {
m_remaining_size = mRemainingSize;
}
Types::CircularBuffer& CircularState::getTestBuffer() {
return m_test_buffer;
}
void CircularState::checkSizes() const {
const FwSizeType allocated_size = (MAX_BUFFER_SIZE - m_remaining_size);
ASSERT_EQ(m_test_buffer.get_free_size(), m_remaining_size);
ASSERT_EQ(m_test_buffer.get_allocated_size(), allocated_size);
}
} // namespace MockTypes

View File

@ -17,96 +17,96 @@
namespace MockTypes { namespace MockTypes {
class CircularState { class CircularState {
public: public:
// Constructor // Constructor
CircularState(); CircularState();
// Destructor // Destructor
~CircularState(); ~CircularState();
/** /**
* Generates a random buffer for input to various calls to the CircularBuffer. * Generates a random buffer for input to various calls to the CircularBuffer.
* @return size of this buffer * @return size of this buffer
*/ */
FwSizeType generateRandomBuffer(); FwSizeType generateRandomBuffer();
/** /**
* Sets the random settings * Sets the random settings
* @param random: random size * @param random: random size
* @param peek_type: peek type (0-3) * @param peek_type: peek type (0-3)
* @param peek_offset: offset size * @param peek_offset: offset size
*/ */
void setRandom(FwSizeType random, FwSizeType peek_type, FwSizeType peek_offset); void setRandom(FwSizeType random, FwSizeType peek_type, FwSizeType peek_offset);
/** /**
* Add to the infinite pool of data. * Add to the infinite pool of data.
* @return true if successful, false otherwise * @return true if successful, false otherwise
*/ */
bool addInfinite(const U8* buffer, FwSizeType size); bool addInfinite(const U8* buffer, FwSizeType size);
/** /**
* Grab a peek buffer for given size and offset. * Grab a peek buffer for given size and offset.
* @return true if successful, false if cannot. * @return true if successful, false if cannot.
*/ */
bool peek(U8*& buffer, FwSizeType size, FwSizeType offset = 0); bool peek(U8*& buffer, FwSizeType size, FwSizeType offset = 0);
/** /**
* Rotate the circular buffer. * Rotate the circular buffer.
* @param size: size to rotate * @param size: size to rotate
* @return true if successful, false otherwise * @return true if successful, false otherwise
*/ */
bool rotate(FwSizeType size); bool rotate(FwSizeType size);
/** /**
* Get the size of the random buffer data. * Get the size of the random buffer data.
* @return size of the buffer * @return size of the buffer
*/ */
FwSizeType getRandomSize() const; FwSizeType getRandomSize() const;
/** /**
* Get the size of the random buffer data. * Get the size of the random buffer data.
* @return size of the buffer * @return size of the buffer
*/ */
FwSizeType getPeekOffset() const; FwSizeType getPeekOffset() const;
/** /**
* Get the size of the random buffer data. * Get the size of the random buffer data.
* @return size of the buffer * @return size of the buffer
*/ */
FwSizeType getPeekType() const; FwSizeType getPeekType() const;
/** /**
* Gets a pointer to the random buffer. * Gets a pointer to the random buffer.
* @return random buffer storing data * @return random buffer storing data
*/ */
const U8 *getBuffer() const; const U8* getBuffer() const;
/** /**
* Get the remaining size of the circular buffer. This is a shadow field. * Get the remaining size of the circular buffer. This is a shadow field.
* @return shadow field for circular buffer. * @return shadow field for circular buffer.
*/ */
FwSizeType getRemainingSize() const; FwSizeType getRemainingSize() const;
/** /**
* Set the remaining size shadow field input. * Set the remaining size shadow field input.
* @param mRemainingSize: remaining size shadow field * @param mRemainingSize: remaining size shadow field
*/ */
void setRemainingSize(FwSizeType mRemainingSize); void setRemainingSize(FwSizeType mRemainingSize);
/** /**
* Get the in-test circular buffer. * Get the in-test circular buffer.
* @return in-test circular buffer * @return in-test circular buffer
*/ */
Types::CircularBuffer& getTestBuffer(); Types::CircularBuffer& getTestBuffer();
/** /**
* Check allocated and free sizes * Check allocated and free sizes
*/ */
void checkSizes() const; void checkSizes() const;
private: private:
FwSizeType m_remaining_size; FwSizeType m_remaining_size;
FwSizeType m_random_size; FwSizeType m_random_size;
FwSizeType m_peek_offset; FwSizeType m_peek_offset;
FwSizeType m_peek_type; FwSizeType m_peek_type;
U8 m_buffer[MAX_BUFFER_SIZE]; U8 m_buffer[MAX_BUFFER_SIZE];
// May use just under 100MB of space // May use just under 100MB of space
U8* m_infinite_store; U8* m_infinite_store;
FwSizeType m_infinite_read; FwSizeType m_infinite_read;
FwSizeType m_infinite_write; FwSizeType m_infinite_write;
FwSizeType m_infinite_size; FwSizeType m_infinite_size;
Types::CircularBuffer m_test_buffer; Types::CircularBuffer m_test_buffer;
}; };
} } // namespace MockTypes
#endif //FPRIME_CIRCULARSTATE_HPP #endif // FPRIME_CIRCULARSTATE_HPP

View File

@ -6,16 +6,16 @@
* Created on: May 23, 2019 * Created on: May 23, 2019
* Author: mstarch * Author: mstarch
*/ */
#include <STest/Scenario/Scenario.hpp>
#include <STest/Scenario/RandomScenario.hpp>
#include <STest/Scenario/BoundedScenario.hpp> #include <STest/Scenario/BoundedScenario.hpp>
#include <STest/Scenario/RandomScenario.hpp>
#include <STest/Scenario/Scenario.hpp>
#include <gtest/gtest.h>
#include <Fw/Test/UnitTest.hpp> #include <Fw/Test/UnitTest.hpp>
#include <Utils/Types/test/ut/CircularBuffer/CircularRules.hpp> #include <Utils/Types/test/ut/CircularBuffer/CircularRules.hpp>
#include <gtest/gtest.h>
#include <cstdio>
#include <cmath> #include <cmath>
#include <cstdio>
#define STEP_COUNT 1000 #define STEP_COUNT 1000
@ -41,22 +41,13 @@ TEST(CircularBufferTests, RandomCircularTests) {
Types::PeekBadRule rotateBad("rotateBad"); Types::PeekBadRule rotateBad("rotateBad");
// Setup a list of rules to choose from // Setup a list of rules to choose from
STest::Rule<MockTypes::CircularState>* rules[] = { STest::Rule<MockTypes::CircularState>* rules[] = {&randomize, &serializeOk, &serializeOverflow, &peekOk,
&randomize, &peekBad, &rotateOk, &rotateBad};
&serializeOk,
&serializeOverflow,
&peekOk,
&peekBad,
&rotateOk,
&rotateBad
};
// Construct the random scenario and run it with the defined bounds // Construct the random scenario and run it with the defined bounds
STest::RandomScenario<MockTypes::CircularState> random("Random Rules", rules, STest::RandomScenario<MockTypes::CircularState> random("Random Rules", rules, FW_NUM_ARRAY_ELEMENTS(rules));
FW_NUM_ARRAY_ELEMENTS(rules));
// Setup a bounded scenario to run rules a set number of times // Setup a bounded scenario to run rules a set number of times
STest::BoundedScenario<MockTypes::CircularState> bounded("Bounded Random Rules Scenario", STest::BoundedScenario<MockTypes::CircularState> bounded("Bounded Random Rules Scenario", random, STEP_COUNT);
random, STEP_COUNT);
// Run! // Run!
const U32 numSteps = bounded.run(state); const U32 numSteps = bounded.run(state);
printf("Ran %u steps.\n", numSteps); printf("Ran %u steps.\n", numSteps);
@ -82,7 +73,7 @@ TEST(CircularBufferTests, BasicSerializeTest) {
TEST(CircularBufferTests, BasicOverflowTest) { TEST(CircularBufferTests, BasicOverflowTest) {
// Setup state and fill it with garbage // Setup state and fill it with garbage
MockTypes::CircularState state; MockTypes::CircularState state;
ASSERT_EQ(Fw::FW_SERIALIZE_OK , state.getTestBuffer().serialize(state.getBuffer(), state.getRandomSize())); ASSERT_EQ(Fw::FW_SERIALIZE_OK, state.getTestBuffer().serialize(state.getBuffer(), state.getRandomSize()));
state.setRemainingSize(0); state.setRemainingSize(0);
// Create rules, and assign them into the array // Create rules, and assign them into the array
@ -100,7 +91,7 @@ TEST(CircularBufferTests, BasicPeekTest) {
char peek_char = static_cast<char>(0x85); char peek_char = static_cast<char>(0x85);
U8 peek_u8 = 0x95; U8 peek_u8 = 0x95;
U32 peek_u32 = 0xdeadc0de; U32 peek_u32 = 0xdeadc0de;
U8 buffer[1024] = {}; // Clear out memory to appease valgrind U8 buffer[1024] = {}; // Clear out memory to appease valgrind
// Setup all circular state // Setup all circular state
MockTypes::CircularState state; MockTypes::CircularState state;
state.addInfinite(reinterpret_cast<U8*>(&peek_char), sizeof(peek_char)); state.addInfinite(reinterpret_cast<U8*>(&peek_char), sizeof(peek_char));

View File

@ -13,140 +13,124 @@
#include "RateLimiterTester.hpp" #include "RateLimiterTester.hpp"
namespace Utils { namespace Utils {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Construction and destruction // Construction and destruction
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
RateLimiterTester :: RateLimiterTester ::RateLimiterTester() {}
RateLimiterTester()
{
}
RateLimiterTester :: RateLimiterTester ::~RateLimiterTester() {}
~RateLimiterTester()
{
} // ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- void RateLimiterTester ::testCounterTriggering() {
// Tests
// ----------------------------------------------------------------------
void RateLimiterTester ::
testCounterTriggering()
{
U32 testCycles[] = {0, 5, 50, 832}; U32 testCycles[] = {0, 5, 50, 832};
for (U32 i = 0; i < FW_NUM_ARRAY_ELEMENTS(testCycles); i++) { for (U32 i = 0; i < FW_NUM_ARRAY_ELEMENTS(testCycles); i++) {
const U32 cycles = testCycles[i]; const U32 cycles = testCycles[i];
// triggers at the beginning // triggers at the beginning
RateLimiter limiter(cycles, 0); RateLimiter limiter(cycles, 0);
ASSERT_TRUE(limiter.trigger()); ASSERT_TRUE(limiter.trigger());
limiter.reset();
// does not trigger if skipped
if (cycles > 0) {
limiter.setCounter(1);
ASSERT_FALSE(limiter.trigger());
limiter.reset(); limiter.reset();
}
// test number of times triggered // does not trigger if skipped
const U32 numIter = 10000; if (cycles > 0) {
U32 triggerCount = 0; limiter.setCounter(1);
for (U32 iter = 0; iter < numIter; iter++) { ASSERT_FALSE(limiter.trigger());
bool shouldTrigger = (cycles == 0) || (iter % cycles == 0); limiter.reset();
bool triggered = limiter.trigger();
ASSERT_EQ(shouldTrigger, triggered) << " for cycles " << cycles << " at " << iter;
triggerCount += triggered;
}
if (cycles > 0) {
U32 expectedCount = (numIter / cycles) + (numIter % cycles > 0);
ASSERT_EQ(triggerCount, expectedCount);
}
}
}
void RateLimiterTester ::
testTimeTriggering()
{
U32 testCycles[] = {0, 5, 50, 832};
for (U32 i = 0; i < FW_NUM_ARRAY_ELEMENTS(testCycles); i++) {
const U32 cycles = testCycles[i];
Fw::Time timeCyclesTime(cycles, 0);
// triggers at the beginning
RateLimiter limiter(0, cycles);
ASSERT_TRUE(limiter.trigger(Fw::Time::zero()));
limiter.reset();
// does not trigger if skipped
if (cycles > 0) {
limiter.setTime(Fw::Time(1,0));
ASSERT_FALSE(limiter.trigger(Fw::Time::zero()));
limiter.reset();
}
// test number of times triggered
const U32 numIter = 100000;
Fw::Time curTime(0, 0);
Fw::Time nextTriggerTime(0, 0);
for (U32 iter = 0; iter < numIter; iter++) {
curTime.add(0, STest::Pick::lowerUpper(1, 5) * 100000);
bool shouldTrigger = (cycles == 0) || (curTime >= nextTriggerTime);
bool triggered = limiter.trigger(curTime);
ASSERT_EQ(shouldTrigger, triggered) << " for cycles " << cycles << " at " << curTime.getSeconds() << "." << curTime.getUSeconds();
if (triggered) {
nextTriggerTime = Fw::Time::add(curTime, timeCyclesTime);
} }
}
}
}
void RateLimiterTester :: // test number of times triggered
testCounterAndTimeTriggering() const U32 numIter = 10000;
{ U32 triggerCount = 0;
for (U32 iter = 0; iter < numIter; iter++) {
bool shouldTrigger = (cycles == 0) || (iter % cycles == 0);
bool triggered = limiter.trigger();
ASSERT_EQ(shouldTrigger, triggered) << " for cycles " << cycles << " at " << iter;
triggerCount += triggered;
}
if (cycles > 0) {
U32 expectedCount = (numIter / cycles) + (numIter % cycles > 0);
ASSERT_EQ(triggerCount, expectedCount);
}
}
}
void RateLimiterTester ::testTimeTriggering() {
U32 testCycles[] = {0, 5, 50, 832};
for (U32 i = 0; i < FW_NUM_ARRAY_ELEMENTS(testCycles); i++) {
const U32 cycles = testCycles[i];
Fw::Time timeCyclesTime(cycles, 0);
// triggers at the beginning
RateLimiter limiter(0, cycles);
ASSERT_TRUE(limiter.trigger(Fw::Time::zero()));
limiter.reset();
// does not trigger if skipped
if (cycles > 0) {
limiter.setTime(Fw::Time(1, 0));
ASSERT_FALSE(limiter.trigger(Fw::Time::zero()));
limiter.reset();
}
// test number of times triggered
const U32 numIter = 100000;
Fw::Time curTime(0, 0);
Fw::Time nextTriggerTime(0, 0);
for (U32 iter = 0; iter < numIter; iter++) {
curTime.add(0, STest::Pick::lowerUpper(1, 5) * 100000);
bool shouldTrigger = (cycles == 0) || (curTime >= nextTriggerTime);
bool triggered = limiter.trigger(curTime);
ASSERT_EQ(shouldTrigger, triggered)
<< " for cycles " << cycles << " at " << curTime.getSeconds() << "." << curTime.getUSeconds();
if (triggered) {
nextTriggerTime = Fw::Time::add(curTime, timeCyclesTime);
}
}
}
}
void RateLimiterTester ::testCounterAndTimeTriggering() {
U32 testCounterCycles[] = {37, 981, 4110}; U32 testCounterCycles[] = {37, 981, 4110};
U32 testTimeCycles[] = {12, 294, 1250}; U32 testTimeCycles[] = {12, 294, 1250};
for (U32 i = 0; i < (FW_NUM_ARRAY_ELEMENTS(testCounterCycles) * FW_NUM_ARRAY_ELEMENTS(testTimeCycles)); i++) { for (U32 i = 0; i < (FW_NUM_ARRAY_ELEMENTS(testCounterCycles) * FW_NUM_ARRAY_ELEMENTS(testTimeCycles)); i++) {
const U32 counterCycles = testCounterCycles[i % FW_NUM_ARRAY_ELEMENTS(testCounterCycles)]; const U32 counterCycles = testCounterCycles[i % FW_NUM_ARRAY_ELEMENTS(testCounterCycles)];
const U32 timeCycles = testTimeCycles[i / FW_NUM_ARRAY_ELEMENTS(testCounterCycles)]; const U32 timeCycles = testTimeCycles[i / FW_NUM_ARRAY_ELEMENTS(testCounterCycles)];
Fw::Time timeCyclesTime(timeCycles, 0); Fw::Time timeCyclesTime(timeCycles, 0);
// triggers at the beginning // triggers at the beginning
RateLimiter limiter(counterCycles, timeCycles); RateLimiter limiter(counterCycles, timeCycles);
ASSERT_TRUE(limiter.trigger(Fw::Time::zero())); ASSERT_TRUE(limiter.trigger(Fw::Time::zero()));
limiter.reset(); limiter.reset();
// test trigger locations // test trigger locations
const U32 numIter = 100000; // each iter is 0.1 seconds const U32 numIter = 100000; // each iter is 0.1 seconds
Fw::Time curTime(0, 0); Fw::Time curTime(0, 0);
U32 lastTriggerIter = 0; U32 lastTriggerIter = 0;
Fw::Time nextTriggerTime(0, 0); Fw::Time nextTriggerTime(0, 0);
for (U32 iter = 0; iter < numIter; iter++) { for (U32 iter = 0; iter < numIter; iter++) {
curTime.add(0, STest::Pick::lowerUpper(1, 5) * 100000); curTime.add(0, STest::Pick::lowerUpper(1, 5) * 100000);
bool shouldTrigger = ((iter-lastTriggerIter) % counterCycles == 0) || (curTime >= nextTriggerTime); bool shouldTrigger = ((iter - lastTriggerIter) % counterCycles == 0) || (curTime >= nextTriggerTime);
bool triggered = limiter.trigger(curTime); bool triggered = limiter.trigger(curTime);
ASSERT_EQ(shouldTrigger, triggered) << " for cycles " << counterCycles << "/" << timeCycles << " at " << iter << "/" << curTime.getSeconds() << "." << curTime.getUSeconds(); ASSERT_EQ(shouldTrigger, triggered) << " for cycles " << counterCycles << "/" << timeCycles << " at "
if (triggered) { << iter << "/" << curTime.getSeconds() << "." << curTime.getUSeconds();
nextTriggerTime = Fw::Time::add(curTime, timeCyclesTime); if (triggered) {
lastTriggerIter = iter; nextTriggerTime = Fw::Time::add(curTime, timeCyclesTime);
lastTriggerIter = iter;
}
} }
}
} }
} }
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- void RateLimiterTester ::initComponents() {}
// Helper methods
// ----------------------------------------------------------------------
void RateLimiterTester :: } // end namespace Utils
initComponents()
{
}
} // end namespace Utils

View File

@ -14,60 +14,51 @@
#ifndef RATELIMITERTESTER_HPP #ifndef RATELIMITERTESTER_HPP
#define RATELIMITERTESTER_HPP #define RATELIMITERTESTER_HPP
#include "Utils/RateLimiter.hpp"
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
#include "gtest/gtest.h"
#include <STest/Pick/Pick.hpp> #include <STest/Pick/Pick.hpp>
#include "Utils/RateLimiter.hpp"
#include "gtest/gtest.h"
namespace Utils { namespace Utils {
class RateLimiterTester class RateLimiterTester {
{ // ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- public:
// Construction and destruction //! Construct object RateLimiterTester
// ---------------------------------------------------------------------- //!
RateLimiterTester();
public: //! Destroy object RateLimiterTester
//!
~RateLimiterTester();
//! Construct object RateLimiterTester public:
//! // ----------------------------------------------------------------------
RateLimiterTester(); // Tests
// ----------------------------------------------------------------------
//! Destroy object RateLimiterTester void testCounterTriggering();
//! void testTimeTriggering();
~RateLimiterTester(); void testCounterAndTimeTriggering();
public: private:
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- //! Initialize components
// Tests //!
// ---------------------------------------------------------------------- void initComponents();
void testCounterTriggering(); private:
void testTimeTriggering(); // ----------------------------------------------------------------------
void testCounterAndTimeTriggering(); // Variables
// ----------------------------------------------------------------------
};
private: } // end namespace Utils
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
//! Initialize components
//!
void initComponents();
private:
// ----------------------------------------------------------------------
// Variables
// ----------------------------------------------------------------------
};
} // end namespace Utils
#endif #endif

View File

@ -16,60 +16,49 @@
namespace Utils { namespace Utils {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Construction and destruction // Construction and destruction
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
TokenBucketTester :: TokenBucketTester ::TokenBucketTester() {}
TokenBucketTester()
{
}
TokenBucketTester :: TokenBucketTester ::~TokenBucketTester() {}
~TokenBucketTester()
{
} // ----------------------------------------------------------------------
// Tests
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- void TokenBucketTester ::testTriggering() {
// Tests
// ----------------------------------------------------------------------
void TokenBucketTester ::
testTriggering()
{
const U32 interval = 1000000; const U32 interval = 1000000;
U32 testMaxTokens[] = {1, 5, 50, 832}; U32 testMaxTokens[] = {1, 5, 50, 832};
for (U32 i = 0; i < FW_NUM_ARRAY_ELEMENTS(testMaxTokens); i++) { for (U32 i = 0; i < FW_NUM_ARRAY_ELEMENTS(testMaxTokens); i++) {
const U32 maxTokens = testMaxTokens[i]; const U32 maxTokens = testMaxTokens[i];
TokenBucket bucket(interval, maxTokens); TokenBucket bucket(interval, maxTokens);
// can activate maxTokens times in a row // can activate maxTokens times in a row
for (U32 j = 0; j < maxTokens; j++) { for (U32 j = 0; j < maxTokens; j++) {
bool triggered = bucket.trigger(Fw::Time(0, 0)); bool triggered = bucket.trigger(Fw::Time(0, 0));
ASSERT_TRUE(triggered); ASSERT_TRUE(triggered);
ASSERT_EQ(bucket.getTokens(), maxTokens - j - 1); ASSERT_EQ(bucket.getTokens(), maxTokens - j - 1);
} }
// replenish // replenish
bucket.replenish(); bucket.replenish();
Fw::Time time(0, 0); Fw::Time time(0, 0);
const U32 attempts = maxTokens * 5; const U32 attempts = maxTokens * 5;
Fw::Time attemptInterval(0, interval / 4); Fw::Time attemptInterval(0, interval / 4);
U32 triggerCount = 0; U32 triggerCount = 0;
for (U32 attempt = 0; attempt < attempts; attempt++) { for (U32 attempt = 0; attempt < attempts; attempt++) {
triggerCount += bucket.trigger(time); triggerCount += bucket.trigger(time);
time = Fw::Time::add(time, attemptInterval); time = Fw::Time::add(time, attemptInterval);
} }
U32 expected = maxTokens + (attempts - 1) / 4; U32 expected = maxTokens + (attempts - 1) / 4;
ASSERT_EQ(expected, triggerCount); ASSERT_EQ(expected, triggerCount);
} }
} }
void TokenBucketTester :: void TokenBucketTester ::testReconfiguring() {
testReconfiguring()
{
U32 initialInterval = 1000000; U32 initialInterval = 1000000;
U32 initialMaxTokens = 5; U32 initialMaxTokens = 5;
@ -80,44 +69,43 @@ namespace Utils {
// trigger // trigger
bucket.trigger(Fw::Time(0, 0)); bucket.trigger(Fw::Time(0, 0));
ASSERT_EQ(bucket.getTokens(), initialMaxTokens-1); ASSERT_EQ(bucket.getTokens(), initialMaxTokens - 1);
// replenished, then triggered // replenished, then triggered
bucket.trigger(Fw::Time(1, 0)); bucket.trigger(Fw::Time(1, 0));
ASSERT_EQ(bucket.getTokens(), initialMaxTokens-1); ASSERT_EQ(bucket.getTokens(), initialMaxTokens - 1);
// set new interval, can't replenish using old interval // set new interval, can't replenish using old interval
U32 newInterval = 2000000; U32 newInterval = 2000000;
bucket.setReplenishInterval(newInterval); bucket.setReplenishInterval(newInterval);
ASSERT_EQ(bucket.getReplenishInterval(), newInterval); ASSERT_EQ(bucket.getReplenishInterval(), newInterval);
ASSERT_TRUE(bucket.trigger(Fw::Time(2, 0))); ASSERT_TRUE(bucket.trigger(Fw::Time(2, 0)));
ASSERT_EQ(bucket.getTokens(), initialMaxTokens-2); ASSERT_EQ(bucket.getTokens(), initialMaxTokens - 2);
// set new max tokens, replenish up to new max // set new max tokens, replenish up to new max
U32 newMaxTokens = 10; U32 newMaxTokens = 10;
bucket.setMaxTokens(newMaxTokens); bucket.setMaxTokens(newMaxTokens);
ASSERT_EQ(bucket.getMaxTokens(), newMaxTokens); ASSERT_EQ(bucket.getMaxTokens(), newMaxTokens);
ASSERT_TRUE(bucket.trigger(Fw::Time(20, 0))); ASSERT_TRUE(bucket.trigger(Fw::Time(20, 0)));
ASSERT_EQ(bucket.getTokens(), newMaxTokens-1); ASSERT_EQ(bucket.getTokens(), newMaxTokens - 1);
// set new rate, replenish quickly // set new rate, replenish quickly
while (bucket.trigger(Fw::Time(0,0))); while (bucket.trigger(Fw::Time(0, 0)))
;
bucket.setReplenishInterval(1000000); bucket.setReplenishInterval(1000000);
U32 newRate = 2; U32 newRate = 2;
bucket.setReplenishRate(newRate); bucket.setReplenishRate(newRate);
ASSERT_EQ(bucket.getReplenishRate(), newRate); ASSERT_EQ(bucket.getReplenishRate(), newRate);
ASSERT_TRUE(bucket.trigger(Fw::Time(21, 0))); ASSERT_TRUE(bucket.trigger(Fw::Time(21, 0)));
ASSERT_EQ(bucket.getTokens(), 1); ASSERT_EQ(bucket.getTokens(), 1);
} }
void TokenBucketTester :: void TokenBucketTester ::testInitialSettings() {
testInitialSettings()
{
U32 interval = 1000000; U32 interval = 1000000;
U32 maxTokens = 5; U32 maxTokens = 5;
U32 rate = 2; U32 rate = 2;
U32 startTokens = 2; U32 startTokens = 2;
Fw::Time startTime(5,0); Fw::Time startTime(5, 0);
TokenBucket bucket(interval, maxTokens, rate, startTokens, startTime); TokenBucket bucket(interval, maxTokens, rate, startTokens, startTime);
ASSERT_NE(bucket.getTokens(), maxTokens); ASSERT_NE(bucket.getTokens(), maxTokens);
@ -125,20 +113,16 @@ namespace Utils {
ASSERT_EQ(bucket.getReplenishRate(), rate); ASSERT_EQ(bucket.getReplenishRate(), rate);
for (U32 i = 0; i < startTokens; i++) { for (U32 i = 0; i < startTokens; i++) {
bool triggered = bucket.trigger(Fw::Time(0,0)); bool triggered = bucket.trigger(Fw::Time(0, 0));
ASSERT_TRUE(triggered); ASSERT_TRUE(triggered);
} }
ASSERT_FALSE(bucket.trigger(Fw::Time(0,0))); ASSERT_FALSE(bucket.trigger(Fw::Time(0, 0)));
} }
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- void TokenBucketTester ::initComponents() {}
// Helper methods
// ----------------------------------------------------------------------
void TokenBucketTester :: } // end namespace Utils
initComponents()
{
}
} // end namespace Utils

View File

@ -14,57 +14,50 @@
#ifndef TOKENBUCKETTESTER_HPP #ifndef TOKENBUCKETTESTER_HPP
#define TOKENBUCKETTESTER_HPP #define TOKENBUCKETTESTER_HPP
#include "Utils/TokenBucket.hpp"
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
#include "Utils/TokenBucket.hpp"
#include "gtest/gtest.h" #include "gtest/gtest.h"
namespace Utils { namespace Utils {
class TokenBucketTester class TokenBucketTester {
{ // ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- public:
// Construction and destruction //! Construct object TokenBucketTester
// ---------------------------------------------------------------------- //!
TokenBucketTester();
public: //! Destroy object TokenBucketTester
//!
~TokenBucketTester();
//! Construct object TokenBucketTester public:
//! // ----------------------------------------------------------------------
TokenBucketTester(); // Tests
// ----------------------------------------------------------------------
//! Destroy object TokenBucketTester void testTriggering();
//! void testReconfiguring();
~TokenBucketTester(); void testInitialSettings();
public: private:
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
// ---------------------------------------------------------------------- //! Initialize components
// Tests //!
// ---------------------------------------------------------------------- void initComponents();
void testTriggering(); private:
void testReconfiguring(); // ----------------------------------------------------------------------
void testInitialSettings(); // Variables
// ----------------------------------------------------------------------
};
private: } // end namespace Utils
// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------
//! Initialize components
//!
void initComponents();
private:
// ----------------------------------------------------------------------
// Variables
// ----------------------------------------------------------------------
};
} // end namespace Utils
#endif #endif

View File

@ -35,7 +35,7 @@ TEST(TokenBucketTest, TestInitialSettings) {
tester.testInitialSettings(); tester.testInitialSettings();
} }
int main(int argc, char **argv) { int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

View File

@ -1,29 +1,27 @@
/* /*
* \author: Tim Canham * \author: Tim Canham
* \file: * \file:
* \brief * \brief
* *
* This file has configuration settings for the ActiveRateGroup component. * This file has configuration settings for the ActiveRateGroup component.
* *
* *
* Copyright 2014-2015, by the California Institute of Technology. * Copyright 2014-2015, by the California Institute of Technology.
* ALL RIGHTS RESERVED. United States Government Sponsorship * ALL RIGHTS RESERVED. United States Government Sponsorship
* acknowledged. * acknowledged.
* *
*/ */
#ifndef ACTIVERATEGROUP_ACTIVERATEGROUPCFG_HPP_ #ifndef ACTIVERATEGROUP_ACTIVERATEGROUPCFG_HPP_
#define ACTIVERATEGROUP_ACTIVERATEGROUPCFG_HPP_ #define ACTIVERATEGROUP_ACTIVERATEGROUPCFG_HPP_
namespace Svc { namespace Svc {
enum { enum {
//! Number of overruns allowed before overrun event is throttled //! Number of overruns allowed before overrun event is throttled
ACTIVE_RATE_GROUP_OVERRUN_THROTTLE = 5, ACTIVE_RATE_GROUP_OVERRUN_THROTTLE = 5,
}; };
} }
#endif /* ACTIVERATEGROUP_ACTIVERATEGROUPCFG_HPP_ */ #endif /* ACTIVERATEGROUP_ACTIVERATEGROUPCFG_HPP_ */

View File

@ -2,7 +2,7 @@
#define Config_ActiveTextLoggerCfg_HPP_ #define Config_ActiveTextLoggerCfg_HPP_
enum { enum {
ACTIVE_TEXT_LOGGER_ID_FILTER_SIZE = 25, //!< Size of event ID filter ACTIVE_TEXT_LOGGER_ID_FILTER_SIZE = 25, //!< Size of event ID filter
}; };
#endif /* Config_ActiveTextLoggerCfg_HPP_ */ #endif /* Config_ActiveTextLoggerCfg_HPP_ */

View File

@ -4,8 +4,7 @@
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
namespace Svc { namespace Svc {
static const U16 BUFFERMGR_MAX_NUM_BINS = 10; static const U16 BUFFERMGR_MAX_NUM_BINS = 10;
} }
#endif // __BUFFERMANAGERCOMPONENTIMPLCFG_HPP__
#endif // __BUFFERMANAGERCOMPONENTIMPLCFG_HPP__

View File

@ -8,7 +8,6 @@
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
// Default block size used when reading files for CRC calculation // Default block size used when reading files for CRC calculation
constexpr FwSignedSizeType CONFIG_CRC_FILE_READ_BLOCK = 2048; constexpr FwSignedSizeType CONFIG_CRC_FILE_READ_BLOCK = 2048;

View File

@ -11,10 +11,8 @@
// Define configuration values for dispatcher // Define configuration values for dispatcher
enum { enum {
CMD_DISPATCHER_DISPATCH_TABLE_SIZE = 100, // !< The size of the table holding opcodes to dispatch CMD_DISPATCHER_DISPATCH_TABLE_SIZE = 100, // !< The size of the table holding opcodes to dispatch
CMD_DISPATCHER_SEQUENCER_TABLE_SIZE = 25, // !< The size of the table holding commands in progress CMD_DISPATCHER_SEQUENCER_TABLE_SIZE = 25, // !< The size of the table holding commands in progress
}; };
#endif /* CMDDISPATCHER_COMMANDDISPATCHERIMPLCFG_HPP_ */ #endif /* CMDDISPATCHER_COMMANDDISPATCHERIMPLCFG_HPP_ */

View File

@ -9,12 +9,12 @@
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
namespace Svc { namespace Svc {
// Sets the maximum number of directories where // Sets the maximum number of directories where
// data products can be stored. The array passed // data products can be stored. The array passed
// to the initializer for DpCatalog cannot exceed // to the initializer for DpCatalog cannot exceed
// this size. // this size.
static const FwIndexType DP_MAX_DIRECTORIES = 2; static const FwIndexType DP_MAX_DIRECTORIES = 2;
static const FwIndexType DP_MAX_FILES = 127; static const FwIndexType DP_MAX_FILES = 127;
} } // namespace Svc
#endif /* SVC_DPCATALOG_CONFIG_HPP_ */ #endif /* SVC_DPCATALOG_CONFIG_HPP_ */

View File

@ -18,6 +18,6 @@
// The format string for a file name // The format string for a file name
// The format arguments are base directory, container ID, time seconds, and time microseconds // The format arguments are base directory, container ID, time seconds, and time microseconds
#define DP_EXT ".fdp" #define DP_EXT ".fdp"
constexpr const char *DP_FILENAME_FORMAT = "%s/Dp_%08" PRI_FwDpIdType "_%08" PRIu32 "_%08" PRIu32 DP_EXT; constexpr const char* DP_FILENAME_FORMAT = "%s/Dp_%08" PRI_FwDpIdType "_%08" PRIu32 "_%08" PRIu32 DP_EXT;
#endif #endif

View File

@ -11,17 +11,16 @@
// set default filters // set default filters
enum { enum {
FILTER_WARNING_HI_DEFAULT = true, //!< WARNING HI events are filtered at input FILTER_WARNING_HI_DEFAULT = true, //!< WARNING HI events are filtered at input
FILTER_WARNING_LO_DEFAULT = true, //!< WARNING LO events are filtered at input FILTER_WARNING_LO_DEFAULT = true, //!< WARNING LO events are filtered at input
FILTER_COMMAND_DEFAULT = true, //!< COMMAND events are filtered at input FILTER_COMMAND_DEFAULT = true, //!< COMMAND events are filtered at input
FILTER_ACTIVITY_HI_DEFAULT = true, //!< ACTIVITY HI events are filtered at input FILTER_ACTIVITY_HI_DEFAULT = true, //!< ACTIVITY HI events are filtered at input
FILTER_ACTIVITY_LO_DEFAULT = true, //!< ACTIVITY LO events are filtered at input FILTER_ACTIVITY_LO_DEFAULT = true, //!< ACTIVITY LO events are filtered at input
FILTER_DIAGNOSTIC_DEFAULT = false, //!< DIAGNOSTIC events are filtered at input FILTER_DIAGNOSTIC_DEFAULT = false, //!< DIAGNOSTIC events are filtered at input
}; };
enum { enum {
TELEM_ID_FILTER_SIZE = 25, //!< Size of telemetry ID filter TELEM_ID_FILTER_SIZE = 25, //!< Size of telemetry ID filter
}; };
#endif /* Config_EventManagerCfg_HPP_ */ #endif /* Config_EventManagerCfg_HPP_ */

View File

@ -22,7 +22,7 @@
#ifndef FPRIME_INTEGER_CONFIG_H #ifndef FPRIME_INTEGER_CONFIG_H
#define FPRIME_INTEGER_CONFIG_H #define FPRIME_INTEGER_CONFIG_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -31,8 +31,7 @@ extern "C" {
#define FW_HAS_16_BIT 1 //!< Architecture supports 16 bit integers #define FW_HAS_16_BIT 1 //!< Architecture supports 16 bit integers
#define SKIP_FLOAT_IEEE_754_COMPLIANCE 0 //!< Check IEEE 754 compliance of floating point arithmetic #define SKIP_FLOAT_IEEE_754_COMPLIANCE 0 //!< Check IEEE 754 compliance of floating point arithmetic
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif // FPRIME_INTEGER_CONFIG_H #endif // FPRIME_INTEGER_CONFIG_H

View File

@ -9,18 +9,20 @@
#include <Fw/FPrimeBasicTypes.hpp> #include <Fw/FPrimeBasicTypes.hpp>
namespace Svc { namespace Svc {
// If this is set to true, the run handler will look to
// see if a packet is ready. If it is false, the next packet // If this is set to true, the run handler will look to
// will be sent as soon as the previous is complete. // see if a packet is ready. If it is false, the next packet
static const bool FILEDOWNLINK_PACKETS_BY_RUN = false; // will be sent as soon as the previous is complete.
// If this is set, errors that would cause FileDownlink to return an error response, such as a static const bool FILEDOWNLINK_PACKETS_BY_RUN = false;
// missing file or attempting to send a partial chunk past the end of the file will instead // If this is set, errors that would cause FileDownlink to return an error response, such as a
// return success. This is recommended to avoid a non-serious FileDownlink error aborting a // missing file or attempting to send a partial chunk past the end of the file will instead
// sequence early. These errors will still be logged as events. // return success. This is recommended to avoid a non-serious FileDownlink error aborting a
static const bool FILEDOWNLINK_COMMAND_FAILURES_DISABLED = true; // sequence early. These errors will still be logged as events.
// Size of the internal file downlink buffer. This must now be static as static const bool FILEDOWNLINK_COMMAND_FAILURES_DISABLED = true;
// file down maintains its own internal buffer. // Size of the internal file downlink buffer. This must now be static as
static const U32 FILEDOWNLINK_INTERNAL_BUFFER_SIZE = FW_FILE_BUFFER_MAX_SIZE; // file down maintains its own internal buffer.
} static const U32 FILEDOWNLINK_INTERNAL_BUFFER_SIZE = FW_FILE_BUFFER_MAX_SIZE;
} // namespace Svc
#endif /* SVC_FILEDOWNLINK_FILEDOWNLINKCFG_HPP_ */ #endif /* SVC_FILEDOWNLINK_FILEDOWNLINKCFG_HPP_ */

View File

@ -4,13 +4,13 @@
#include <config/FpConfig.hpp> #include <config/FpConfig.hpp>
namespace Svc { namespace Svc {
namespace FileManagerConfig { namespace FileManagerConfig {
//! Number of directory entries to process per rate group tick //! Number of directory entries to process per rate group tick
//! Higher values = faster directory listing but more events per tick //! Higher values = faster directory listing but more events per tick
//! Lower values = slower directory listing but bounded event rate //! Lower values = slower directory listing but bounded event rate
//! Default: 1 //! Default: 1
static constexpr U32 FILES_PER_RATE_TICK = 1; static constexpr U32 FILES_PER_RATE_TICK = 1;
} } // namespace FileManagerConfig
} } // namespace Svc
#endif #endif

View File

@ -11,12 +11,11 @@
#ifndef FPCONFIG_H_ #ifndef FPCONFIG_H_
#define FPCONFIG_H_ #define FPCONFIG_H_
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <Platform/PlatformTypes.h>
#include <Fw/Types/BasicTypes.h> #include <Fw/Types/BasicTypes.h>
#include <Platform/PlatformTypes.h>
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Type aliases // Type aliases
@ -90,8 +89,8 @@ extern "C" {
// This generates code to connect to serialized ports // This generates code to connect to serialized ports
#ifndef FW_PORT_SERIALIZATION #ifndef FW_PORT_SERIALIZATION
#define FW_PORT_SERIALIZATION \ #define FW_PORT_SERIALIZATION \
1 //!< Indicates whether there is code in ports to serialize the call (more code, but ability to serialize calls 1 //!< Indicates whether there is code in ports to serialize the call (more code, but ability to serialize
//!< for multi-note systems) //!< calls for multi-note systems)
#endif #endif
// Component Facilities // Component Facilities
@ -333,7 +332,7 @@ extern "C" {
// *** NOTE configuration checks are in Fw/Cfg/ConfigCheck.cpp in order to have // *** NOTE configuration checks are in Fw/Cfg/ConfigCheck.cpp in order to have
// the type definitions in Fw/Types/BasicTypes available. // the type definitions in Fw/Types/BasicTypes available.
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -23,5 +23,4 @@ enum IpCfg {
}; };
static const Fw::TimeInterval SOCKET_RETRY_INTERVAL = Fw::TimeInterval(1, 0); static const Fw::TimeInterval SOCKET_RETRY_INTERVAL = Fw::TimeInterval(1, 0);
#endif // REF_IPCFG_HPP
#endif //REF_IPCFG_HPP

View File

@ -2,7 +2,7 @@
#define Config_PassiveTextLoggerCfg_HPP_ #define Config_PassiveTextLoggerCfg_HPP_
enum { enum {
PASSIVE_TEXT_LOGGER_ID_FILTER_SIZE = 25, //!< Size of event ID filter PASSIVE_TEXT_LOGGER_ID_FILTER_SIZE = 25, //!< Size of event ID filter
}; };
#endif /* Config_PassiveTextLoggerCfg_HPP_ */ #endif /* Config_PassiveTextLoggerCfg_HPP_ */

View File

@ -11,13 +11,12 @@
// Anonymous namespace for configuration parameters // Anonymous namespace for configuration parameters
namespace { namespace {
enum { enum {
PRMDB_NUM_DB_ENTRIES = 25, // !< Number of entries in the parameter database PRMDB_NUM_DB_ENTRIES = 25, // !< Number of entries in the parameter database
PRMDB_ENTRY_DELIMITER = 0xA5 // !< Byte value that should precede each parameter in file; sanity check against file integrity. Should match ground system. PRMDB_ENTRY_DELIMITER = 0xA5 // !< Byte value that should precede each parameter in file; sanity check against
}; // file integrity. Should match ground system.
};
} }
#endif /* PRMDB_PRMDBLIMPLCFG_HPP_ */ #endif /* PRMDB_PRMDBLIMPLCFG_HPP_ */

View File

@ -8,10 +8,6 @@
#ifndef PRMDB_TEST_UT_PRMDBIMPLTESTERCFG_HPP_ #ifndef PRMDB_TEST_UT_PRMDBIMPLTESTERCFG_HPP_
#define PRMDB_TEST_UT_PRMDBIMPLTESTERCFG_HPP_ #define PRMDB_TEST_UT_PRMDBIMPLTESTERCFG_HPP_
enum { enum { PRMDB_IMPL_TESTER_MAX_READ_BUFFER = 256 };
PRMDB_IMPL_TESTER_MAX_READ_BUFFER = 256
};
#endif /* PRMDB_TEST_UT_PRMDBIMPLTESTERCFG_HPP_ */ #endif /* PRMDB_TEST_UT_PRMDBIMPLTESTERCFG_HPP_ */

View File

@ -8,10 +8,7 @@
#define SVC_STATIC_MEMORY_CFG_HPP_ #define SVC_STATIC_MEMORY_CFG_HPP_
namespace Svc { namespace Svc {
enum StaticMemoryConfig { enum StaticMemoryConfig { STATIC_MEMORY_ALLOCATION_SIZE = 2048 };
STATIC_MEMORY_ALLOCATION_SIZE = 2048
};
} }
#endif #endif

View File

@ -15,7 +15,6 @@
// Anonymous namespace for configuration parameters // Anonymous namespace for configuration parameters
// The parameters below provide for tuning of the hash function used to // The parameters below provide for tuning of the hash function used to
// write and read entries in the database. The has function is very simple; // write and read entries in the database. The has function is very simple;
// It first takes the telemetry ID and does a modulo computation with // It first takes the telemetry ID and does a modulo computation with
@ -41,16 +40,15 @@
namespace { namespace {
enum { enum {
TLMCHAN_NUM_TLM_HASH_SLOTS = 15, // !< Number of slots in the hash table. TLMCHAN_NUM_TLM_HASH_SLOTS = 15, // !< Number of slots in the hash table.
// Works best when set to about twice the number of components producing telemetry // Works best when set to about twice the number of components producing telemetry
TLMCHAN_HASH_MOD_VALUE = 99, // !< The modulo value of the hashing function. TLMCHAN_HASH_MOD_VALUE = 99, // !< The modulo value of the hashing function.
// Should be set to a little below the ID gaps to spread the entries around // Should be set to a little below the ID gaps to spread the entries around
TLMCHAN_HASH_BUCKETS = 500 // !< Buckets assignable to a hash slot.
// Buckets must be >= number of telemetry channels in system
};
TLMCHAN_HASH_BUCKETS = 500 // !< Buckets assignable to a hash slot.
// Buckets must be >= number of telemetry channels in system
};
} }

View File

@ -17,18 +17,17 @@
namespace Svc { namespace Svc {
static const FwChanIdType MAX_PACKETIZER_PACKETS = 200; static const FwChanIdType MAX_PACKETIZER_PACKETS = 200;
static const FwChanIdType TLMPACKETIZER_NUM_TLM_HASH_SLOTS =
15; // !< Number of slots in the hash table.
// Works best when set to about twice the number of components producing telemetry
static const FwChanIdType TLMPACKETIZER_HASH_MOD_VALUE =
99; // !< The modulo value of the hashing function.
// Should be set to a little below the ID gaps to spread the entries around
static const FwChanIdType TLMPACKETIZER_HASH_BUCKETS = // Works best when set to about twice the number of components producing telemetry
1000; // !< Buckets assignable to a hash slot. static const FwChanIdType TLMPACKETIZER_NUM_TLM_HASH_SLOTS = 15; // !< Number of slots in the hash table.
// Buckets must be >= number of telemetry channels in system
static const FwChanIdType TLMPACKETIZER_MAX_MISSING_TLM_CHECK = // Should be set to a little below the ID gaps to spread the entries around
25; // !< Maximum number of missing telemetry channel checks static const FwChanIdType TLMPACKETIZER_HASH_MOD_VALUE = 99; // !< The modulo value of the hashing function.
// Buckets must be >= number of telemetry channels in system
static const FwChanIdType TLMPACKETIZER_HASH_BUCKETS = 1000; // !< Buckets assignable to a hash slot.
static const FwChanIdType TLMPACKETIZER_MAX_MISSING_TLM_CHECK = 25; // !< Max number of missing channel checks
// packet update mode // packet update mode
enum PacketUpdateMode { enum PacketUpdateMode {