flash read request

This commit is contained in:
Jakob Meier 2021-12-22 16:06:30 +01:00
parent 8a104c4af2
commit 1331c9e7e9
6 changed files with 221 additions and 38 deletions

View File

@ -127,12 +127,15 @@ void initmission::initTasks() {
initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::FILE_SYSTEM_HANDLER);
}
#if OBSW_ADD_STAR_TRACKER == 1
PeriodicTaskIF* strImgLoaderTask = factory->createPeriodicTask(
"FILE_SYSTEM_TASK", 20, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
result = strImgLoaderTask->addComponent(objects::STR_HELPER);
if(result != HasReturnvaluesIF::RETURN_OK) {
initmission::printAddObjectError("FILE_SYSTEM_TASK", objects::STR_HELPER);
}
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
#endif /* BOARD_TE0720 */
#if OBSW_TEST_CCSDS_BRIDGE == 1
@ -194,7 +197,9 @@ void initmission::initTasks() {
#if BOARD_TE0720 == 0
fsTask->startTask();
#if OBSW_ADD_STAR_TRACKER == 1
strImgLoaderTask->startTask();
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
#endif
sif::info << "Tasks started.." << std::endl;

View File

@ -202,6 +202,7 @@ static const DeviceCommandId_t STOP_IMAGE_LOADER = 55;
static const DeviceCommandId_t RESET_ERROR = 56;
static const DeviceCommandId_t CHANGE_DOWNLOAD_FILE = 57;
static const DeviceCommandId_t SET_JSON_FILE_NAME = 58;
static const DeviceCommandId_t SET_READ_FILENAME = 59;
static const DeviceCommandId_t NONE = 0xFFFFFFFF;
static const uint32_t VERSION_SET_ID = REQ_VERSION;

View File

@ -145,6 +145,18 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
strHelperExecuting = true;
return EXECUTION_FINISHED;
}
case(StarTracker::READ): {
result = DeviceHandlerBase::acceptExternalDeviceCommands();
if (result != RETURN_OK) {
return result;
}
result = executeReadCommand(data, size);
if (result != RETURN_OK) {
return result;
}
strHelperExecuting = true;
return EXECUTION_FINISHED;
}
case(StarTracker::CHANGE_DOWNLOAD_FILE): {
if (size > MAX_FILE_NAME) {
return FILENAME_TOO_LONG;
@ -153,6 +165,14 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
std::string(reinterpret_cast<const char*>(data), size));
return EXECUTION_FINISHED;
}
case(StarTracker::SET_READ_FILENAME): {
if (size > MAX_FILE_NAME) {
return FILENAME_TOO_LONG;
}
strHelper->setDownloadImageName(
std::string(reinterpret_cast<const char*>(data), size));
return EXECUTION_FINISHED;
}
default:
break;
}
@ -396,6 +416,10 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
result = prepareParamCommand(commandData, commandDataLen, tracking);
return result;
}
case (StarTracker::UNLOCK): {
result = prepareUnlockCommand(commandData, commandDataLen);
return result;
}
default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
@ -454,6 +478,8 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
StarTracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(StarTracker::RESET_ERROR, 3, nullptr,
StarTracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(StarTracker::UNLOCK, 3, nullptr,
StarTracker::MAX_FRAME_SIZE * 2 + 2);
}
ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize,
@ -522,15 +548,10 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con
result = handlePingReply();
break;
}
case (StarTracker::BOOT): {
result = handleActionReply();
break;
}
case (StarTracker::RESET_ERROR): {
result = handleActionReply();
break;
}
case (StarTracker::TAKE_IMAGE): {
case (StarTracker::BOOT):
case (StarTracker::TAKE_IMAGE):
case (StarTracker::RESET_ERROR):
case (StarTracker::UNLOCK): {
result = handleActionReply();
break;
}
@ -809,6 +830,10 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId)
*foundId = StarTracker::RESET_ERROR;
break;
}
case (StarTracker::ID::UNLOCK): {
*foundId = StarTracker::UNLOCK;
break;
}
default:
sif::warning << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id"
<< std::endl;
@ -966,6 +991,49 @@ ReturnValue_t StarTrackerHandler::executeWriteCommand(const uint8_t* commandData
return result;
}
ReturnValue_t StarTrackerHandler::executeReadCommand(const uint8_t* commandData,
size_t commandDataLen) {
ReturnValue_t result = RETURN_OK;
if (commandDataLen < ReadCmd::MIN_LENGTH) {
sif::warning << "StarTrackerHandler::executeReadCommand: Command too short" << std::endl;
return COMMAND_TOO_SHORT;
}
uint8_t region = *(commandData);
uint32_t address;
size_t size = sizeof(address);
const uint8_t* addressPtr = commandData + ReadCmd::ADDRESS_OFFSET;
result = SerializeAdapter::deSerialize(&address, addressPtr, &size,
SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) {
sif::debug << "StarTrackerHandler::executeReadCommand: Deserialization of address failed"
<< std::endl;
return result;
}
uint16_t length;
size = sizeof(length);
const uint8_t* lengthPtr = commandData + ReadCmd::LENGTH_OFFSET;
result = SerializeAdapter::deSerialize(&address, lengthPtr, &size,
SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) {
sif::debug << "StarTrackerHandler::executeReadCommand: Deserialization of length failed"
<< std::endl;
return result;
}
if (commandDataLen - sizeof(address) - sizeof(region) - sizeof(length) > MAX_PATH_SIZE) {
sif::warning << "StarTrackerHandler::executeReadCommand: Received command with invalid"
<< " path and filename" << std::endl;
return FILE_PATH_TOO_LONG;
}
const uint8_t* filePtr = commandData + ReadCmd::FILE_OFFSET;
std::string fullname = std::string(reinterpret_cast<const char*>(filePtr),
commandDataLen - sizeof(address) - sizeof(region) - sizeof(length));
result = strHelper->startFlashRead(fullname, region, address, length);
if (result != RETURN_OK) {
return result;
}
return result;
}
void StarTrackerHandler::prepareBootCommand() {
uint32_t length = 0;
struct BootActionRequest bootRequest = {BOOT_REGION_ID};
@ -975,6 +1043,25 @@ void StarTrackerHandler::prepareBootCommand() {
rawPacketLen = dataLinkLayer.getEncodedLength();
}
ReturnValue_t StarTrackerHandler::prepareUnlockCommand(const uint8_t* commandData, size_t commandDataLen) {
ReturnValue_t result = RETURN_OK;
uint32_t length = 0;
struct UnlockActionRequest req;
req.region = *commandData;
size_t size = sizeof(req.code);
const uint8_t* codePtr = commandData + UnlockCmd::CODE_OFFSET;
result = SerializeAdapter::deSerialize(&req.code, &codePtr, &size,
SerializeIF::Endianness::BIG);
if (result != RETURN_OK) {
return result;
}
arc_pack_unlock_action_req(&req, commandBuffer, &length);
dataLinkLayer.encodeFrame(commandBuffer, length);
rawPacket = dataLinkLayer.getEncodedFrame();
rawPacketLen = dataLinkLayer.getEncodedLength();
return result;
}
void StarTrackerHandler::prepareTimeRequest() {
uint32_t length = 0;
arc_tm_pack_time_req(commandBuffer, &length);

View File

@ -147,6 +147,20 @@ private:
static const size_t MIN_LENGTH = 7;
};
class ReadCmd {
public:
static const uint8_t ADDRESS_OFFSET = 1;
static const uint8_t LENGTH_OFFSET = 5;
static const uint8_t FILE_OFFSET = 7;
// Minimum length of a read command (region, address, length and filename)
static const size_t MIN_LENGTH = 9;
};
class UnlockCmd {
public:
static const uint8_t CODE_OFFSET = 1;
};
MessageQueueIF* eventQueue = nullptr;
ArcsecDatalinkLayer dataLinkLayer;
@ -245,12 +259,28 @@ private:
*/
ReturnValue_t executeWriteCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Extracts information for flash-read-command from TC data and starts execution of
* flash-read-procedure
*
* @param commandData Pointer to received command data
* @param commandDataLen Size of received command data
*
* @return RETURN_OK if start of execution was successful, otherwise error return value
*/
ReturnValue_t executeReadCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Fills command buffer with data to boot image (works only when star tracker is
* in bootloader mode).
*/
void prepareBootCommand();
/**
* @brief Fills command buffer with command to unlock flash region
*/
ReturnValue_t prepareUnlockCommand(const uint8_t* commandData, size_t commandDataLen);
/**
* @brief Fills the command buffer with the command to take an image.
*/

View File

@ -63,6 +63,17 @@ ReturnValue_t StrHelper::performOperation(uint8_t operationCode) {
internalState = InternalState::IDLE;
break;
}
case InternalState::FLASH_READ: {
result = performFlashRead();
if (result == RETURN_OK){
triggerEvent(FLASH_READ_SUCCESSFUL);
}
else {
triggerEvent(FLASH_READ_FAILED);
}
internalState = InternalState::IDLE;
break;
}
default:
sif::debug << "StrHelper::performOperation: Invalid state" << std::endl;
break;
@ -121,8 +132,12 @@ void StrHelper::setDownloadImageName(std::string image) {
downloadImage = image;
}
void StrHelper::setFlashReadFilename(std::string filename) {
flashReadFile = filename;
}
ReturnValue_t StrHelper::startFlashWrite(std::string flashWriteFile_, uint8_t region,
uint32_t flashWriteAddress) {
uint32_t address) {
ReturnValue_t result = checkPath(flashWriteFile_);
if (result != RETURN_OK) {
return result;
@ -131,12 +146,33 @@ ReturnValue_t StrHelper::startFlashWrite(std::string flashWriteFile_, uint8_t re
if(not std::filesystem::exists(flashWriteFile)) {
return FILE_NOT_EXISTS;
}
flashWriteAddress = address;
flashWriteRegion = region;
internalState = InternalState::FLASH_WRITE;
semaphore.release();
terminate = false;
return RETURN_OK;
}
ReturnValue_t StrHelper::startFlashRead(std::string flashReadFile_, uint8_t region,
uint32_t address, uint16_t length) {
ReturnValue_t result = checkPath(flashReadFile_);
if (result != RETURN_OK) {
return result;
}
flashReadFile = flashReadFile_;
if(not std::filesystem::exists(flashReadFile)) {
return FILE_NOT_EXISTS;
}
flashReadAddress = address;
flashReadRegion = region;
flashReadSize = length;
internalState = InternalState::FLASH_READ;
semaphore.release();
terminate = false;
return RETURN_OK;
}
ReturnValue_t StrHelper::performImageDownload() {
ReturnValue_t result;
struct DownloadActionRequest downloadReq;
@ -184,7 +220,7 @@ ReturnValue_t StrHelper::performImageDownload() {
file.close();
return result;
}
file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + DATA_OFFSET),
file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + IMAGE_DATA_OFFSET),
IMAGE_DATA_SIZE);
downloadReq.position++;
retries = 0;
@ -274,7 +310,7 @@ ReturnValue_t StrHelper::performFlashWrite() {
if (result != RETURN_OK) {
return RETURN_FAILED;
}
result = checkFlashWriteReply(req);
result = checkFlashActionReply(req.region, req.address, req.length);
if (result != RETURN_OK) {
return result;
}
@ -288,7 +324,7 @@ ReturnValue_t StrHelper::performFlashWrite() {
if (result != RETURN_OK) {
return RETURN_FAILED;
}
result = checkFlashWriteReply(req);
result = checkFlashActionReply(req.region, req.address, req.length);
if (result != RETURN_OK) {
return result;
}
@ -302,13 +338,12 @@ ReturnValue_t StrHelper::performFlashRead() {
uint32_t size = 0;
uint32_t retries = 0;
Timestamp timestamp;
std::string file = flashReadPath + "/" + timestamp.str() + flashReadFile ;
std::ofstream file(file, std::ios_base::app | std::ios_base::out);
if(not std::filesystem::exists(file)) {
std::string fullname = flashReadPath + "/" + timestamp.str() + flashReadFile ;
std::ofstream file(fullname, std::ios_base::app | std::ios_base::out);
if (not std::filesystem::exists(fullname)) {
return FILE_CREATION_FAILED;
}
req.region = flashReadRegion;
req.address = flashReadAddress;
while(bytesRead < flashReadSize) {
if (terminate) {
return RETURN_OK;
@ -319,12 +354,9 @@ ReturnValue_t StrHelper::performFlashRead() {
else {
req.length = MAX_FLASH_DATA;
}
arc_pack_read_action_req(&req, commandBuffer, static_cast<uint32_t>(req.length));
result = sendAndRead(size, downloadReq.position);
req.address = flashReadAddress + bytesRead;
arc_pack_read_action_req(&req, commandBuffer, &size);
result = sendAndRead(size, req.address);
if (result != RETURN_OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
uartComIF->flushUartRxBuffer(comCookie);
@ -344,7 +376,7 @@ ReturnValue_t StrHelper::performFlashRead() {
file.close();
return result;
}
result = checkReplyPosition(downloadReq.position);
result = checkFlashActionReply(req.region, req.address, req.length);
if (result != RETURN_OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
uartComIF->flushUartRxBuffer(comCookie);
@ -354,9 +386,9 @@ ReturnValue_t StrHelper::performFlashRead() {
file.close();
return result;
}
file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + DATA_OFFSET),
IMAGE_DATA_SIZE);
downloadReq.position++;
file.write(reinterpret_cast<const char*>(datalinkLayer.getReply() + FLASH_READ_DATA_OFFSET),
req.length);
bytesRead += req.length;
retries = 0;
}
file.close();
@ -446,8 +478,13 @@ ReturnValue_t StrHelper::checkReplyPosition(uint32_t expectedPosition) {
return RETURN_OK;
}
ReturnValue_t StrHelper::checkFlashWriteReply(struct WriteActionRequest& req) {
ReturnValue_t StrHelper::checkFlashActionReply(uint8_t region_, uint32_t address_,
uint16_t length_) {
ReturnValue_t result = RETURN_OK;
result = checkReply();
if (result != RETURN_OK) {
return result;
}
const uint8_t* data = datalinkLayer.getReply();
uint8_t region = *(data + REGION_OFFSET);
uint32_t address;
@ -456,7 +493,7 @@ ReturnValue_t StrHelper::checkFlashWriteReply(struct WriteActionRequest& req) {
result = SerializeAdapter::deSerialize(&address, &addressData, &size,
SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) {
sif::warning << "StrHelper::checkFlashWriteReply: Deserialization of address failed"
sif::warning << "StrHelper::checkFlashActionReply: Deserialization of address failed"
<< std::endl;
}
uint16_t length;
@ -465,16 +502,16 @@ ReturnValue_t StrHelper::checkFlashWriteReply(struct WriteActionRequest& req) {
result = SerializeAdapter::deSerialize(&length, lengthData, &size,
SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) {
sif::warning << "StrHelper::checkFlashWriteReply: Deserialization of length failed"
sif::warning << "StrHelper::checkFlashActionReply: Deserialization of length failed"
<< std::endl;
}
if (region != req.region) {
if (region != region_) {
return REGION_MISMATCH;
}
if (address != req.address) {
if (address != address_) {
return ADDRESS_MISMATCH;
}
if (region != req.length) {
if (region != length_) {
return LENGTH_MISMATCH;
}
return RETURN_OK;

View File

@ -103,10 +103,21 @@ public:
*
* @param flashWriteFile_ Full name including absolute path of file to write to flash
* @param region Region ID of flash region to write to
* @param flashWriteAddress Start address of flash write procedure
* @param address Start address of flash write procedure
*/
ReturnValue_t startFlashWrite(std::string flashWriteFile_, uint8_t region,
uint32_t flashWriteAddress);
uint32_t address);
/**
* @brief Starts the flash read procedure
*
* @param flashWriteFile_ Full name including absolute path of file to write to flash
* @param region Region ID of flash region to read from
* @param flashWriteAddress Start address of flash section to read
* @param length Number of bytes to read from flash
*/
ReturnValue_t startFlashRead(std::string flashReadFile_, uint8_t region,
uint32_t address, uint16_t length);
/**
* @brief Can be used to interrupt a running data transfer.
@ -118,6 +129,11 @@ public:
*/
void setDownloadImageName(std::string image);
/**
* @brief Sets the name of the file which will be created to store the data read from flash
*/
void setFlashReadFilename(std::string filename);
private:
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER;
@ -145,7 +161,8 @@ private:
static const uint32_t MAX_POLLS = 10000;
static const uint8_t POS_OFFSET = 2;
static const uint8_t DATA_OFFSET = 5;
static const uint8_t IMAGE_DATA_OFFSET = 5;
static const uint8_t FLASH_READ_DATA_OFFSET = 8;
static const uint8_t REGION_OFFSET = 2;
static const uint8_t ADDRESS_OFFSET = 3;
static const uint8_t LENGTH_OFFSET = 7;
@ -232,6 +249,12 @@ private:
*/
ReturnValue_t performFlashWrite();
/**
* @brief Sends a sequence of commands to the star tracker to read larger parts from the
* flash memory.
*/
ReturnValue_t performFlashRead();
/**
* @brief Sends packet to the star tracker and reads reply by using the communication
* interface
@ -260,12 +283,12 @@ private:
ReturnValue_t checkReplyPosition(uint32_t expectedPosition);
/**
* @brief Checks the region, address and length value of a flash write reply.
* @brief Checks the region, address and length value of a flash write or read reply.
*
* @return RETURN_OK if values match expected values, otherwise appropriate error return
* value.
*/
ReturnValue_t checkFlashWriteReply(struct WriteActionRequest& req);
ReturnValue_t checkFlashActionReply(uint8_t region_, uint32_t address_, uint16_t length_);
/**
* @brief Checks if a path points to an sd card and whether the SD card is monuted.