From 02e24f0f533fe904c3a5275c4060c10c38d7c17a Mon Sep 17 00:00:00 2001 From: Ján Sučan Date: Wed, 10 May 2017 15:13:29 +0200 Subject: Uvodny commit, subory su rovnake ako na CD prilozenom k vytlacenemu texu bakalarskej prace, naviac je pridany len subor LICENCIA --- main.cpp | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100755 main.cpp (limited to 'main.cpp') diff --git a/main.cpp b/main.cpp new file mode 100755 index 0000000..2d25318 --- /dev/null +++ b/main.cpp @@ -0,0 +1,219 @@ +#include +#include +#include +#include /* strerror() */ +#include + +#include +#include +#include +#include +#include +#include + +#include "ExitCodes.hpp" +#include "Logger.hpp" +#include "ExitException.hpp" +#include "UserConfig.hpp" +#include "SerialPortFactory.hpp" +#include "SerialPort.hpp" +#include "Mcu.hpp" + +using std::cout; +using std::endl; +using std::string; +using std::ostringstream; +using std::vector; +using std::unique_ptr; + +void opSpeeds(CUserConfig & uc); +void opRead(CUserConfig & uc, CMcu & mcu); +void opErase(CUserConfig & uc, CMcu & mcu); +void opWrite(CUserConfig & uc, CMcu & mcu); + +vector readDataFile(const string fpath); +void writeDataFile(const string fpath, vector data); + +// Global variable to be accessed in signal handler +unique_ptr sp; + +// Uvolnime zdroje pri ukonceni na signal +void +signalHandler(int dummy) +{ + CLogger::info("Exiting on signal"); + sp->close(); + exit(EXIT_MAIN_SIGNAL); +} + +int +main(int argc, char **argv) +{ + // Set signal handler + signal(SIGINT, signalHandler); + + CSerialPortFactory serialPortFactory; + sp = serialPortFactory.getSerialPort(); + + try { + // Parse user command line configuration + CUserConfig uc(argc, argv); + // Configure logging + if (uc.isVerboseModeSet()) + CLogger::setLogInfo(true); + // Execute selected operation + if (uc.isHelpSet()) { + cout << uc.getHelpMessage(string(argv[0])); + } else if (uc.isVersionSet()) { + cout << PROGRAM_NAME << " " << PROGRAM_VERSION << endl; + } else if (uc.isSpeedsSet()) { + opSpeeds(uc); + } else if (uc.isIdentSet() || uc.isEraseSet() || uc.isReadSet() || uc.isWriteSet()) { + // Open serial port + sp->open(uc.getSerialPortName(), uc.getSerialSpeed()); + // Get MCU model + unique_ptr mcu(new CMcu(*sp, uc.getMcuFrequency())); + // Execute requested operation + if (!uc.isIdentSet()) { + if (uc.isReadSet()) + opRead(uc, *mcu); + else if (uc.isEraseSet()) + opErase(uc, *mcu); + else if (uc.isWriteSet()) + opWrite(uc, *mcu); + } else { + cout << mcu->ident() << endl; + } + } else { + CLogger::error("No operation requested. To get help type: " + string(argv[0]) + " help" , EXIT_MAIN_NOOP); + } + + sp->close(); + return 0; + } catch (CExitException & e) { + return e.getReturnValue(); + } +} + +void +opSpeeds(CUserConfig & uc) +{ + + string s = sp->getSpeeds(uc.getSerialPortName()); + cout << "Baudrates supported by serial port " << uc.getSerialPortName() << ":" << endl; + cout << s; +} + +void +opRead(CUserConfig & uc, CMcu & mcu) +{ + CLogger::info("Reading memory"); + + int rl = uc.getReadLength(); + vector r; + + if (rl == -1) + r = mcu.read(uc.isPrintProgressSet()); + else + r = mcu.read(rl, uc.isPrintProgressSet()); + // Write data file musi dostat spravnu hodnotu + writeDataFile(uc.getReadOutputFname(), r); +} + +void +opErase(CUserConfig & uc, CMcu & mcu) +{ + if (uc.getEraseBlockList().size() != 0) { + CLogger::info("Erasing memory by blocks"); + mcu.erase(uc.getEraseBlockList()); + } else { + CLogger::info("Erasing whole memory"); + mcu.erase(); + } +} + +void +opWrite(CUserConfig & uc, CMcu & mcu) +{ + vector data; + + data = readDataFile(uc.getWriteInputFname()); + + if (uc.getWriteEraseWholeMemory()) { + CLogger::info("Erasing whole memory"); + mcu.erase(); + } else { + CLogger::info("Erasing memory by blocks"); + mcu.erase(0, data.size() - 1); + } + + CLogger::info("Writing memory"); + mcu.write(data, uc.isPrintProgressSet()); + + if (uc.getWriteCheckByRead()) { + CLogger::info("Checking result of write operation by reading"); + + vector rdata = mcu.read(data.size()); + for (size_t i = 0; i < data.size(); i++) { + if (rdata[i] != data[i]) + CLogger::error("Write operation unsucessful", EXIT_MAIN_PROG_VERIFY); + } + + CLogger::info("Write operation was successful"); + } +} + + +vector +readDataFile(const string fpath) +{ + FILE *f; + size_t size; +#ifdef UNIX + char mode[3] = "r"; +#else + char mode[3] = "rb"; +#endif + + if ((f = fopen(fpath.c_str(), mode)) == NULL) + CLogger::error("Cannot open file for reading: " + fpath, EXIT_MAIN_FILE_INOUT); + + // Determine file size + fseek(f, 0, SEEK_END); + size = ftell(f); + fseek(f, 0, SEEK_SET); + + vector data; + data.resize(size); + + size_t r = fread(data.data(), sizeof(uint8_t), size, f); + fclose(f); + + if (r != size) + CLogger::error("Cannot read from file: " + fpath, EXIT_MAIN_FILE_INOUT); + + return data; +} + +void +writeDataFile(const string fpath, vector data) +{ + FILE *out; +#ifdef UNIX + char mode[3] = "w"; +#else + char mode[3] = "wb"; +#endif + + if ((out = fopen(fpath.c_str(), mode)) == NULL) { + ostringstream os; + os << "Cannot open file for writing: " << fpath << ": " << strerror(errno); + CLogger::error(os.str(), EXIT_MAIN_FILE_INOUT); + } + + size_t r = fwrite(data.data(), sizeof(uint8_t), data.size(), out); + fclose(out); + + if (r != data.size()) + CLogger::error("Cannot write to file: " + fpath, EXIT_MAIN_FILE_INOUT); +} -- cgit v1.2.3