upload fpga image command
Some checks failed
EIVE/eive-obsw/pipeline/pr-develop There was a failure building this commit

This commit is contained in:
Jakob Meier 2021-12-30 12:52:08 +01:00
parent 3833b7a875
commit 29e7ac210a
5 changed files with 172 additions and 14 deletions

View File

@ -242,6 +242,9 @@ static const DeviceCommandId_t SET_TIME = 60;
static const DeviceCommandId_t DOWNLOAD_DBIMAGE = 61; static const DeviceCommandId_t DOWNLOAD_DBIMAGE = 61;
static const DeviceCommandId_t DOWNLOAD_BLOBPIXEL = 62; static const DeviceCommandId_t DOWNLOAD_BLOBPIXEL = 62;
static const DeviceCommandId_t DOWNLOAD_FPGA_IMAGE = 63; static const DeviceCommandId_t DOWNLOAD_FPGA_IMAGE = 63;
static const DeviceCommandId_t CHANGE_FPGA_DOWNLOAD_FILE = 64;
static const DeviceCommandId_t UPLOAD_FPGA_IMAGE = 65;
static const DeviceCommandId_t FPGA_ACTION = 66;
static const DeviceCommandId_t NONE = 0xFFFFFFFF; static const DeviceCommandId_t NONE = 0xFFFFFFFF;
static const uint32_t VERSION_SET_ID = REQ_VERSION; static const uint32_t VERSION_SET_ID = REQ_VERSION;
@ -313,6 +316,7 @@ namespace ID {
static const uint8_t DOWNLOAD_MATCHED_STAR = 18; static const uint8_t DOWNLOAD_MATCHED_STAR = 18;
static const uint8_t DOWNLOAD_DBIMAGE = 19; static const uint8_t DOWNLOAD_DBIMAGE = 19;
static const uint8_t DOWNLOAD_BLOBPIXEL = 24; static const uint8_t DOWNLOAD_BLOBPIXEL = 24;
static const uint8_t FPGA_ACTION = 22;
} }
namespace Program { namespace Program {

View File

@ -107,7 +107,7 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
if (size > MAX_PATH_SIZE) { if (size > MAX_PATH_SIZE + MAX_FILE_NAME) {
return FILE_PATH_TOO_LONG; return FILE_PATH_TOO_LONG;
} }
result = strHelper->startImageUpload( result = strHelper->startImageUpload(
@ -167,6 +167,13 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
std::string(reinterpret_cast<const char*>(data), size)); std::string(reinterpret_cast<const char*>(data), size));
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
case(StarTracker::CHANGE_FPGA_DOWNLOAD_FILE): {
if (size > MAX_FILE_NAME) {
return FILENAME_TOO_LONG;
}
strHelper->setDownloadFpgaImage(std::string(reinterpret_cast<const char*>(data), size));
return EXECUTION_FINISHED;
}
case(StarTracker::SET_READ_FILENAME): { case(StarTracker::SET_READ_FILENAME): {
if (size > MAX_FILE_NAME) { if (size > MAX_FILE_NAME) {
return FILENAME_TOO_LONG; return FILENAME_TOO_LONG;
@ -190,6 +197,21 @@ ReturnValue_t StarTrackerHandler::executeAction(ActionId_t actionId, MessageQueu
strHelperExecuting = true; strHelperExecuting = true;
return EXECUTION_FINISHED; return EXECUTION_FINISHED;
} }
case(StarTracker::UPLOAD_FPGA_IMAGE): {
result = DeviceHandlerBase::acceptExternalDeviceCommands();
if (result != RETURN_OK) {
return result;
}
if (size > MAX_PATH_SIZE + MAX_FILE_NAME) {
return FILE_PATH_TOO_LONG;
}
result = strHelper->startFpgaUpload(std::string(reinterpret_cast<const char*>(data), size));
if (result != RETURN_OK) {
return result;
}
strHelperExecuting = true;
return EXECUTION_FINISHED;
}
default: default:
break; break;
} }
@ -469,6 +491,10 @@ ReturnValue_t StarTrackerHandler::buildCommandFromCommand(DeviceCommandId_t devi
result = prepareDownloadBlobPixelCommand(commandData, commandDataLen); result = prepareDownloadBlobPixelCommand(commandData, commandDataLen);
return result; return result;
} }
case (StarTracker::FPGA_ACTION): {
result = prepareFpgaActionCommand(commandData, commandDataLen);
return result;
}
default: default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED; return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
} }
@ -545,6 +571,8 @@ void StarTrackerHandler::fillCommandAndReplyMap() {
StarTracker::MAX_FRAME_SIZE * 2 + 2); StarTracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_BLOBPIXEL, 3, &downloadBlobPixel, this->insertInCommandAndReplyMap(StarTracker::DOWNLOAD_BLOBPIXEL, 3, &downloadBlobPixel,
StarTracker::MAX_FRAME_SIZE * 2 + 2); StarTracker::MAX_FRAME_SIZE * 2 + 2);
this->insertInCommandAndReplyMap(StarTracker::FPGA_ACTION, 3, nullptr,
StarTracker::MAX_FRAME_SIZE * 2 + 2);
} }
ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize, ReturnValue_t StarTrackerHandler::scanForReply(const uint8_t *start, size_t remainingSize,
@ -617,7 +645,8 @@ ReturnValue_t StarTrackerHandler::interpretDeviceReply(DeviceCommandId_t id, con
case (StarTracker::TAKE_IMAGE): case (StarTracker::TAKE_IMAGE):
case (StarTracker::RESET_ERROR): case (StarTracker::RESET_ERROR):
case (StarTracker::UNLOCK): case (StarTracker::UNLOCK):
case (StarTracker::SET_TIME): { case (StarTracker::SET_TIME):
case (StarTracker::FPGA_ACTION): {
result = handleActionReply(); result = handleActionReply();
break; break;
} }
@ -995,6 +1024,10 @@ ReturnValue_t StarTrackerHandler::scanForActionReply(DeviceCommandId_t *foundId)
*foundId = StarTracker::DOWNLOAD_BLOBPIXEL; *foundId = StarTracker::DOWNLOAD_BLOBPIXEL;
break; break;
} }
case (StarTracker::ID::FPGA_ACTION): {
*foundId = StarTracker::FPGA_ACTION;
break;
}
default: default:
sif::warning << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id" sif::warning << "StarTrackerHandler::scanForParameterReply: Unknown parameter reply id"
<< std::endl; << std::endl;
@ -1649,6 +1682,24 @@ ReturnValue_t StarTrackerHandler::prepareDownloadBlobPixelCommand(const uint8_t*
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StarTrackerHandler::prepareFpgaActionCommand(const uint8_t* commandData,
size_t commandDataLen) {
if (commandDataLen != FpgaActionCmd::LENGTH) {
return INVALID_LENGTH;
}
struct FPGAActionActionRequest req;
req.id = *commandData;
if (req.id != FpgaActionCmd::ID) {
return INVALID_ID;
}
uint32_t length = 0;
arc_pack_fpgaaction_action_req(&req, commandBuffer, &length);
dataLinkLayer.encodeFrame(commandBuffer, length);
rawPacket = dataLinkLayer.getEncodedFrame();
rawPacketLen = dataLinkLayer.getEncodedLength();
return RETURN_OK;
}
ReturnValue_t StarTrackerHandler::handleSetParamReply() { ReturnValue_t StarTrackerHandler::handleSetParamReply() {
const uint8_t* reply = dataLinkLayer.getReply(); const uint8_t* reply = dataLinkLayer.getReply();
uint8_t status = *(reply + STATUS_OFFSET); uint8_t status = *(reply + STATUS_OFFSET);

View File

@ -131,6 +131,8 @@ private:
static const ReturnValue_t UPLOAD_CENTROID_ID_MISMATCH = MAKE_RETURN_CODE(0xB5); static const ReturnValue_t UPLOAD_CENTROID_ID_MISMATCH = MAKE_RETURN_CODE(0xB5);
//! [EXPORT] : [COMMENT] Download blob pixel command has invalid type field //! [EXPORT] : [COMMENT] Download blob pixel command has invalid type field
static const ReturnValue_t INVALID_TYPE = MAKE_RETURN_CODE(0xB6); static const ReturnValue_t INVALID_TYPE = MAKE_RETURN_CODE(0xB6);
//! [EXPORT] : [COMMENT] Received FPGA action command with invalid ID
static const ReturnValue_t INVALID_ID = MAKE_RETURN_CODE(0xB7);
static const size_t MAX_PATH_SIZE = 50; static const size_t MAX_PATH_SIZE = 50;
static const size_t MAX_FILE_NAME = 30; static const size_t MAX_FILE_NAME = 30;
@ -235,6 +237,12 @@ private:
static const uint8_t MIN_LENGTH = 10; static const uint8_t MIN_LENGTH = 10;
}; };
class FpgaActionCmd {
public:
static const uint8_t LENGTH = 1;
static const uint8_t ID = 3;
};
MessageQueueIF* eventQueue = nullptr; MessageQueueIF* eventQueue = nullptr;
ArcsecDatalinkLayer dataLinkLayer; ArcsecDatalinkLayer dataLinkLayer;
@ -479,6 +487,11 @@ private:
ReturnValue_t prepareDownloadBlobPixelCommand(const uint8_t* commandData, ReturnValue_t prepareDownloadBlobPixelCommand(const uint8_t* commandData,
size_t commandDataLen); size_t commandDataLen);
/**
* @brief With this command the FPGA update will be applied to the star tracker
*/
ReturnValue_t prepareFpgaActionCommand(const uint8_t* commandData, size_t commandDataLen);
/** /**
* @brief Handles action replies with datasets. * @brief Handles action replies with datasets.
*/ */

View File

@ -85,6 +85,17 @@ ReturnValue_t StrHelper::performOperation(uint8_t operationCode) {
internalState = InternalState::IDLE; internalState = InternalState::IDLE;
break; break;
} }
case InternalState::UPLOAD_FPGA_IMAGE: {
result = performFpgaUpload();
if (result == RETURN_OK){
triggerEvent(FPGA_UPLOAD_SUCCESSFUL);
}
else {
triggerEvent(FPGA_UPLOAD_FAILED);
}
internalState = InternalState::IDLE;
break;
}
default: default:
sif::debug << "StrHelper::performOperation: Invalid state" << std::endl; sif::debug << "StrHelper::performOperation: Invalid state" << std::endl;
break; break;
@ -114,7 +125,7 @@ ReturnValue_t StrHelper::startImageUpload(std::string uploadImage_) {
if(not std::filesystem::exists(uploadImage)) { if(not std::filesystem::exists(uploadImage)) {
return FILE_NOT_EXISTS; return FILE_NOT_EXISTS;
} }
internalState = InternalState::UPLOAD_IMAGE; internalState = InternalState::UPLOAD_FPGA_IMAGE;
semaphore.release(); semaphore.release();
terminate = false; terminate = false;
return RETURN_OK; return RETURN_OK;
@ -147,6 +158,10 @@ void StrHelper::setFlashReadFilename(std::string filename) {
flashReadFile = filename; flashReadFile = filename;
} }
void StrHelper::setDownloadFpgaImage(std::string filename) {
fpgaDownload.fileName = filename;
}
ReturnValue_t StrHelper::startFlashWrite(std::string flashWriteFile_, uint8_t region, ReturnValue_t StrHelper::startFlashWrite(std::string flashWriteFile_, uint8_t region,
uint32_t address) { uint32_t address) {
ReturnValue_t result = checkPath(flashWriteFile_); ReturnValue_t result = checkPath(flashWriteFile_);
@ -195,6 +210,14 @@ ReturnValue_t StrHelper::startFpgaDownload(std::string path, uint32_t startPosit
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::startFpgaUpload(std::string uploadFile) {
fpgaUpload.uploadFile = uploadFile;
internalState = InternalState::UPLOAD_FPGA_IMAGE;
semaphore.release();
terminate = false;
return RETURN_OK;
}
ReturnValue_t StrHelper::performImageDownload() { ReturnValue_t StrHelper::performImageDownload() {
ReturnValue_t result; ReturnValue_t result;
struct DownloadActionRequest downloadReq; struct DownloadActionRequest downloadReq;
@ -450,7 +473,7 @@ ReturnValue_t StrHelper::performFpgaDownload() {
file.close(); file.close();
return result; return result;
} }
result = checkFpgaDownloadReply(req.pos, req.length); result = checkFpgaActionReply(req.pos, req.length);
if (result != RETURN_OK) { if (result != RETURN_OK) {
if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) { if (retries < CONFIG_MAX_DOWNLOAD_RETRIES) {
uartComIF->flushUartRxBuffer(comCookie); uartComIF->flushUartRxBuffer(comCookie);
@ -469,6 +492,47 @@ ReturnValue_t StrHelper::performFpgaDownload() {
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::performFpgaUpload() {
ReturnValue_t result = RETURN_OK;
uint32_t commandSize = 0;
uint32_t bytesUploaded = 0;
uint32_t fileSize = 0;
struct UploadFPGAImageActionRequest req;
if (not std::filesystem::exists(fpgaUpload.uploadFile)) {
triggerEvent(STR_HELPER_FILE_NOT_EXISTS, static_cast<uint32_t>(internalState));
internalState = InternalState::IDLE;
return RETURN_FAILED;
}
std::ifstream file(flashWriteFile, std::ifstream::binary);
file.seekg(0, file.end);
fileSize = file.tellg();
req.pos = 0;
while(bytesUploaded <= fileSize) {
if (terminate) {
return RETURN_OK;
}
if (fileSize - bytesUploaded > FpgaUpload::MAX_DATA) {
req.length = FpgaUpload::MAX_DATA;
}
else {
req.length = fileSize - bytesUploaded;
}
file.seekg(bytesUploaded, file.beg);
file.read(reinterpret_cast<char*>(req.data), req.length);
arc_pack_uploadfpgaimage_action_req(&req, commandBuffer, &commandSize);
result = sendAndRead(commandSize, req.pos);
if (result != RETURN_OK) {
return RETURN_FAILED;
}
result = checkFpgaActionReply(req.pos, req.length);
if (result != RETURN_OK) {
return result;
}
bytesUploaded += req.length;
}
return RETURN_OK;
}
ReturnValue_t StrHelper::sendAndRead(size_t size, uint32_t parameter) { ReturnValue_t StrHelper::sendAndRead(size_t size, uint32_t parameter) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
ReturnValue_t decResult = RETURN_OK; ReturnValue_t decResult = RETURN_OK;
@ -591,20 +655,20 @@ ReturnValue_t StrHelper::checkFlashActionReply(uint8_t region_, uint32_t address
return RETURN_OK; return RETURN_OK;
} }
ReturnValue_t StrHelper::checkFpgaDownloadReply(uint32_t expectedPosition, ReturnValue_t StrHelper::checkFpgaActionReply(uint32_t expectedPosition,
uint32_t expectedLength) { uint32_t expectedLength) {
ReturnValue_t result = RETURN_OK; ReturnValue_t result = RETURN_OK;
result = checkActionReply(); result = checkActionReply();
if (result != RETURN_OK) { if (result != RETURN_OK) {
return result; return result;
} }
const uint8_t* data = datalinkLayer.getReply() + FpgaDownload::POSITION_OFFSET; const uint8_t* data = datalinkLayer.getReply() + ACTION_DATA_OFFSET;
uint32_t position; uint32_t position;
size_t size = sizeof(position); size_t size = sizeof(position);
result = SerializeAdapter::deSerialize(&position, &data, &size, result = SerializeAdapter::deSerialize(&position, &data, &size,
SerializeIF::Endianness::LITTLE); SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::warning << "StrHelper::checkFpgaDownloadReply: Deserialization of position failed" sif::warning << "StrHelper::checkFpgaActionReply: Deserialization of position failed"
<< std::endl; << std::endl;
return result; return result;
} }
@ -613,11 +677,11 @@ ReturnValue_t StrHelper::checkFpgaDownloadReply(uint32_t expectedPosition,
result = SerializeAdapter::deSerialize(&length, &data, &size, result = SerializeAdapter::deSerialize(&length, &data, &size,
SerializeIF::Endianness::LITTLE); SerializeIF::Endianness::LITTLE);
if (result != RETURN_OK) { if (result != RETURN_OK) {
sif::warning << "StrHelper::checkFpgaDownloadReply: Deserialization of length failed" sif::warning << "StrHelper::checkFpgaActionReply: Deserialization of length failed"
<< std::endl; << std::endl;
return result; return result;
} }
return RETURN_OK; return result;
} }
ReturnValue_t StrHelper::checkPath(std::string name) { ReturnValue_t StrHelper::checkPath(std::string name) {

View File

@ -133,6 +133,13 @@ public:
*/ */
ReturnValue_t startFpgaDownload(std::string path, uint32_t startPosition, uint32_t length); ReturnValue_t startFpgaDownload(std::string path, uint32_t startPosition, uint32_t length);
/**
* @brief Starts upload of new image to FPGA
*
* @param uploadFile Full name of file containing FPGA image data
*/
ReturnValue_t startFpgaUpload(std::string uploadFile);
/** /**
* @brief Can be used to interrupt a running data transfer. * @brief Can be used to interrupt a running data transfer.
*/ */
@ -148,6 +155,11 @@ public:
*/ */
void setFlashReadFilename(std::string filename); void setFlashReadFilename(std::string filename);
/**
* @brief Set download FPGA image name
*/
void setDownloadFpgaImage(std::string filename);
private: private:
static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER; static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER;
@ -182,9 +194,7 @@ private:
class FpgaDownload { class FpgaDownload {
public: public:
static const uint16_t MAX_DATA = 1024; static const uint16_t MAX_DATA = 1024;
static const uint8_t POSITION_OFFSET = 3; static const uint8_t DATA_OFFSET = 10;
static const uint8_t LENGTH_OFFSET = 7;
static const uint8_t DATA_OFFSET = 11;
// Start position of fpga image part to download // Start position of fpga image part to download
uint32_t startPosition = 0; uint32_t startPosition = 0;
// Length of image part to download // Length of image part to download
@ -197,8 +207,18 @@ private:
FpgaDownload fpgaDownload; FpgaDownload fpgaDownload;
class FpgaUpload {
public:
static const uint32_t MAX_DATA = 1024;
// Full name of file to upload
std::string uploadFile;
};
FpgaUpload fpgaUpload;
static const uint32_t MAX_POLLS = 10000; static const uint32_t MAX_POLLS = 10000;
static const uint8_t ACTION_DATA_OFFSET = 2;
static const uint8_t POS_OFFSET = 2; static const uint8_t POS_OFFSET = 2;
static const uint8_t IMAGE_DATA_OFFSET = 5; static const uint8_t IMAGE_DATA_OFFSET = 5;
static const uint8_t FLASH_READ_DATA_OFFSET = 8; static const uint8_t FLASH_READ_DATA_OFFSET = 8;
@ -302,6 +322,12 @@ private:
*/ */
ReturnValue_t performFpgaDownload(); ReturnValue_t performFpgaDownload();
/**
* @brief Performs upload of new FPGA image. Upload sequence split over multiple commands
* because one command can only transport 1024 bytes of image data.
*/
ReturnValue_t performFpgaUpload();
/** /**
* @brief Sends packet to the star tracker and reads reply by using the communication * @brief Sends packet to the star tracker and reads reply by using the communication
* interface * interface
@ -338,12 +364,12 @@ private:
ReturnValue_t checkFlashActionReply(uint8_t region_, uint32_t address_, uint16_t length_); ReturnValue_t checkFlashActionReply(uint8_t region_, uint32_t address_, uint16_t length_);
/** /**
* @brief Checks the reply to the fpga download request * @brief Checks the reply to the fpga download and upload request
* *
* @param expectedPosition The expected position value in the reply * @param expectedPosition The expected position value in the reply
* @param expectedLength The expected length field in the reply * @param expectedLength The expected length field in the reply
*/ */
ReturnValue_t checkFpgaDownloadReply(uint32_t expectedPosition, uint32_t expectedLength); ReturnValue_t checkFpgaActionReply(uint32_t expectedPosition, uint32_t expectedLength);
/** /**
* @brief Checks if a path points to an sd card and whether the SD card is monuted. * @brief Checks if a path points to an sd card and whether the SD card is monuted.