Go to the documentation of this file.00001 #include <iostream>
00002 #include <fstream>
00003 #include <inttypes.h>
00004
00005 #include <boost/program_options.hpp>
00006 #include <crazyflie_cpp/Crazyflie.h>
00007
00008 std::istream& operator>>(std::istream& in, Crazyflie::BootloaderTarget& target)
00009 {
00010 std::string token;
00011 in >> token;
00012 if (token == "stm32")
00013 target = Crazyflie::TargetSTM32;
00014 else if (token == "nrf51")
00015 target = Crazyflie::TargetNRF51;
00016 else throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
00017 return in;
00018 }
00019
00020 enum Mode
00021 {
00022 FlashAndVerify,
00023 FlashOnly,
00024 VerifyOnly,
00025 };
00026
00027 std::istream& operator>>(std::istream& in, Mode& mode)
00028 {
00029 std::string token;
00030 in >> token;
00031 if (token == "flashAndVerify")
00032 mode = FlashAndVerify;
00033 else if (token == "flashOnly")
00034 mode = FlashOnly;
00035 else if (token == "verifyOnly")
00036 mode = VerifyOnly;
00037 else throw boost::program_options::validation_error(boost::program_options::validation_error::invalid_option_value);
00038 return in;
00039 }
00040
00041 class MyLogger : public Logger
00042 {
00043 public:
00044 MyLogger(bool verbose)
00045 : m_verbose(verbose)
00046 {
00047 }
00048
00049 virtual void info(const std::string& msg)
00050 {
00051 if (m_verbose) {
00052 std::cout << msg << std::endl;
00053 }
00054 }
00055
00056
00057 private:
00058 bool m_verbose;
00059 };
00060
00061 int main(int argc, char **argv)
00062 {
00063
00064 std::string fileName;
00065 std::string uri;
00066 std::string defaultUri("radio://0/0/2M");
00067 Crazyflie::BootloaderTarget target;
00068 Mode mode = FlashAndVerify;
00069 bool verbose = false;
00070
00071 namespace po = boost::program_options;
00072
00073 po::options_description desc("Allowed options");
00074 desc.add_options()
00075 ("help", "produce help message")
00076 ("target", po::value<Crazyflie::BootloaderTarget>(&target)->required(), "target {stm32,nrf51}")
00077 ("filename", po::value<std::string>(&fileName)->required(), "file to flash")
00078 ("uri", po::value<std::string>(&uri)->default_value(defaultUri), "unique ressource identifier")
00079 ("mode", po::value<Mode>(&mode)->default_value(mode), "mode {default=flashAndVerify, flashOnly, verifyOnly}")
00080 ("verbose,v", "verbose output")
00081 ;
00082
00083 try
00084 {
00085 po::variables_map vm;
00086 po::store(po::parse_command_line(argc, argv, desc), vm);
00087 po::notify(vm);
00088
00089 if (vm.count("help")) {
00090 std::cout << desc << "\n";
00091 return 0;
00092 }
00093 verbose = vm.count("verbose");
00094 }
00095 catch(po::error& e)
00096 {
00097 std::cerr << e.what() << std::endl << std::endl;
00098 std::cerr << desc << std::endl;
00099 return 1;
00100 }
00101
00102 try
00103 {
00104 MyLogger logger(verbose);
00105
00106 bool success = true;
00107 Crazyflie cf(uri, logger);
00108 if (uri != defaultUri) {
00109 logger.info("Reboot to Bootloader...");
00110 uint64_t address = cf.rebootToBootloader();
00111 logger.info("...Done");
00112
00113 char addr[17];
00114 std::sprintf(addr, "%" SCNx64, address);
00115 defaultUri += "/" + std::string(addr);
00116 }
00117
00118 std::ifstream stream(fileName.c_str(), std::ios::binary);
00119 if (!stream.good()) {
00120 std::cerr << "Couldn't open " << fileName << "!" << std::endl;
00121 return 1;
00122 }
00123 std::vector<uint8_t> targetData((
00124 std::istreambuf_iterator<char>(stream)),
00125 (std::istreambuf_iterator<char>()));
00126
00127
00128
00129 if (mode == FlashAndVerify || mode == FlashOnly) {
00130 logger.info("Flashing...");
00131 cf.writeFlash(target, targetData);
00132 }
00133 if (mode == FlashAndVerify || mode == VerifyOnly) {
00134 logger.info("Reading...");
00135 std::vector<uint8_t> currentData;
00136 cf.readFlash(target, targetData.size(), currentData);
00137 std::ofstream dbg("data.bin", std::ios::binary);
00138 dbg.write((char*)currentData.data(), currentData.size());
00139 if (memcmp(targetData.data(), currentData.data(), targetData.size()) == 0) {
00140 logger.info("Verification successful!");
00141 } else {
00142 std::cerr << "Verification NOT successful!" << std::endl;
00143 success = false;
00144 }
00145 }
00146
00147 logger.info("Reboot to firmware");
00148 cf.rebootFromBootloader();
00149
00150 if (success) {
00151 return 0;
00152 }
00153 return 1;
00154 }
00155 catch(std::exception& e)
00156 {
00157 std::cerr << e.what() << std::endl;
00158 return 1;
00159 }
00160 }