#ifndef BSP_Q7S_DEVICES_STRHELPER_H_ #define BSP_Q7S_DEVICES_STRHELPER_H_ #include #include "ArcsecDatalinkLayer.h" #include "OBSWConfig.h" #ifdef XIPHOS_Q7S #include "bsp_q7s/fs/SdCardManager.h" #endif #include "arcsec/client/generated/actionreq.h" #include "arcsec/common/generated/tmtcstructs.h" #include "fsfw/devicehandlers/CookieIF.h" #include "fsfw/objectmanager/SystemObject.h" #include "fsfw/osal/linux/BinarySemaphore.h" #include "fsfw/returnvalues/returnvalue.h" #include "fsfw/tasks/ExecutableObjectIF.h" #include "fsfw_hal/linux/serial/SerialComIF.h" /** * @brief Helper class for the star tracker handler to accelerate large data transfers. * * @author J. Meier */ class StrComHandler : public SystemObject, public DeviceCommunicationIF, public ExecutableObjectIF { public: static const uint8_t INTERFACE_ID = CLASS_ID::STR_HELPER; //! [EXPORT] : [COMMENT] SD card specified in path string not mounted static const ReturnValue_t SD_NOT_MOUNTED = MAKE_RETURN_CODE(1); //! [EXPORT] : [COMMENT] Specified file does not exist on filesystem static const ReturnValue_t FILE_NOT_EXISTS = MAKE_RETURN_CODE(2); //! [EXPORT] : [COMMENT] Specified path does not exist static const ReturnValue_t PATH_NOT_EXISTS = MAKE_RETURN_CODE(3); //! [EXPORT] : [COMMENT] Failed to create download image or read flash file static const ReturnValue_t FILE_CREATION_FAILED = MAKE_RETURN_CODE(4); //! [EXPORT] : [COMMENT] Region in flash write/read reply does not match expected region static const ReturnValue_t REGION_MISMATCH = MAKE_RETURN_CODE(5); //! [EXPORT] : [COMMENT] Address in flash write/read reply does not match expected address static const ReturnValue_t ADDRESS_MISMATCH = MAKE_RETURN_CODE(6); //! [EXPORT] : [COMMENT] Length in flash write/read reply does not match expected length static const ReturnValue_t LENGTH_MISMATCH = MAKE_RETURN_CODE(7); //! [EXPORT] : [COMMENT] Status field in reply signals error static const ReturnValue_t STATUS_ERROR = MAKE_RETURN_CODE(8); //! [EXPORT] : [COMMENT] Reply has invalid type ID (should be of action reply type) static const ReturnValue_t INVALID_TYPE_ID = MAKE_RETURN_CODE(9); static const ReturnValue_t RECEPTION_TIMEOUT = MAKE_RETURN_CODE(10); static const ReturnValue_t DECODING_ERROR = MAKE_RETURN_CODE(11); static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::STR_HELPER; //! [EXPORT] : [COMMENT] Image upload failed static const Event IMAGE_UPLOAD_FAILED = MAKE_EVENT(0, severity::LOW); //! [EXPORT] : [COMMENT] Image download failed static const Event IMAGE_DOWNLOAD_FAILED = MAKE_EVENT(1, severity::LOW); //! [EXPORT] : [COMMENT] Uploading image to star tracker was successfulop static const Event IMAGE_UPLOAD_SUCCESSFUL = MAKE_EVENT(2, severity::LOW); //! [EXPORT] : [COMMENT] Image download was successful static const Event IMAGE_DOWNLOAD_SUCCESSFUL = MAKE_EVENT(3, severity::LOW); //! [EXPORT] : [COMMENT] Finished flash write procedure successfully static const Event FLASH_WRITE_SUCCESSFUL = MAKE_EVENT(4, severity::LOW); //! [EXPORT] : [COMMENT] Finished flash read procedure successfully static const Event FLASH_READ_SUCCESSFUL = MAKE_EVENT(5, severity::LOW); //! [EXPORT] : [COMMENT] Flash read procedure failed static const Event FLASH_READ_FAILED = MAKE_EVENT(6, severity::LOW); //! [EXPORT] : [COMMENT] Firmware update was successful static const Event FIRMWARE_UPDATE_SUCCESSFUL = MAKE_EVENT(7, severity::LOW); //! [EXPORT] : [COMMENT] Firmware update failed static const Event FIRMWARE_UPDATE_FAILED = MAKE_EVENT(8, severity::LOW); //! [EXPORT] : [COMMENT] Failed to read communication interface reply data //! P1: Return code of failed communication interface read call //! P1: Upload/download position for which the read call failed static const Event STR_HELPER_READING_REPLY_FAILED = MAKE_EVENT(9, severity::LOW); //! [EXPORT] : [COMMENT] Unexpected stop of decoding sequence //! P1: Return code of failed communication interface read call //! P1: Upload/download position for which the read call failed static const Event STR_HELPER_COM_ERROR = MAKE_EVENT(10, severity::LOW); //! [EXPORT] : [COMMENT] Star tracker did not send a valid reply for a certain timeout. //! P1: Position of upload or download packet for which the packet wa sent. P2: Timeout static const Event STR_COM_REPLY_TIMEOUT = MAKE_EVENT(11, severity::LOW); //! [EXPORT] : [COMMENT] Error during decoding of received reply occurred //! P1: Return value of decoding function //! P2: Position of upload/download packet, or address of flash write/read request static const Event STR_HELPER_DEC_ERROR = MAKE_EVENT(13, severity::LOW); //! [EXPORT] : [COMMENT] Position mismatch //! P1: The expected position and thus the position for which the image upload/download failed static const Event POSITION_MISMATCH = MAKE_EVENT(14, severity::LOW); //! [EXPORT] : [COMMENT] Specified file does not exist //! P1: Internal state of str helper static const Event STR_HELPER_FILE_NOT_EXISTS = MAKE_EVENT(15, severity::LOW); //! [EXPORT] : [COMMENT] Sending packet to star tracker failed //! P1: Return code of communication interface sendMessage function //! P2: Position of upload/download packet, or address of flash write/read request for which //! sending failed static const Event STR_HELPER_SENDING_PACKET_FAILED = MAKE_EVENT(16, severity::LOW); //! [EXPORT] : [COMMENT] Communication interface requesting reply failed //! P1: Return code of failed request //! P1: Upload/download position, or address of flash write/read request for which transmission //! failed static const Event STR_HELPER_REQUESTING_MSG_FAILED = MAKE_EVENT(17, severity::LOW); StrComHandler(object_id_t objectId); virtual ~StrComHandler(); ReturnValue_t initialize() override; ReturnValue_t performOperation(uint8_t operationCode = 0) override; /** * @brief Starts sequence to upload image to star tracker * * @param uploadImage_ Name including absolute path of the image to upload. Must be previously * transferred to the OBC with the CFDP protocol. */ ReturnValue_t startImageUpload(std::string uploadImage_); /** * @brief Calling this function initiates the download of an image from the star tracker. * * @param path Path where downloaded image will be stored */ ReturnValue_t startImageDownload(std::string path); /** * @brief Will start the firmware update * * @param fullname Full name including absolute path of file containing firmware * update. */ ReturnValue_t startFirmwareUpdate(std::string fullname); /** * @brief Starts the flash read procedure * * @param path Path where file with read flash data will be created * @param startRegion Region form where to start reading * @param length Number of bytes to read from flash */ ReturnValue_t startFlashRead(std::string path, uint8_t startRegion, uint32_t length); /** * @brief Can be used to interrupt a running data transfer. */ void stopProcess(); /** * @brief Changes the dafault name of downloaded images */ void setDownloadImageName(std::string filename); /** * @brief Sets the name of the file which will be created to store the data read from flash */ void setFlashReadFilename(std::string filename); /** * @brief Disables timestamp generation when new file is created */ void disableTimestamping(); /** * @brief Enables timestamp generation when new file is created */ void enableTimestamping(); private: //! [EXPORT] : [SKIP] static constexpr ReturnValue_t NO_SERIAL_DATA_READ = MAKE_RETURN_CODE(128); // Size of one image part which can be sent per action request static const size_t SIZE_IMAGE_PART = 1024; static const uint32_t FLASH_REGION_SIZE = 0x20000; struct ImageDownload { static const uint32_t LAST_POSITION = 4095; }; static const uint32_t MAX_POLLS = 10000; static const uint8_t ACTION_DATA_OFFSET = 3; static const uint8_t POS_OFFSET = 3; static const uint8_t IMAGE_DATA_OFFSET = 6; static const uint8_t FLASH_READ_DATA_OFFSET = 9; static const uint8_t REGION_OFFSET = 3; static const uint8_t ADDRESS_OFFSET = 4; static const size_t CHUNK_SIZE = 1024; static const size_t CONFIG_MAX_DOWNLOAD_RETRIES = 3; static const uint32_t FLASH_ERASE_DELAY = 500; enum class InternalState { SLEEPING, POLL_ONE_REPLY, UPLOAD_IMAGE, DOWNLOAD_IMAGE, FLASH_READ, FIRMWARE_UPDATE }; InternalState state = InternalState::SLEEPING; ArcsecDatalinkLayer datalinkLayer; MutexIF *lock; BinarySemaphore semaphore; Countdown replyTimeout = Countdown(20); struct UploadImage { // Name including absolute path of image to upload std::string uploadFile; }; UploadImage uploadImage; struct DownloadImage { // Path where the downloaded image will be stored std::string path; // Default name of downloaded image, can be changed via command std::string filename = "image.bin"; }; DownloadImage downloadImage; struct FlashWrite { // File which contains data to write when executing the flash write command std::string fullname; // The first region to write to uint8_t firstRegion = 0; // Maximum region the flash write command is allowed to write to uint8_t lastRegion = 0; // Will be set with the flash write command and specifies the start address where to write the // flash data to uint32_t address = 0; }; FlashWrite flashWrite; struct FlashRead { // Path where the file containing the read data will be stored std::string path = ""; // Default name of file containing the data read from flash, can be changed via command std::string filename = "flashread.bin"; // Will be set with the flash read command uint8_t startRegion = 0; // Number of bytes to read from flash uint32_t size = 0; }; FlashRead flashRead; #ifdef XIPHOS_Q7S SdCardManager *sdcMan = nullptr; #endif std::array cmdBuf{}; std::array recBuf{}; bool replyWasReceived = false; const uint8_t *replyPtr = nullptr; size_t replyLen = 0; ReturnValue_t replyResult = returnvalue::OK; bool terminate = false; #ifdef EGSE bool timestamping = false; #else bool timestamping = true; #endif int serialPort = 0; struct termios tty = {}; // Queue id of raw data receiver MessageQueueId_t rawDataReceiver = MessageQueueIF::NO_QUEUE; ReturnValue_t initializeInterface(CookieIF *cookie) override; ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) override; ReturnValue_t getSendSuccess(CookieIF *cookie) override; ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override; ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) override; ReturnValue_t handleSerialReception(); /** * @brief Performs image uploading */ ReturnValue_t performImageUpload(); /** * @brief Performs firmware update * * @return returnvalue::OK if successful, otherwise error return value */ ReturnValue_t performFirmwareUpdate(); /** * @brief Performs download of last taken image from the star tracker. * * @details Download is split over multiple packets transporting each a maximum of 1024 bytes. * In case the download of one position fails, the same packet will be again * requested. If the download of the packet fails CONFIG_MAX_DOWNLOAD_RETRIES times, * the download will be stopped. */ ReturnValue_t performImageDownload(); /** * @brief Handles flash write procedure * * @param ID of first region to write to * * @return returnvalue::OK if successful, otherwise returnvalue::FAILED */ 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 * @details * The reply frame is stored in the data link layer helper. A pointer to the start of the frame * is assigned to the @replyPtr member of this class. The frame length will be assigned to * the @replyLen member. * @param size Size of data beforehand written to the commandBuffer * @param parameter Parameter 2 of trigger event function * * @return returnvalue::OK if successful, otherwise returnvalue::FAILED */ ReturnValue_t sendAndRead(size_t size, uint32_t parameter); /** * @brief Checks the header (type id and status fields) of the action reply * * @return returnvalue::OK if reply confirms success of packet transfer, otherwise REUTRN_FAILED */ ReturnValue_t checkActionReply(size_t replySize); /** * @brief Checks the position field in a star tracker upload/download reply. * * @param expectedPosition Value of expected position * * @return returnvalue::OK if received position matches expected position, otherwise * returnvalue::FAILED */ ReturnValue_t checkReplyPosition(uint32_t expectedPosition); #ifdef XIPHOS_Q7S /** * @brief Checks if a path points to an sd card and whether the SD card is monuted. * * @return SD_NOT_MOUNTED id SD card is not mounted, otherwise returnvalue::OK */ ReturnValue_t checkPath(std::string name); #endif /** * @brief Unlocks a range of flash regions * * @param from First region in range to unlock * @param to Last region in range to unlock * */ ReturnValue_t unlockAndEraseRegions(uint32_t from, uint32_t to); /** * The reply frame is stored in the data link layer helper. A pointer to the start of the frame * is assigned to the @replyPtr member of this class. The frame length will be assigned to * the @replyLen member. * @param failParameter * @return */ ReturnValue_t readOneReply(uint32_t failParameter); }; #endif /* BSP_Q7S_DEVICES_STRHELPER_H_ */