Skip to content

Commit be0fabc

Browse files
committed
Final start stuff
1 parent 0beef0a commit be0fabc

File tree

3 files changed

+85
-20
lines changed

3 files changed

+85
-20
lines changed

FprimeZephyrReference/Components/StartupManager/StartupManager.cpp

Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ StartupManager ::~StartupManager() {}
2424
FwSizeType StartupManager ::update_boot_count() {
2525
// Read the boot count file path from parameter and assert that it is either valid or the default value
2626
Fw::ParamValid is_valid;
27-
auto boot_count_file = this->paramGet_BOOT_COUNT_FILE(0, is_valid);
27+
auto boot_count_file = this->paramGet_BOOT_COUNT_FILE(is_valid);
2828
FW_ASSERT(is_valid == Fw::ParamValid::VALID || is_valid == Fw::ParamValid::DEFAULT);
2929

3030
// Open the boot count file and read the current boot count
@@ -47,7 +47,8 @@ FwSizeType StartupManager ::update_boot_count() {
4747
}
4848
file.close();
4949
}
50-
boot_count = boot_count + 1;
50+
// Boot count of zero is a flag value, so ensure a minimum boot count of 1
51+
boot_count = FW_MAX(1, boot_count + 1);
5152

5253
// Open the file for writing the boot count
5354
status = file.open(boot_count_file.toChar(), Os::File::OPEN_CREATE, Os::File::OVERWRITE);
@@ -64,25 +65,80 @@ FwSizeType StartupManager ::update_boot_count() {
6465
return boot_count;
6566
}
6667

67-
void StartupManager ::run_handler(FwIndexType portNum, U32 context) {
68-
// On the first call, update the boot count
69-
if (this->m_boot_count == 0) {
70-
this->m_boot_count = this->update_boot_count();
71-
}
68+
Fw::Time StartupManager ::get_quiescence_start() {
69+
// Read the quiescence start time file path from parameter and assert that it is either valid or the default value
7270
Fw::ParamValid is_valid;
73-
while (this->m_boot_count == 1 && armed) {
74-
armed = this->paramGet_ARMED(is_valid);
75-
}
7671

77-
char buffer[Fw::TimeIntervalValue::SERIALIZED_SIZE];
72+
auto time_file = this->paramGet_QUIESCENCE_START_FILE(is_valid);
73+
FW_ASSERT(is_valid == Fw::ParamValid::VALID || is_valid == Fw::ParamValid::DEFAULT);
74+
75+
// Open the boot count file and read the current boot count
76+
Fw::Time time;
77+
Os::File file;
78+
Os::File::Status status = file.open(time_file.toChar(), Os::File::OPEN_READ);
79+
U8 buffer[Fw::Time::SERIALIZED_SIZE];
80+
81+
// If the file read ok, then we read the quiescence start time.
82+
if (status == Os::File::OP_OK) {
83+
FwSizeType size = sizeof(buffer);
84+
status = file.read(buffer, size);
85+
if (status == Os::File::OP_OK) {
86+
Fw::ExternalSerializeBuffer buffer_obj(buffer, sizeof(buffer));
87+
Fw::SerializeStatus serialization_status = buffer_obj.deserializeTo(time);
88+
if (serialization_status != Fw::SerializeStatus::FW_SERIALIZE_OK) {
89+
time = this->getTime(); // Default to current time if deserialization fails
90+
}
91+
}
92+
(void)file.close();
93+
}
94+
// Write quiescence start time if read failed
95+
if (status != Os::File::OP_OK) {
96+
FwSizeType size = sizeof(buffer);
97+
time = this->getTime();
98+
status = file.open(time_file.toChar(), Os::File::OPEN_CREATE, Os::File::OVERWRITE);
99+
if (status == Os::File::OP_OK) {
100+
Fw::ExternalSerializeBuffer buffer_obj(buffer, sizeof(Fw::Time::SERIALIZED_SIZE));
101+
Fw::SerializeStatus serialize_status = buffer_obj.serializeFrom(time);
102+
if (serialize_status == Fw::SerializeStatus::FW_SERIALIZE_OK) {
103+
(void)file.write(buffer, size);
104+
}
105+
}
106+
(void)file.close();
107+
}
108+
return time;
109+
}
78110

79-
Fw::ParamString bootCount =
111+
void StartupManager ::run_handler(FwIndexType portNum, U32 context) {
112+
Fw::ParamValid is_valid;
80113

81-
Os::File file;
114+
// On the first call, update the boot count, set the quiescence start time, and dispatch the start-up sequence
115+
if (this->m_boot_count == 0) {
116+
this->m_boot_count = this->update_boot_count();
117+
this->m_quiescence_start = this->get_quiescence_start();
82118

83-
Os::File::Status status = file.open(, Os::File::OPEN_READ);
119+
Fw::ParamString first_sequence = this->paramGet_STARTUP_SEQUENCE_FILE(is_valid);
120+
FW_ASSERT(is_valid == Fw::ParamValid::VALID || is_valid == Fw::ParamValid::DEFAULT);
121+
this->runSequence_out(0, first_sequence);
122+
}
84123

85-
this->cmdResponse_out(this->m_stored_opcode, this->m_stored_sequence, Fw::CmdResponse::OK);
124+
// Are we waiting for quiescence?
125+
if (this->m_waiting) {
126+
// Check if the system is armed or if this is not the first boot. In both cases, we skip waiting.
127+
bool armed = this->paramGet_ARMED(is_valid);
128+
FW_ASSERT(is_valid == Fw::ParamValid::VALID || is_valid == Fw::ParamValid::DEFAULT);
129+
130+
Fw::TimeIntervalValue quiescence_period = this->paramGet_QUIESCENCE_TIME(is_valid);
131+
Fw::Time quiescence_interval(quiescence_period.get_seconds(), quiescence_period.get_useconds());
132+
FW_ASSERT(is_valid == Fw::ParamValid::VALID || is_valid == Fw::ParamValid::DEFAULT);
133+
Fw::Time end_time = Fw::Time::add(this->m_quiescence_start, quiescence_interval);
134+
135+
// If not armed or this is not the first boot, we skip waiting
136+
if (!armed || end_time <= this->getTime()) {
137+
this->m_waiting = false;
138+
this->cmdResponse_out(this->m_stored_opcode, this->m_stored_sequence, Fw::CmdResponse::OK);
139+
}
140+
}
141+
this->tlmWrite_BootCount(this->m_boot_count);
86142
}
87143

88144
// ----------------------------------------------------------------------
@@ -92,6 +148,7 @@ void StartupManager ::run_handler(FwIndexType portNum, U32 context) {
92148
void StartupManager ::WAIT_FOR_QUIESCENCE_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
93149
this->m_stored_opcode = opCode;
94150
this->m_stored_sequence = cmdSeq;
151+
this->m_waiting = true;
95152
}
96153

97154
} // namespace Components

FprimeZephyrReference/Components/StartupManager/StartupManager.fpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,25 @@ module Components {
55
sync input port run: Svc.Sched
66

77
@ Port for sending sequence dispatches
8-
output port seqRunIn: Svc.CmdSeqIn
8+
output port runSequence: Svc.CmdSeqIn
99

1010
@ Command to wait for system quiescence before proceeding with start-up
1111
sync command WAIT_FOR_QUIESCENCE()
1212

13+
@ Telemetry for boot count
14+
telemetry BootCount: FwSizeType update on change
15+
1316
@ Whether the start-up manager is armed to wait for quiescence
1417
param ARMED: bool default true
1518

1619
@ Time to wait before allowing start-up to proceed
1720
param QUIESCENCE_TIME: Fw.TimeIntervalValue default {seconds = 45 * 60, useconds = 0}
1821

1922
@ File storing the quiescence start time
20-
param QUIESCENCE_START_TIME: string default "/quiescence_start.bin"
23+
param QUIESCENCE_START_FILE: string default "/quiescence_start.bin"
2124

2225
@ Path to the start-up sequence file
23-
param STARTUP_SEQUENCE: string default "/startup.bin"
26+
param STARTUP_SEQUENCE_FILE: string default "/startup.bin"
2427

2528
@ File to store the boot count
2629
param BOOT_COUNT_FILE: string default "/boot_count.bin"
@@ -46,6 +49,7 @@ module Components {
4649
@ Port for sending command responses
4750
command resp port cmdResponseOut
4851

49-
52+
@ Port for sending telemetry channels to downlink
53+
telemetry port tlmOut
5054
}
5155
}

FprimeZephyrReference/Components/StartupManager/StartupManager.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#ifndef Components_StartupManager_HPP
88
#define Components_StartupManager_HPP
99

10+
#include <atomic>
1011
#include "FprimeZephyrReference/Components/StartupManager/StartupManagerComponentAc.hpp"
1112

1213
namespace Components {
@@ -27,6 +28,9 @@ class StartupManager final : public StartupManagerComponentBase {
2728
// Update and return the boot count
2829
FwSizeType update_boot_count();
2930

31+
// Get the quiescence start time
32+
Fw::Time get_quiescence_start();
33+
3034
private:
3135
// ----------------------------------------------------------------------
3236
// Handler implementations for typed input ports
@@ -56,7 +60,7 @@ class StartupManager final : public StartupManagerComponentBase {
5660
FwOpcodeType m_stored_opcode; //!< Stored opcode for delayed response
5761
FwSizeType m_boot_count; //!< Current boot count
5862
U32 m_stored_sequence; //!< Stored sequence number for delayed response
59-
bool m_first; //!< Indicates if first run_handler call
63+
std::atomic<bool> m_waiting; //!< Indicates if waiting for quiescence
6064
};
6165

6266
} // namespace Components

0 commit comments

Comments
 (0)