str img loader wip

This commit is contained in:
Jakob Meier
2021-12-02 08:05:33 +01:00
parent 8c649b3e70
commit a7ab2bb93a
11 changed files with 526 additions and 214 deletions

View File

@ -0,0 +1,68 @@
#include "ArcsecDatalinkLayer.h"
ArcsecDatalinkLayer::ArcsecDatalinkLayer() {
slipInit();
}
ArcsecDatalinkLayer::~ArcsecDatalinkLayer() {
}
void ArcsecDatalinkLayer::slipInit() {
slipInfo.buffer = rxBuffer;
slipInfo.maxlength = StarTracker::MAX_FRAME_SIZE;
slipInfo.length = 0;
slipInfo.unescape_next = 0;
slipInfo.prev_state = SLIP_COMPLETE;
}
ReturnValue_t ArcsecDatalinkLayer::decodeFrame(const uint8_t* rawData, size_t rawDataSize,
size_t* bytesLeft) {
size_t bytePos = 0;
for (bytePos = 0; bytePos < rawDataSize; bytePos++) {
enum arc_dec_result decResult = arc_transport_decode_body(*(rawData + bytePos), &slipInfo,
decodedFrame, &decFrameSize);
*bytesLeft = rawDataSize - bytePos;
switch (decResult) {
case ARC_DEC_INPROGRESS: {
if (bytePos == rawDataSize - 1) {
return DEC_IN_PROGRESS;
}
continue;
}
case ARC_DEC_ERROR_FRAME_SHORT:
return REPLY_TOO_SHORT;
case ARC_DEC_ERROR_CHECKSUM:
return CRC_FAILURE;
case ARC_DEC_ASYNC:
case ARC_DEC_SYNC: {
// Reset length of SLIP struct for next frame
slipInfo.length = 0;
RETURN_OK;
}
default:
sif::debug << "ArcsecDatalinkLayer::decodeFrame: Unknown result code" << std::endl;
break;
}
}
}
uint8_t ArcsecDatalinkLayer::getReplyFrameType() {
return decodedFrame[0];
}
const uint8_t* ArcsecDatalinkLayer::getReply() {
return &decodedFrame[1];
}
void ArcsecDatalinkLayer::encodeFrame(const uint8_t* data, uint32_t length) {
arc_transport_encode_body(commandBuffer, length, encBuffer, &encFrameSize);
}
uint8_t* ArcsecDatalinkLayer::getEncodedFrame() {
return encBuffer;
}
uint32_t ArcsecDatalinkLayer::getEncodedLength() {
return encFrameSize;
}

View File

@ -0,0 +1,84 @@
#ifndef BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_
#define BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_
#include "mission/devices/devicedefinitions/StarTrackerDefinitions.h"
#include "fsfw/returnvalues/HasReturnValuesIF.h"
extern "C" {
#include "common/misc.h"
}
/**
* @brief Helper class to handle the datalinklayer of replies from the star tracker of arcsec.
*/
class ArcsecDatalinkLayer: public HasReturnvaluesIF {
public:
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HANDLER;
//! [EXPORT] : [COMMENT] More data required to complete frame
static const ReturnValue_t DEC_IN_PROGRESS = MAKE_RETURN_CODE(0xA0);
//! [EXPORT] : [COMMENT] Data too short to represent a valid frame
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);
ArcsecDatalinkLayer();
virtual ~ArcsecDatalinkLayer();
/**
* @brief Applies decoding to data referenced by rawData pointer
*
* @param rawData Pointer to raw data received from star tracker
* @param rawDataSize Size of raw data stream
* @param remainingBytes Number of bytes left
*/
ReturnValue_t decodeFrame(const uint8_t* rawData, size_t rawDataSize, size_t* bytesLeft);
/**
* @brief SLIP encodes data pointed to by data pointer.
*
* @param data Pointer to data to encode
* @param length Length of buffer to encode
*/
void encodeFrame(const uint8_t* data, uint32_t length);
/**
* @brief Returns the frame type field of a decoded frame.
*/
uint8_t getReplyFrameType();
/**
* @brief Returns pointer to reply packet.
*/
const uint8_t* getReply();
/**
* @brief Returns size of encoded frame
*/
uint32_t getEncodedLength();
/**
* @brief Returns pointer to encoded frame
*/
uint8_t* getEncodedFrame();
private:
// Used by arcsec slip decoding function process received data
uint8_t rxBuffer[StarTracker::MAX_FRAME_SIZE];
// Decoded frame will be copied to this buffer
uint8_t decodedFrame[StarTracker::MAX_FRAME_SIZE];
// Buffer where encoded frames will be stored
uint8_t encBuffer[StarTracker::MAX_FRAME_SIZE * 2 + 2];
// Size of decoded frame
uint32_t decFrameSize = 0;
// Size of encoded frame
uint32_t encFrameSize = 0;
slip_decode_state slipInfo;
void slipInit();
};
#endif /* BSP_Q7S_DEVICES_ARCSECDATALINKLAYER_H_ */

View File

@ -17,15 +17,21 @@ ReturnValue_t StrImageLoader::initialize() {
}
ReturnValue_t StrImageLoader::performOperation(uint8_t operationCode) {
ReturnValue_t result = RETURN_OK;
semaphore.acquire();
while(true) {
switch(internalState) {
case InternalState::IDLE:
case InternalState::IDLE: {
semaphore.acquire();
break;
case InternalState::UPLOAD_IMAGE:
uploadImage();
}
case InternalState::UPLOAD_IMAGE: {
result = uploadImage();
if (result == RETURN_OK){
triggerEvent(IMAGE_UPLOAD_SUCCESSFUL);
}
break;
}
case InternalState::DOWNLOAD_IMAGE:
break;
}
@ -42,7 +48,6 @@ void StrImageLoader::setComCookie(CookieIF* comCookie_) {
ReturnValue_t StrImageLoader::startImageUpload(std::string image) {
//TODO: Use string part not data pointer
// Check if file is stored on SD card and if associated SD card is mounted
if (image.substr(0, sizeof(SdCardManager::SD_0_MOUNT_POINT))
== std::string(SdCardManager::SD_0_MOUNT_POINT)) {
@ -70,6 +75,82 @@ ReturnValue_t StrImageLoader::startImageUpload(std::string image) {
}
ReturnValue_t StrImageLoader::uploadImage() {
ReturnValue_t result = RETURN_OK;
size_t receivedDataLen = 0;
uint8_t *receivedData = nullptr;
size_t bytesLeft = 0;
uint32_t readSize = 0;
uint32_t imageSize = 0;
struct UploadActionRequest uploadReq;
uploadReq.position = 0;
uploadReq.data = {0};
if (not std::filesystem::exists(uploadImage)) {
triggerEvent(IMAGE_FILE_NOT_EXISTS, uploadReq.position);
state = State::IDLE;
return RETURN_FAILED;
}
std::ifstream file(uploadImage, std::ifstream::binary);
file.seekg(0, file.end);
imageSize = file.tellg();
file.seekg(uploadReq.position * SIZE_IMAGE_PART, file.beg);
while(uploadReq.position * SIZE_IMAGE_PART < imageSize) {
result =
}
uint32_t remainder = imageSize - uploadReq.position * SIZE_IMAGE_PART;
file.read(reinterpret_cast<char*>(uploadReq.data), remainder);
uploadReq.position++;
datalinkLayer.encodeFrame(uploadReq.data, remainder);
result = communicationInterface->sendMessage(comCookie, datalinkLayer.getEncodedFrame(),
datalinkLayer.getEncodedLength());
if (result = RETURN_OK) {
sif::warning << "StrImageLoader::uploadImage: Failed to send upload packet" << std::endl;
triggerEvent(SENDING_UPLOAD_PACKET_FAILED, result, uploadReq.position);
return RETURN_FAILED;
}
result = ArcsecDatalinkLayer::DEC_IN_PROGRESS;
while(result == ArcsecDatalinkLayer::DEC_IN_PROGRESS) {
result = communicationInterface->requestReceiveMessage(comCookie, StarTracker::MAX_FRAME_SIZE* 2 + 2);
if (result != RETURN_OK) {
sif::warning << "StrImageLoader::uploadImage: Failed to request reply" << std::endl;
triggerEvent(UPLOAD_REQUESTING_MSG_FAILED, result, uploadReq.position);
return RETURN_FAILED;
}
result = communicationInterface->readReceivedMessage(comCookie, receivedData,
receivedDataLen);
if (result != RETURN_OK) {
sif::warning << "StrImageLoader::uploadImage: Failed to read received message"
<< std::endl;
triggerEvent(UPLOAD_READING_REPLY_FAILED, result, uploadReq.position);
}
result = datalinkLayer.decodeFrame(receivedData, receivedDataLen, &bytesLeft);
if (bytesLeft != 0) {
// This should never happen
triggerEvent(UPLOAD_COM_ERROR, result, uploadReq.position);
return RETURN_FAILED;
}
}
if (remainingCommands == 1) {
dataLen = imageSize - file.tellg();
}
else {
dataLen = SIZE_IMAGE_PART;
}
size_t size = 0;
size_t maxSize = sizeof(position);
uint8_t* commandBufferPtr = tmpCommandBuffer;
uint8_t** buffer = &commandBufferPtr;
SerializeAdapter::serialize(&position, buffer, &size, maxSize,
SerializeIF::Endianness::BIG);
file.read(reinterpret_cast<char*>(uploadReq.data), dataLen);
file.close();
arc_pack_upload_action_req()
communicationInterface->requestReceiveMessage(comCookie, )
}

View File

@ -5,6 +5,8 @@
#include "fsfw/osal/linux/BinarySemaphore.h"
#include "bsp_q7s/memory/SdCardManager.h"
#include "bsp_q7s/devices/ArcsecDatalinkLayer.h"
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
/**
* @brief An object of this class runs in a separate task and is responsible for uploading and
@ -12,8 +14,33 @@
* downloading via the star tracker handler takes a lot of time because each upload or
* download packet can transport a maximum of 1024 bytes.
*/
class StrImageLoader: public SystemObject, public ExecutableObjectIF {
class StrImageLoader: public SystemObject, public ExecutableObjectIF, public HasReturnvaluesIF {
public:
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_IMAGE_LOADER;
//! [EXPORT] : [COMMENT] Try to upload image but specified image does not exist
static const Event IMAGE_FILE_NOT_EXISTS = MAKE_EVENT(0, severity::LOW);
//! [EXPORT] : [COMMENT] Sending image upload packet to star tracker failed
//!P1: Return code of communication interface sendMessage function
//!P2: Position of upload packet for which the transmission failed
static const Event SENDING_UPLOAD_PACKET_FAILED = MAKE_EVENT(1, severity::LOW);
//! [EXPORT] : [COMMENT] Communication interface requesting reply failed
//!P1: Return code of failed request
//!P1: Upload position for which the request failed
static const Event UPLOAD_REQUESTING_MSG_FAILED = MAKE_EVENT(2, severity::LOW);
//! [EXPORT] : [COMMENT] Uploading image to star tracker was successful
static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] Failed to read communication interface reply data
//!P1: Return code of failed communication interface read call
//!P1: Upload position for which the read call failed
static const Event UPLOAD_READING_REPLY_FAILED = MAKE_EVENT(3, severity::LOW);
//! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence
//!P1: Return code of failed communication interface read call
//!P1: Upload position for which the read call failed
static const Event UPLOAD_COM_ERROR = MAKE_EVENT(4, severity::LOW);
StrImageLoader(object_id_t objectId);
virtual ~StrImageLoader();
@ -22,6 +49,14 @@ public:
void setComIF(DeviceCommunicationIF* communicationInterface_);
void setComCookie(CookieIF* comCookie_);
/**
* @brief Starts sequence to upload image to star tracker
*
* @param image Name including absolute path if to image to upload. Must be previously
* transferred to the OBC with the CFDP protocoll.
*/
ReturnValue_t startImageUpload(std::string image);
private:
static const uint8_t INTERFACE_ID = CLASS_ID::STR_IMG_LOADER;
@ -31,6 +66,9 @@ private:
//! [EXPORT] : [COMMENT] Specified file does not exist on filesystem
static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(0xA1);
// Size of one image part which can be sent per action request
static const size_t SIZE_IMAGE_PART = 1024;
enum class InternalState {
IDLE,
UPLOAD_IMAGE,
@ -39,6 +77,8 @@ private:
InternalState internalState = InternalState::IDLE;
ArcsecDatalinkLayer datalinkLayer;
BinarySemaphore semaphore;
// Absolute path and name to image to upload
@ -51,6 +91,13 @@ private:
* Must be set by star tracker handler
*/
DeviceCommunicationIF * communicationInterface = nullptr;
// Communication cookie. Must be set by the star tracker handler
CookieIF* comCookie = nullptr;
/**
* @brief Performs image uploading
*/
ReturnValue_t uploadImage();
};
#endif /* BSP_Q7S_DEVICES_STRIMAGELOADER_H_ */