mirror of
https://github.com/nasa/fprime.git
synced 2025-12-10 00:44:37 -06:00
Finish code formatting (#4134)
This commit is contained in:
parent
c8e2d44877
commit
ba65039fff
5
.github/workflows/format-check.yml
vendored
5
.github/workflows/format-check.yml
vendored
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
// \title CFDP/Checksum/GTest/Checksums.cpp
|
// \title CFDP/Checksum/GTest/Checksums.cpp
|
||||||
// \author bocchino
|
// \author bocchino
|
||||||
// \brief cpp file for CFDP Checksum gtest utilities
|
// \brief cpp file for CFDP Checksum gtest utilities
|
||||||
@ -7,26 +7,21 @@
|
|||||||
// Copyright (C) 2016, California Institute of Technology.
|
// Copyright (C) 2016, California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
// acknowledged.
|
// acknowledged.
|
||||||
//
|
//
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include "CFDP/Checksum/GTest/Checksums.hpp"
|
#include "CFDP/Checksum/GTest/Checksums.hpp"
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
// \title CFDP/Checksum/GTest/Checksums.hpp
|
// \title CFDP/Checksum/GTest/Checksums.hpp
|
||||||
// \author bocchino
|
// \author bocchino
|
||||||
// \brief hpp file for CFDP Checksum gtest utilities
|
// \brief hpp file for CFDP Checksum gtest utilities
|
||||||
@ -7,8 +7,8 @@
|
|||||||
// Copyright (C) 2016 California Institute of Technology.
|
// Copyright (C) 2016 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
// acknowledged.
|
// acknowledged.
|
||||||
//
|
//
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef GTest_CFDP_Checksums_HPP
|
#ifndef GTest_CFDP_Checksums_HPP
|
||||||
#define GTest_CFDP_Checksums_HPP
|
#define GTest_CFDP_Checksums_HPP
|
||||||
@ -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
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Main.cpp
|
// Main.cpp
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
*
|
*
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace Ref {
|
namespace Ref {
|
||||||
|
|
||||||
typedef PingReceiverComponentImpl PingReceiver;
|
typedef PingReceiverComponentImpl PingReceiver;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace Ref {
|
namespace Ref {
|
||||||
|
|
||||||
typedef RecvBuffImpl RecvBuff;
|
typedef RecvBuffImpl RecvBuff;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace Ref {
|
namespace Ref {
|
||||||
|
|
||||||
typedef SendBuffImpl SendBuff;
|
typedef SendBuffImpl SendBuff;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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();
|
||||||
|
|
||||||
|
|||||||
@ -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
|
*
|
||||||
* that implement whatever timers are available for that platform in place of Svc/LinuxTimer.
|
* For embedded Linux, this could be used to drive the system rate groups. For other embedded systems, projects should
|
||||||
|
* 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.
|
||||||
*
|
*
|
||||||
@ -80,11 +81,11 @@ void teardownTopology(const TopologyState& state);
|
|||||||
void startRateGroups(const Fw::TimeInterval& interval);
|
void startRateGroups(const Fw::TimeInterval& interval);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief stop the rate groups
|
* \brief stop the rate groups
|
||||||
*
|
*
|
||||||
* This stops the cycle started by startRateGroups.
|
* This stops the cycle started by startRateGroups.
|
||||||
*/
|
*/
|
||||||
void stopRateGroups();
|
void stopRateGroups();
|
||||||
|
|
||||||
} // namespace Ref
|
} // namespace Ref
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
// \title CRCChecker.hpp
|
// \title CRCChecker.hpp
|
||||||
// \author ortega
|
// \author ortega
|
||||||
// \brief hpp file for a crc32 checker
|
// \brief hpp file for a crc32 checker
|
||||||
@ -7,7 +7,7 @@
|
|||||||
// Copyright 2009-2020, by the California Institute of Technology.
|
// Copyright 2009-2020, by the California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
// acknowledged.
|
// acknowledged.
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef CRC_CHECKER_HPP
|
#ifndef CRC_CHECKER_HPP
|
||||||
#define CRC_CHECKER_HPP
|
#define CRC_CHECKER_HPP
|
||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
// 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
|
||||||
//! implementation. This is required.
|
//! implementation. This is required.
|
||||||
#ifndef HASH_HANDLE_TYPE
|
#ifndef HASH_HANDLE_TYPE
|
||||||
#define HASH_HANDLE_TYPE U32
|
#define HASH_HANDLE_TYPE U32
|
||||||
@ -18,7 +18,7 @@ extern "C" {
|
|||||||
#define HASH_DIGEST_LENGTH (4)
|
#define HASH_DIGEST_LENGTH (4)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Define the string to be used as a filename
|
//! Define the string to be used as a filename
|
||||||
//! extension (ie. file.txt.SHA256) for this
|
//! extension (ie. file.txt.SHA256) for this
|
||||||
//! implementation. This is required.
|
//! implementation. This is required.
|
||||||
#ifndef HASH_EXTENSION_STRING
|
#ifndef HASH_EXTENSION_STRING
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
// clang-format off
|
||||||
#include "lib_crc.h"
|
#include "lib_crc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
// clang-format off
|
||||||
/*******************************************************************\
|
/*******************************************************************\
|
||||||
* *
|
* *
|
||||||
* Library : lib_crc *
|
* Library : lib_crc *
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
// Include the sha library:
|
// Include the sha library:
|
||||||
#include <Utils/Hash/openssl/sha.h>
|
#include <Utils/Hash/openssl/sha.h>
|
||||||
|
|
||||||
//! Define the hash handle type for this
|
//! Define the hash handle type for this
|
||||||
//! implementation. This is required.
|
//! implementation. This is required.
|
||||||
#ifndef HASH_HANDLE_TYPE
|
#ifndef HASH_HANDLE_TYPE
|
||||||
#define HASH_HANDLE_TYPE SHA256_CTX
|
#define HASH_HANDLE_TYPE SHA256_CTX
|
||||||
@ -16,7 +16,7 @@
|
|||||||
#define HASH_DIGEST_LENGTH (SHA256_DIGEST_LENGTH)
|
#define HASH_DIGEST_LENGTH (SHA256_DIGEST_LENGTH)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//! Define the string to be used as a filename
|
//! Define the string to be used as a filename
|
||||||
//! extension (ie. file.txt.SHA256) for this
|
//! extension (ie. file.txt.SHA256) for this
|
||||||
//! implementation. This is required.
|
//! implementation. This is required.
|
||||||
#ifndef HASH_EXTENSION_STRING
|
#ifndef HASH_EXTENSION_STRING
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
// \title RateLimiter.cpp
|
// \title RateLimiter.cpp
|
||||||
// \author vwong
|
// \author vwong
|
||||||
// \brief cpp file for a rate limiter utility class
|
// \brief cpp file for a rate limiter utility class
|
||||||
@ -7,89 +7,52 @@
|
|||||||
// Copyright (C) 2009-2020 California Institute of Technology.
|
// Copyright (C) 2009-2020 California Institute of Technology.
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
// acknowledged.
|
// acknowledged.
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#include <Utils/RateLimiter.hpp>
|
#include <Utils/RateLimiter.hpp>
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
// \title RateLimiter.hpp
|
// \title RateLimiter.hpp
|
||||||
// \author vwong
|
// \author vwong
|
||||||
// \brief hpp file for a rate limiter utility class
|
// \brief hpp file for a rate limiter utility class
|
||||||
@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
// acknowledged.
|
// acknowledged.
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef RateLimiter_HPP
|
#ifndef RateLimiter_HPP
|
||||||
#define RateLimiter_HPP
|
#define RateLimiter_HPP
|
||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
// \title TokenBucket.hpp
|
// \title TokenBucket.hpp
|
||||||
// \author vwong
|
// \author vwong
|
||||||
// \brief hpp file for a rate limiter utility class
|
// \brief hpp file for a rate limiter utility class
|
||||||
@ -9,7 +9,7 @@
|
|||||||
//
|
//
|
||||||
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
// ALL RIGHTS RESERVED. United States Government Sponsorship
|
||||||
// acknowledged.
|
// acknowledged.
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
#ifndef TokenBucket_HPP
|
#ifndef TokenBucket_HPP
|
||||||
#define TokenBucket_HPP
|
#define TokenBucket_HPP
|
||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -6,7 +6,4 @@
|
|||||||
|
|
||||||
#include "CircularBufferTester.hpp"
|
#include "CircularBufferTester.hpp"
|
||||||
|
|
||||||
|
namespace Types {}
|
||||||
namespace Types {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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__
|
|
||||||
|
|||||||
@ -6,10 +6,9 @@
|
|||||||
#ifndef CONFIG_CRC_CHECKER_CONFIG_HPP
|
#ifndef CONFIG_CRC_CHECKER_CONFIG_HPP
|
||||||
#define CONFIG_CRC_CHECKER_CONFIG_HPP
|
#define CONFIG_CRC_CHECKER_CONFIG_HPP
|
||||||
|
|
||||||
#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;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user