Skip to content
Snippets Groups Projects
Commit c78942f4 authored by thodkatz's avatar thodkatz
Browse files

Preliminary implementation of time format

parent 4d087f39
No related branches found
No related tags found
No related merge requests found
...@@ -3,6 +3,25 @@ ...@@ -3,6 +3,25 @@
<option name="RIGHT_MARGIN" value="100" /> <option name="RIGHT_MARGIN" value="100" />
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" /> <option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
<Objective-C-extensions> <Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions> <extensions>
<pair source="cpp" header="hpp" fileNamingConvention="PASCAL_CASE" /> <pair source="cpp" header="hpp" fileNamingConvention="PASCAL_CASE" />
<pair source="c" header="h" fileNamingConvention="NONE" /> <pair source="c" header="h" fileNamingConvention="NONE" />
......
...@@ -17,14 +17,13 @@ add_custom_target(check ...@@ -17,14 +17,13 @@ add_custom_target(check
add_library(common OBJECT add_library(common OBJECT
src/ErrorHandler.cpp src/ErrorHandler.cpp
src/Message.cpp src/Message.cpp
src/MessageParser.cpp src/MessageParser.cpp
src/Helpers/CRCHelper.cpp src/Helpers/CRCHelper.cpp
src/Services/EventReportService.cpp src/Services/EventReportService.cpp
src/Services/MemoryManagementService.cpp src/Services/MemoryManagementService.cpp
src/Services/ParameterService.cpp src/Services/ParameterService.cpp
src/Services/RequestVerificationService.cpp src/Services/RequestVerificationService.cpp
src/Services/TestService.cpp src/Services/TestService.cpp src/Helpers/TimeHelper.cpp)
)
# Specify the .cpp files for the executables # Specify the .cpp files for the executables
add_executable(ecss_services add_executable(ecss_services
...@@ -42,7 +41,7 @@ IF (EXISTS "${PROJECT_SOURCE_DIR}/lib/Catch2/CMakeLists.txt") ...@@ -42,7 +41,7 @@ IF (EXISTS "${PROJECT_SOURCE_DIR}/lib/Catch2/CMakeLists.txt")
add_executable(tests add_executable(tests
$<TARGET_OBJECTS:common> $<TARGET_OBJECTS:common>
${test_main_SRC} ${test_main_SRC}
${test_SRC}) ${test_SRC} test/Helpers/TimeHelper.cpp)
target_link_libraries(tests Catch2::Catch2) target_link_libraries(tests Catch2::Catch2)
ENDIF () ENDIF ()
#ifndef ECSS_SERVICES_TIMEHELPER_HPP
#define ECSS_SERVICES_TIMEHELPER_HPP
#include <cstdint>
#include <Message.hpp>
/**
* This class formats the spacecraft time and cooperates closely with the ST[09] time management.
* The ECSS standard supports two time formats:the CUC and CSD that are described in
* CCSDS 301.0-B-4 standard
* The chosen time format is CUC. The reasons for this selection are the followings:
* 1)It is more flexible from the CSD. The designer is free to decide how much memory will use
* for the time unit and what that time unit will be(seconds, minutes, hours etc.).
* 2)It can use TAI(international atomic time) as reference time scale. So there is not need
* to worry about leap seconds(code UTC-based)
*
* Note: The implementation of the time formats are in general RTC-dependent. First, we need to
* get the time data from the RTC, so we know what time is it and then format it!
*/
class TimeHelper {
public:
/**
* Implement the CUC time format
*
* @details The CUC time format consists of two main fields: the time code preamble field
* (P-field) and the time specification field(T-field).The P-Field is the metadata for the
* T-Field. The T-Field contains the value of the time unit and the designer decides what the
* time unit will be, so this is a subject for discussion. The recommended time unit from the
* standard is the second and it is probably the best solution for accuracy.
* @param seconds the seconds provided from the RTC. This function in general should have
* parameters corresponding with the RTC. For the time being we assume that the RTC has a
* 32-bit counter that counts seconds(the RTC in Nucleo F103RB!)
* @param data it is needed to access the data-member data of class Message. Remember this
* function will be used from the ST[09] service to generate time reports
* @todo check if we need milliseconds(fractions of the time unit)
* @todo the time unit should be declared in the metadata. But how?
* @todo check if we need to define other epoch than the 1 January 1958
* @todo time security for critical time operations
*/
static void implementCUCTimeFormat(uint32_t seconds, Message &data);
};
#endif //ECSS_SERVICES_TIMEHELPER_HPP
Subproject commit 77f29c2f1cde8bd2e17f06cc04092b990d2acc2c Subproject commit 62460fafe6b54c3173bc5cbc46d05a5f071017ff
#include "Helpers/TimeHelper.hpp"
void TimeHelper::implementCUCTimeFormat(uint32_t seconds, Message &data) {
// the total number of octets including the p-field (1 octet) and the 4 time units is 5
// define the P-field
uint8_t bit0 = 0; // P-field extension(‘zero’: no extension; ‘one’: field is extended)
uint8_t bits1_3 = 1; // Time code identification ( 001 -> 1958 January 1 epoch )
uint8_t bits4_5 = 4 - 1; // Number of octets of the basic time unit minus one
uint8_t bits6_7 = 0; // Number of octets of the fractional time unit
// just a reminder to be careful with the assigned values
assert(bit0 < 2);
assert(bits1_3 < 16);
assert(bits4_5 < 4);
assert(bits6_7 < 4);
/**
* Define the T-field, the seconds passed from the defined epoch 1 January 1958
* We use 4 octets(32 bits)for the time unit(seconds) because 32 bits for the seconds are enough
* to count 136 years! But if we use 24 bits for the seconds then it will count 0,5 years and
* this isn't enough. Remember we can use only integers numbers of octets for the time unit
* (second)
*
* @todo the implementation of the total seconds depends on the structure of the RTC
*/
uint32_t totalSeconds = seconds;
// define data
data.appendBits(1, bit0);
data.appendBits(3, bits1_3);
data.appendBits(2, bits4_5);
data.appendBits(2, bits6_7);
data.appendWord(totalSeconds);
}
#include <iostream> #include <iostream>
#include "Helpers/CRCHelper.hpp" #include "Helpers/CRCHelper.hpp"
#include "Helpers/TimeHelper.hpp"
#include "Services/TestService.hpp" #include "Services/TestService.hpp"
#include "Services/ParameterService.hpp" #include "Services/ParameterService.hpp"
#include "Services/RequestVerificationService.hpp" #include "Services/RequestVerificationService.hpp"
...@@ -155,5 +156,10 @@ int main() { ...@@ -155,5 +156,10 @@ int main() {
errorMessage.appendBits(2, 7); errorMessage.appendBits(2, 7);
errorMessage.appendByte(15); errorMessage.appendByte(15);
// TimeHelper test
Message receive = Message(9, 2, Message::TC, 1); // random values
TimeHelper::implementCUCTimeFormat(60, receive);
for (int i = 0; i < 5; i++)
std::cout << static_cast<int>(receive.data[i]) << " ";
return 0; return 0;
} }
#include "catch2/catch.hpp"
#include "Helpers/TimeHelper.hpp"
TEST_CASE("Time format implementation", "[CUC]") {
// a very simple test for the TimeHelper. Check the pField and the tField
Message receive = Message(9, 2, Message::TC, 1); // random values
TimeHelper::implementCUCTimeFormat(60, receive);
// the pField as defined in the implementCUCTimeFormat()
CHECK(receive.readBits(1) == 0);
CHECK(receive.readBits(3) == 1);
CHECK(receive.readBits(2) == 3);
CHECK(receive.readBits(2) == 0);
// the tField as defined in the implementCUCTimeFormat()
CHECK(receive.readWord() == 60);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment