aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils
diff options
context:
space:
mode:
Diffstat (limited to 'host/utils')
-rw-r--r--host/utils/CMakeLists.txt2
-rw-r--r--host/utils/b2xx_fx3_utils.cpp268
-rw-r--r--host/utils/uhd_images_downloader.py.in435
-rw-r--r--host/utils/usrp_n2xx_simple_net_burner.cpp12
4 files changed, 503 insertions, 214 deletions
diff --git a/host/utils/CMakeLists.txt b/host/utils/CMakeLists.txt
index f73690475..abf2a546b 100644
--- a/host/utils/CMakeLists.txt
+++ b/host/utils/CMakeLists.txt
@@ -47,7 +47,7 @@ SET(util_share_sources
IF(ENABLE_USB)
LIST(APPEND util_share_sources
fx2_init_eeprom.cpp
- b2xx_fx3_utils
+ b2xx_fx3_utils.cpp
)
INCLUDE_DIRECTORIES(${LIBUSB_INCLUDE_DIRS})
# Additional include directories for b2xx_fx3_utils
diff --git a/host/utils/b2xx_fx3_utils.cpp b/host/utils/b2xx_fx3_utils.cpp
index c182548b7..96cd1f3e7 100644
--- a/host/utils/b2xx_fx3_utils.cpp
+++ b/host/utils/b2xx_fx3_utils.cpp
@@ -44,6 +44,27 @@
namespace po = boost::program_options;
namespace fs = boost::filesystem;
+struct vid_pid_t {
+ boost::uint16_t vid;
+ boost::uint16_t pid;
+};
+const static vid_pid_t known_vid_pids[] = {
+ {FX3_VID, FX3_DEFAULT_PID},
+ {FX3_VID, FX3_REENUM_PID},
+ {B200_VENDOR_ID, B200_PRODUCT_ID}
+ };
+const static std::vector<vid_pid_t> known_vid_pid_vector(known_vid_pids, known_vid_pids + (sizeof(known_vid_pids) / sizeof(known_vid_pids[0])));
+const static boost::uint8_t eeprom_init_values[] = {
+ 0x43,
+ 0x59,
+ 0x14,
+ 0xB2,
+ (B200_PRODUCT_ID & 0xff),
+ (B200_PRODUCT_ID >> 8),
+ (B200_VENDOR_ID & 0xff),
+ (B200_VENDOR_ID >> 8)
+ };
+const static uhd::byte_vector_t eeprom_init_value_vector(eeprom_init_values, eeprom_init_values + (sizeof(eeprom_init_values) / sizeof(eeprom_init_values[0])));
//!used with lexical cast to parse a hex string
template <class T> struct to_hex{
@@ -96,6 +117,9 @@ int reset_usb()
std::string file = fs::path((*it).filename()).string();
+ if (file.length() < 5)
+ continue;
+
if(file.compare(0, 5, "0000:") == 0) {
/* Un-bind the device. */
std::fstream unbind((devpath.string() + "unbind").c_str(),
@@ -118,22 +142,30 @@ int reset_usb()
return 0;
}
-uhd::transport::usb_device_handle::sptr open_device(const boost::uint16_t vid, const boost::uint16_t pid)
+uhd::transport::usb_device_handle::sptr open_device(const boost::uint16_t vid, const boost::uint16_t pid, const bool user_supplied = false)
{
std::vector<uhd::transport::usb_device_handle::sptr> handles;
uhd::transport::usb_device_handle::sptr handle;
+ vid_pid_t vp = {vid, pid};
try {
- handles = uhd::transport::usb_device_handle::get_device_list(vid, pid); // try caller's VID/PID first
- if (handles.size() == 0)
- handles = uhd::transport::usb_device_handle::get_device_list(FX3_VID, FX3_DEFAULT_PID); // try default Cypress FX3 VID/PID next
- if (handles.size() == 0)
- handles = uhd::transport::usb_device_handle::get_device_list(FX3_VID, FX3_REENUM_PID); // try reenumerated Cypress FX3 VID/PID next
- if (handles.size() == 0)
- handles = uhd::transport::usb_device_handle::get_device_list(B200_VENDOR_ID, B200_PRODUCT_ID); // try default B200 VID/PID last
+ // try caller's VID/PID first
+ handles = uhd::transport::usb_device_handle::get_device_list(vp.vid,vp.pid);
+ if (user_supplied && handles.size() == 0)
+ std::cerr << (boost::format("Failed to open device with VID 0x%04x and PID 0x%04x - trying other known VID/PIDs") % vid % pid).str() << std::endl;
+
+ // try known VID/PIDs next
+ for (size_t i = 0; handles.size() == 0 && i < known_vid_pid_vector.size(); i++)
+ {
+ vp = known_vid_pid_vector[i];
+ handles = uhd::transport::usb_device_handle::get_device_list(vp.vid,vp.pid);
+ }
if (handles.size() > 0)
+ {
handle = handles[0];
+ std::cout << (boost::format("Device opened (VID=0x%04x,PID=0x%04x)") % vp.vid % vp.pid).str() << std::endl;
+ }
if (!handle)
std::cerr << "Cannot open device" << std::endl;
@@ -141,7 +173,7 @@ uhd::transport::usb_device_handle::sptr open_device(const boost::uint16_t vid, c
catch(const std::exception &e) {
std::cerr << "Failed to communicate with the device!" << std::endl;
#ifdef UHD_PLATFORM_WIN32
- std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details." << std::endl;
+ std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details:\nhttp://files.ettus.com/uhd_docs/manual/html/transport.html" << std::endl;
#endif /* UHD_PLATFORM_WIN32 */
handle.reset();
}
@@ -163,7 +195,7 @@ b200_iface::sptr make_b200_iface(const uhd::transport::usb_device_handle::sptr &
catch(const std::exception &e) {
std::cerr << "Failed to communicate with the device!" << std::endl;
#ifdef UHD_PLATFORM_WIN32
- std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details." << std::endl;
+ std::cerr << "The necessary drivers are not installed. Read the UHD Transport Application Notes for details:\nhttp://files.ettus.com/uhd_docs/manual/html/transport.html" << std::endl;
#endif /* UHD_PLATFORM_WIN32 */
b200.reset();
}
@@ -171,9 +203,83 @@ b200_iface::sptr make_b200_iface(const uhd::transport::usb_device_handle::sptr &
return b200;
}
+int read_eeprom(b200_iface::sptr& b200, uhd::byte_vector_t& data)
+{
+ try {
+ data = b200->read_eeprom(0x0, 0x0, 8);
+ } catch (std::exception &e) {
+ std::cerr << "Exception while reading EEPROM: " << e.what() << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
+
+int write_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data)
+{
+ try {
+ b200->write_eeprom(0x0, 0x0, data);
+ } catch (std::exception &e) {
+ std::cerr << "Exception while writing EEPROM: " << e.what() << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
+
+int verify_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data)
+{
+ bool verified = true;
+ uhd::byte_vector_t read_bytes;
+ if (read_eeprom(b200, read_bytes))
+ return -1;
+
+ if (data.size() != read_bytes.size())
+ {
+ std::cerr << "ERROR: Only able to verify first " << std::min(data.size(), read_bytes.size()) << " bytes." << std::endl;
+ verified = false;
+ }
+
+ for (size_t i = 0; i < std::min(data.size(), read_bytes.size()); i++) {
+ if (data[i] != read_bytes[i]) {
+ verified = false;
+ std::cerr << "Byte " << i << " Expected: " << data[i] << ", Got: " << read_bytes[i] << std::endl;
+ }
+ }
+
+ if (!verified) {
+ std::cerr << "Verification failed" << std::endl;
+ return -1;
+ }
+
+ return 0;
+}
+
+int write_and_verify_eeprom(b200_iface::sptr& b200, const uhd::byte_vector_t& data)
+{
+ if (write_eeprom(b200, data))
+ return -1;
+ if (verify_eeprom(b200, data))
+ return -1;
+
+ return 0;
+}
+
+int erase_eeprom(b200_iface::sptr& b200)
+{
+ uhd::byte_vector_t bytes(8);
+
+ memset(&bytes[0], 0xFF, 8);
+ if (write_and_verify_eeprom(b200, bytes))
+ return -1;
+
+ return 0;
+}
+
boost::int32_t main(boost::int32_t argc, char *argv[]) {
boost::uint16_t vid, pid;
std::string pid_str, vid_str, fw_file, fpga_file;
+ bool user_supplied_vid_pid = false;
po::options_description visible("Allowed options");
visible.add_options()
@@ -205,13 +311,24 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
desc.add(hidden);
po::variables_map vm;
- po::store(po::parse_command_line(argc, argv, desc), vm);
- po::notify(vm);
- if (vm.count("help")){
+ try {
+ po::store(po::parse_command_line(argc, argv, desc), vm);
+ po::notify(vm);
+ } catch (std::exception &e) {
+ std::cerr << "Exception while parsing arguments: " << e.what() << std::endl;
std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl;
return ~0;
- } else if (vm.count("reset-usb")) {
+ }
+
+ if (vm.count("help")){
+ try {
+ std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl;
+ } catch(...) {}
+ return ~0;
+ }
+
+ if (vm.count("reset-usb")) {
return reset_usb();
}
@@ -220,13 +337,20 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
vid = B200_VENDOR_ID; // Default
pid = B200_PRODUCT_ID; // Default
- if (vm.count("vid"))
- vid = atoh(vid_str);
- if (vm.count("pid"))
- pid = atoh(pid_str);
+ if (vm.count("vid") && vm.count("pid"))
+ {
+ try {
+ vid = atoh(vid_str);
+ pid = atoh(pid_str);
+ } catch (std::exception &e) {
+ std::cerr << "Exception while parsing VID and PID: " << e.what() << std:: endl;
+ return ~0;
+ }
+ user_supplied_vid_pid = true;
+ }
// open the device
- handle = open_device(vid, pid);
+ handle = open_device(vid, pid, user_supplied_vid_pid);
if (!handle)
return -1;
std::cout << "B2xx detected..." << std::flush;
@@ -242,8 +366,19 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
{
std::cout << "Overwriting existing firmware" << std::endl;
+ // before we reset, make sure we have a good firmware file
+ if(!(fs::exists(fw_file)))
+ {
+ std::cerr << "Invalid firmware filepath: " << fw_file << std::endl;
+ return -1;
+ }
+
// reset the device
- b200->reset_fx3();
+ try {
+ b200->reset_fx3();
+ } catch (std::exception &e) {
+ std::cerr << "Exception while reseting FX3: " << e.what() << std::endl;
+ }
// re-open device
b200.reset();
@@ -264,19 +399,24 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
if (fw_file.empty())
fw_file = uhd::find_image_path(B200_FW_FILE_NAME);
-
+
if(fw_file.empty()) {
std::cerr << "Firmware image not found!" << std::endl;
return -1;
}
-
+
if(!(fs::exists(fw_file))) {
std::cerr << "Invalid filepath: " << fw_file << std::endl;
return -1;
}
// load firmware
- b200->load_firmware(fw_file);
+ try {
+ b200->load_firmware(fw_file);
+ } catch (std::exception &e) {
+ std::cerr << "Exception while loading firmware: " << e.what() << std::endl;
+ return ~0;
+ }
// re-open device
b200.reset();
@@ -287,6 +427,8 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
b200 = make_b200_iface(handle);
if (!b200)
return -1;
+
+ std::cout << "Firmware loaded" << std::endl;
}
// Added for testing purposes - not exposed
@@ -294,12 +436,9 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
{
uhd::byte_vector_t data;
- try {
- data = b200->read_eeprom(0x0, 0x0, 8);
- } catch (std::exception &e) {
- std::cerr << "Exception while reading EEPROM: " << e.what() << std::endl;
+ if (read_eeprom(b200, data))
return -1;
- }
+
for (int i = 0; i < 8; i++)
std::cout << i << ": " << boost::format("0x%X") % (int)data[i] << std::endl;
@@ -309,34 +448,8 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
// Added for testing purposes - not exposed
if (vm.count("erase-eeprom"))
{
- uhd::byte_vector_t bytes(8);
- memset(&bytes[0], 0xFF, 8);
- try {
- b200->write_eeprom(0x0, 0x0, bytes);
- } catch (uhd::exception &e) {
- std::cerr << "Exception while writing to EEPROM: " << e.what() << std::endl;
- return -1;
- }
-
- // verify
- uhd::byte_vector_t read_bytes(8);
- try {
- read_bytes = b200->read_eeprom(0x0, 0x0, 8);
- } catch (uhd::exception &e) {
- std::cerr << "Exception while reading from EEPROM: " << e.what() << std::endl;
+ if (erase_eeprom(b200))
return -1;
- }
- bool verified = true;
- for (int i = 0; i < 8; i++) {
- if (bytes[i] != read_bytes[i]) {
- verified = false;
- std::cerr << "Expected: " << bytes[i] << ", Got: " << read_bytes[i] << std::endl;
- }
- }
- if (!verified) {
- std::cerr << "Verification failed" << std::endl;
- return -1;
- }
std::cout << "Erase Successful!" << std::endl;
@@ -346,16 +459,8 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
// Added for testing purposes - not exposed
if (vm.count("uninit-device"))
{
- // uninitialize the device
- uhd::byte_vector_t bytes(8);
- memset(&bytes[0], 0xFF, 8);
-
- try {
- b200->write_eeprom(0x0, 0x0, bytes);
- } catch (uhd::exception &e) {
- std::cerr << "Exception while writing to EEPROM: " << e.what() << std::endl;
- return -1;
- }
+ // erase EEPROM
+ erase_eeprom(b200);
std::cout << "EEPROM uninitialized, resetting device..."
<< std::endl << std::endl;
@@ -379,22 +484,8 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
if (vm.count("init-device"))
{
/* Now, initialize the device. */
- uhd::byte_vector_t bytes(8);
- bytes[0] = 0x43;
- bytes[1] = 0x59;
- bytes[2] = 0x14;
- bytes[3] = 0xB2;
- bytes[4] = (B200_PRODUCT_ID & 0xff);
- bytes[5] = (B200_PRODUCT_ID >> 8);
- bytes[6] = (B200_VENDOR_ID & 0xff);
- bytes[7] = (B200_VENDOR_ID >> 8);
-
- try {
- b200->write_eeprom(0x0, 0x0, bytes);
- } catch (uhd::exception &e) {
- std::cerr << "Exception while writing to EEPROM: " << e.what() << std::endl;
+ if (write_and_verify_eeprom(b200, eeprom_init_value_vector))
return -1;
- }
std::cout << "EEPROM initialized, resetting device..."
<< std::endl << std::endl;
@@ -403,7 +494,7 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
try {
b200->reset_fx3();
} catch (const std::exception &e) {
- std::cerr << "Exceptions while resetting device: " << e.what() << std::endl;
+ std::cerr << "Exception while resetting device: " << e.what() << std::endl;
return -1;
}
@@ -423,8 +514,9 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
return -1;
}
std::cout << "Currently operating at USB " << (int) speed << std::endl;
+ }
- } else if (vm.count("reset-device")) {
+ if (vm.count("reset-device")) {
try {b200->reset_fx3();}
catch (uhd::exception &e) {
std::cerr << "Exception while resetting FX3: " << e.what() << std::endl;
@@ -438,10 +530,6 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
return -1;
}
- } else if (vm.count("load-fw")) {
- std::cout << "Firmware load complete, releasing USB interface..."
- << std::endl;
-
} else if (vm.count("load-fpga")) {
std::cout << "Loading FPGA image (" << fpga_file << ")" << std::endl;
uint32_t fx3_state;
@@ -452,17 +540,13 @@ boost::int32_t main(boost::int32_t argc, char *argv[]) {
}
if (fx3_state != 0) {
- std::cerr << std::flush << "Error loading FPGA. FX3 state: "
- << fx3_state << std::endl;
+ std::cerr << std::flush << "Error loading FPGA. FX3 state ("
+ << fx3_state << "): " << b200_iface::fx3_state_string(fx3_state) << std::endl;
return ~0;
}
std::cout << "FPGA load complete, releasing USB interface..."
<< std::endl;
-
- } else {
- std::cout << boost::format("B2xx Utility Program %s") % visible << std::endl;
- return ~0;
}
std::cout << "Operation complete! I did it! I did it!" << std::endl;
diff --git a/host/utils/uhd_images_downloader.py.in b/host/utils/uhd_images_downloader.py.in
index bb082190c..697bd4e16 100644
--- a/host/utils/uhd_images_downloader.py.in
+++ b/host/utils/uhd_images_downloader.py.in
@@ -16,144 +16,341 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import atexit
-import hashlib
+import sys, os, string, tempfile, math
+import traceback
+import shutil, hashlib, urllib2, zipfile
+
from optparse import OptionParser
-import os
-import os.path
-import shutil
-import string
-import sys
-import tempfile
-import urllib2
-import zipfile
+
+_DEFAULT_BUFFER_SIZE = 8192
+_BASE_DIR_STRUCTURE_PARTS = ["share", "uhd", "images"]
+_BASE_DIR_STRUCTURE = os.path.join(_BASE_DIR_STRUCTURE_PARTS)
+_DEFAULT_INSTALL_PATH = os.path.join("@CMAKE_INSTALL_PREFIX@", *_BASE_DIR_STRUCTURE)
+_AUTOGEN_IMAGES_SOURCE = "@UHD_IMAGES_DOWNLOAD_SRC@"
+_AUTOGEN_IMAGES_CHECKSUM = "@UHD_IMAGES_MD5SUM@"
+_IMAGES_CHECKSUM_TYPE = "md5"
+_CONTACT = "support@ettus.com"
def md5Checksum(filePath):
- with open(filePath, 'rb') as fh:
- m = hashlib.md5()
- while True:
- data = fh.read(8192)
- if not data:
- break
- m.update(data)
- return m.hexdigest()
+ try:
+ with open(filePath, 'rb') as fh:
+ m = hashlib.md5()
+ while True:
+ data = fh.read(_DEFAULT_BUFFER_SIZE)
+ if not data:
+ break
+ m.update(data)
+ return m.hexdigest()
+ except Exception, e:
+ print "Failed to calculated MD5 sum of: %s (%s)" % (filePath, e)
+ raise e
-class temp_dir():
+_checksum_fns = {
+ 'md5': md5Checksum
+}
+class temporary_directory():
def __enter__(self):
- self.name = tempfile.mkdtemp()
- return self.name
+ try:
+ self.name = tempfile.mkdtemp()
+ return self.name
+ except Exception, e:
+ print "Failed to create a temporary directory (%s)" % (e)
+ raise e
+
+ # Can return 'True' to suppress incoming exception
def __exit__(self, type, value, traceback):
try:
shutil.rmtree(self.name)
- except OSError,e:
- #Utility should have already detected this, but this is for safety
- print str(e)
- raise Exception("Could not install images! Make sure you have write permissions.")
-
-if __name__ == "__main__":
-
- print
- if os.environ.get("UHD_IMAGES_DIR") != None and os.environ.get("UHD_IMAGES_DIR") != "":
- default_images_dir = os.environ.get("UHD_IMAGES_DIR")
- print "UHD_IMAGES_DIR environment variable is set. Default install location: %s" % default_images_dir
- else:
- default_images_dir = "@CMAKE_INSTALL_PREFIX@/share/uhd/images"
+ except Exception, e:
+ print "Could not delete temporary directory: %s (%s)" % (self.name, e)
- #Command line options
- parser = OptionParser()
- parser.add_option("--install-location", type="string", default=default_images_dir, help="Set custom install location for images")
- parser.add_option("--buffer-size", type="int", default=8192, help="Set download buffer size, [default=%default]",)
- (options, args) = parser.parse_args()
+class uhd_images_downloader():
+ def __init__(self):
+ pass
- #Configuring image download info
- images_src = "@UHD_IMAGES_DOWNLOAD_SRC@"
- images_zip_md5sum = "@UHD_IMAGES_MD5SUM@"
- filename = images_src.split("/")[-1]
-
- #Use this directory with relative paths
- current_directory = os.getcwd()
-
- with temp_dir() as dirname:
- os.chdir(dirname)
-
- if os.path.isabs(options.install_location):
- #Custom absolute path given
- images_dir = options.install_location
- else:
- #Custom relative path given, so construct absolute path
- images_dir = os.path.abspath(os.path.join(current_directory, options.install_location))
-
- #Before doing anything, check for write permissions in parent directory
- parent_directory = os.path.dirname(images_dir)
- if os.access(parent_directory, os.W_OK):
- print "Downloading images to: %s" % images_dir
- else:
- print "You do not have write permissions at the install location!"
- sys.exit(1)
-
+ def download(self, images_url, filename, buffer_size=_DEFAULT_BUFFER_SIZE, print_progress=False):
opener = urllib2.build_opener()
opener.add_headers = [('User-Agent', 'UHD Images Downloader')]
- u = opener.open(images_src)
- f = open(filename, "wb")
+ u = opener.open(images_url)
meta = u.info()
filesize = float(meta.getheaders("Content-Length")[0])
- print "Downloading images from: %s" % images_src
+ filesize_dl = 0
- filesize_dl = 0.0
-
- #Downloading file
- while True:
- buffer = u.read(options.buffer_size)
- if not buffer:
- break
-
- filesize_dl -= len(buffer)
- f.write(buffer)
+ with open(filename, "wb") as f:
+ while True:
+ buffer = u.read(buffer_size)
+ if not buffer:
+ break
+
+ f.write(buffer)
- status = r"%2.2f MB/%2.2f MB (%3.2f" % (-filesize_dl/1e6, filesize/1e6, (-filesize_dl*100.)/filesize) + r"%)"
- status += chr(8)*(len(status)+1)
- print status,
+ filesize_dl += len(buffer)
+
+ if print_progress:
+ status = r"%05d kB / %05d kB (%03d%%)" % (int(math.ceil(filesize_dl/1000.)), int(math.ceil(filesize/1000.)), int(math.ceil(filesize_dl*100.)/filesize))
+ status += chr(8)*(len(status)+1)
+ print status,
- f.close()
-
- #Checking md5sum of zip file
- downloaded_zip_md5sum = md5Checksum(filename)
- if images_zip_md5sum != downloaded_zip_md5sum:
- print "\nMD5 checksum does not match!"
- print "Expected %s, got %s" % (images_zip_md5sum, downloaded_zip_md5sum)
- print "Images did not install. If problem persists, please contact support@ettus.com."
- os.remove(filename)
- os.chdir("/".join(images_dir.split("/")[:-1]))
- sys.exit(1)
+ if print_progress:
+ print
+
+ return (filesize, filesize_dl)
+
+ def check_directories(self, dirs, print_progress=False):
+ if dirs is None or dirs == "":
+ dirs = "."
+ dirs = os.path.abspath(dirs)
+
+ def _check_part(head, tail=None):
+ if print_progress:
+ print "Checking: %s" % (head)
+ if tail is not None and tail == "":
+ return True
+ if not os.path.exists(head):
+ if print_progress:
+ print "Does not exist: %s" % (head)
+ return _check_part(*os.path.split(head))
+ if not os.path.isdir(head):
+ if print_progress:
+ print "Is not a directory: %s" % (head)
+ return (False, head)
+ if not os.access(head, os.W_OK):
+ if print_progress:
+ print "Write permission denied on: %s" % (head)
+ return (False, head)
+ if print_progress:
+ print "Write permission granted on: %s" % (head)
+ return (True, head)
+
+ return _check_part(dirs)
+
+ def validate_checksum(self, checksum_fn, file_path, expecting, print_progress=False):
+ if checksum_fn is None:
+ return (True, "")
+
+ calculated_checksum = checksum_fn(file_path)
+
+ if (expecting is not None) and (expecting != "") and calculated_checksum != expecting:
+ return (False, calculated_checksum)
+
+ return (True, calculated_checksum)
+
+ def extract_images_archive(self, archive_path, destination=None, print_progress=False):
+ if not os.path.exists(archive_path):
+ if print_progress:
+ print "Path does not exist: %s" % (archive_path)
+ raise Exception("path does not exist: %s" % (archive_path))
+
+ if print_progress:
+ print "Archive path: %s" % (archive_path)
+
+ (head, tail) = os.path.split(archive_path)
+
+ if not os.access(head, os.W_OK):
+ if print_progress:
+ print "Write access denied on: %s" % (head)
+ raise Exception("write access denied on: %s" % (head))
+
+ (root, ext) = os.path.splitext(tail)
+ temp_dir = os.path.join(head, root)
+
+ if print_progress:
+ print "Temporary extraction location: %s" % (temp_dir)
+
+ if os.path.exists(temp_dir):
+ if print_progress:
+ print "Deleting existing location: %s" % (temp_dir)
+ shutil.rmtree(temp_dir)
+
+ if print_progress:
+ print "Creating directory: %s" % (temp_dir)
+ os.mkdir(temp_dir)
+
+ if print_progress:
+ print "Extracting archive %s to %s" % (archive_path, temp_dir)
+
+ images_zip = zipfile.ZipFile(archive_path)
+ images_zip.extractall(temp_dir)
+ images_zip.close()
+
+ return temp_dir
+
+ def install_images(self, source, dest, keep=False, print_progress=False):
+ if not os.path.exists(source):
+ if print_progress:
+ print "Source path does not exist: %s" % (source)
+ return
+
+ if keep:
+ if print_progress:
+ print "Not wiping directory tree (existing files will be overwritten): %s" % (dest)
+ elif os.path.exists(dest):
+ if print_progress:
+ print "Deleting directory tree: %s" % (dest)
+ shutil.rmtree(dest)
+
+ (head, tail) = os.path.split(source)
+
+ if print_progress:
+ print "Source install path: %s" % (source)
+
+ uhd_source = os.path.join(source, tail, *_BASE_DIR_STRUCTURE_PARTS)
+
+ if print_progress:
+ print "Copying files from: %s" % (uhd_source)
+ print "Copying files to: %s" % (dest)
+
+ if keep:
+ # mgrant @ http://stackoverflow.com/questions/12683834/how-to-copy-directory-recursively-in-python-and-overwrite-all
+ def _recursive_overwrite(src, dest, ignore=None):
+ if os.path.isdir(src):
+ if not os.path.isdir(dest):
+ os.makedirs(dest)
+ files = os.listdir(src)
+ if ignore is not None:
+ ignored = ignore(src, files)
+ else:
+ ignored = set()
+ for f in files:
+ if f not in ignored:
+ _recursive_overwrite(os.path.join(src, f), os.path.join(dest, f), ignore)
+ else:
+ shutil.copyfile(src, dest)
+
+ _recursive_overwrite(uhd_source, dest)
else:
- temp_path = "tempdir"
-
- #Extracting contents of zip file
- if os.path.exists(temp_path):
- shutil.rmtree(temp_path)
- os.mkdir(temp_path)
-
- images_zip = zipfile.ZipFile(filename)
- images_zip.extractall(temp_path)
+ shutil.copytree(uhd_source, dest)
- #Removing images currently in images_dir
- if os.path.exists(images_dir):
- try:
- shutil.rmtree(images_dir)
- except OSError,e:
- print str(e)
- print "Make sure you have write permissions in the images directory."
- sys.exit(1)
-
- #Copying downloaded images into images_dir
- shutil.copytree(os.path.join(temp_path, os.path.splitext(filename)[0], 'share', 'uhd', 'images'), images_dir)
-
- #Removing tempdir and zip file
- shutil.rmtree(temp_path)
- images_zip.close()
- os.remove(filename)
+def main():
+ if os.environ.get("UHD_IMAGES_DIR") != None and os.environ.get("UHD_IMAGES_DIR") != "":
+ default_images_dir = os.environ.get("UHD_IMAGES_DIR")
+ print "UHD_IMAGES_DIR environment variable is set. Default install location: %s" % default_images_dir
+ else:
+ default_images_dir = _DEFAULT_INSTALL_PATH
+
+ parser = OptionParser()
+ parser.add_option("-i", "--install-location", type="string", default=default_images_dir,
+ help="Set custom install location for images [default=%default]")
+ parser.add_option("--buffer-size", type="int", default=_DEFAULT_BUFFER_SIZE,
+ help="Set download buffer size [default=%default]")
+ parser.add_option("-u", "--url", type="string", default=_AUTOGEN_IMAGES_SOURCE,
+ help="Set images download location [default=%default]")
+ parser.add_option("-c", "--checksum", type="string", default=_AUTOGEN_IMAGES_CHECKSUM,
+ help="Validate images archive against this checksum (blank to skip) [default=%default]")
+ parser.add_option("-t", "--checksum-type", type="string", default=_IMAGES_CHECKSUM_TYPE,
+ help=("Select checksum hash function (options: %s) [default=%%default]" % (",".join(_checksum_fns.keys()))))
+ parser.add_option("-k", "--keep", action="store_true", default=False,
+ help="Do not clear images directory before extracting new files [default=%default]")
+ parser.add_option("-v", "--verbose", action="store_true", default=False,
+ help="Enable verbose output [default=%default]")
+
+ (options, args) = parser.parse_args()
+
+ if options.buffer_size <= 0:
+ print "Invalid buffer size: %s" % (options.buffer_size)
+ return 1
+
+ checksum_fn = None
+ if options.checksum != "":
+ options.checksum_type = options.checksum_type.lower()
+ if not _checksum_fns.has_key(options.checksum_type):
+ print "Not a supported checksum function: %s" % (options.checksum_type)
+ return 1
+ checksum_fn = _checksum_fns[options.checksum_type]
+
+ url_parts = options.url.split("/")
+ if len(url_parts) <= 1 or url_parts[-1] == "":
+ print "Not a valid URL: %s" % (options.url)
+ return 1
+ images_filename = url_parts[-1]
+
+ images_dir = os.path.abspath(options.install_location) # This will use the current working directory if it's not absolute
+
+ if options.verbose:
+ print "Requested install location: %s" % (options.install_location)
+ print "Images source: %s" % (options.url)
+ print "Images filename: %s" % (images_filename)
+ print "Images checksum: %s (%s)" % (options.checksum, _IMAGES_CHECKSUM_TYPE)
+ print "Final install location: %s" % (images_dir)
+ else:
+ print "Images destination: %s" % (images_dir)
+
+ downloader = uhd_images_downloader()
+
+ try:
+ (access, last_path) = downloader.check_directories(images_dir, print_progress=options.verbose)
+ if access:
+ with temporary_directory() as temp_dir:
+ if options.verbose:
+ print "Using temporary directory: %s" % (temp_dir)
+
+ print "Downloading images from: %s" % options.url
+
+ temp_images_dest = os.path.join(temp_dir, images_filename)
+
+ print "Downloading images to: %s" % (temp_images_dest)
+
+ (reported_size, downloaded_size) = downloader.download(images_url=options.url, filename=temp_images_dest, buffer_size=options.buffer_size, print_progress=True)
+
+ if options.verbose:
+ print "Downloaded %d of %d bytes" % (downloaded_size, reported_size)
+
+ (checksum_match, calculated_checksum) = downloader.validate_checksum(checksum_fn, temp_images_dest, options.checksum, print_progress=options.verbose)
+
+ if options.verbose:
+ print "Calculated checksum: %s" % (calculated_checksum)
+
+ if checksum_match:
+ if options.verbose:
+ if options.checksum == "":
+ print "Ignoring checksum"
+ else:
+ print "Checksum OK"
+
+ try:
+ extract_path = downloader.extract_images_archive(temp_images_dest, print_progress=options.verbose)
+
+ if options.verbose:
+ print "Image archive extracted to: %s" % (extract_path)
+
+ downloader.install_images(extract_path, images_dir, options.keep, print_progress=options.verbose)
+
+ print
+ print "Images successfully installed to: %s" % (images_dir)
+ except Exception, e:
+ print "Failed to install image archive: %s" % (e)
+ print "This is usually a permissions problem."
+ print "Please check your file system access rights and try again."
+
+ if options.verbose:
+ traceback.print_exc()
+ else:
+ print "You can run this again with the '--verbose' flag to see more information"
+ print "If the problem persists, please email the output to: %s" % (_CONTACT)
+ else:
+ print "Checksum of downloaded file is not correct (not installing - see options to override)"
+ print "Expected: %s" % (options.checksum)
+ print "Calculated: %s" % (calculated_checksum)
+ print "Please try downloading again."
+ print "If the problem persists, please email the output to: %s" % (_CONTACT)
+ else:
+ print "You do not have sufficient permissions to write to: %s" % (last_path)
+ print "Are you root?"
+ except KeyboardInterrupt:
+ print
+ print "Cancelled at user request"
+ except Exception, e:
+ print "Downloader raised an unhandled exception: %s" % (e)
+ if options.verbose:
+ traceback.print_exc()
+ else:
+ print "You can run this again with the '--verbose' flag to see more information"
+ print "If the problem persists, please email the output to: %s" % (_CONTACT)
+ return 1
+
+ return 0
- os.chdir(images_dir)
- print "\n\nImages successfully installed!"
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/host/utils/usrp_n2xx_simple_net_burner.cpp b/host/utils/usrp_n2xx_simple_net_burner.cpp
index c3ccba173..1898ee9ae 100644
--- a/host/utils/usrp_n2xx_simple_net_burner.cpp
+++ b/host/utils/usrp_n2xx_simple_net_burner.cpp
@@ -468,13 +468,21 @@ int UHD_SAFE_MAIN(int argc, char *argv[]){
std::cout << "Searching for specified images." << std::endl << std::endl;
if(burn_fpga){
if(!use_custom_fpga) fpga_path = find_image_path(default_fpga_filename);
- else validate_custom_fpga_file(filename_map[hw_rev], fpga_path);
+ else{
+ //Replace ~ with home directory
+ if(fpga_path.find("~/") == 0) fpga_path.replace(0,1,getenv("HOME"));
+ validate_custom_fpga_file(filename_map[hw_rev], fpga_path);
+ }
grab_fpga_image(fpga_path);
}
if(burn_fw){
if(!use_custom_fw) fw_path = find_image_path(default_fw_filename);
- else validate_custom_fw_file(filename_map[hw_rev], fw_path);
+ else{
+ //Replace ~ with home directory
+ if(fw_path.find("~/") == 0) fw_path.replace(0,1,getenv("HOME"));
+ validate_custom_fw_file(filename_map[hw_rev], fw_path);
+ }
grab_fw_image(fw_path);
}