Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
0eb6b7cccb | |||
74ee291983 | |||
a146c34140 | |||
61ced11766 | |||
468fb096c9 | |||
4a2dd19a73 | |||
2658cabc9d | |||
dc83061f80 | |||
00da51b6a2 | |||
f846a18b33 | |||
ab588b4844 | |||
d12dca183d | |||
701ecbd182 | |||
bdd2b23ec3 | |||
d70245b56a | |||
9097a3f3c7 | |||
e05d9d4b2a | |||
07572ab3a0 | |||
304aabc336 | |||
07e8f95a31 | |||
babea226ab | |||
8c24a7310d | |||
8f5982fd72 | |||
611a2c0b45 | |||
61e6b09704 | |||
a9a0266a84 | |||
b7e6315be7 | |||
740275f57a | |||
58dd53def8 | |||
ddbe30f832 | |||
680d496b28 | |||
9c163419b2 | |||
f4fedd20c9 | |||
016fab105e | |||
767a0eda30 | |||
f2c71d962a | |||
7bf880a29f | |||
0185691dba | |||
9997aa5470 | |||
c1ccfe66eb | |||
ae9f43c707 | |||
143002de48 | |||
d439aedee7 | |||
b8d010cd39 |
49
CHANGELOG.md
49
CHANGELOG.md
@ -16,6 +16,55 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v2.0.3] 2023-04-17
|
||||
|
||||
- eive-tmtc: v3.1.1
|
||||
|
||||
## Fixed
|
||||
|
||||
- Fixed shadowing within the `SafeCtrl`, which prevented actuator commands to be calculated during
|
||||
eclipse phase.
|
||||
- EM build idle mode fixes for RW dummy.
|
||||
|
||||
## Added
|
||||
|
||||
- Add `MGT_OVERHEATING` event and fallback to system SAFE mode if the MGT is overheating for
|
||||
whatever reason.
|
||||
|
||||
## Changed
|
||||
|
||||
- Low-pass filters can no longer be executed if no actual data is available.
|
||||
|
||||
# [v2.0.2] 2023-04-16
|
||||
|
||||
- Bump patch version to 2.
|
||||
|
||||
# [v2.0.1] 2023-04-16
|
||||
|
||||
- eive-tmtc: v3.1.0
|
||||
|
||||
# [v2.0.0] 2023-04-16
|
||||
|
||||
This is the version which will fly on the satellite for the initial launch phase.
|
||||
|
||||
- q7s-package: v2.5.0
|
||||
- eive-tmtc: v3.0.0
|
||||
- `wire` library is now on version v10.7 as well.
|
||||
|
||||
## Added
|
||||
|
||||
- Added `mv`, `cp` and `rm` action helpers for the core controller for common filesystem operations.
|
||||
- Extended directory listing helpers. There is now a directory listing helper which dumps the
|
||||
directory listing as an action data reply immediately. For smaller directory listings, this
|
||||
allows a listing without requiring a separate file downlink (which also has not been implemented
|
||||
yet)
|
||||
|
||||
## Changed
|
||||
|
||||
- The directory listing action commands now allow compressing of either the target output file
|
||||
for the directory listing into file action command, or compression in the helper which dumps
|
||||
the directory listing directly.
|
||||
|
||||
# [v1.45.0] 2023-04-14
|
||||
|
||||
- q7s-package: v2.5.0
|
||||
|
@ -9,9 +9,9 @@
|
||||
# ##############################################################################
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(OBSW_VERSION_MAJOR 1)
|
||||
set(OBSW_VERSION_MINOR 45)
|
||||
set(OBSW_VERSION_REVISION 0)
|
||||
set(OBSW_VERSION_MAJOR 2)
|
||||
set(OBSW_VERSION_MINOR 0)
|
||||
set(OBSW_VERSION_REVISION 3)
|
||||
|
||||
# set(CMAKE_VERBOSE TRUE)
|
||||
|
||||
|
6
automation/Jenkinsfile
vendored
6
automation/Jenkinsfile
vendored
@ -22,7 +22,7 @@ pipeline {
|
||||
steps {
|
||||
dir(BUILDDIR_Q7S) {
|
||||
sh 'cmake -DTGT_BSP="arm/q7s" -DCMAKE_BUILD_TYPE=Debug ..'
|
||||
sh 'cmake --build . -j6'
|
||||
sh 'cmake --build . -j8'
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -30,7 +30,7 @@ pipeline {
|
||||
steps {
|
||||
dir(BUILDDIR_Q7S_EM) {
|
||||
sh 'cmake -DTGT_BSP="arm/q7s" -DEIVE_Q7S_EM=ON -DCMAKE_BUILD_TYPE=Debug ..'
|
||||
sh 'cmake --build . -j6'
|
||||
sh 'cmake --build . -j8'
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -38,7 +38,7 @@ pipeline {
|
||||
steps {
|
||||
dir(BUILDDIR_LINUX) {
|
||||
sh 'cmake ..'
|
||||
sh 'cmake --build . -j6'
|
||||
sh 'cmake --build . -j8'
|
||||
sh './eive-unittest'
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 290 translations.
|
||||
* @brief Auto-generated event translation file. Contains 291 translations.
|
||||
* @details
|
||||
* Generated on: 2023-04-14 20:23:17
|
||||
* Generated on: 2023-04-17 11:34:19
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -280,6 +280,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
|
||||
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
||||
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
||||
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
||||
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||
@ -848,6 +849,8 @@ const char *translateEvents(Event event) {
|
||||
return PCDU_SYSTEM_OVERHEATING_STRING;
|
||||
case (14107):
|
||||
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
||||
case (14108):
|
||||
return MGT_OVERHEATING_STRING;
|
||||
case (14201):
|
||||
return TX_TIMER_EXPIRED_STRING;
|
||||
case (14202):
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 171 translations.
|
||||
* Generated on: 2023-04-14 20:23:17
|
||||
* Generated on: 2023-04-17 11:34:19
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
|
@ -233,6 +233,84 @@ ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_
|
||||
case (LIST_DIRECTORY_INTO_FILE): {
|
||||
return actionListDirectoryIntoFile(actionId, commandedBy, data, size);
|
||||
}
|
||||
case (LIST_DIRECTORY_DUMP_DIRECTLY): {
|
||||
return actionListDirectoryDumpDirectly(actionId, commandedBy, data, size);
|
||||
}
|
||||
case (CP_HELPER): {
|
||||
CpHelperParser parser(data, size);
|
||||
ReturnValue_t result = parser.parse();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
std::ostringstream oss("cp ", std::ostringstream::ate);
|
||||
if (parser.isRecursiveOptSet()) {
|
||||
oss << "-r ";
|
||||
}
|
||||
auto &sourceTgt = parser.destTgtPair();
|
||||
oss << sourceTgt.sourceName << " " << sourceTgt.targetName;
|
||||
sif::info << "CoreController: Performing copy command: " << oss.str() << std::endl;
|
||||
int ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case (MV_HELPER): {
|
||||
MvHelperParser parser(data, size);
|
||||
ReturnValue_t result = parser.parse();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
std::ostringstream oss("mv ", std::ostringstream::ate);
|
||||
auto &sourceTgt = parser.destTgtPair();
|
||||
oss << sourceTgt.sourceName << " " << sourceTgt.targetName;
|
||||
sif::info << "CoreController: Performing move command: " << oss.str() << std::endl;
|
||||
int ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case (RM_HELPER): {
|
||||
RmHelperParser parser(data, size);
|
||||
ReturnValue_t result = parser.parse();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
std::ostringstream oss("rm ", std::ostringstream::ate);
|
||||
if (parser.isRecursiveOptSet() or parser.isForceOptSet()) {
|
||||
oss << "-";
|
||||
}
|
||||
if (parser.isRecursiveOptSet()) {
|
||||
oss << "r";
|
||||
}
|
||||
if (parser.isForceOptSet()) {
|
||||
oss << "f";
|
||||
}
|
||||
size_t removeTargetSize = 0;
|
||||
const char *removeTgt = parser.getRemoveTarget(removeTargetSize);
|
||||
oss << " " << removeTgt;
|
||||
sif::info << "CoreController: Performing remove command: " << oss.str() << std::endl;
|
||||
int ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case (MKDIR_HELPER): {
|
||||
if (size < 1) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
std::string createdDir = std::string(reinterpret_cast<const char *>(data), size);
|
||||
std::ostringstream oss("mkdir ", std::ostringstream::ate);
|
||||
oss << createdDir;
|
||||
sif::info << "CoreController: Performing directory creation: " << oss.str() << std::endl;
|
||||
int ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
case (SWITCH_REBOOT_FILE_HANDLING): {
|
||||
if (size < 1) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
@ -911,59 +989,144 @@ ReturnValue_t CoreController::initVersionFile() {
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) {
|
||||
// TODO: Packet definition for clean deserialization
|
||||
// 2 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
|
||||
// null termination, at least 7 bytes for minimum target file name /tmp/a with
|
||||
// null termination.
|
||||
if (size < 14) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
ReturnValue_t CoreController::actionListDirectoryDumpDirectly(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) {
|
||||
core::ListDirectoryCmdBase parser(data, size);
|
||||
ReturnValue_t result = parser.parse();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
// We could also make -l optional, but I can't think of a reason why to not use -l..
|
||||
|
||||
// This flag specifies to run ls with -a
|
||||
bool aFlag = data[0];
|
||||
data += 1;
|
||||
// This flag specifies to run ls with -R
|
||||
bool RFlag = data[1];
|
||||
data += 1;
|
||||
|
||||
size_t remainingSize = size - 2;
|
||||
// One larger for null termination, which prevents undefined behaviour if the sent
|
||||
// strings are not 0 terminated properly
|
||||
std::vector<uint8_t> repoAndTargetFileBuffer(remainingSize + 1, 0);
|
||||
std::memcpy(repoAndTargetFileBuffer.data(), data, remainingSize);
|
||||
const char *currentCharPtr = reinterpret_cast<const char *>(repoAndTargetFileBuffer.data());
|
||||
// Full target file name
|
||||
std::string repoName(currentCharPtr);
|
||||
size_t repoLength = repoName.length();
|
||||
// The other string needs to be at least one letter plus NULL termination to be valid at all
|
||||
// The first string also needs to be NULL terminated, but the termination is not included
|
||||
// in the string length, so this is subtracted from the remaining size as well
|
||||
if (repoLength > remainingSize - 3) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
// The file length will not include the NULL termination, so we skip it
|
||||
currentCharPtr += repoLength + 1;
|
||||
std::string targetFileName(currentCharPtr);
|
||||
std::ostringstream oss;
|
||||
oss << "ls -l";
|
||||
if (aFlag) {
|
||||
std::ostringstream oss("ls -l", std::ostringstream::ate);
|
||||
if (parser.aFlagSet()) {
|
||||
oss << "a";
|
||||
}
|
||||
if (RFlag) {
|
||||
if (parser.rFlagSet()) {
|
||||
oss << "R";
|
||||
}
|
||||
|
||||
oss << " " << repoName << " > " << targetFileName;
|
||||
int result = std::system(oss.str().c_str());
|
||||
if (result != 0) {
|
||||
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
||||
actionHelper.finish(false, commandedBy, actionId);
|
||||
size_t repoNameLen = 0;
|
||||
const char *repoName = parser.getRepoName(repoNameLen);
|
||||
|
||||
oss << " " << repoName << " > " << LIST_DIR_DUMP_WORK_FILE;
|
||||
sif::info << "Executing " << oss.str() << " for direct dump";
|
||||
if (parser.compressionOptionSet()) {
|
||||
sif::info << " with compression";
|
||||
}
|
||||
return returnvalue::OK;
|
||||
sif::info << std::endl;
|
||||
int ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
if (parser.compressionOptionSet()) {
|
||||
std::string compressedName = LIST_DIR_DUMP_WORK_FILE + std::string(".gz");
|
||||
oss.str("");
|
||||
oss << "gzip " << LIST_DIR_DUMP_WORK_FILE;
|
||||
ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
oss.str("");
|
||||
// Overwrite the work file with the compressed archive.
|
||||
oss << "mv " << compressedName << " " << LIST_DIR_DUMP_WORK_FILE;
|
||||
ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
utility::handleSystemError(result, "CoreController::actionListDirectoryDumpDirectly");
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
std::array<uint8_t, 1024> dirListingBuf{};
|
||||
dirListingBuf[8] = parser.compressionOptionSet();
|
||||
// First four bytes reserved for segment index. One byte for compression option information
|
||||
std::strcpy(reinterpret_cast<char *>(dirListingBuf.data() + 2 * sizeof(uint32_t) + 1), repoName);
|
||||
std::ifstream ifile(LIST_DIR_DUMP_WORK_FILE, std::ios::binary);
|
||||
if (ifile.bad()) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
std::error_code e;
|
||||
size_t totalFileSize = std::filesystem::file_size(LIST_DIR_DUMP_WORK_FILE, e);
|
||||
uint32_t segmentIdx = 0;
|
||||
size_t dumpedBytes = 0;
|
||||
size_t nextDumpLen = 0;
|
||||
size_t dummy = 0;
|
||||
size_t maxDumpLen = dirListingBuf.size() - 2 * sizeof(uint32_t) - 1 - repoNameLen - 1;
|
||||
size_t listingDataOffset = 2 * sizeof(uint32_t) + 1 + repoNameLen + 1;
|
||||
uint32_t chunks = totalFileSize / maxDumpLen;
|
||||
if (totalFileSize % maxDumpLen != 0) {
|
||||
chunks++;
|
||||
}
|
||||
SerializeAdapter::serialize(&chunks, dirListingBuf.data() + sizeof(uint32_t), &dummy,
|
||||
dirListingBuf.size() - sizeof(uint32_t),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
while (dumpedBytes < totalFileSize) {
|
||||
ifile.seekg(dumpedBytes, std::ios::beg);
|
||||
nextDumpLen = maxDumpLen;
|
||||
if (totalFileSize - dumpedBytes < maxDumpLen) {
|
||||
nextDumpLen = totalFileSize - dumpedBytes;
|
||||
}
|
||||
SerializeAdapter::serialize(&segmentIdx, dirListingBuf.data(), &dummy, dirListingBuf.size(),
|
||||
SerializeIF::Endianness::NETWORK);
|
||||
ifile.read(reinterpret_cast<char *>(dirListingBuf.data() + listingDataOffset), nextDumpLen);
|
||||
result = actionHelper.reportData(commandedBy, actionId, dirListingBuf.data(),
|
||||
listingDataOffset + nextDumpLen);
|
||||
if (result != returnvalue::OK) {
|
||||
// Remove work file when we are done
|
||||
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||
return result;
|
||||
}
|
||||
segmentIdx++;
|
||||
dumpedBytes += nextDumpLen;
|
||||
}
|
||||
// Remove work file when we are done
|
||||
std::filesystem::remove(LIST_DIR_DUMP_WORK_FILE, e);
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
|
||||
ReturnValue_t CoreController::actionListDirectoryIntoFile(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) {
|
||||
core::ListDirectoryIntoFile parser(data, size);
|
||||
ReturnValue_t result = parser.parse();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::ostringstream oss("ls -l", std::ostringstream::ate);
|
||||
if (parser.aFlagSet()) {
|
||||
oss << "a";
|
||||
}
|
||||
if (parser.rFlagSet()) {
|
||||
oss << "R";
|
||||
}
|
||||
|
||||
size_t repoNameLen = 0;
|
||||
const char *repoName = parser.getRepoName(repoNameLen);
|
||||
size_t targetFileNameLen = 0;
|
||||
const char *targetFileName = parser.getTargetName(targetFileNameLen);
|
||||
oss << " " << repoName << " > " << targetFileName;
|
||||
sif::info << "Executing list directory request, command: " << oss.str() << std::endl;
|
||||
int ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
|
||||
// Compression will add a .gz ending. I don't have any issue with this, it makes it explicit
|
||||
// that this is a compressed file.
|
||||
if (parser.compressionOptionSet()) {
|
||||
oss.str("");
|
||||
oss << "gzip " << targetFileName;
|
||||
sif::info << "Compressing directory listing: " << oss.str() << std::endl;
|
||||
ret = std::system(oss.str().c_str());
|
||||
if (ret != 0) {
|
||||
utility::handleSystemError(result, "CoreController::actionListDirectoryIntoFile");
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
|
||||
ReturnValue_t CoreController::initBootCopyFile() {
|
||||
@ -2049,6 +2212,8 @@ ReturnValue_t CoreController::executeSwUpdate(SwUpdateSources sourceDir, const u
|
||||
if (not exists(archivePath, e)) {
|
||||
return HasFileSystemIF::FILE_DOES_NOT_EXIST;
|
||||
}
|
||||
// TODO: Decompressing without limiting memory usage with xz is actually a bit risky..
|
||||
// But has not been an issue so far.
|
||||
ostringstream cmd("tar -xJf", ios::app);
|
||||
cmd << " " << archivePath << " -C " << prefixPath;
|
||||
int result = system(cmd.str().c_str());
|
||||
|
@ -66,6 +66,7 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
||||
static constexpr char CHIP_0_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi0-gold-rootfs";
|
||||
static constexpr char CHIP_1_COPY_0_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-nom-rootfs";
|
||||
static constexpr char CHIP_1_COPY_1_MOUNT_DIR[] = "/tmp/mntupdate-xdi-qspi1-gold-rootfs";
|
||||
static constexpr char LIST_DIR_DUMP_WORK_FILE[] = "/tmp/dir_listing.tmp";
|
||||
|
||||
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
|
||||
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
|
||||
@ -250,6 +251,12 @@ class CoreController : public ExtendedControllerBase, public ReceivesParameterMe
|
||||
|
||||
ReturnValue_t actionListDirectoryIntoFile(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size);
|
||||
ReturnValue_t actionListDirectoryDumpDirectly(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size);
|
||||
|
||||
ReturnValue_t actionListDirectoryCommonCommandCreator(const uint8_t* data, size_t size,
|
||||
std::ostringstream& oss);
|
||||
|
||||
ReturnValue_t actionXscReboot(const uint8_t* data, size_t size);
|
||||
ReturnValue_t actionReboot(const uint8_t* data, size_t size);
|
||||
|
||||
|
@ -37,6 +37,9 @@ uint32_t RwDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
|
||||
|
||||
ReturnValue_t RwDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(rws::RW_SPEED, &rwSpeed);
|
||||
localDataPoolMap.emplace(rws::RAMP_TIME, &rampTime);
|
||||
|
||||
localDataPoolMap.emplace(rws::TEMPERATURE_C, new PoolEntry<int32_t>({0}));
|
||||
|
||||
localDataPoolMap.emplace(rws::CURR_SPEED, new PoolEntry<int32_t>({0}));
|
||||
|
@ -15,6 +15,9 @@ class RwDummy : public DeviceHandlerBase {
|
||||
virtual ~RwDummy();
|
||||
|
||||
protected:
|
||||
PoolEntry<int32_t> rwSpeed = PoolEntry<int32_t>({0});
|
||||
PoolEntry<uint16_t> rampTime = PoolEntry<uint16_t>({10});
|
||||
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
||||
|
@ -96,6 +96,16 @@ ReturnValue_t TemperatureSensorInserter::performOperation(uint8_t opCode) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (TestCase::COLD_CAMERA): {
|
||||
if (cycles == 15) {
|
||||
sif::debug << "Setting cold CAM temperature" << std::endl;
|
||||
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(-40, true);
|
||||
}
|
||||
if (cycles == 30) {
|
||||
sif::debug << "Setting CAM temperature back to normal" << std::endl;
|
||||
max31865DummyMap[objects::RTD_2_IC5_4K_CAMERA]->setTemperature(0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
cycles++;
|
||||
return returnvalue::OK;
|
||||
|
@ -31,6 +31,7 @@ class TemperatureSensorInserter : public ExecutableObjectIF, public SystemObject
|
||||
COLD_MGT = 3,
|
||||
COLD_STR = 4,
|
||||
COLD_STR_CONSECUTIVE = 5,
|
||||
COLD_CAMERA = 6,
|
||||
};
|
||||
int iteration = 0;
|
||||
uint32_t cycles = 0;
|
||||
|
@ -274,6 +274,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||
14108;0x371c;MGT_OVERHEATING;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
||||
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
||||
|
|
@ -274,6 +274,7 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
14105;0x3719;CAMERA_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||
14106;0x371a;PCDU_SYSTEM_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||
14107;0x371b;HEATER_NOT_OFF_FOR_OFF_MODE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||
14108;0x371c;MGT_OVERHEATING;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||
14201;0x3779;TX_TIMER_EXPIRED;INFO;The transmit timer to protect the Syrlinks expired P1: The current timer value;mission/system/com/ComSubsystem.h
|
||||
14202;0x377a;BIT_LOCK_TX_ON;INFO;Transmitter will be turned on due to detection of bitlock;mission/system/com/ComSubsystem.h
|
||||
14300;0x37dc;POSSIBLE_FILE_CORRUPTION;LOW;P1: Result code of TM packet parser. P2: Timestamp of possibly corrupt file as a unix timestamp.;mission/persistentTmStoreDefs.h
|
||||
|
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 290 translations.
|
||||
* @brief Auto-generated event translation file. Contains 291 translations.
|
||||
* @details
|
||||
* Generated on: 2023-04-14 20:23:17
|
||||
* Generated on: 2023-04-17 11:34:19
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -280,6 +280,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
|
||||
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
||||
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
||||
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
||||
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||
@ -848,6 +849,8 @@ const char *translateEvents(Event event) {
|
||||
return PCDU_SYSTEM_OVERHEATING_STRING;
|
||||
case (14107):
|
||||
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
||||
case (14108):
|
||||
return MGT_OVERHEATING_STRING;
|
||||
case (14201):
|
||||
return TX_TIMER_EXPIRED_STRING;
|
||||
case (14202):
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 175 translations.
|
||||
* Generated on: 2023-04-14 20:23:17
|
||||
* Generated on: 2023-04-17 11:34:19
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 290 translations.
|
||||
* @brief Auto-generated event translation file. Contains 291 translations.
|
||||
* @details
|
||||
* Generated on: 2023-04-14 20:23:17
|
||||
* Generated on: 2023-04-17 11:34:19
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -280,6 +280,7 @@ const char *OBC_OVERHEATING_STRING = "OBC_OVERHEATING";
|
||||
const char *CAMERA_OVERHEATING_STRING = "CAMERA_OVERHEATING";
|
||||
const char *PCDU_SYSTEM_OVERHEATING_STRING = "PCDU_SYSTEM_OVERHEATING";
|
||||
const char *HEATER_NOT_OFF_FOR_OFF_MODE_STRING = "HEATER_NOT_OFF_FOR_OFF_MODE";
|
||||
const char *MGT_OVERHEATING_STRING = "MGT_OVERHEATING";
|
||||
const char *TX_TIMER_EXPIRED_STRING = "TX_TIMER_EXPIRED";
|
||||
const char *BIT_LOCK_TX_ON_STRING = "BIT_LOCK_TX_ON";
|
||||
const char *POSSIBLE_FILE_CORRUPTION_STRING = "POSSIBLE_FILE_CORRUPTION";
|
||||
@ -848,6 +849,8 @@ const char *translateEvents(Event event) {
|
||||
return PCDU_SYSTEM_OVERHEATING_STRING;
|
||||
case (14107):
|
||||
return HEATER_NOT_OFF_FOR_OFF_MODE_STRING;
|
||||
case (14108):
|
||||
return MGT_OVERHEATING_STRING;
|
||||
case (14201):
|
||||
return TX_TIMER_EXPIRED_STRING;
|
||||
case (14202):
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 175 translations.
|
||||
* Generated on: 2023-04-14 20:23:17
|
||||
* Generated on: 2023-04-17 11:34:19
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
|
@ -435,8 +435,7 @@ ReturnValue_t PdecHandler::releasePdec() {
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::pdecToReset() {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
result = gpioComIF->pullLow(pdecReset);
|
||||
ReturnValue_t result = gpioComIF->pullLow(pdecReset);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::error << "PdecHandler::pdecToReset: Failed to pull PDEC reset line"
|
||||
" to low"
|
||||
|
@ -1,10 +1,11 @@
|
||||
#include "ArcsecDatalinkLayer.h"
|
||||
|
||||
extern "C" {
|
||||
#include <wire/common/SLIP.h>
|
||||
#include <wire/common/misc.h>
|
||||
}
|
||||
|
||||
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) { slipInit(); }
|
||||
ArcsecDatalinkLayer::ArcsecDatalinkLayer() : decodeRingBuf(BUFFER_LENGTHS, true) {}
|
||||
|
||||
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {}
|
||||
|
||||
@ -15,35 +16,50 @@ ReturnValue_t ArcsecDatalinkLayer::checkRingBufForFrame(const uint8_t** decodedF
|
||||
return DEC_IN_PROGRESS;
|
||||
}
|
||||
decodeRingBuf.readData(rxAnalysisBuffer, currentLen);
|
||||
|
||||
bool startFound = false;
|
||||
size_t startIdx = 0;
|
||||
for (size_t idx = 0; idx < currentLen; idx++) {
|
||||
enum arc_dec_result decResult =
|
||||
arc_transport_decode_body(rxAnalysisBuffer[idx], &slipInfo, decodedRxFrame, &rxFrameSize);
|
||||
switch (decResult) {
|
||||
case ARC_DEC_INPROGRESS: {
|
||||
break;
|
||||
}
|
||||
case ARC_DEC_ERROR: {
|
||||
decodeRingBuf.deleteData(idx);
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
case ARC_DEC_ASYNC:
|
||||
case ARC_DEC_SYNC: {
|
||||
// Reset length of SLIP struct for next frame
|
||||
slipInfo.length = 0;
|
||||
if (rxAnalysisBuffer[idx] != SLIP_START_AND_END) {
|
||||
continue;
|
||||
}
|
||||
if (not startFound) {
|
||||
startFound = true;
|
||||
startIdx = idx;
|
||||
continue;
|
||||
}
|
||||
// Now we can try decoding the whole frame.
|
||||
size_t encodedDataSize = 0;
|
||||
slip_error_t slipError =
|
||||
slip_decode_frame(decodedRxFrame, &rxFrameSize, rxAnalysisBuffer + startIdx,
|
||||
idx - startIdx + 1, &encodedDataSize, ARC_DEF_SAGITTA_SLIP_ID);
|
||||
decodeRingBuf.deleteData(idx + 1);
|
||||
switch (slipError) {
|
||||
case (SLIP_OK): {
|
||||
if (decodedFrame != nullptr) {
|
||||
*decodedFrame = decodedRxFrame;
|
||||
}
|
||||
frameLen = rxFrameSize;
|
||||
decodeRingBuf.deleteData(idx);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default:
|
||||
sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl;
|
||||
break;
|
||||
case (SLIP_BAD_CRC): {
|
||||
return CRC_FAILURE;
|
||||
}
|
||||
case (SLIP_OVERFLOW): {
|
||||
return SLIP_OVERFLOW_RETVAL;
|
||||
}
|
||||
// Should not happen, we searched for start and end marker..
|
||||
case (SLIP_NO_END): {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
case (SLIP_ID_MISMATCH): {
|
||||
return SLIP_ID_MISSMATCH_RETVAL;
|
||||
}
|
||||
default: {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
decodeRingBuf.deleteData(currentLen);
|
||||
return DEC_IN_PROGRESS;
|
||||
}
|
||||
|
||||
@ -56,18 +72,11 @@ ReturnValue_t ArcsecDatalinkLayer::feedData(const uint8_t* rawData, size_t rawDa
|
||||
return decodeRingBuf.writeData(rawData, rawDataLen);
|
||||
}
|
||||
|
||||
void ArcsecDatalinkLayer::reset() {
|
||||
slipInit();
|
||||
decodeRingBuf.clear();
|
||||
}
|
||||
|
||||
void ArcsecDatalinkLayer::slipInit() {
|
||||
slip_decode_init(rxBufferArc, sizeof(rxBufferArc), &slipInfo);
|
||||
}
|
||||
void ArcsecDatalinkLayer::reset() { decodeRingBuf.clear(); }
|
||||
|
||||
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, size_t length, const uint8_t** txFrame,
|
||||
size_t& size) {
|
||||
arc_transport_encode_body(data, length, txEncoded, &size);
|
||||
slip_encode_frame(data, length, txEncoded, &size, ARC_DEF_SAGITTA_SLIP_ID);
|
||||
if (txFrame != nullptr) {
|
||||
*txFrame = txEncoded;
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ class ArcsecDatalinkLayer {
|
||||
static const ReturnValue_t REPLY_TOO_SHORT = MAKE_RETURN_CODE(0xA1);
|
||||
//! [EXPORT] : [COMMENT] Detected CRC failure in received frame
|
||||
static const ReturnValue_t CRC_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||
static const ReturnValue_t SLIP_OVERFLOW_RETVAL = MAKE_RETURN_CODE(0xA3);
|
||||
static const ReturnValue_t SLIP_ID_MISSMATCH_RETVAL = MAKE_RETURN_CODE(0xA4);
|
||||
|
||||
static const uint8_t STATUS_OK = 0;
|
||||
|
||||
@ -77,7 +79,7 @@ class ArcsecDatalinkLayer {
|
||||
// Decoded frame will be copied to this buffer
|
||||
uint8_t decodedRxFrame[startracker::MAX_FRAME_SIZE];
|
||||
// Size of decoded frame
|
||||
uint32_t rxFrameSize = 0;
|
||||
size_t rxFrameSize = 0;
|
||||
|
||||
// Buffer where encoded frames will be stored. First byte of encoded frame represents type of
|
||||
// reply
|
||||
@ -85,7 +87,7 @@ class ArcsecDatalinkLayer {
|
||||
// Size of encoded frame
|
||||
uint32_t txFrameSize = 0;
|
||||
|
||||
slip_decode_state slipInfo;
|
||||
// slip_decode_state slipInfo;
|
||||
|
||||
void slipInit();
|
||||
};
|
||||
|
@ -5,7 +5,11 @@
|
||||
#include <mission/acs/str/strJsonCommands.h>
|
||||
|
||||
extern "C" {
|
||||
#include <sagitta/client/arc_client.h>
|
||||
#include <sagitta/client/actionreq.h>
|
||||
#include <sagitta/client/client_tm_structs.h>
|
||||
#include <sagitta/client/parameter.h>
|
||||
#include <sagitta/client/telemetry.h>
|
||||
#include <wire/common/genericstructs.h>
|
||||
}
|
||||
|
||||
#include <atomic>
|
||||
@ -880,7 +884,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
|
||||
switch (id) {
|
||||
case (startracker::REQ_TIME): {
|
||||
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE);
|
||||
result = handleTm(packet, timeSet, startracker::TimeSet::SIZE, "REQ_TIME");
|
||||
break;
|
||||
}
|
||||
case (startracker::PING_REQUEST): {
|
||||
@ -895,7 +899,7 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_VERSION): {
|
||||
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE);
|
||||
result = handleTm(packet, versionSet, startracker::VersionSet::SIZE, "REQ_VERSION");
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
@ -906,23 +910,23 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_INTERFACE): {
|
||||
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE);
|
||||
result = handleTm(packet, interfaceSet, startracker::InterfaceSet::SIZE, "REQ_INTERFACE");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_POWER): {
|
||||
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE);
|
||||
result = handleTm(packet, powerSet, startracker::PowerSet::SIZE, "REQ_POWER");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_SOLUTION): {
|
||||
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE);
|
||||
result = handleTm(packet, solutionSet, startracker::SolutionSet::SIZE, "REQ_SOLUTION");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_TEMPERATURE): {
|
||||
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE);
|
||||
result = handleTm(packet, temperatureSet, startracker::TemperatureSet::SIZE, "REQ_TEMP");
|
||||
break;
|
||||
}
|
||||
case (startracker::REQ_HISTOGRAM): {
|
||||
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE);
|
||||
result = handleTm(packet, histogramSet, startracker::HistogramSet::SIZE, "REQ_HISTO");
|
||||
break;
|
||||
}
|
||||
case (startracker::SUBSCRIPTION):
|
||||
@ -1972,7 +1976,7 @@ ReturnValue_t StarTrackerHandler::checkProgram() {
|
||||
}
|
||||
|
||||
ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset,
|
||||
size_t size) {
|
||||
size_t size, const char* context) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
uint8_t status = startracker::getStatusField(rawFrame);
|
||||
if (status != startracker::STATUS_OK) {
|
||||
@ -1988,7 +1992,8 @@ ReturnValue_t StarTrackerHandler::handleTm(const uint8_t* rawFrame, LocalPoolDat
|
||||
dataset.setValidityBufferGeneration(false);
|
||||
result = dataset.deSerialize(&reply, &size, SerializeIF::Endianness::LITTLE);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed" << std::endl;
|
||||
sif::warning << "StarTrackerHandler::handleTm: Deserialization failed for " << context
|
||||
<< std::endl;
|
||||
}
|
||||
dataset.setValidityBufferGeneration(true);
|
||||
dataset.setValidity(true, true);
|
||||
|
@ -481,7 +481,8 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
*
|
||||
* @return returnvalue::OK if successful, otherwise error return value
|
||||
*/
|
||||
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size);
|
||||
ReturnValue_t handleTm(const uint8_t* rawFrame, LocalPoolDataSetBase& dataset, size_t size,
|
||||
const char* context);
|
||||
|
||||
/**
|
||||
* @brief Checks if star tracker is in valid mode for executing the received command.
|
||||
|
@ -641,7 +641,7 @@ class TimeSet : public StaticLocalDataSet<TIME_SET_ENTRIES> {
|
||||
*/
|
||||
class SolutionSet : public StaticLocalDataSet<SOLUTION_SET_ENTRIES> {
|
||||
public:
|
||||
static const size_t SIZE = 78;
|
||||
static const size_t SIZE = 79;
|
||||
|
||||
SolutionSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SOLUTION_SET_ID) {}
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#define LOWER_SYRLINKS_UPPER_LIMITS 0
|
||||
#define LOWER_EBAND_UPPER_LIMITS 0
|
||||
#define LOWER_PLOC_UPPER_LIMITS 0
|
||||
#define LOWER_MGT_UPPER_LIMITS 0
|
||||
#define LOWER_RW_UPPER_LIMITS 0
|
||||
|
||||
ThermalController::ThermalController(object_id_t objectId, HeaterHandler& heater,
|
||||
const std::atomic_bool& tcsBoardShortUnavailable)
|
||||
@ -111,7 +113,7 @@ void ThermalController::performControlOperation() {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cycles == 50) {
|
||||
if (cycles == 40) {
|
||||
bool changedLimits = false;
|
||||
#if LOWER_SYRLINKS_UPPER_LIMITS == 1
|
||||
changedLimits = true;
|
||||
@ -130,9 +132,21 @@ void ThermalController::performControlOperation() {
|
||||
hpaLimits.cutOffLimit = 0;
|
||||
hpaLimits.opUpperLimit = 0;
|
||||
hpaLimits.nopUpperLimit = 0;
|
||||
#endif
|
||||
#if LOWER_MGT_UPPER_LIMITS == 1
|
||||
changedLimits = true;
|
||||
mgtLimits.cutOffLimit = 0;
|
||||
mgtLimits.opUpperLimit = 0;
|
||||
mgtLimits.nopUpperLimit = 0;
|
||||
#endif
|
||||
#if LOWER_RW_UPPER_LIMITS == 1
|
||||
changedLimits = true;
|
||||
rwLimits.cutOffLimit = 0;
|
||||
rwLimits.opUpperLimit = 0;
|
||||
rwLimits.nopUpperLimit = 0;
|
||||
#endif
|
||||
if (changedLimits) {
|
||||
sif::debug << "ThermalController: changing limits" << std::endl; // TODO: rausschmeissen
|
||||
sif::debug << "ThermalController: changing limits" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1055,7 +1069,12 @@ void ThermalController::ctrlMgt() {
|
||||
numSensors = 3;
|
||||
HeaterContext htrCtx(heater::HEATER_2_ACS_BRD, heater::HEATER_3_PCDU_PDU, mgtLimits);
|
||||
ctrlComponentTemperature(htrCtx);
|
||||
// TODO: trigger special event
|
||||
if (componentAboveUpperLimit and not mgtTooHotFlag) {
|
||||
triggerEvent(tcsCtrl::MGT_OVERHEATING, tempFloatToU32());
|
||||
mgtTooHotFlag = true;
|
||||
} else if (not componentAboveUpperLimit) {
|
||||
mgtTooHotFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ThermalController::ctrlRw() {
|
||||
@ -1240,7 +1259,7 @@ void ThermalController::ctrlObcIfBoard() {
|
||||
triggerEvent(tcsCtrl::OBC_OVERHEATING, tempFloatToU32());
|
||||
obcTooHotFlag = true;
|
||||
} else if (not componentAboveUpperLimit) {
|
||||
obcTooHotFlag = false; // TODO: !!
|
||||
obcTooHotFlag = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,6 +267,7 @@ class ThermalController : public ExtendedControllerBase {
|
||||
bool pcduSystemTooHotFlag = false;
|
||||
bool syrlinksTooHotFlag = false;
|
||||
bool obcTooHotFlag = false;
|
||||
bool mgtTooHotFlag = false;
|
||||
bool strTooHotFlag = false;
|
||||
bool rwTooHotFlag = false;
|
||||
|
||||
|
@ -150,7 +150,8 @@ void SensorProcessing::processMgm(const float *mgm0Value, bool mgm0valid, const
|
||||
}
|
||||
timeOfSavedMagFieldEst = timeOfMgmMeasurement;
|
||||
|
||||
if (mgmDataProcessed->mgmVecTotDerivative.isValid()) {
|
||||
if (VectorOperations<double>::norm(mgmVecTotDerivative, 3) != 0 and
|
||||
mgmDataProcessed->mgmVecTotDerivative.isValid()) {
|
||||
lowPassFilter(mgmVecTotDerivative, mgmDataProcessed->mgmVecTotDerivative.value,
|
||||
mgmParameters->mgmDerivativeFilterWeight);
|
||||
}
|
||||
@ -533,7 +534,7 @@ void SensorProcessing::processGyr(
|
||||
}
|
||||
}
|
||||
|
||||
if (gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
if (VectorOperations<double>::norm(gyrVecTot, 3) != 0 and gyrDataProcessed->gyrVecTot.isValid()) {
|
||||
lowPassFilter(gyrVecTot, gyrDataProcessed->gyrVecTot.value, gyrParameters->gyrFilterWeight);
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,6 @@ void SafeCtrl::safeRateDamping(const double *magFieldB, const double *satRotRate
|
||||
acsParameters->safeModeControllerParameters.k_orthoNonMekf);
|
||||
|
||||
// sum of all torques
|
||||
double cmdTorque[3] = {0, 0, 0};
|
||||
VectorOperations<double>::add(cmdParallel, cmdOrtho, cmdTorque, 3);
|
||||
|
||||
// calculate magnetic moment to command
|
||||
|
@ -17,6 +17,7 @@ static constexpr Event OBC_OVERHEATING = MAKE_EVENT(4, severity::HIGH);
|
||||
static constexpr Event CAMERA_OVERHEATING = MAKE_EVENT(5, severity::HIGH);
|
||||
static constexpr Event PCDU_SYSTEM_OVERHEATING = MAKE_EVENT(6, severity::HIGH);
|
||||
static constexpr Event HEATER_NOT_OFF_FOR_OFF_MODE = MAKE_EVENT(7, severity::MEDIUM);
|
||||
static constexpr Event MGT_OVERHEATING = MAKE_EVENT(8, severity::HIGH);
|
||||
|
||||
enum SetId : uint32_t {
|
||||
SENSOR_TEMPERATURES = 0,
|
||||
|
@ -32,7 +32,6 @@ static constexpr char VERSION_FILE_NAME[] = "version.txt";
|
||||
static constexpr char REBOOT_FILE_NAME[] = "reboot.txt";
|
||||
static constexpr char TIME_FILE_NAME[] = "time_backup.txt";
|
||||
|
||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
||||
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
|
||||
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
|
||||
static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3;
|
||||
@ -59,6 +58,13 @@ static constexpr ActionId_t EXECUTE_SHELL_CMD_BLOCKING = 40;
|
||||
static constexpr ActionId_t EXECUTE_SHELL_CMD_NON_BLOCKING = 41;
|
||||
static constexpr ActionId_t SYSTEMCTL_CMD_EXECUTOR = 42;
|
||||
|
||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 50;
|
||||
static constexpr ActionId_t LIST_DIRECTORY_DUMP_DIRECTLY = 51;
|
||||
static constexpr ActionId_t CP_HELPER = 52;
|
||||
static constexpr ActionId_t MV_HELPER = 53;
|
||||
static constexpr ActionId_t RM_HELPER = 54;
|
||||
static constexpr ActionId_t MKDIR_HELPER = 55;
|
||||
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
||||
|
||||
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||
@ -96,6 +102,198 @@ static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity:
|
||||
//! [EXPORT] : [COMMENT] PDEC recovery through reset was not possible, performing full reboot.
|
||||
static constexpr Event PDEC_REBOOT = event::makeEvent(SUBSYSTEM_ID, 12, severity::HIGH);
|
||||
|
||||
class ListDirectoryCmdBase {
|
||||
public: // TODO: Packet definition for clean deserialization
|
||||
// 3 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
|
||||
// null termination
|
||||
static constexpr size_t MIN_DATA_LEN = 8;
|
||||
|
||||
ListDirectoryCmdBase(const uint8_t* data, size_t maxSize) : data(data), maxSize(maxSize) {}
|
||||
virtual ~ListDirectoryCmdBase() = default;
|
||||
|
||||
virtual ReturnValue_t parse() {
|
||||
if (maxSize < MIN_DATA_LEN) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
aFlag = data[0];
|
||||
rFlag = data[1];
|
||||
compressOption = data[2];
|
||||
|
||||
repoNameLen = strnlen(reinterpret_cast<const char*>(data + 3), maxSize - 3);
|
||||
// Last byte MUST be null terminated!
|
||||
if (repoNameLen >= maxSize - 3) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
repoName = reinterpret_cast<const char*>(data + 3);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
bool aFlagSet() const { return this->aFlag; }
|
||||
bool rFlagSet() const { return this->rFlag; }
|
||||
|
||||
bool compressionOptionSet() const { return this->compressOption; }
|
||||
|
||||
const char* getRepoName(size_t& repoNameLen) const {
|
||||
repoNameLen = this->repoNameLen;
|
||||
return this->repoName;
|
||||
}
|
||||
|
||||
size_t getBaseSize() {
|
||||
// Include NULL termination
|
||||
if (repoName != nullptr) {
|
||||
return 3 + repoNameLen + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
const uint8_t* data;
|
||||
size_t maxSize;
|
||||
|
||||
bool aFlag = false;
|
||||
bool rFlag = false;
|
||||
bool compressOption = false;
|
||||
const char* repoName = nullptr;
|
||||
size_t repoNameLen = 0;
|
||||
};
|
||||
|
||||
class ListDirectoryIntoFile : public ListDirectoryCmdBase {
|
||||
public:
|
||||
// TODO: Packet definition for clean deserialization
|
||||
// 3 bytes for a and R flag, at least 5 bytes for minimum valid path /tmp with
|
||||
// null termination, at least 7 bytes for minimum target file name /tmp/a with
|
||||
// null termination.
|
||||
static constexpr size_t MIN_DATA_LEN = 15;
|
||||
|
||||
ListDirectoryIntoFile(const uint8_t* data, size_t maxSize)
|
||||
: ListDirectoryCmdBase(data, maxSize) {}
|
||||
ReturnValue_t parse() override {
|
||||
if (maxSize < MIN_DATA_LEN) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
ReturnValue_t result = ListDirectoryCmdBase::parse();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
targetNameLen =
|
||||
strnlen(reinterpret_cast<const char*>(data + getBaseSize()), maxSize - getBaseSize());
|
||||
if (targetNameLen >= maxSize - getBaseSize()) {
|
||||
// Again: String MUST be null terminated.
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
targetName = reinterpret_cast<const char*>(data + getBaseSize());
|
||||
return result;
|
||||
}
|
||||
const char* getTargetName(size_t& targetNameLen) const {
|
||||
targetNameLen = this->targetNameLen;
|
||||
return this->targetName;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* targetName = nullptr;
|
||||
size_t targetNameLen = 0;
|
||||
};
|
||||
|
||||
struct SourceTargetPair {
|
||||
const char* sourceName = nullptr;
|
||||
size_t sourceNameSize = 0;
|
||||
const char* targetName = nullptr;
|
||||
size_t targetNameSize = 0;
|
||||
};
|
||||
|
||||
static ReturnValue_t parseDestTargetString(const uint8_t* data, size_t maxLen,
|
||||
SourceTargetPair& destTgt) {
|
||||
if (maxLen < 4) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
destTgt.sourceNameSize = strnlen(reinterpret_cast<const char*>(data), maxLen);
|
||||
if (destTgt.sourceNameSize >= maxLen) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
destTgt.sourceName = reinterpret_cast<const char*>(data);
|
||||
size_t remainingLen = maxLen - destTgt.sourceNameSize - 1;
|
||||
if (remainingLen == 0) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
destTgt.targetNameSize =
|
||||
strnlen(reinterpret_cast<const char*>(data + destTgt.sourceNameSize + 1), remainingLen);
|
||||
if (destTgt.targetNameSize >= remainingLen) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
destTgt.targetName = reinterpret_cast<const char*>(data + destTgt.sourceNameSize + 1);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
class CpHelperParser {
|
||||
public:
|
||||
CpHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
|
||||
|
||||
ReturnValue_t parse() {
|
||||
if (maxLen < 1) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
recursiveOpt = data[0];
|
||||
return parseDestTargetString(data + 1, maxLen - 1, destTgt);
|
||||
}
|
||||
const SourceTargetPair& destTgtPair() const { return destTgt; }
|
||||
bool isRecursiveOptSet() const { return recursiveOpt; }
|
||||
|
||||
private:
|
||||
const uint8_t* data;
|
||||
size_t maxLen;
|
||||
bool recursiveOpt = false;
|
||||
SourceTargetPair destTgt;
|
||||
};
|
||||
|
||||
class MvHelperParser {
|
||||
public:
|
||||
MvHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
|
||||
|
||||
ReturnValue_t parse() { return parseDestTargetString(data, maxLen, destTgt); }
|
||||
const SourceTargetPair& destTgtPair() const { return destTgt; }
|
||||
|
||||
private:
|
||||
const uint8_t* data;
|
||||
size_t maxLen;
|
||||
SourceTargetPair destTgt;
|
||||
};
|
||||
|
||||
class RmHelperParser {
|
||||
public:
|
||||
RmHelperParser(const uint8_t* data, size_t maxLen) : data(data), maxLen(maxLen) {}
|
||||
|
||||
ReturnValue_t parse() {
|
||||
if (maxLen < 2) {
|
||||
return SerializeIF::STREAM_TOO_SHORT;
|
||||
}
|
||||
recursiveOpt = data[0];
|
||||
forceOpt = data[1];
|
||||
removeTargetSize = strnlen(reinterpret_cast<const char*>(data + 2), maxLen - 2);
|
||||
// Must be null-terminated
|
||||
if (removeTargetSize >= maxLen - 2) {
|
||||
return HasActionsIF::INVALID_PARAMETERS;
|
||||
}
|
||||
removeTarget = reinterpret_cast<const char*>(data + 2);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
bool isRecursiveOptSet() const { return recursiveOpt; }
|
||||
bool isForceOptSet() const { return forceOpt; }
|
||||
|
||||
const char* getRemoveTarget(size_t& removeTargetSize) {
|
||||
removeTargetSize = this->removeTargetSize;
|
||||
return removeTarget;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t* data;
|
||||
size_t maxLen;
|
||||
bool recursiveOpt = false;
|
||||
bool forceOpt = false;
|
||||
const char* removeTarget = nullptr;
|
||||
size_t removeTargetSize = 0;
|
||||
};
|
||||
|
||||
} // namespace core
|
||||
|
||||
#endif /* MISSION_SYSDEFS_H_ */
|
||||
|
@ -114,6 +114,7 @@ ReturnValue_t EiveSystem::initialize() {
|
||||
manager->subscribeToEvent(eventQueue->getId(),
|
||||
event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::MGT_OVERHEATING));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(pdec::INVALID_TC_FRAME));
|
||||
return Subsystem::initialize();
|
||||
}
|
||||
@ -132,6 +133,7 @@ void EiveSystem::handleEventMessages() {
|
||||
break;
|
||||
}
|
||||
case tcsCtrl::OBC_OVERHEATING:
|
||||
case tcsCtrl::MGT_OVERHEATING:
|
||||
case tcsCtrl::PCDU_SYSTEM_OVERHEATING: {
|
||||
if (isInTransition) {
|
||||
performSafeRecovery = true;
|
||||
|
2
thirdparty/sagittactl
vendored
2
thirdparty/sagittactl
vendored
Submodule thirdparty/sagittactl updated: 29e876671a...20f32a2f29
2
tmtc
2
tmtc
Submodule tmtc updated: d00e4247f6...0c6a9677e1
Reference in New Issue
Block a user