diff options
| author | Nicholas Corgan <nick.corgan@ettus.com> | 2015-07-15 09:32:18 -0700 | 
|---|---|---|
| committer | Nicholas Corgan <nick.corgan@ettus.com> | 2015-07-15 09:32:18 -0700 | 
| commit | 0595900eccfffee9e944dc53466337b44655caac (patch) | |
| tree | 7db7ee8e908b604236b04cf49f3d8d978e386543 /host/utils | |
| parent | 012381d999c4a895593412aaf06e73432b458810 (diff) | |
| download | uhd-0595900eccfffee9e944dc53466337b44655caac.tar.gz uhd-0595900eccfffee9e944dc53466337b44655caac.tar.bz2 uhd-0595900eccfffee9e944dc53466337b44655caac.zip  | |
Added uhd::image_loader class and uhd_image_loader utility
* Single class for loading firmware/FPGA images onto devices instead of multiple utilities
* Loading functions are registered for each device, corresponding to their --args="type=foo" name
* Deprecation warnings added to all product-specific image loading utilities
Diffstat (limited to 'host/utils')
| -rw-r--r-- | host/utils/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | host/utils/octoclock_firmware_burner.cpp | 24 | ||||
| -rw-r--r-- | host/utils/uhd_image_loader.cpp | 122 | ||||
| -rwxr-xr-x | host/utils/usrp_n2xx_net_burner.py | 51 | ||||
| -rw-r--r-- | host/utils/usrp_n2xx_simple_net_burner.cpp | 57 | ||||
| -rw-r--r-- | host/utils/usrp_x3xx_fpga_burner.cpp | 69 | 
6 files changed, 321 insertions, 5 deletions
diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt index e24b417c1..2f61c3c2e 100644 --- a/host/utils/CMakeLists.txt +++ b/host/utils/CMakeLists.txt @@ -1,5 +1,5 @@  # -# Copyright 2010-2014 Ettus Research LLC +# Copyright 2010-2015 Ettus Research LLC  #  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@  SET(util_runtime_sources      uhd_find_devices.cpp      uhd_usrp_probe.cpp +    uhd_image_loader.cpp      uhd_cal_rx_iq_balance.cpp      uhd_cal_tx_dc_offset.cpp      uhd_cal_tx_iq_balance.cpp diff --git a/host/utils/octoclock_firmware_burner.cpp b/host/utils/octoclock_firmware_burner.cpp index eb8198a2b..1ec77d0c8 100644 --- a/host/utils/octoclock_firmware_burner.cpp +++ b/host/utils/octoclock_firmware_burner.cpp @@ -104,6 +104,28 @@ void list_octoclocks(){      }  } +void print_image_loader_warning(const std::string &fw_path, const po::variables_map &vm){ +    // Newline + indent +    #ifdef UHD_PLATFORM_WIN32 +    const std::string nl = " ^\n    "; +    #else +    const std::string nl = " \\\n    "; +    #endif + +    std::string uhd_image_loader = str(boost::format("uhd_image_loader --args=\"type=octoclock,addr=%s\"" +                                                     "%s --fw-path=%s") +                                       % vm["addr"].as<std::string>() % nl % fw_path); + +    std::cout << "************************************************************************************************" << std::endl +              << "WARNING: This utility will be removed in an upcoming version of UHD. In the future, use" << std::endl +              << "         this command:" << std::endl +              << std::endl +              << uhd_image_loader << std::endl +              << std::endl +              << "************************************************************************************************" << std::endl +              << std::endl;  +} +  /*   * Manually find bootloader. This sends multiple packets in order to increase chances of getting   * bootloader before it switches to the application. @@ -363,6 +385,8 @@ int UHD_SAFE_MAIN(UHD_UNUSED(int argc), UHD_UNUSED(char *argv[])){      read_firmware(); +    print_image_loader_warning(firmware_path, vm); +      std::signal(SIGINT, &sig_int_handler);      burn_firmware(udp_transport); diff --git a/host/utils/uhd_image_loader.cpp b/host/utils/uhd_image_loader.cpp new file mode 100644 index 000000000..39efc8f1e --- /dev/null +++ b/host/utils/uhd_image_loader.cpp @@ -0,0 +1,122 @@ +// +// Copyright 2015 Ettus Research LLC +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program.  If not, see <http://www.gnu.org/licenses/>. +// + +#include <csignal> +#include <cstdlib> +#include <iostream> + +#include <boost/assign.hpp> +#include <boost/filesystem.hpp> +#include <boost/format.hpp> + +#include <uhd/config.hpp> +#include <uhd/image_loader.hpp> +#include <uhd/types/device_addr.hpp> +#include <uhd/utils/safe_main.hpp> +#include <boost/program_options.hpp> + +namespace fs = boost::filesystem; +namespace po = boost::program_options; + +static std::string device_type = ""; +static int num_ctrl_c = 0; + +/* + * If the user presses Ctrl+C, warn them that they may corrupt their device. + * If they press it again, provide instructions on restoring the device + * (if applicable) and exit. + */ +void sigint_handler(int){ +    num_ctrl_c++; +    if(num_ctrl_c == 1){ +        std::cout << std::endl +                  << "Are you sure you want to abort? If you do, your device will likely" << std::endl +                  << "be in an unstable or unusable state." << std::endl +                  << "Press Ctrl+C again to abort." << std::endl << std::endl; +    } +    else{ +        std::cout << std::endl << uhd::image_loader::get_recovery_instructions(device_type) << std::endl; +        exit(EXIT_FAILURE); +    } +} + +int UHD_SAFE_MAIN(int argc, char *argv[]){ + +    std::string fw_path = ""; +    std::string fpga_path = ""; + +    po::options_description desc("Allowed options"); +    desc.add_options() +        ("help", "help message") +        ("args", po::value<std::string>()->default_value(""), "Device args, optional loader args") +        ("fw-path", po::value<std::string>(&fw_path)->default_value(""), "Firmware path (uses default if none specified)") +        ("fpga-path", po::value<std::string>(&fpga_path)->default_value(""), "FPGA path (uses default if none specified)") +        ("no-fw", "Don't burn firmware") +        ("no-fpga", "Don't burn FPGA") +    ; + +    po::variables_map vm; +    po::store(po::parse_command_line(argc, argv, desc), vm); +    po::notify(vm); + +    // Help message +    if (vm.count("help")){ +        std::cout << "UHD Image Loader" << std::endl +                  << std::endl +                  << "Load firmware and/or FPGA images onto an Ettus Research device." << std::endl +                  << std::endl +                  << desc << std::endl; +        return EXIT_FAILURE; +    } + +    // Convert user options +    uhd::image_loader::image_loader_args_t image_loader_args; +    image_loader_args.args          = vm["args"].as<std::string>(); +    image_loader_args.load_firmware = (vm.count("no-fw") == 0); +    image_loader_args.load_fpga     = (vm.count("no-fpga") == 0); +    image_loader_args.firmware_path = vm["fw-path"].as<std::string>(); +    image_loader_args.fpga_path     = vm["fpga-path"].as<std::string>(); + +    // Clean up paths, if given +    if(image_loader_args.firmware_path != ""){ +        #ifndef UHD_PLATFORM_WIN32 +        if(image_loader_args.firmware_path.find("~") == 0){ +            image_loader_args.firmware_path.replace(0,1,getenv("HOME")); +        } +        #endif /* UHD_PLATFORM_WIN32 */ +        image_loader_args.firmware_path = fs::absolute(image_loader_args.firmware_path).string(); +    } +    if(image_loader_args.fpga_path != ""){ +        #ifndef UHD_PLATFORM_WIN32 +        if(image_loader_args.fpga_path.find("~") == 0){ +            image_loader_args.fpga_path.replace(0,1,getenv("HOME")); +        } +        #endif /* UHD_PLATFORM_WIN32 */ +        image_loader_args.fpga_path = fs::absolute(image_loader_args.fpga_path).string(); +    } + +    // Detect which type of device we're working with +    device_type = image_loader_args.args.get("type",""); + +    std::signal(SIGINT, &sigint_handler); +    if(not uhd::image_loader::load(image_loader_args)){ +        std::cerr << "No applicable UHD devices found" << std::endl; +        return EXIT_FAILURE; +    } + +    return EXIT_SUCCESS; +} diff --git a/host/utils/usrp_n2xx_net_burner.py b/host/utils/usrp_n2xx_net_burner.py index 8f16de501..5605b0028 100755 --- a/host/utils/usrp_n2xx_net_burner.py +++ b/host/utils/usrp_n2xx_net_burner.py @@ -1,6 +1,6 @@  #!/usr/bin/env python  # -# Copyright 2010-2011 Ettus Research LLC +# Copyright 2010-2011,2015 Ettus Research LLC  #  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU General Public License as published by @@ -91,6 +91,45 @@ def seq():      return _seq  ######################################################################## +# print equivalent uhd_image_loader command +######################################################################## +def print_image_loader_warning(fw, fpga, reset, safe, addr): + +    # Newline + indent +    if platform.system() == "Windows": +        nl = " ^\n    " +    else: +        nl = " \\\n    " + +    # Generate uhd_image_loader command based on given arguments +    uhd_image_loader = "uhd_image_loader --args=\"type=usrp2,addr={0}".format(addr) +    if reset: +        uhd_image_loader += ",reset" +    if safe: +        uhd_image_loader += ",overwrite-safe" +    uhd_image_loader += "\"" + +    if fw: +        uhd_image_loader += "{0}--fw-path=\"{1}\"".format(nl, fw) +    else: +        uhd_image_loader += "{0}--no-fw".format(nl) + +    if fpga: +        uhd_image_loader += "{0}--fpga-path=\"{1}\"".format(nl, fpga) +    else: +        uhd_image_loader += "{0}--no-fpga".format(nl) + +    print("") +    print("************************************************************************************************") +    print("WARNING: This utility will be removed in an upcoming version of UHD. In the future, use") +    print("         this command:") +    print("") +    print(uhd_image_loader) +    print("") +    print("************************************************************************************************") +    print("") + +########################################################################  # helper functions  ########################################################################  def unpack_flash_args_fmt(s): @@ -234,6 +273,7 @@ def enumerate_devices():  class burner_socket(object):      def __init__(self, addr, quiet):          self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +        self._addr = addr          self._quiet = quiet          self._sock.settimeout(UDP_TIMEOUT)          self._sock.connect((addr, UDP_FW_UPDATE_PORT)) @@ -284,6 +324,8 @@ class burner_socket(object):          return (self.memory_size_bytes, self.sector_size_bytes)      def burn_fw(self, fw, fpga, reset, safe, check_rev=True): +        print_image_loader_warning(fw, fpga, reset, safe, self._addr) +          (flash_size, sector_size) = self.get_flash_info()          hw_rev = self.get_hw_rev() @@ -501,7 +543,12 @@ if __name__=='__main__':      if options.overwrite_safe and not options.read:          print("Are you REALLY, REALLY sure you want to overwrite the safe image? This is ALMOST ALWAYS a terrible idea.")          print("If your image is faulty, your USRP2+ will become a brick until reprogrammed via JTAG.") -        response = raw_input("""Type "yes" to continue, or anything else to quit: """) + +        python_major_version = int(platform.python_version_tuple()[0]) +        if python_major_version > 2: +            response = input("""Type "yes" to continue, or anything else to quit: """) +        else: +            response = raw_input("""Type "yes" to continue, or anything else to quit: """)          if response != "yes": sys.exit(0)      burner = burner_socket(addr=options.addr,quiet=False) diff --git a/host/utils/usrp_n2xx_simple_net_burner.cpp b/host/utils/usrp_n2xx_simple_net_burner.cpp index 642e9a407..b105e9cb6 100644 --- a/host/utils/usrp_n2xx_simple_net_burner.cpp +++ b/host/utils/usrp_n2xx_simple_net_burner.cpp @@ -1,5 +1,5 @@  // -// Copyright 2012-2014 Ettus Research LLC +// Copyright 2012-2015 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -184,6 +184,59 @@ void list_usrps(){  /***********************************************************************   * Find USRP N2XX with specified IP address and return type   **********************************************************************/ +void print_image_loader_warning(const std::string &fw_path, +                                const std::string &fpga_path, +                                const po::variables_map &vm){ + +    // Newline + indent +    #ifdef UHD_PLATFORM_WIN32 +    const std::string nl = " ^\n    "; +    #else +    const std::string nl = " \\\n    "; +    #endif + +    std::string uhd_image_loader = str(boost::format("uhd_image_loader --args=\"type=usrp2,addr=%s") +                                       % vm["addr"].as<std::string>()); +    if(vm.count("auto-reboot") > 0) +        uhd_image_loader += ",reset"; +    if(vm.count("overwrite-safe") > 0) +        uhd_image_loader += ",overwrite-safe"; +    if(vm.count("dont-check-rev") > 0) +        uhd_image_loader += ",dont-check-rev"; + +    uhd_image_loader += "\""; + +    if(vm.count("no-fw") == 0){ +        uhd_image_loader += str(boost::format("%s--fw-path=\"%s\"") +                                % nl % fw_path); +    } +    else{ +        uhd_image_loader += str(boost::format("%s--no-fw") +                                % nl); +    } + +    if(vm.count("no-fpga") == 0){ +        uhd_image_loader += str(boost::format("%s--fpga-path=\"%s\"") +                                % nl % fpga_path); +    } +    else{ +        uhd_image_loader += str(boost::format("%s--no-fpga") +                                % nl); +    } + +    std::cout << "************************************************************************************************" << std::endl +              << "WARNING: This utility will be removed in an upcoming version of UHD. In the future, use" << std::endl +              << "         this command:" << std::endl +              << std::endl +              << uhd_image_loader << std::endl +              << std::endl +              << "************************************************************************************************" << std::endl +              << std::endl; +} + +/*********************************************************************** + * Find USRP N2XX with specified IP address and return type + **********************************************************************/  boost::uint32_t find_usrp(udp_simple::sptr udp_transport, bool check_rev){      boost::uint32_t hw_rev;      bool found_it = false; @@ -627,6 +680,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          fw_image_size = read_fw_image(fw_path);      } +    print_image_loader_warning(fw_path, fpga_path, vm); +      std::cout << "Will burn the following images:" << std::endl;      if(burn_fw) std::cout << boost::format(" * Firmware: %s\n") % fw_path;      if(burn_fpga) std::cout << boost::format(" * FPGA:     %s\n") % fpga_path; diff --git a/host/utils/usrp_x3xx_fpga_burner.cpp b/host/utils/usrp_x3xx_fpga_burner.cpp index 3c6225531..0b3d2da27 100644 --- a/host/utils/usrp_x3xx_fpga_burner.cpp +++ b/host/utils/usrp_x3xx_fpga_burner.cpp @@ -1,5 +1,5 @@  // -// Copyright 2013-2014 Ettus Research LLC +// Copyright 2013-2015 Ettus Research LLC  //  // This program is free software: you can redistribute it and/or modify  // it under the terms of the GNU General Public License as published by @@ -195,6 +195,71 @@ void extract_from_lvbitx(std::string lvbitx_path, std::vector<char> &bitstream){      bitstream.swap(decoded_bitstream);  } +void print_image_loader_warning(const std::string &fpga_path, const po::variables_map &vm){ + +    // Newline + indent +    #ifdef UHD_PLATFORM_WIN32 +    const std::string nl = " ^\n    "; +    #else +    const std::string nl = " \\\n    "; +    #endif + +    // Generate equivalent uhd_image_loader command +    std::string uhd_image_loader = "uhd_image_loader --args=\"type=x300"; + +    if(vm.count("addr") > 0){ +        uhd_image_loader += str(boost::format(",addr=%s") +                                % vm["addr"].as<std::string>()); + +        if(vm.count("configure") > 0){ +            uhd_image_loader += ",configure"; +        } + +        if(vm.count("verify") > 0){ +            uhd_image_loader += ",verify"; +        } +    } +    else{ +        uhd_image_loader += str(boost::format(",resource=%s") +                                % vm["resource"].as<std::string>()); + +        /* +         * Since we have a default value, vm.count("rpc-port") will +         * always be > 0, so only add the option if a different port +         * is given. +         */ +        if(vm["rpc-port"].as<std::string>() != "5444"){ +            uhd_image_loader += str(boost::format(",rpc-port=%s") +                                    % vm["rpc-port"].as<std::string>()); +        } +    } + +    if(vm.count("type") > 0){ +        uhd_image_loader += str(boost::format(",fpga=%s") +                                % vm["type"].as<std::string>()); +    } + +    uhd_image_loader += "\""; + +    /* +     * The --type option overrides any given path, so only add an FPGA path +     * if there was no --type argument. +     */ +    if(vm.count("type") == 0){ +        uhd_image_loader += str(boost::format("%s--fpga-path=\"%s\"") +                                % nl % fpga_path); +    } + +    std::cout << "************************************************************************************************" << std::endl +              << "WARNING: This utility will be removed in an upcoming version of UHD. In the future, use" << std::endl +              << "         this command:" << std::endl +              << std::endl +              << uhd_image_loader << std::endl +              << std::endl +              << "************************************************************************************************" << std::endl +              << std::endl; +} +  void ethernet_burn(udp_simple::sptr udp_transport, std::string fpga_path, bool verify){      boost::uint32_t max_size;      std::vector<char> bitstream; @@ -479,6 +544,8 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){          throw std::runtime_error("The image filename must end in .bin, .bit, or .lvbitx.");      } +    print_image_loader_warning(fpga_path, vm); +      std::signal(SIGINT, &sig_int_handler);      if(vm.count("addr")){          udp_simple::sptr udp_transport = udp_simple::make_connected(ip_addr, BOOST_STRINGIZE(X300_FPGA_PROG_UDP_PORT));  | 
