v1.14.0 #304
@ -1,7 +1,6 @@
|
|||||||
#include "Q7STestTask.h"
|
#include "Q7STestTask.h"
|
||||||
|
|
||||||
#include <bsp_q7s/core/CoreController.h>
|
#include <bsp_q7s/core/CoreController.h>
|
||||||
#include <bsp_q7s/memory/FileSystemHandler.h>
|
|
||||||
#include <bsp_q7s/xadc/Xadc.h>
|
#include <bsp_q7s/xadc/Xadc.h>
|
||||||
#include <fsfw/globalfunctions/arrayprinter.h>
|
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||||
#include <fsfw/objectmanager/ObjectManager.h>
|
#include <fsfw/objectmanager/ObjectManager.h>
|
||||||
@ -17,6 +16,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include "OBSWConfig.h"
|
||||||
#include "bsp_q7s/memory/SdCardManager.h"
|
#include "bsp_q7s/memory/SdCardManager.h"
|
||||||
#include "bsp_q7s/memory/scratchApi.h"
|
#include "bsp_q7s/memory/scratchApi.h"
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
@ -365,148 +365,7 @@ void Q7STestTask::testGpsDaemonSocket() {
|
|||||||
sif::info << "Longitude: " << gps->fix.longitude << std::endl;
|
sif::info << "Longitude: " << gps->fix.longitude << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {
|
void Q7STestTask::testFileSystemHandlerDirect(FsOpCodes opCode) {}
|
||||||
auto fsHandler = ObjectManager::instance()->get<FileSystemHandler>(objects::FILE_SYSTEM_HANDLER);
|
|
||||||
if (fsHandler == nullptr) {
|
|
||||||
sif::warning << "Q7STestTask::testFileSystemHandlerDirect: No FS handler running.."
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
FileSystemHandler::FsCommandCfg cfg = {};
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
|
|
||||||
// Lambda for common code
|
|
||||||
auto createNonEmptyTmpDir = [&]() {
|
|
||||||
if (not std::filesystem::exists("/tmp/test")) {
|
|
||||||
result = fsHandler->createDirectory("/tmp", "test", false, &cfg);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Creating sample files
|
|
||||||
sif::info << "Creating sample files in directory" << std::endl;
|
|
||||||
result = fsHandler->createFile("/tmp/test", "test1.txt", nullptr, 0, &cfg);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
result = fsHandler->createFile("/tmp/test", "test2.txt", nullptr, 0, &cfg);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (opCode) {
|
|
||||||
case (FsOpCodes::CREATE_EMPTY_FILE_IN_TMP): {
|
|
||||||
// No mount prefix, cause file is created in tmp
|
|
||||||
cfg.useMountPrefix = false;
|
|
||||||
sif::info << "Creating empty file in /tmp folder" << std::endl;
|
|
||||||
// Do not delete file, user can check existence in shell
|
|
||||||
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (FsOpCodes::REMOVE_TMP_FILE): {
|
|
||||||
sif::info << "Deleting /tmp/test.txt sample file" << std::endl;
|
|
||||||
// No mount prefix, cause file is created in tmp
|
|
||||||
cfg.useMountPrefix = false;
|
|
||||||
if (not std::filesystem::exists("/tmp/test.txt")) {
|
|
||||||
// Creating sample file
|
|
||||||
sif::info << "Creating sample file /tmp/test.txt to delete" << std::endl;
|
|
||||||
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
|
||||||
}
|
|
||||||
result = fsHandler->removeFile("/tmp", "test.txt", &cfg);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
sif::info << "File removed successfully" << std::endl;
|
|
||||||
} else {
|
|
||||||
sif::warning << "File removal failed!" << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (FsOpCodes::CREATE_DIR_IN_TMP): {
|
|
||||||
// No mount prefix, cause file is created in tmp
|
|
||||||
cfg.useMountPrefix = false;
|
|
||||||
sif::info << "Creating empty file in /tmp folder" << std::endl;
|
|
||||||
// Do not delete file, user can check existence in shell
|
|
||||||
ReturnValue_t result = fsHandler->createDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
sif::info << "Directory created successfully" << std::endl;
|
|
||||||
} else {
|
|
||||||
sif::warning << "Directory creation failed!" << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (FsOpCodes::REMOVE_EMPTY_DIR_IN_TMP): {
|
|
||||||
// No mount prefix, cause file is created in tmp
|
|
||||||
cfg.useMountPrefix = false;
|
|
||||||
if (not std::filesystem::exists("/tmp/test")) {
|
|
||||||
result = fsHandler->createDirectory("/tmp", "test", false, &cfg);
|
|
||||||
} else {
|
|
||||||
// Delete any leftover files to regular dir removal works
|
|
||||||
std::remove("/tmp/test/*");
|
|
||||||
}
|
|
||||||
result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
sif::info << "Directory removed successfully" << std::endl;
|
|
||||||
} else {
|
|
||||||
sif::warning << "Directory removal failed!" << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (FsOpCodes::REMOVE_FILLED_DIR_IN_TMP): {
|
|
||||||
result = createNonEmptyTmpDir();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
result = fsHandler->removeDirectory("/tmp/", "test", true, &cfg);
|
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
sif::info << "Directory removed recursively successfully" << std::endl;
|
|
||||||
} else {
|
|
||||||
sif::warning << "Recursive directory removal failed!" << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (FsOpCodes::ATTEMPT_DIR_REMOVAL_NON_EMPTY): {
|
|
||||||
result = createNonEmptyTmpDir();
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
result = fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
sif::info << "Directory removal attempt failed as expected" << std::endl;
|
|
||||||
} else {
|
|
||||||
sif::warning << "Directory removal worked when it should not have!" << std::endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (FsOpCodes::RENAME_FILE): {
|
|
||||||
// No mount prefix, cause file is created in tmp
|
|
||||||
cfg.useMountPrefix = false;
|
|
||||||
if (std::filesystem::exists("/tmp/test.txt")) {
|
|
||||||
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
}
|
|
||||||
sif::info << "Creating empty file /tmp/test.txt and rename to /tmp/test2.txt" << std::endl;
|
|
||||||
// Do not delete file, user can check existence in shell
|
|
||||||
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
|
||||||
fsHandler->renameFile("/tmp/", "test.txt", "test2.txt", &cfg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (FsOpCodes::APPEND_TO_FILE): {
|
|
||||||
// No mount prefix, cause file is created in tmp
|
|
||||||
cfg.useMountPrefix = false;
|
|
||||||
if (std::filesystem::exists("/tmp/test.txt")) {
|
|
||||||
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
}
|
|
||||||
if (std::filesystem::exists("/tmp/test.txt")) {
|
|
||||||
fsHandler->removeDirectory("/tmp/", "test", false, &cfg);
|
|
||||||
}
|
|
||||||
sif::info << "Creating empty file /tmp/test.txt and adding content" << std::endl;
|
|
||||||
std::string content = "Hello World\n";
|
|
||||||
// Do not delete file, user can check existence in shell
|
|
||||||
fsHandler->createFile("/tmp/", "test.txt", nullptr, 0, &cfg);
|
|
||||||
fsHandler->appendToFile("/tmp/", "test.txt", reinterpret_cast<const uint8_t*>(content.data()),
|
|
||||||
content.size(), 0, &cfg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Q7STestTask::xadcTest() {
|
void Q7STestTask::xadcTest() {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = returnvalue::OK;
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "bsp_q7s/callbacks/pcduSwitchCb.h"
|
#include "bsp_q7s/callbacks/pcduSwitchCb.h"
|
||||||
#include "bsp_q7s/callbacks/q7sGpioCallbacks.h"
|
#include "bsp_q7s/callbacks/q7sGpioCallbacks.h"
|
||||||
#include "bsp_q7s/callbacks/rwSpiCallback.h"
|
#include "bsp_q7s/callbacks/rwSpiCallback.h"
|
||||||
#include "bsp_q7s/memory/FileSystemHandler.h"
|
|
||||||
#include "busConf.h"
|
#include "busConf.h"
|
||||||
#include "ccsdsConfig.h"
|
#include "ccsdsConfig.h"
|
||||||
#include "devConf.h"
|
#include "devConf.h"
|
||||||
@ -908,10 +907,7 @@ void ObjectFactory::createBpxBatteryComponent() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectFactory::createMiscComponents() {
|
void ObjectFactory::createMiscComponents() { new PlocMemoryDumper(objects::PLOC_MEMORY_DUMPER); }
|
||||||
new FileSystemHandler(objects::FILE_SYSTEM_HANDLER);
|
|
||||||
new PlocMemoryDumper(objects::PLOC_MEMORY_DUMPER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectFactory::testAcsBrdAss(AcsBoardAssembly* acsAss) {
|
void ObjectFactory::testAcsBrdAss(AcsBoardAssembly* acsAss) {
|
||||||
CommandMessage msg;
|
CommandMessage msg;
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
target_sources(${OBSW_NAME} PRIVATE FileSystemHandler.cpp SdCardManager.cpp
|
target_sources(${OBSW_NAME} PRIVATE helpers.cpp SdCardManager.cpp
|
||||||
scratchApi.cpp FilesystemHelper.cpp)
|
scratchApi.cpp FilesystemHelper.cpp)
|
||||||
|
@ -1,238 +0,0 @@
|
|||||||
#include "FileSystemHandler.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include "bsp_q7s/core/CoreController.h"
|
|
||||||
#include "fsfw/ipc/QueueFactory.h"
|
|
||||||
#include "fsfw/memory/GenericFileSystemMessage.h"
|
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
|
||||||
|
|
||||||
FileSystemHandler::FileSystemHandler(object_id_t fileSystemHandler)
|
|
||||||
: SystemObject(fileSystemHandler) {
|
|
||||||
auto mqArgs = MqArgs(this->getObjectId());
|
|
||||||
mq = QueueFactory::instance()->createMessageQueue(FS_MAX_QUEUE_SIZE,
|
|
||||||
MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
FileSystemHandler::~FileSystemHandler() { QueueFactory::instance()->deleteMessageQueue(mq); }
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::performOperation(uint8_t unsignedChar) {
|
|
||||||
while (true) {
|
|
||||||
try {
|
|
||||||
fileSystemHandlerLoop();
|
|
||||||
} catch (std::bad_alloc& e) {
|
|
||||||
// Restart OBSW, hints at a memory leak
|
|
||||||
sif::error << "Allocation error in FileSystemHandler::performOperation" << e.what()
|
|
||||||
<< std::endl;
|
|
||||||
// Set up an error file or a special flag in the scratch buffer for these cases
|
|
||||||
triggerEvent(CoreController::ALLOC_FAILURE, 0, 0);
|
|
||||||
CoreController::incrementAllocationFailureCount();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileSystemHandler::fileSystemHandlerLoop() {
|
|
||||||
CommandMessage filemsg;
|
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
while (true) {
|
|
||||||
if (opCounter % 5 == 0) {
|
|
||||||
if (coreCtrl->sdInitFinished()) {
|
|
||||||
fileSystemCheckup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = mq->receiveMessage(&filemsg);
|
|
||||||
if (result == MessageQueueIF::EMPTY) {
|
|
||||||
break;
|
|
||||||
} else if (result != returnvalue::FAILED) {
|
|
||||||
sif::warning << "FileSystemHandler::performOperation: Message reception failed!" << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Command_t command = filemsg.getCommand();
|
|
||||||
switch (command) {
|
|
||||||
case (GenericFileSystemMessage::CMD_CREATE_DIRECTORY): {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case (GenericFileSystemMessage::CMD_CREATE_FILE): {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opCounter++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This task will have a low priority and will run permanently in the background
|
|
||||||
// so we will just run in a permanent loop here and check file system
|
|
||||||
// messages permanently
|
|
||||||
opCounter++;
|
|
||||||
TaskFactory::instance()->delayTask(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileSystemHandler::fileSystemCheckup() {
|
|
||||||
SdCardManager::SdStatePair statusPair;
|
|
||||||
sdcMan->getSdCardsStatus(statusPair);
|
|
||||||
sd::SdCard preferredSdCard = sdcMan->getPreferredSdCard();
|
|
||||||
if ((preferredSdCard == sd::SdCard::SLOT_0) and (statusPair.first == sd::SdState::MOUNTED)) {
|
|
||||||
currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
|
||||||
} else if ((preferredSdCard == sd::SdCard::SLOT_1) and
|
|
||||||
(statusPair.second == sd::SdState::MOUNTED)) {
|
|
||||||
currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT;
|
|
||||||
} else {
|
|
||||||
std::string sdString;
|
|
||||||
if (preferredSdCard == sd::SdCard::SLOT_0) {
|
|
||||||
sdString = "0";
|
|
||||||
} else {
|
|
||||||
sdString = "1";
|
|
||||||
}
|
|
||||||
sif::warning << "FileSystemHandler::performOperation: "
|
|
||||||
"Inconsistent state detected"
|
|
||||||
<< std::endl;
|
|
||||||
sif::warning << "Preferred SD card is " << sdString
|
|
||||||
<< " but does not appear to be mounted. Attempting fix.." << std::endl;
|
|
||||||
// This function will appear to fix the inconsistent state
|
|
||||||
ReturnValue_t result = sdcMan->sanitizeState(&statusPair, preferredSdCard);
|
|
||||||
if (result != returnvalue::OK) {
|
|
||||||
// Oh no.
|
|
||||||
triggerEvent(SdCardManager::SANITIZATION_FAILED, 0, 0);
|
|
||||||
sif::error << "FileSystemHandler::fileSystemCheckup: Sanitization failed" << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageQueueId_t FileSystemHandler::getCommandQueue() const { return mq->getId(); }
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::initialize() {
|
|
||||||
coreCtrl = ObjectManager::instance()->get<CoreController>(objects::CORE_CONTROLLER);
|
|
||||||
if (coreCtrl == nullptr) {
|
|
||||||
sif::error << "FileSystemHandler::initialize: Could not retrieve core controller handle"
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
sdcMan = SdCardManager::instance();
|
|
||||||
sd::SdCard preferredSdCard = sdcMan->getPreferredSdCard();
|
|
||||||
if (preferredSdCard == sd::SdCard::SLOT_0) {
|
|
||||||
currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
|
||||||
} else if (preferredSdCard == sd::SdCard::SLOT_1) {
|
|
||||||
currentMountPrefix = SdCardManager::SD_1_MOUNT_POINT;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::appendToFile(const char* repositoryPath, const char* filename,
|
|
||||||
const uint8_t* data, size_t size,
|
|
||||||
uint16_t packetNumber, FileSystemArgsIF* args) {
|
|
||||||
auto path = getInitPath(args) / repositoryPath / filename;
|
|
||||||
if (not std::filesystem::exists(path)) {
|
|
||||||
return FILE_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
std::ofstream file(path, std::ios_base::app | std::ios_base::out);
|
|
||||||
file.write(reinterpret_cast<const char*>(data), size);
|
|
||||||
if (not file.good()) {
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::createFile(const char* repositoryPath, const char* filename,
|
|
||||||
const uint8_t* data, size_t size,
|
|
||||||
FileSystemArgsIF* args) {
|
|
||||||
auto path = getInitPath(args) / filename;
|
|
||||||
if (std::filesystem::exists(path)) {
|
|
||||||
return FILE_ALREADY_EXISTS;
|
|
||||||
}
|
|
||||||
std::ofstream file(path);
|
|
||||||
file.write(reinterpret_cast<const char*>(data), size);
|
|
||||||
if (not file.good()) {
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::removeFile(const char* repositoryPath, const char* filename,
|
|
||||||
FileSystemArgsIF* args) {
|
|
||||||
auto path = getInitPath(args) / repositoryPath / filename;
|
|
||||||
if (not std::filesystem::exists(path)) {
|
|
||||||
return FILE_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
int result = std::remove(path.c_str());
|
|
||||||
if (result != 0) {
|
|
||||||
sif::warning << "FileSystemHandler::deleteFile: Failed with code " << result << std::endl;
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::createDirectory(const char* repositoryPath, const char* dirname,
|
|
||||||
bool createParentDirs, FileSystemArgsIF* args) {
|
|
||||||
auto path = getInitPath(args) / repositoryPath / dirname;
|
|
||||||
if (std::filesystem::exists(path)) {
|
|
||||||
return DIRECTORY_ALREADY_EXISTS;
|
|
||||||
}
|
|
||||||
if (std::filesystem::create_directory(path)) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
sif::warning << "Creating directory " << path << " failed" << std::endl;
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::removeDirectory(const char* repositoryPath, const char* dirname,
|
|
||||||
bool deleteRecurively, FileSystemArgsIF* args) {
|
|
||||||
auto path = getInitPath(args) / repositoryPath / dirname;
|
|
||||||
if (not std::filesystem::exists(path)) {
|
|
||||||
return DIRECTORY_DOES_NOT_EXIST;
|
|
||||||
}
|
|
||||||
std::error_code err;
|
|
||||||
if (not deleteRecurively) {
|
|
||||||
if (std::filesystem::remove(path, err)) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
} else {
|
|
||||||
// Check error code. Most probably denied permissions because folder is not empty
|
|
||||||
sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with "
|
|
||||||
"code "
|
|
||||||
<< err.value() << ": " << strerror(err.value()) << std::endl;
|
|
||||||
if (err.value() == ENOTEMPTY) {
|
|
||||||
return DIRECTORY_NOT_EMPTY;
|
|
||||||
} else {
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (std::filesystem::remove_all(path, err)) {
|
|
||||||
return returnvalue::OK;
|
|
||||||
} else {
|
|
||||||
sif::warning << "FileSystemHandler::removeDirectory: Deleting directory failed with "
|
|
||||||
"code "
|
|
||||||
<< err.value() << ": " << strerror(err.value()) << std::endl;
|
|
||||||
// Check error code
|
|
||||||
if (err.value() == ENOTEMPTY) {
|
|
||||||
return DIRECTORY_NOT_EMPTY;
|
|
||||||
} else {
|
|
||||||
return GENERIC_FILE_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReturnValue_t FileSystemHandler::renameFile(const char* repositoryPath, const char* oldFilename,
|
|
||||||
const char* newFilename, FileSystemArgsIF* args) {
|
|
||||||
auto basepath = getInitPath(args) / repositoryPath;
|
|
||||||
std::filesystem::rename(basepath / oldFilename, basepath / newFilename);
|
|
||||||
return returnvalue::OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileSystemHandler::parseCfg(FsCommandCfg* cfg, bool& useMountPrefix) {
|
|
||||||
if (cfg != nullptr) {
|
|
||||||
useMountPrefix = cfg->useMountPrefix;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::filesystem::path FileSystemHandler::getInitPath(FileSystemArgsIF* args) {
|
|
||||||
bool useMountPrefix = true;
|
|
||||||
parseCfg(reinterpret_cast<FsCommandCfg*>(args), useMountPrefix);
|
|
||||||
std::string path;
|
|
||||||
if (useMountPrefix) {
|
|
||||||
path = currentMountPrefix;
|
|
||||||
}
|
|
||||||
return std::filesystem::path(path);
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
#ifndef BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_
|
|
||||||
#define BSP_Q7S_MEMORY_FILESYSTEMHANDLER_H_
|
|
||||||
|
|
||||||
#include <filesystem>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
|
||||||
#include "SdCardManager.h"
|
|
||||||
#include "eive/definitions.h"
|
|
||||||
#include "fsfw/ipc/MessageQueueIF.h"
|
|
||||||
#include "fsfw/memory/HasFileSystemIF.h"
|
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
|
||||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
|
||||||
|
|
||||||
class CoreController;
|
|
||||||
|
|
||||||
class FileSystemHandler : public SystemObject, public ExecutableObjectIF, public HasFileSystemIF {
|
|
||||||
public:
|
|
||||||
struct FsCommandCfg : public FileSystemArgsIF {
|
|
||||||
// Can be used to automatically use mount prefix of active SD card.
|
|
||||||
// Otherwise, the operator has to specify the full path to the mounted SD card as well.
|
|
||||||
bool useMountPrefix = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
FileSystemHandler(object_id_t fileSystemHandler);
|
|
||||||
virtual ~FileSystemHandler();
|
|
||||||
|
|
||||||
ReturnValue_t performOperation(uint8_t) override;
|
|
||||||
|
|
||||||
ReturnValue_t initialize() override;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to get the MessageQueueId_t of the implementing object
|
|
||||||
* @return MessageQueueId_t of the object
|
|
||||||
*/
|
|
||||||
MessageQueueId_t getCommandQueue() const override;
|
|
||||||
ReturnValue_t appendToFile(const char* repositoryPath, const char* filename, const uint8_t* data,
|
|
||||||
size_t size, uint16_t packetNumber,
|
|
||||||
FileSystemArgsIF* args = nullptr) override;
|
|
||||||
ReturnValue_t createFile(const char* repositoryPath, const char* filename,
|
|
||||||
const uint8_t* data = nullptr, size_t size = 0,
|
|
||||||
FileSystemArgsIF* args = nullptr) override;
|
|
||||||
ReturnValue_t removeFile(const char* repositoryPath, const char* filename,
|
|
||||||
FileSystemArgsIF* args = nullptr) override;
|
|
||||||
ReturnValue_t createDirectory(const char* repositoryPath, const char* dirname,
|
|
||||||
bool createParentDirs, FileSystemArgsIF* args = nullptr) override;
|
|
||||||
ReturnValue_t removeDirectory(const char* repositoryPath, const char* dirname,
|
|
||||||
bool deleteRecurively = false,
|
|
||||||
FileSystemArgsIF* args = nullptr) override;
|
|
||||||
ReturnValue_t renameFile(const char* repositoryPath, const char* oldFilename,
|
|
||||||
const char* newFilename, FileSystemArgsIF* args = nullptr) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
CoreController* coreCtrl = nullptr;
|
|
||||||
MessageQueueIF* mq = nullptr;
|
|
||||||
std::string currentMountPrefix = SdCardManager::SD_0_MOUNT_POINT;
|
|
||||||
static constexpr uint32_t FS_MAX_QUEUE_SIZE = config::OBSW_FILESYSTEM_HANDLER_QUEUE_SIZE;
|
|
||||||
|
|
||||||
SdCardManager* sdcMan = nullptr;
|
|
||||||
uint8_t opCounter = 0;
|
|
||||||
|
|
||||||
void fileSystemHandlerLoop();
|
|
||||||
void fileSystemCheckup();
|
|
||||||
std::filesystem::path getInitPath(FileSystemArgsIF* args);
|
|
||||||
void parseCfg(FsCommandCfg* cfg, bool& useMountPrefix);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* BSP_Q7S_MEMORY_FILESYSTEMMANAGER_H_ */
|
|
8
bsp_q7s/memory/helpers.cpp
Normal file
8
bsp_q7s/memory/helpers.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
std::filesystem::path fshelpers::buildPrefixedPath(SdCardManager &man,
|
||||||
|
std::filesystem::path pathWihtoutPrefix) {
|
||||||
|
auto prefix = man.getCurrentMountPrefix();
|
||||||
|
auto resPath = prefix / pathWihtoutPrefix;
|
||||||
|
return resPath;
|
||||||
|
}
|
15
bsp_q7s/memory/helpers.h
Normal file
15
bsp_q7s/memory/helpers.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef BSP_Q7S_MEMORY_HELPERS_H_
|
||||||
|
#define BSP_Q7S_MEMORY_HELPERS_H_
|
||||||
|
|
||||||
|
#include <bsp_q7s/memory/SdCardManager.h>
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace fshelpers {
|
||||||
|
|
||||||
|
std::filesystem::path buildPrefixedPath(SdCardManager& man,
|
||||||
|
std::filesystem::path pathWihtoutPrefix);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* BSP_Q7S_MEMORY_HELPERS_H_ */
|
2
fsfw
2
fsfw
@ -1 +1 @@
|
|||||||
Subproject commit 7e0a5d5a9e4f38c6d818bbdd5b44d34d8007eb1e
|
Subproject commit 3d2fc2846833ee9c125d11107bbd56b3e13536f1
|
@ -1,6 +1,6 @@
|
|||||||
#include "PlocSupervisorHandler.h"
|
#include "PlocSupervisorHandler.h"
|
||||||
|
|
||||||
#include <fsfw/memory/HasFileSystemIF.h>
|
#include <fsfw/filesystem/HasFileSystemIF.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include "AxiPtmeConfig.h"
|
#include "AxiPtmeConfig.h"
|
||||||
#include "fsfw/objectmanager/SystemObject.h"
|
#include "fsfw/objectmanager/SystemObject.h"
|
||||||
#include "fsfw/returnvalues/returnvalue.h"
|
#include "fsfw/returnvalues/returnvalue.h"
|
||||||
#include "returnvalues/classIds.h"
|
|
||||||
#include "linux/obc/PtmeConfig.h"
|
#include "linux/obc/PtmeConfig.h"
|
||||||
|
#include "returnvalues/classIds.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class to configure donwlink specific parameters in the PTME IP core.
|
* @brief Class to configure donwlink specific parameters in the PTME IP core.
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include <fsfw/pus/Service8FunctionManagement.h>
|
#include <fsfw/pus/Service8FunctionManagement.h>
|
||||||
#include <fsfw/pus/Service9TimeManagement.h>
|
#include <fsfw/pus/Service9TimeManagement.h>
|
||||||
#include <fsfw/storagemanager/PoolManager.h>
|
#include <fsfw/storagemanager/PoolManager.h>
|
||||||
#include <fsfw/tcdistribution/CCSDSDistributor.h>
|
#include <fsfw/tcdistribution/CcsdsDistributor.h>
|
||||||
#include <fsfw/tcdistribution/PusDistributor.h>
|
#include <fsfw/tcdistribution/PusDistributor.h>
|
||||||
#include <fsfw/timemanager/CdsShortTimeStamper.h>
|
#include <fsfw/timemanager/CdsShortTimeStamper.h>
|
||||||
#include <mission/tmtc/TmFunnel.h>
|
#include <mission/tmtc/TmFunnel.h>
|
||||||
@ -75,7 +75,7 @@ void ObjectFactory::produceGenericObjects(HealthTableIF** healthTable_) {
|
|||||||
new PoolManager(objects::IPC_STORE, poolCfg);
|
new PoolManager(objects::IPC_STORE, poolCfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* ccsdsDistrib = new CCSDSDistributor(apid::EIVE_OBSW, objects::CCSDS_PACKET_DISTRIBUTOR);
|
auto* ccsdsDistrib = new CcsdsDistributor(apid::EIVE_OBSW, objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||||
new PusDistributor(apid::EIVE_OBSW, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
|
new PusDistributor(apid::EIVE_OBSW, objects::PUS_PACKET_DISTRIBUTOR, ccsdsDistrib);
|
||||||
|
|
||||||
uint8_t vc = 0;
|
uint8_t vc = 0;
|
||||||
|
@ -4,10 +4,9 @@
|
|||||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
|
|
||||||
#include "devicedefinitions/SusDefinitions.h"
|
#include "devicedefinitions/SusDefinitions.h"
|
||||||
|
#include "events/subsystemIdRanges.h"
|
||||||
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
#include "fsfw/globalfunctions/PeriodicOperationDivider.h"
|
||||||
#include "mission/devices/max1227.h"
|
#include "mission/devices/max1227.h"
|
||||||
|
|
||||||
#include "events/subsystemIdRanges.h"
|
|
||||||
#include "returnvalues/classIds.h"
|
#include "returnvalues/classIds.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,7 +39,7 @@ class SpTcBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateSpFields() {
|
void updateSpFields() {
|
||||||
spParams.creator.setDataLen(spParams.dataFieldLen - 1);
|
spParams.creator.setDataLenField(spParams.dataFieldLen - 1);
|
||||||
spParams.creator.setPacketType(ccsds::PacketType::TC);
|
spParams.creator.setPacketType(ccsds::PacketType::TC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "fsfw/memory/HasFileSystemIF.h"
|
#include "fsfw/filesystem/HasFileSystemIF.h"
|
||||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||||
|
|
||||||
NVMParameterBase::NVMParameterBase(std::string fullName) : fullName(fullName) {}
|
NVMParameterBase::NVMParameterBase(std::string fullName) : fullName(fullName) {}
|
||||||
|
@ -203,9 +203,9 @@ ReturnValue_t CCSDSHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentif
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t CCSDSHandler::getIdentifier() { return 0; }
|
uint32_t CCSDSHandler::getIdentifier() const { return 0; }
|
||||||
|
|
||||||
MessageQueueId_t CCSDSHandler::getRequestQueue() {
|
MessageQueueId_t CCSDSHandler::getRequestQueue() const {
|
||||||
// Forward packets directly to TC distributor
|
// Forward packets directly to TC distributor
|
||||||
return tcDistributorQueueId;
|
return tcDistributorQueueId;
|
||||||
}
|
}
|
||||||
@ -345,3 +345,5 @@ void CCSDSHandler::disableTransmit() {
|
|||||||
forwardLinkstate();
|
forwardLinkstate();
|
||||||
transmitterCountdown.setTimeout(0);
|
transmitterCountdown.setTimeout(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* CCSDSHandler::getName() const { return "CCSDS Handler"; }
|
||||||
|
@ -72,8 +72,9 @@ class CCSDSHandler : public SystemObject,
|
|||||||
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
ParameterWrapper* parameterWrapper, const ParameterWrapper* newValues,
|
||||||
uint16_t startAtIndex);
|
uint16_t startAtIndex);
|
||||||
|
|
||||||
uint16_t getIdentifier() override;
|
uint32_t getIdentifier() const override;
|
||||||
MessageQueueId_t getRequestQueue() override;
|
MessageQueueId_t getRequestQueue() const override;
|
||||||
|
const char* getName() const override;
|
||||||
|
|
||||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||||
const uint8_t* data, size_t size);
|
const uint8_t* data, size_t size);
|
||||||
|
@ -121,3 +121,5 @@ ReturnValue_t TmFunnel::initialize() {
|
|||||||
|
|
||||||
return SystemObject::initialize();
|
return SystemObject::initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* TmFunnel::getName() const { return "TM Funnel"; }
|
||||||
|
@ -28,9 +28,10 @@ class TmFunnel : public AcceptsTelemetryIF, public ExecutableObjectIF, public Sy
|
|||||||
uint8_t reportReceptionVc = 0);
|
uint8_t reportReceptionVc = 0);
|
||||||
virtual ~TmFunnel();
|
virtual ~TmFunnel();
|
||||||
|
|
||||||
virtual MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override;
|
const char* getName() const override;
|
||||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
MessageQueueId_t getReportReceptionQueue(uint8_t virtualChannel = 0) override;
|
||||||
virtual ReturnValue_t initialize() override;
|
ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static object_id_t downlinkDestination;
|
static object_id_t downlinkDestination;
|
||||||
|
@ -12,6 +12,7 @@ VirtualChannel::VirtualChannel(uint8_t vcId, uint32_t tmQueueDepth, object_id_t
|
|||||||
auto mqArgs = MqArgs(ownerId, reinterpret_cast<void*>(vcId));
|
auto mqArgs = MqArgs(ownerId, reinterpret_cast<void*>(vcId));
|
||||||
tmQueue = QueueFactory::instance()->createMessageQueue(
|
tmQueue = QueueFactory::instance()->createMessageQueue(
|
||||||
tmQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
tmQueueDepth, MessageQueueMessage::MAX_MESSAGE_SIZE, &mqArgs);
|
||||||
|
vcName = "VC " + vcId;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t VirtualChannel::initialize() {
|
ReturnValue_t VirtualChannel::initialize() {
|
||||||
@ -65,3 +66,5 @@ void VirtualChannel::setPtmeObject(PtmeIF* ptme_) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VirtualChannel::setLinkState(bool linkIsUp_) { linkIsUp = linkIsUp_; }
|
void VirtualChannel::setLinkState(bool linkIsUp_) { linkIsUp = linkIsUp_; }
|
||||||
|
|
||||||
|
const char* VirtualChannel::getName() const { return vcName.c_str(); }
|
||||||
|
@ -42,11 +42,13 @@ class VirtualChannel : public AcceptsTelemetryIF {
|
|||||||
* to ground station is down.
|
* to ground station is down.
|
||||||
*/
|
*/
|
||||||
void setLinkState(bool linkIsUp_);
|
void setLinkState(bool linkIsUp_);
|
||||||
|
const char* getName() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PtmeIF* ptme = nullptr;
|
PtmeIF* ptme = nullptr;
|
||||||
MessageQueueIF* tmQueue = nullptr;
|
MessageQueueIF* tmQueue = nullptr;
|
||||||
uint8_t vcId = 0;
|
uint8_t vcId = 0;
|
||||||
|
std::string vcName;
|
||||||
|
|
||||||
bool linkIsUp = false;
|
bool linkIsUp = false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user