From c9124630941847bcf7b172f4ebf16b6a947e6f75 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 19 Feb 2011 11:16:07 -0800 Subject: usrp-n2xx: reimplemented the net burner to use one socket per session This fixes the timeout issue seen on windows. (tested in virtualbox windows 7 and ubuntu linux) The issue was the the net burner was opening a socket for every transaction, which is likely more than some OS can keep up with. --- host/utils/usrp_n2xx_net_burner.py | 373 ++++++++++++++++++------------------- 1 file changed, 186 insertions(+), 187 deletions(-) diff --git a/host/utils/usrp_n2xx_net_burner.py b/host/utils/usrp_n2xx_net_burner.py index f52a2cbc1..ce0dbf2f3 100755 --- a/host/utils/usrp_n2xx_net_burner.py +++ b/host/utils/usrp_n2xx_net_burner.py @@ -27,6 +27,7 @@ import re import struct import socket import sys +import time ######################################################################## # constants @@ -75,77 +76,28 @@ class update_id_t: _seq = -1 def seq(): - global _seq - _seq = _seq+1 - return _seq + global _seq + _seq = _seq+1 + return _seq ######################################################################## # helper functions ######################################################################## def unpack_flash_args_fmt(s): - return struct.unpack(FLASH_ARGS_FMT, s) #(proto_ver, pktid, seq, flash_addr, length, data) + return struct.unpack(FLASH_ARGS_FMT, s) #(proto_ver, pktid, seq, flash_addr, length, data) def unpack_flash_info_fmt(s): - return struct.unpack(FLASH_INFO_FMT, s) #(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) + return struct.unpack(FLASH_INFO_FMT, s) #(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) def unpack_flash_ip_fmt(s): - return struct.unpack(FLASH_IP_FMT, s) #(proto_ver, pktid, seq, ip_addr) + return struct.unpack(FLASH_IP_FMT, s) #(proto_ver, pktid, seq, ip_addr) def pack_flash_args_fmt(proto_ver, pktid, seq, flash_addr, length, data): - return struct.pack(FLASH_ARGS_FMT, proto_ver, pktid, seq, flash_addr, length, data) + return struct.pack(FLASH_ARGS_FMT, proto_ver, pktid, seq, flash_addr, length, data) def pack_flash_info_fmt(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes): - return struct.pack(FLASH_INFO_FMT, proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) + return struct.pack(FLASH_INFO_FMT, proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) -def send_and_recv(pkt, ip): - update_socket = create_socket() - - try: - update_socket.sendto(pkt, (ip, UDP_FW_UPDATE_PORT)) - except Exception, e: - print e - sys.exit(1) - - try: - (recv_pkt, recv_addr) = update_socket.recvfrom(UDP_MAX_XFER_BYTES) - except Exception, e: - print e - sys.exit(1) - - if recv_addr != (options.ip, UDP_FW_UPDATE_PORT): - raise Exception, "Packet received from invalid IP %s, expected %s" % (recv_addr, options.ip) - - return recv_pkt - -def create_socket(): - socket.setdefaulttimeout(UDP_TIMEOUT) - update_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - return update_socket - -#just here to validate comms -def init_update(ip): - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0, "") - in_pkt = send_and_recv(out_pkt, ip) - (proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(in_pkt) - if pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG: - print "USRP2P found." - else: - raise Exception, "Invalid reply received from device." - -# print "Incoming:\n\tVer: %i\n\tID: %c\n\tSeq: %i\n\tIP: %i\n" % (proto_ver, chr(pktid), rxseq, ip_addr) - -def get_flash_info(ip): - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL, seq(), 0, 0, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, sector_size_bytes, memory_size_bytes) = unpack_flash_info_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - - return (memory_size_bytes, sector_size_bytes) - def is_valid_fpga_image(fpga_image): for i in range(0,63): if ord(fpga_image[i]) == 0xFF: @@ -154,7 +106,7 @@ def is_valid_fpga_image(fpga_image): return 1 return 0 - + def is_valid_fw_image(fw_image): for i in range(0,4): if ord(fw_image[i]) != 0x0B: @@ -162,132 +114,179 @@ def is_valid_fw_image(fw_image): return 1 -def burn_fw(ip, fw, fpga, reset, safe): - init_update(ip) - (flash_size, sector_size) = get_flash_info(ip) - - print "Flash size: %i\nSector size: %i" % (flash_size, sector_size) - - if fpga: - if safe: - image_location = SAFE_FPGA_IMAGE_LOCATION_ADDR - else: - image_location = PROD_FPGA_IMAGE_LOCATION_ADDR - - fpga_file = open(fpga, 'rb') - fpga_image = fpga_file.read() - - if len(fpga_image) > FPGA_IMAGE_SIZE_BYTES: - print "Error: FPGA image file too large." - return 0 - - if not is_valid_fpga_image(fpga_image): - print "Error: Invalid FPGA image file." - return 0 - - erase_image(ip, image_location, FPGA_IMAGE_SIZE_BYTES) - write_image(ip, fpga_image, image_location) - verify_image(ip, fpga_image, image_location) - - if fw: - if safe: - image_location = SAFE_FW_IMAGE_LOCATION_ADDR - else: - image_location = PROD_FW_IMAGE_LOCATION_ADDR - - fw_file = open(fw, 'rb') - fw_image = fw_file.read() - - if len(fw_image) > FW_IMAGE_SIZE_BYTES: - print "Error: Firmware image file too large." - return 0 - - if not is_valid_fw_image(fw_image): - print "Error: Invalid firmware image file." - return 0 - - erase_image(ip, image_location, FW_IMAGE_SIZE_BYTES) - write_image(ip, fw_image, image_location) - verify_image(ip, fw_image, image_location) - - if reset: - reset_usrp(ip) - -def write_image(ip, image, addr): - print "Writing image" -#we split the image into smaller (256B) bits and send them down the wire - while image: - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, image[:FLASH_DATA_PACKET_SIZE]) - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - image = image[FLASH_DATA_PACKET_SIZE:] - addr += FLASH_DATA_PACKET_SIZE - -def verify_image(ip, image, addr): - print "Verifying data" - readsize = len(image) - readdata = str() - while readsize > 0: - if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize - else: thisreadsize = FLASH_DATA_PACKET_SIZE - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - readdata += data[:thisreadsize] - readsize -= FLASH_DATA_PACKET_SIZE - addr += FLASH_DATA_PACKET_SIZE - - print "Read back %i bytes" % len(readdata) -# print readdata - -# for i in range(256, 512): -# print "out: %i in: %i" % (ord(image[i]), ord(readdata[i])) - - if readdata != image: - print "Verify failed. Image did not write correctly." - else: - print "Success." - -def reset_usrp(ip): - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - if pktid == update_id_t.USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG: - raise Exception, "Device failed to reset." - -def erase_image(ip, addr, length): - #get flash info first - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL, seq(), addr, length, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - print "Erasing %i bytes at %i" % (length, addr) - - #now wait for it to finish - while(1): - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL, seq(), 0, 0, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid == update_id_t.USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG: break - elif pktid != update_id_t.USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) +######################################################################## +# Burner class, holds a socket and send/recv routines +######################################################################## +class burner_socket(object): + def __init__(self, ip): + self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self._sock.settimeout(UDP_TIMEOUT) + self._sock.connect((ip, UDP_FW_UPDATE_PORT)) + + def send_and_recv(self, pkt): + try: self._sock.send(pkt) + except Exception, e: + print e + sys.exit(1) + + try: recv_pkt = self._sock.recv(UDP_MAX_XFER_BYTES) + except Exception, e: + print e + sys.exit(1) + + return recv_pkt + + #just here to validate comms + def init_update(self): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0, "") + in_pkt = self.send_and_recv(out_pkt) + (proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(in_pkt) + if pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG: + print "USRP2P found." + else: + raise Exception, "Invalid reply received from device." + + # print "Incoming:\n\tVer: %i\n\tID: %c\n\tSeq: %i\n\tIP: %i\n" % (proto_ver, chr(pktid), rxseq, ip_addr) + + def get_flash_info(self): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL, seq(), 0, 0, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, sector_size_bytes, memory_size_bytes) = unpack_flash_info_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + return (memory_size_bytes, sector_size_bytes) + + def burn_fw(self, fw, fpga, reset, safe): + (flash_size, sector_size) = self.get_flash_info() + + print "Flash size: %i\nSector size: %i\n\n" % (flash_size, sector_size) + + if fpga: + if safe: image_location = SAFE_FPGA_IMAGE_LOCATION_ADDR + else: image_location = PROD_FPGA_IMAGE_LOCATION_ADDR + + fpga_file = open(fpga, 'rb') + fpga_image = fpga_file.read() + + if len(fpga_image) > FPGA_IMAGE_SIZE_BYTES: + print "Error: FPGA image file too large." + return 0 + + if not is_valid_fpga_image(fpga_image): + print "Error: Invalid FPGA image file." + return 0 + + print "Begin FPGA write: this should take about 1 minute..." + start_time = time.time() + self.erase_image(image_location, FPGA_IMAGE_SIZE_BYTES) + self.write_image(fpga_image, image_location) + self.verify_image(fpga_image, image_location) + print "Time elapsed: %f seconds"%(time.time() - start_time) + print "\n\n" + + if fw: + if safe: image_location = SAFE_FW_IMAGE_LOCATION_ADDR + else: image_location = PROD_FW_IMAGE_LOCATION_ADDR + + fw_file = open(fw, 'rb') + fw_image = fw_file.read() + + if len(fw_image) > FW_IMAGE_SIZE_BYTES: + print "Error: Firmware image file too large." + return 0 + + if not is_valid_fw_image(fw_image): + print "Error: Invalid firmware image file." + return 0 + + print "Begin firmware write: this should take about 1 second..." + start_time = time.time() + self.erase_image(image_location, FW_IMAGE_SIZE_BYTES) + self.write_image(fw_image, image_location) + self.verify_image(fw_image, image_location) + print "Time elapsed: %f seconds"%(time.time() - start_time) + print "\n\n" + + if reset: self.reset_usrp() + + def write_image(self, image, addr): + print "Writing image" + #we split the image into smaller (256B) bits and send them down the wire + while image: + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, image[:FLASH_DATA_PACKET_SIZE]) + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + image = image[FLASH_DATA_PACKET_SIZE:] + addr += FLASH_DATA_PACKET_SIZE + + def verify_image(self, image, addr): + print "Verifying data" + readsize = len(image) + readdata = str() + while readsize > 0: + if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize + else: thisreadsize = FLASH_DATA_PACKET_SIZE + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + readdata += data[:thisreadsize] + readsize -= FLASH_DATA_PACKET_SIZE + addr += FLASH_DATA_PACKET_SIZE + + print "Read back %i bytes" % len(readdata) + # print readdata + + # for i in range(256, 512): + # print "out: %i in: %i" % (ord(image[i]), ord(readdata[i])) + + if readdata != image: + print "Verify failed. Image did not write correctly." + else: + print "Success." + + def reset_usrp(self): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + if pktid == update_id_t.USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG: + raise Exception, "Device failed to reset." + + def erase_image(self, addr, length): + #get flash info first + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL, seq(), addr, length, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + print "Erasing %i bytes at %i" % (length, addr) + + #now wait for it to finish + while(True): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL, seq(), 0, 0, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid == update_id_t.USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG: break + elif pktid != update_id_t.USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) ######################################################################## @@ -312,12 +311,12 @@ if __name__=='__main__': if not options.ip: raise Exception, 'no ip address specified' if not options.fpga and not options.fw and not options.reset: raise Exception, 'Must specify either a firmware image or FPGA image, and/or reset.' - + if options.overwrite_safe: 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: """) if response != "yes": sys.exit(0) - - burn_fw(ip=options.ip, fw=options.fw, fpga=options.fpga, reset=options.reset, safe=options.overwrite_safe) + + burner_socket(ip=options.ip).burn_fw(fw=options.fw, fpga=options.fpga, reset=options.reset, safe=options.overwrite_safe) -- cgit v1.2.3 From 08727845c1613a4aa8f3cc272998bec92753b334 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 19 Feb 2011 11:40:31 -0800 Subject: usrp-n2xx: reimplemented nicks image readback ontop of changes --- host/utils/usrp_n2xx_net_burner.py | 59 ++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/host/utils/usrp_n2xx_net_burner.py b/host/utils/usrp_n2xx_net_burner.py index ce0dbf2f3..6fdc9df20 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 Ettus Research LLC +# Copyright 2010-2011 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 @@ -257,6 +257,32 @@ class burner_socket(object): else: print "Success." + def read_image(self, image, size, addr): + print "Reading image" + readsize = size + readdata = str() + while readsize > 0: + if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize + else: thisreadsize = FLASH_DATA_PACKET_SIZE + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + readdata += data[:thisreadsize] + readsize -= FLASH_DATA_PACKET_SIZE + addr += FLASH_DATA_PACKET_SIZE + + print "Read back %i bytes" % len(readdata) + + #write to disk + f = open(image, 'w') + f.write(readdata) + f.close() + def reset_usrp(self): out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0, "") in_pkt = self.send_and_recv(out_pkt) @@ -298,6 +324,7 @@ def get_options(): parser.add_option("--fw", type="string", help="firmware image path (optional)", default='') parser.add_option("--fpga", type="string", help="fpga image path (optional)", default='') parser.add_option("--reset", action="store_true", help="reset the device after writing", default=False) + parser.add_option("--read", action="store_true", help="read to file instead of write from file", default=False) parser.add_option("--overwrite-safe", action="store_true", help="never ever use this option", default=False) (options, args) = parser.parse_args() @@ -312,11 +339,31 @@ if __name__=='__main__': if not options.fpga and not options.fw and not options.reset: raise Exception, 'Must specify either a firmware image or FPGA image, and/or reset.' - if options.overwrite_safe: + 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: """) - if response != "yes": - sys.exit(0) - - burner_socket(ip=options.ip).burn_fw(fw=options.fw, fpga=options.fpga, reset=options.reset, safe=options.overwrite_safe) + if response != "yes": sys.exit(0) + + burner = burner_socket(ip=options.ip) + + if options.read: + if options.fw: + file = options.fw + if os.path.isfile(file): + response = raw_input("File already exists -- overwrite? (y/n) ") + if response != "y": sys.exit(0) + size = FW_IMAGE_SIZE_BYTES + addr = SAFE_FW_IMAGE_LOCATION_ADDR if options.overwrite_safe else PROD_FW_IMAGE_LOCATION_ADDR + burner.read_image(file, size, addr) + + if options.fpga: + file = options.fpga + if os.path.isfile(file): + response = raw_input("File already exists -- overwrite? (y/n) ") + if response != "y": sys.exit(0) + size = FPGA_IMAGE_SIZE_BYTES + addr = SAFE_FPGA_IMAGE_LOCATION_ADDR if options.overwrite_safe else PROD_FPGA_IMAGE_LOCATION_ADDR + burner.read_image(file, size, addr) + + else: burner.burn_fw(fw=options.fw, fpga=options.fpga, reset=options.reset, safe=options.overwrite_safe) -- cgit v1.2.3 From 70737ccef58fe3fdfad9d33cf713d74daefab2d1 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 19 Feb 2011 11:41:28 -0800 Subject: usrp-n2xx: checkout burner into next branch --- host/utils/usrp_n2xx_net_burner.py | 451 ++++++++++++++++++------------------- 1 file changed, 224 insertions(+), 227 deletions(-) diff --git a/host/utils/usrp_n2xx_net_burner.py b/host/utils/usrp_n2xx_net_burner.py index db94d50a4..6fdc9df20 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 Ettus Research LLC +# Copyright 2010-2011 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 @@ -27,7 +27,7 @@ import re import struct import socket import sys -import os.path +import time ######################################################################## # constants @@ -76,77 +76,28 @@ class update_id_t: _seq = -1 def seq(): - global _seq - _seq = _seq+1 - return _seq + global _seq + _seq = _seq+1 + return _seq ######################################################################## # helper functions ######################################################################## def unpack_flash_args_fmt(s): - return struct.unpack(FLASH_ARGS_FMT, s) #(proto_ver, pktid, seq, flash_addr, length, data) + return struct.unpack(FLASH_ARGS_FMT, s) #(proto_ver, pktid, seq, flash_addr, length, data) def unpack_flash_info_fmt(s): - return struct.unpack(FLASH_INFO_FMT, s) #(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) + return struct.unpack(FLASH_INFO_FMT, s) #(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) def unpack_flash_ip_fmt(s): - return struct.unpack(FLASH_IP_FMT, s) #(proto_ver, pktid, seq, ip_addr) + return struct.unpack(FLASH_IP_FMT, s) #(proto_ver, pktid, seq, ip_addr) def pack_flash_args_fmt(proto_ver, pktid, seq, flash_addr, length, data): - return struct.pack(FLASH_ARGS_FMT, proto_ver, pktid, seq, flash_addr, length, data) + return struct.pack(FLASH_ARGS_FMT, proto_ver, pktid, seq, flash_addr, length, data) def pack_flash_info_fmt(proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes): - return struct.pack(FLASH_INFO_FMT, proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) + return struct.pack(FLASH_INFO_FMT, proto_ver, pktid, seq, sector_size_bytes, memory_size_bytes) -def send_and_recv(pkt, ip): - update_socket = create_socket() - - try: - update_socket.sendto(pkt, (ip, UDP_FW_UPDATE_PORT)) - except Exception, e: - print e - sys.exit(1) - - try: - (recv_pkt, recv_addr) = update_socket.recvfrom(UDP_MAX_XFER_BYTES) - except Exception, e: - print e - sys.exit(1) - - if recv_addr != (options.ip, UDP_FW_UPDATE_PORT): - raise Exception, "Packet received from invalid IP %s, expected %s" % (recv_addr, options.ip) - - return recv_pkt - -def create_socket(): - socket.setdefaulttimeout(UDP_TIMEOUT) - update_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - return update_socket - -#just here to validate comms -def init_update(ip): - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0, "") - in_pkt = send_and_recv(out_pkt, ip) - (proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(in_pkt) - if pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG: - print "USRP2P found." - else: - raise Exception, "Invalid reply received from device." - -# print "Incoming:\n\tVer: %i\n\tID: %c\n\tSeq: %i\n\tIP: %i\n" % (proto_ver, chr(pktid), rxseq, ip_addr) - -def get_flash_info(ip): - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL, seq(), 0, 0, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, sector_size_bytes, memory_size_bytes) = unpack_flash_info_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - - return (memory_size_bytes, sector_size_bytes) - def is_valid_fpga_image(fpga_image): for i in range(0,63): if ord(fpga_image[i]) == 0xFF: @@ -155,7 +106,7 @@ def is_valid_fpga_image(fpga_image): return 1 return 0 - + def is_valid_fw_image(fw_image): for i in range(0,4): if ord(fw_image[i]) != 0x0B: @@ -163,158 +114,205 @@ def is_valid_fw_image(fw_image): return 1 -def burn_fw(ip, fw, fpga, reset, safe): - init_update(ip) - (flash_size, sector_size) = get_flash_info(ip) - - print "Flash size: %i\nSector size: %i" % (flash_size, sector_size) - - if fpga: - if safe: - image_location = SAFE_FPGA_IMAGE_LOCATION_ADDR - else: - image_location = PROD_FPGA_IMAGE_LOCATION_ADDR - - fpga_file = open(fpga, 'rb') - fpga_image = fpga_file.read() - - if len(fpga_image) > FPGA_IMAGE_SIZE_BYTES: - print "Error: FPGA image file too large." - return 0 - - if not is_valid_fpga_image(fpga_image): - print "Error: Invalid FPGA image file." - return 0 - - erase_image(ip, image_location, FPGA_IMAGE_SIZE_BYTES) - write_image(ip, fpga_image, image_location) - verify_image(ip, fpga_image, image_location) - - if fw: - if safe: - image_location = SAFE_FW_IMAGE_LOCATION_ADDR - else: - image_location = PROD_FW_IMAGE_LOCATION_ADDR - - fw_file = open(fw, 'rb') - fw_image = fw_file.read() - - if len(fw_image) > FW_IMAGE_SIZE_BYTES: - print "Error: Firmware image file too large." - return 0 - - if not is_valid_fw_image(fw_image): - print "Error: Invalid firmware image file." - return 0 - - erase_image(ip, image_location, FW_IMAGE_SIZE_BYTES) - write_image(ip, fw_image, image_location) - verify_image(ip, fw_image, image_location) - - if reset: - reset_usrp(ip) - -def write_image(ip, image, addr): - print "Writing image" -#we split the image into smaller (256B) bits and send them down the wire - while image: - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, image[:FLASH_DATA_PACKET_SIZE]) - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - image = image[FLASH_DATA_PACKET_SIZE:] - addr += FLASH_DATA_PACKET_SIZE - -def verify_image(ip, image, addr): - print "Verifying data" - readsize = len(image) - readdata = str() - while readsize > 0: - if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize - else: thisreadsize = FLASH_DATA_PACKET_SIZE - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - readdata += data[:thisreadsize] - readsize -= FLASH_DATA_PACKET_SIZE - addr += FLASH_DATA_PACKET_SIZE - - print "Read back %i bytes" % len(readdata) -# print readdata - -# for i in range(256, 512): -# print "out: %i in: %i" % (ord(image[i]), ord(readdata[i])) - - if readdata != image: - print "Verify failed. Image did not write correctly." - else: - print "Success." - -def read_flash(ip, image, size, addr): - print "Reading image" - readsize = size - readdata = str() - while readsize > 0: - if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize - else: thisreadsize = FLASH_DATA_PACKET_SIZE - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - readdata += data[:thisreadsize] - readsize -= FLASH_DATA_PACKET_SIZE - addr += FLASH_DATA_PACKET_SIZE - - print "Read back %i bytes" % len(readdata) - - #write to disk - f = open(image, 'w') - f.write(readdata) - f.close() - -def reset_usrp(ip): - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - if pktid == update_id_t.USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG: - raise Exception, "Device failed to reset." - -def erase_image(ip, addr, length): - #get flash info first - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL, seq(), addr, length, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid != update_id_t.USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) - - print "Erasing %i bytes at %i" % (length, addr) - - #now wait for it to finish - while(1): - out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL, seq(), 0, 0, "") - in_pkt = send_and_recv(out_pkt, ip) - - (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) - - if pktid == update_id_t.USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG: break - elif pktid != update_id_t.USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG: - raise Exception, "Invalid reply %c from device." % (chr(pktid)) +######################################################################## +# Burner class, holds a socket and send/recv routines +######################################################################## +class burner_socket(object): + def __init__(self, ip): + self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self._sock.settimeout(UDP_TIMEOUT) + self._sock.connect((ip, UDP_FW_UPDATE_PORT)) + + def send_and_recv(self, pkt): + try: self._sock.send(pkt) + except Exception, e: + print e + sys.exit(1) + + try: recv_pkt = self._sock.recv(UDP_MAX_XFER_BYTES) + except Exception, e: + print e + sys.exit(1) + + return recv_pkt + + #just here to validate comms + def init_update(self): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_OHAI_LOL, seq(), 0, 0, "") + in_pkt = self.send_and_recv(out_pkt) + (proto_ver, pktid, rxseq, ip_addr) = unpack_flash_ip_fmt(in_pkt) + if pktid == update_id_t.USRP2_FW_UPDATE_ID_OHAI_OMG: + print "USRP2P found." + else: + raise Exception, "Invalid reply received from device." + + # print "Incoming:\n\tVer: %i\n\tID: %c\n\tSeq: %i\n\tIP: %i\n" % (proto_ver, chr(pktid), rxseq, ip_addr) + + def get_flash_info(self): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WATS_TEH_FLASH_INFO_LOL, seq(), 0, 0, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, sector_size_bytes, memory_size_bytes) = unpack_flash_info_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_HERES_TEH_FLASH_INFO_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + return (memory_size_bytes, sector_size_bytes) + + def burn_fw(self, fw, fpga, reset, safe): + (flash_size, sector_size) = self.get_flash_info() + + print "Flash size: %i\nSector size: %i\n\n" % (flash_size, sector_size) + + if fpga: + if safe: image_location = SAFE_FPGA_IMAGE_LOCATION_ADDR + else: image_location = PROD_FPGA_IMAGE_LOCATION_ADDR + + fpga_file = open(fpga, 'rb') + fpga_image = fpga_file.read() + + if len(fpga_image) > FPGA_IMAGE_SIZE_BYTES: + print "Error: FPGA image file too large." + return 0 + + if not is_valid_fpga_image(fpga_image): + print "Error: Invalid FPGA image file." + return 0 + + print "Begin FPGA write: this should take about 1 minute..." + start_time = time.time() + self.erase_image(image_location, FPGA_IMAGE_SIZE_BYTES) + self.write_image(fpga_image, image_location) + self.verify_image(fpga_image, image_location) + print "Time elapsed: %f seconds"%(time.time() - start_time) + print "\n\n" + + if fw: + if safe: image_location = SAFE_FW_IMAGE_LOCATION_ADDR + else: image_location = PROD_FW_IMAGE_LOCATION_ADDR + + fw_file = open(fw, 'rb') + fw_image = fw_file.read() + + if len(fw_image) > FW_IMAGE_SIZE_BYTES: + print "Error: Firmware image file too large." + return 0 + + if not is_valid_fw_image(fw_image): + print "Error: Invalid firmware image file." + return 0 + + print "Begin firmware write: this should take about 1 second..." + start_time = time.time() + self.erase_image(image_location, FW_IMAGE_SIZE_BYTES) + self.write_image(fw_image, image_location) + self.verify_image(fw_image, image_location) + print "Time elapsed: %f seconds"%(time.time() - start_time) + print "\n\n" + + if reset: self.reset_usrp() + + def write_image(self, image, addr): + print "Writing image" + #we split the image into smaller (256B) bits and send them down the wire + while image: + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_WRITE_TEH_FLASHES_LOL, seq(), addr, FLASH_DATA_PACKET_SIZE, image[:FLASH_DATA_PACKET_SIZE]) + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_WROTE_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + image = image[FLASH_DATA_PACKET_SIZE:] + addr += FLASH_DATA_PACKET_SIZE + + def verify_image(self, image, addr): + print "Verifying data" + readsize = len(image) + readdata = str() + while readsize > 0: + if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize + else: thisreadsize = FLASH_DATA_PACKET_SIZE + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + readdata += data[:thisreadsize] + readsize -= FLASH_DATA_PACKET_SIZE + addr += FLASH_DATA_PACKET_SIZE + + print "Read back %i bytes" % len(readdata) + # print readdata + + # for i in range(256, 512): + # print "out: %i in: %i" % (ord(image[i]), ord(readdata[i])) + + if readdata != image: + print "Verify failed. Image did not write correctly." + else: + print "Success." + + def read_image(self, image, size, addr): + print "Reading image" + readsize = size + readdata = str() + while readsize > 0: + if readsize < FLASH_DATA_PACKET_SIZE: thisreadsize = readsize + else: thisreadsize = FLASH_DATA_PACKET_SIZE + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_READ_TEH_FLASHES_LOL, seq(), addr, thisreadsize, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_KK_READ_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + readdata += data[:thisreadsize] + readsize -= FLASH_DATA_PACKET_SIZE + addr += FLASH_DATA_PACKET_SIZE + + print "Read back %i bytes" % len(readdata) + + #write to disk + f = open(image, 'w') + f.write(readdata) + f.close() + + def reset_usrp(self): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_RESET_MAH_COMPUTORZ_LOL, seq(), 0, 0, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + if pktid == update_id_t.USRP2_FW_UPDATE_ID_RESETTIN_TEH_COMPUTORZ_OMG: + raise Exception, "Device failed to reset." + + def erase_image(self, addr, length): + #get flash info first + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_ERASE_TEH_FLASHES_LOL, seq(), addr, length, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid != update_id_t.USRP2_FW_UPDATE_ID_ERASING_TEH_FLASHES_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) + + print "Erasing %i bytes at %i" % (length, addr) + + #now wait for it to finish + while(True): + out_pkt = pack_flash_args_fmt(USRP2_FW_PROTO_VERSION, update_id_t.USRP2_FW_UPDATE_ID_R_U_DONE_ERASING_LOL, seq(), 0, 0, "") + in_pkt = self.send_and_recv(out_pkt) + + (proto_ver, pktid, rxseq, flash_addr, rxlength, data) = unpack_flash_args_fmt(in_pkt) + + if pktid == update_id_t.USRP2_FW_UPDATE_ID_IM_DONE_ERASING_OMG: break + elif pktid != update_id_t.USRP2_FW_UPDATE_ID_NOPE_NOT_DONE_ERASING_OMG: + raise Exception, "Invalid reply %c from device." % (chr(pktid)) ######################################################################## @@ -340,33 +338,32 @@ if __name__=='__main__': if not options.ip: raise Exception, 'no ip address specified' if not options.fpga and not options.fw and not options.reset: raise Exception, 'Must specify either a firmware image or FPGA image, and/or reset.' - + 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: """) - if response != "yes": - sys.exit(0) - - if options.read is True: + if response != "yes": sys.exit(0) + + burner = burner_socket(ip=options.ip) + + if options.read: if options.fw: file = options.fw if os.path.isfile(file): response = raw_input("File already exists -- overwrite? (y/n) ") - if response != "y": - sys.exit(0) + if response != "y": sys.exit(0) size = FW_IMAGE_SIZE_BYTES addr = SAFE_FW_IMAGE_LOCATION_ADDR if options.overwrite_safe else PROD_FW_IMAGE_LOCATION_ADDR - read_flash(options.ip, file, size, addr) - if options.fpga: + burner.read_image(file, size, addr) + + if options.fpga: file = options.fpga if os.path.isfile(file): response = raw_input("File already exists -- overwrite? (y/n) ") - if response != "y": - sys.exit(0) + if response != "y": sys.exit(0) size = FPGA_IMAGE_SIZE_BYTES addr = SAFE_FPGA_IMAGE_LOCATION_ADDR if options.overwrite_safe else PROD_FPGA_IMAGE_LOCATION_ADDR - read_flash(options.ip, file, size, addr) - - else: - burn_fw(ip=options.ip, fw=options.fw, fpga=options.fpga, reset=options.reset, safe=options.overwrite_safe) + burner.read_image(file, size, addr) + + else: burner.burn_fw(fw=options.fw, fpga=options.fpga, reset=options.reset, safe=options.overwrite_safe) -- cgit v1.2.3 From 2d9838f467013d5397b6daf83afb5ccea92065a4 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 20 Feb 2011 01:13:03 -0800 Subject: udp: update docs for transport, create common header for wait implementation Reimplemented simple udp transport with one impl class. Moved wait for ready/select implementation into common header. Important note on select, timeval should have usecs < 1 second or it may error on some platforms. Fixed in this implementation. --- host/docs/transport.rst | 16 +- host/lib/transport/CMakeLists.txt | 2 +- host/lib/transport/udp_common.hpp | 51 +++++ host/lib/transport/udp_simple.cpp | 160 ++++----------- host/lib/transport/udp_zero_copy.cpp | 304 ++++++++++++++++++++++++++++ host/lib/transport/udp_zero_copy_asio.cpp | 319 ------------------------------ 6 files changed, 400 insertions(+), 452 deletions(-) create mode 100644 host/lib/transport/udp_common.hpp create mode 100644 host/lib/transport/udp_zero_copy.cpp delete mode 100644 host/lib/transport/udp_zero_copy_asio.cpp diff --git a/host/docs/transport.rst b/host/docs/transport.rst index 6b9d28bfa..2371d2497 100644 --- a/host/docs/transport.rst +++ b/host/docs/transport.rst @@ -17,13 +17,9 @@ that are known to perform well on a variety of systems. The transport parameters are defined below for the various transports in the UHD: ------------------------------------------------------------------------ -UDP transport (ASIO) +UDP transport (sockets) ------------------------------------------------------------------------ -The UDP transport is implemented with Boost's ASIO library. -ASIO provides an asynchronous API for user-space sockets. -The transport implementation allocates a number of buffers -and submits asynchronous requests for send and receive. -IO service threads run in the background to process these requests. +The UDP transport is implemented with standard user-space/Berkeley sockets. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Transport parameters @@ -35,8 +31,12 @@ The following parameters can be used to alter the transport's default behavior: * **send_frame_size:** The size of a single send buffer in bytes * **num_send_frames:** The number of send buffers to allocate -**Note:** num_recv_frames and num_send_frames will not have an effect -as the asynchronous send implementation is currently unimplemented. +**Note1:** num_recv_frames and num_send_frames do not affect performance. + +**Note2:** recv_frame_size and send_frame_size can be used to +increase or decrease the maximum number of samples per packet. +The frame sizes default to an MTU of 1472 bytes per IP/UDP packet, +and may be increased if permitted by your network hardware. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Flow control parameters diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt index a98bcc14e..e58957154 100644 --- a/host/lib/transport/CMakeLists.txt +++ b/host/lib/transport/CMakeLists.txt @@ -80,6 +80,6 @@ LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/buffer_pool.cpp ${CMAKE_CURRENT_SOURCE_DIR}/if_addrs.cpp ${CMAKE_CURRENT_SOURCE_DIR}/udp_simple.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/udp_zero_copy_asio.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/udp_zero_copy.cpp ${CMAKE_CURRENT_SOURCE_DIR}/vrt_packet_handler.hpp ) diff --git a/host/lib/transport/udp_common.hpp b/host/lib/transport/udp_common.hpp new file mode 100644 index 000000000..44067b5dc --- /dev/null +++ b/host/lib/transport/udp_common.hpp @@ -0,0 +1,51 @@ +// +// Copyright 2011 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 . +// + +#ifndef INCLUDED_LIBUHD_TRANSPORT_VRT_PACKET_HANDLER_HPP +#define INCLUDED_LIBUHD_TRANSPORT_VRT_PACKET_HANDLER_HPP + +#include +#include + +namespace uhd{ namespace transport{ + + /*! + * Wait for the socket to become ready for a receive operation. + * \param sock_fd the open socket file descriptor + * \param timeout the timeout duration in seconds + * \return true when the socket is ready for receive + */ + UHD_INLINE bool wait_for_recv(int sock_fd, double timeout){ + //setup timeval for timeout + timeval tv; + //If the tv_usec > 1 second on some platforms, select will + //error EINVAL: An invalid timeout interval was specified. + tv.tv_sec = int(timeout); + tv.tv_usec = int(timeout*1000000)%1000000; + + //setup rset for timeout + fd_set rset; + FD_ZERO(&rset); + FD_SET(sock_fd, &rset); + + //call select with timeout on receive socket + return ::select(sock_fd+1, &rset, NULL, NULL, &tv) > 0; + } + +}} //namespace uhd::transport + +#endif /* INCLUDED_LIBUHD_TRANSPORT_VRT_PACKET_HANDLER_HPP */ diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp index 6799ac7b2..094f570ff 100644 --- a/host/lib/transport/udp_simple.cpp +++ b/host/lib/transport/udp_simple.cpp @@ -1,5 +1,5 @@ // -// Copyright 2010 Ettus Research LLC +// Copyright 2010-2011 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 @@ -15,159 +15,71 @@ // along with this program. If not, see . // +#include "udp_common.hpp" #include -#include -#include #include #include using namespace uhd::transport; +namespace asio = boost::asio; /*********************************************************************** - * Helper Functions + * UDP simple implementation: connected and broadcast **********************************************************************/ -/*! - * Wait for available data or timeout. - * \param socket the asio socket - * \param timeout the timeout in seconds - * \return false for timeout, true for data - */ -static bool wait_available( - boost::asio::ip::udp::socket &socket, double timeout -){ - #if defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32) - - //setup timeval for timeout - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = long(timeout*1e6); - - //setup rset for timeout - fd_set rset; - FD_ZERO(&rset); - FD_SET(socket.native(), &rset); - - return ::select(socket.native()+1, &rset, NULL, NULL, &tv) > 0; - - #else /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/ - - //FIXME: why does select fail on macintosh? - for (size_t i = 0; i < size_t(timeout*1e3); i++){ - if (socket.available()) return true; - boost::this_thread::sleep(boost::posix_time::milliseconds(1)); - } - return false; - - #endif /*defined(UHD_PLATFORM_LINUX) || defined(UHD_PLATFORM_WIN32)*/ -} - -/*********************************************************************** - * UDP connected implementation class - **********************************************************************/ -class udp_connected_impl : public udp_simple{ +class udp_simple_impl : public udp_simple{ public: - //structors - udp_connected_impl(const std::string &addr, const std::string &port); - ~udp_connected_impl(void); + typedef boost::shared_ptr socket_sptr; - //send/recv - size_t send(const boost::asio::const_buffer &); - size_t recv(const boost::asio::mutable_buffer &, double); + udp_simple_impl( + const std::string &addr, const std::string &port, bool bcast, bool connect + ):_connected(connect){ + //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; -private: - boost::asio::ip::udp::socket *_socket; - boost::asio::io_service _io_service; -}; + //resolve the address + asio::ip::udp::resolver resolver(_io_service); + asio::ip::udp::resolver::query query(asio::ip::udp::v4(), addr, port); + _receiver_endpoint = *resolver.resolve(query); -udp_connected_impl::udp_connected_impl(const std::string &addr, const std::string &port){ - //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; + //create and open the socket + _socket = socket_sptr(new asio::ip::udp::socket(_io_service)); + _socket->open(asio::ip::udp::v4()); - // resolve the address - boost::asio::ip::udp::resolver resolver(_io_service); - boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port); - boost::asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query); + //allow broadcasting + _socket->set_option(asio::socket_base::broadcast(bcast)); - // Create, open, and connect the socket - _socket = new boost::asio::ip::udp::socket(_io_service); - _socket->open(boost::asio::ip::udp::v4()); - _socket->connect(receiver_endpoint); -} - -udp_connected_impl::~udp_connected_impl(void){ - delete _socket; -} - -size_t udp_connected_impl::send(const boost::asio::const_buffer &buff){ - return _socket->send(boost::asio::buffer(buff)); -} + //connect the socket + if (connect) _socket->connect(_receiver_endpoint); -size_t udp_connected_impl::recv(const boost::asio::mutable_buffer &buff, double timeout){ - if (not wait_available(*_socket, timeout)) return 0; - return _socket->receive(boost::asio::buffer(buff)); -} + } -/*********************************************************************** - * UDP broadcast implementation class - **********************************************************************/ -class udp_broadcast_impl : public udp_simple{ -public: - //structors - udp_broadcast_impl(const std::string &addr, const std::string &port); - ~udp_broadcast_impl(void); + size_t send(const asio::const_buffer &buff){ + if (_connected) return _socket->send(asio::buffer(buff)); + return _socket->send_to(asio::buffer(buff), _receiver_endpoint); + } - //send/recv - size_t send(const boost::asio::const_buffer &); - size_t recv(const boost::asio::mutable_buffer &, double); + size_t recv(const asio::mutable_buffer &buff, double timeout){ + if (not wait_for_recv(_socket->native(), timeout)) return 0; + return _socket->receive(asio::buffer(buff)); + } private: - boost::asio::ip::udp::socket *_socket; - boost::asio::ip::udp::endpoint _receiver_endpoint; - boost::asio::io_service _io_service; + bool _connected; + asio::io_service _io_service; + socket_sptr _socket; + asio::ip::udp::endpoint _receiver_endpoint; }; -udp_broadcast_impl::udp_broadcast_impl(const std::string &addr, const std::string &port){ - //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; - - // resolve the address - boost::asio::ip::udp::resolver resolver(_io_service); - boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), addr, port); - _receiver_endpoint = *resolver.resolve(query); - - // Create and open the socket - _socket = new boost::asio::ip::udp::socket(_io_service); - _socket->open(boost::asio::ip::udp::v4()); - - // Allow broadcasting - boost::asio::socket_base::broadcast option(true); - _socket->set_option(option); - -} - -udp_broadcast_impl::~udp_broadcast_impl(void){ - delete _socket; -} - -size_t udp_broadcast_impl::send(const boost::asio::const_buffer &buff){ - return _socket->send_to(boost::asio::buffer(buff), _receiver_endpoint); -} - -size_t udp_broadcast_impl::recv(const boost::asio::mutable_buffer &buff, double timeout){ - if (not wait_available(*_socket, timeout)) return 0; - boost::asio::ip::udp::endpoint sender_endpoint; - return _socket->receive_from(boost::asio::buffer(buff), sender_endpoint); -} - /*********************************************************************** * UDP public make functions **********************************************************************/ udp_simple::sptr udp_simple::make_connected( const std::string &addr, const std::string &port ){ - return sptr(new udp_connected_impl(addr, port)); + return sptr(new udp_simple_impl(addr, port, false, true /* no bcast, connect */)); } udp_simple::sptr udp_simple::make_broadcast( const std::string &addr, const std::string &port ){ - return sptr(new udp_broadcast_impl(addr, port)); + return sptr(new udp_simple_impl(addr, port, true, false /* bcast, no connect */)); } diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp new file mode 100644 index 000000000..793fc6fba --- /dev/null +++ b/host/lib/transport/udp_zero_copy.cpp @@ -0,0 +1,304 @@ +// +// Copyright 2010-2011 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 . +// + +#include "udp_common.hpp" +#include +#include //mtu +#include +#include +#include +#include +#include +#include + +using namespace uhd; +using namespace uhd::transport; +namespace asio = boost::asio; + +//A reasonable number of frames for send/recv and async/sync +static const size_t DEFAULT_NUM_FRAMES = 32; + +/*********************************************************************** + * Reusable managed receiver buffer: + * - Initialize with memory and a release callback. + * - Call get new with a length in bytes to re-use. + **********************************************************************/ +class udp_zero_copy_asio_mrb : public managed_recv_buffer{ +public: + typedef boost::function release_cb_type; + + udp_zero_copy_asio_mrb(void *mem, const release_cb_type &release_cb): + _mem(mem), _len(0), _release_cb(release_cb){/* NOP */} + + void release(void){ + if (_len == 0) return; + this->_release_cb(this); + _len = 0; + } + + sptr get_new(size_t len){ + _len = len; + return sptr(this, &udp_zero_copy_asio_mrb::fake_deleter); + } + + template T cast(void) const{return static_cast(_mem);} + +private: + static void fake_deleter(void *obj){ + static_cast(obj)->release(); + } + + const void *get_buff(void) const{return _mem;} + size_t get_size(void) const{return _len;} + + void *_mem; + size_t _len; + release_cb_type _release_cb; +}; + +/*********************************************************************** + * Reusable managed send buffer: + * - Initialize with memory and a commit callback. + * - Call get new with a length in bytes to re-use. + **********************************************************************/ +class udp_zero_copy_asio_msb : public managed_send_buffer{ +public: + typedef boost::function commit_cb_type; + + udp_zero_copy_asio_msb(void *mem, const commit_cb_type &commit_cb): + _mem(mem), _len(0), _commit_cb(commit_cb){/* NOP */} + + void commit(size_t len){ + if (_len == 0) return; + this->_commit_cb(this, len); + _len = 0; + } + + sptr get_new(size_t len){ + _len = len; + return sptr(this, &udp_zero_copy_asio_msb::fake_deleter); + } + +private: + static void fake_deleter(void *obj){ + static_cast(obj)->commit(0); + } + + void *get_buff(void) const{return _mem;} + size_t get_size(void) const{return _len;} + + void *_mem; + size_t _len; + commit_cb_type _commit_cb; +}; + +/*********************************************************************** + * Zero Copy UDP implementation with ASIO: + * This is the portable zero copy implementation for systems + * where a faster, platform specific solution is not available. + * However, it is not a true zero copy implementation as each + * send and recv requires a copy operation to/from userspace. + **********************************************************************/ +class udp_zero_copy_asio_impl : public udp_zero_copy{ +public: + typedef boost::shared_ptr sptr; + + udp_zero_copy_asio_impl( + const std::string &addr, + const std::string &port, + const device_addr_t &hints + ): + _recv_frame_size(size_t(hints.cast("recv_frame_size", udp_simple::mtu))), + _num_recv_frames(size_t(hints.cast("num_recv_frames", DEFAULT_NUM_FRAMES))), + _send_frame_size(size_t(hints.cast("send_frame_size", udp_simple::mtu))), + _num_send_frames(size_t(hints.cast("num_send_frames", DEFAULT_NUM_FRAMES))), + _recv_buffer_pool(buffer_pool::make(_num_recv_frames, _recv_frame_size)), + _send_buffer_pool(buffer_pool::make(_num_send_frames, _send_frame_size)), + _pending_recv_buffs(_num_recv_frames), + _pending_send_buffs(_num_send_frames) + { + //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; + + //resolve the address + asio::ip::udp::resolver resolver(_io_service); + asio::ip::udp::resolver::query query(asio::ip::udp::v4(), addr, port); + asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query); + + //create, open, and connect the socket + _socket = new asio::ip::udp::socket(_io_service); + _socket->open(asio::ip::udp::v4()); + _socket->connect(receiver_endpoint); + _sock_fd = _socket->native(); + + //allocate re-usable managed receive buffers + for (size_t i = 0; i < get_num_recv_frames(); i++){ + _mrb_pool.push_back(udp_zero_copy_asio_mrb(_recv_buffer_pool->at(i), + boost::bind(&udp_zero_copy_asio_impl::release, this, _1)) + ); + handle_recv(&_mrb_pool.back()); + } + + //allocate re-usable managed send buffers + for (size_t i = 0; i < get_num_send_frames(); i++){ + _msb_pool.push_back(udp_zero_copy_asio_msb(_send_buffer_pool->at(i), + boost::bind(&udp_zero_copy_asio_impl::commit, this, _1, _2)) + ); + handle_send(&_msb_pool.back()); + } + } + + ~udp_zero_copy_asio_impl(void){ + delete _socket; + } + + //get size for internal socket buffer + template size_t get_buff_size(void) const{ + Opt option; + _socket->get_option(option); + return option.value(); + } + + //set size for internal socket buffer + template size_t resize_buff(size_t num_bytes){ + Opt option(num_bytes); + _socket->set_option(option); + return get_buff_size(); + } + + /******************************************************************* + * Receive implementation: + * + * Use select to perform a blocking receive with timeout. + * Return the managed receive buffer with the new length. + * When the caller is finished with the managed buffer, + * the managed receive buffer is released back into the queue. + ******************************************************************/ + managed_recv_buffer::sptr get_recv_buff(double timeout){ + udp_zero_copy_asio_mrb *mrb = NULL; + bool recv_ready = wait_for_recv(_sock_fd, timeout); + if (recv_ready and _pending_recv_buffs.pop_with_timed_wait(mrb, timeout)){ + return mrb->get_new(::recv(_sock_fd, mrb->cast(), _recv_frame_size, 0)); + } + return managed_recv_buffer::sptr(); + } + + UHD_INLINE void handle_recv(udp_zero_copy_asio_mrb *mrb){ + _pending_recv_buffs.push_with_haste(mrb); + } + + void release(udp_zero_copy_asio_mrb *mrb){ + handle_recv(mrb); + } + + size_t get_num_recv_frames(void) const {return _num_recv_frames;} + size_t get_recv_frame_size(void) const {return _recv_frame_size;} + + /******************************************************************* + * Send implementation: + * + * Get a managed receive buffer immediately with max length set. + * The caller will fill the buffer and commit it when finished. + * The commit routine will perform a blocking send operation, + * and push the managed send buffer back into the queue. + ******************************************************************/ + managed_send_buffer::sptr get_send_buff(double timeout){ + udp_zero_copy_asio_msb *msb = NULL; + if (_pending_send_buffs.pop_with_timed_wait(msb, timeout)){ + return msb->get_new(_send_frame_size); + } + return managed_send_buffer::sptr(); + } + + UHD_INLINE void handle_send(udp_zero_copy_asio_msb *msb){ + _pending_send_buffs.push_with_haste(msb); + } + + void commit(udp_zero_copy_asio_msb *msb, size_t len){ + ::send(_sock_fd, msb->cast(), len, 0); + handle_send(msb); + } + + size_t get_num_send_frames(void) const {return _num_send_frames;} + size_t get_send_frame_size(void) const {return _send_frame_size;} + +private: + //memory management -> buffers and fifos + const size_t _recv_frame_size, _num_recv_frames; + const size_t _send_frame_size, _num_send_frames; + buffer_pool::sptr _recv_buffer_pool, _send_buffer_pool; + bounded_buffer _pending_recv_buffs; + bounded_buffer _pending_send_buffs; + std::list _msb_pool; + std::list _mrb_pool; + + //asio guts -> socket and service + asio::io_service _io_service; + asio::ip::udp::socket *_socket; + int _sock_fd; +}; + +/*********************************************************************** + * UDP zero copy make function + **********************************************************************/ +template static void resize_buff_helper( + udp_zero_copy_asio_impl::sptr udp_trans, + const size_t target_size, + const std::string &name +){ + std::string help_message; + #if defined(UHD_PLATFORM_LINUX) + help_message = str(boost::format( + "Please run: sudo sysctl -w net.core.%smem_max=%d\n" + ) % ((name == "recv")?"r":"w") % target_size); + #endif /*defined(UHD_PLATFORM_LINUX)*/ + + //resize the buffer if size was provided + if (target_size > 0){ + size_t actual_size = udp_trans->resize_buff(target_size); + if (target_size != actual_size) std::cout << boost::format( + "Target %s sock buff size: %d bytes\n" + "Actual %s sock buff size: %d bytes" + ) % name % target_size % name % actual_size << std::endl; + else std::cout << boost::format( + "Current %s sock buff size: %d bytes" + ) % name % actual_size << std::endl; + if (actual_size < target_size) uhd::warning::post(str(boost::format( + "The %s buffer could not be resized sufficiently.\n" + "See the transport application notes on buffer resizing.\n%s" + ) % name % help_message)); + } +} + +udp_zero_copy::sptr udp_zero_copy::make( + const std::string &addr, + const std::string &port, + const device_addr_t &hints +){ + udp_zero_copy_asio_impl::sptr udp_trans( + new udp_zero_copy_asio_impl(addr, port, hints) + ); + + //extract buffer size hints from the device addr + size_t recv_buff_size = size_t(hints.cast("recv_buff_size", 0.0)); + size_t send_buff_size = size_t(hints.cast("send_buff_size", 0.0)); + + //call the helper to resize send and recv buffers + resize_buff_helper(udp_trans, recv_buff_size, "recv"); + resize_buff_helper (udp_trans, send_buff_size, "send"); + + return udp_trans; +} diff --git a/host/lib/transport/udp_zero_copy_asio.cpp b/host/lib/transport/udp_zero_copy_asio.cpp deleted file mode 100644 index 05352ffce..000000000 --- a/host/lib/transport/udp_zero_copy_asio.cpp +++ /dev/null @@ -1,319 +0,0 @@ -// -// Copyright 2010-2011 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 . -// - -#include -#include //mtu -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace uhd; -using namespace uhd::transport; -namespace asio = boost::asio; - -//A reasonable number of frames for send/recv and async/sync -static const size_t DEFAULT_NUM_FRAMES = 32; - -/*********************************************************************** - * Reusable managed receiver buffer: - * - Initialize with memory and a release callback. - * - Call get new with a length in bytes to re-use. - **********************************************************************/ -class udp_zero_copy_asio_mrb : public managed_recv_buffer{ -public: - typedef boost::function release_cb_type; - - udp_zero_copy_asio_mrb(void *mem, const release_cb_type &release_cb): - _mem(mem), _len(0), _release_cb(release_cb){/* NOP */} - - void release(void){ - if (_len == 0) return; - this->_release_cb(this); - _len = 0; - } - - sptr get_new(size_t len){ - _len = len; - return sptr(this, &udp_zero_copy_asio_mrb::fake_deleter); - } - - template T cast(void) const{return static_cast(_mem);} - -private: - static void fake_deleter(void *obj){ - static_cast(obj)->release(); - } - - const void *get_buff(void) const{return _mem;} - size_t get_size(void) const{return _len;} - - void *_mem; - size_t _len; - release_cb_type _release_cb; -}; - -/*********************************************************************** - * Reusable managed send buffer: - * - Initialize with memory and a commit callback. - * - Call get new with a length in bytes to re-use. - **********************************************************************/ -class udp_zero_copy_asio_msb : public managed_send_buffer{ -public: - typedef boost::function commit_cb_type; - - udp_zero_copy_asio_msb(void *mem, const commit_cb_type &commit_cb): - _mem(mem), _len(0), _commit_cb(commit_cb){/* NOP */} - - void commit(size_t len){ - if (_len == 0) return; - this->_commit_cb(this, len); - _len = 0; - } - - sptr get_new(size_t len){ - _len = len; - return sptr(this, &udp_zero_copy_asio_msb::fake_deleter); - } - -private: - static void fake_deleter(void *obj){ - static_cast(obj)->commit(0); - } - - void *get_buff(void) const{return _mem;} - size_t get_size(void) const{return _len;} - - void *_mem; - size_t _len; - commit_cb_type _commit_cb; -}; - -/*********************************************************************** - * Zero Copy UDP implementation with ASIO: - * This is the portable zero copy implementation for systems - * where a faster, platform specific solution is not available. - * However, it is not a true zero copy implementation as each - * send and recv requires a copy operation to/from userspace. - **********************************************************************/ -class udp_zero_copy_asio_impl : public udp_zero_copy{ -public: - typedef boost::shared_ptr sptr; - - udp_zero_copy_asio_impl( - const std::string &addr, - const std::string &port, - const device_addr_t &hints - ): - _recv_frame_size(size_t(hints.cast("recv_frame_size", udp_simple::mtu))), - _num_recv_frames(size_t(hints.cast("num_recv_frames", DEFAULT_NUM_FRAMES))), - _send_frame_size(size_t(hints.cast("send_frame_size", udp_simple::mtu))), - _num_send_frames(size_t(hints.cast("num_send_frames", DEFAULT_NUM_FRAMES))), - _recv_buffer_pool(buffer_pool::make(_num_recv_frames, _recv_frame_size)), - _send_buffer_pool(buffer_pool::make(_num_send_frames, _send_frame_size)), - _pending_recv_buffs(_num_recv_frames), - _pending_send_buffs(_num_send_frames) - { - //std::cout << boost::format("Creating udp transport for %s %s") % addr % port << std::endl; - - //resolve the address - asio::ip::udp::resolver resolver(_io_service); - asio::ip::udp::resolver::query query(asio::ip::udp::v4(), addr, port); - asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query); - - //create, open, and connect the socket - _socket = new asio::ip::udp::socket(_io_service); - _socket->open(asio::ip::udp::v4()); - _socket->connect(receiver_endpoint); - _sock_fd = _socket->native(); - - //allocate re-usable managed receive buffers - for (size_t i = 0; i < get_num_recv_frames(); i++){ - _mrb_pool.push_back(udp_zero_copy_asio_mrb(_recv_buffer_pool->at(i), - boost::bind(&udp_zero_copy_asio_impl::release, this, _1)) - ); - handle_recv(&_mrb_pool.back()); - } - - //allocate re-usable managed send buffers - for (size_t i = 0; i < get_num_send_frames(); i++){ - _msb_pool.push_back(udp_zero_copy_asio_msb(_send_buffer_pool->at(i), - boost::bind(&udp_zero_copy_asio_impl::commit, this, _1, _2)) - ); - handle_send(&_msb_pool.back()); - } - } - - ~udp_zero_copy_asio_impl(void){ - delete _socket; - } - - //get size for internal socket buffer - template size_t get_buff_size(void) const{ - Opt option; - _socket->get_option(option); - return option.value(); - } - - //set size for internal socket buffer - template size_t resize_buff(size_t num_bytes){ - Opt option(num_bytes); - _socket->set_option(option); - return get_buff_size(); - } - - /******************************************************************* - * Receive implementation: - * - * Use select to perform a blocking receive with timeout. - * Return the managed receive buffer with the new length. - * When the caller is finished with the managed buffer, - * the managed receive buffer is released back into the queue. - ******************************************************************/ - UHD_INLINE bool is_recv_ready(double timeout){ - //setup timeval for timeout - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = long(timeout*1e6); - - //setup rset for timeout - fd_set rset; - FD_ZERO(&rset); - FD_SET(_sock_fd, &rset); - - //call select with timeout on receive socket - return ::select(_sock_fd+1, &rset, NULL, NULL, &tv) > 0; - } - - managed_recv_buffer::sptr get_recv_buff(double timeout){ - udp_zero_copy_asio_mrb *mrb = NULL; - if (is_recv_ready(timeout) and _pending_recv_buffs.pop_with_timed_wait(mrb, timeout)){ - return mrb->get_new(::recv(_sock_fd, mrb->cast(), _recv_frame_size, 0)); - } - return managed_recv_buffer::sptr(); - } - - UHD_INLINE void handle_recv(udp_zero_copy_asio_mrb *mrb){ - _pending_recv_buffs.push_with_haste(mrb); - } - - void release(udp_zero_copy_asio_mrb *mrb){ - handle_recv(mrb); - } - - size_t get_num_recv_frames(void) const {return _num_recv_frames;} - size_t get_recv_frame_size(void) const {return _recv_frame_size;} - - /******************************************************************* - * Send implementation: - * - * Get a managed receive buffer immediately with max length set. - * The caller will fill the buffer and commit it when finished. - * The commit routine will perform a blocking send operation, - * and push the managed send buffer back into the queue. - ******************************************************************/ - managed_send_buffer::sptr get_send_buff(double timeout){ - udp_zero_copy_asio_msb *msb = NULL; - if (_pending_send_buffs.pop_with_timed_wait(msb, timeout)){ - return msb->get_new(_send_frame_size); - } - return managed_send_buffer::sptr(); - } - - UHD_INLINE void handle_send(udp_zero_copy_asio_msb *msb){ - _pending_send_buffs.push_with_haste(msb); - } - - void commit(udp_zero_copy_asio_msb *msb, size_t len){ - ::send(_sock_fd, msb->cast(), len, 0); - handle_send(msb); - } - - size_t get_num_send_frames(void) const {return _num_send_frames;} - size_t get_send_frame_size(void) const {return _send_frame_size;} - -private: - //memory management -> buffers and fifos - const size_t _recv_frame_size, _num_recv_frames; - const size_t _send_frame_size, _num_send_frames; - buffer_pool::sptr _recv_buffer_pool, _send_buffer_pool; - bounded_buffer _pending_recv_buffs; - bounded_buffer _pending_send_buffs; - std::list _msb_pool; - std::list _mrb_pool; - - //asio guts -> socket and service - asio::io_service _io_service; - asio::ip::udp::socket *_socket; - int _sock_fd; -}; - -/*********************************************************************** - * UDP zero copy make function - **********************************************************************/ -template static void resize_buff_helper( - udp_zero_copy_asio_impl::sptr udp_trans, - const size_t target_size, - const std::string &name -){ - std::string help_message; - #if defined(UHD_PLATFORM_LINUX) - help_message = str(boost::format( - "Please run: sudo sysctl -w net.core.%smem_max=%d\n" - ) % ((name == "recv")?"r":"w") % target_size); - #endif /*defined(UHD_PLATFORM_LINUX)*/ - - //resize the buffer if size was provided - if (target_size > 0){ - size_t actual_size = udp_trans->resize_buff(target_size); - if (target_size != actual_size) std::cout << boost::format( - "Target %s sock buff size: %d bytes\n" - "Actual %s sock buff size: %d bytes" - ) % name % target_size % name % actual_size << std::endl; - else std::cout << boost::format( - "Current %s sock buff size: %d bytes" - ) % name % actual_size << std::endl; - if (actual_size < target_size) uhd::warning::post(str(boost::format( - "The %s buffer could not be resized sufficiently.\n" - "See the transport application notes on buffer resizing.\n%s" - ) % name % help_message)); - } -} - -udp_zero_copy::sptr udp_zero_copy::make( - const std::string &addr, - const std::string &port, - const device_addr_t &hints -){ - udp_zero_copy_asio_impl::sptr udp_trans( - new udp_zero_copy_asio_impl(addr, port, hints) - ); - - //extract buffer size hints from the device addr - size_t recv_buff_size = size_t(hints.cast("recv_buff_size", 0.0)); - size_t send_buff_size = size_t(hints.cast("send_buff_size", 0.0)); - - //call the helper to resize send and recv buffers - resize_buff_helper(udp_trans, recv_buff_size, "recv"); - resize_buff_helper (udp_trans, send_buff_size, "send"); - - return udp_trans; -} -- cgit v1.2.3 From 4787c77bb089bf50a47207bbad55bd65a44769e4 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 20 Feb 2011 02:41:03 -0800 Subject: udp: try non-blocking recv first for performance --- host/lib/transport/udp_common.hpp | 4 +++- host/lib/transport/udp_simple.cpp | 4 +--- host/lib/transport/udp_zero_copy.cpp | 24 ++++++++++++++---------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/host/lib/transport/udp_common.hpp b/host/lib/transport/udp_common.hpp index 44067b5dc..47775d9c4 100644 --- a/host/lib/transport/udp_common.hpp +++ b/host/lib/transport/udp_common.hpp @@ -23,13 +23,15 @@ namespace uhd{ namespace transport{ + typedef boost::shared_ptr socket_sptr; + /*! * Wait for the socket to become ready for a receive operation. * \param sock_fd the open socket file descriptor * \param timeout the timeout duration in seconds * \return true when the socket is ready for receive */ - UHD_INLINE bool wait_for_recv(int sock_fd, double timeout){ + UHD_INLINE bool wait_for_recv_ready(int sock_fd, double timeout){ //setup timeval for timeout timeval tv; //If the tv_usec > 1 second on some platforms, select will diff --git a/host/lib/transport/udp_simple.cpp b/host/lib/transport/udp_simple.cpp index 094f570ff..1ee036d52 100644 --- a/host/lib/transport/udp_simple.cpp +++ b/host/lib/transport/udp_simple.cpp @@ -28,8 +28,6 @@ namespace asio = boost::asio; **********************************************************************/ class udp_simple_impl : public udp_simple{ public: - typedef boost::shared_ptr socket_sptr; - udp_simple_impl( const std::string &addr, const std::string &port, bool bcast, bool connect ):_connected(connect){ @@ -58,7 +56,7 @@ public: } size_t recv(const asio::mutable_buffer &buff, double timeout){ - if (not wait_for_recv(_socket->native(), timeout)) return 0; + if (not wait_for_recv_ready(_socket->native(), timeout)) return 0; return _socket->receive(asio::buffer(buff)); } diff --git a/host/lib/transport/udp_zero_copy.cpp b/host/lib/transport/udp_zero_copy.cpp index 793fc6fba..dda3bb547 100644 --- a/host/lib/transport/udp_zero_copy.cpp +++ b/host/lib/transport/udp_zero_copy.cpp @@ -139,7 +139,7 @@ public: asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query); //create, open, and connect the socket - _socket = new asio::ip::udp::socket(_io_service); + _socket = socket_sptr(new asio::ip::udp::socket(_io_service)); _socket->open(asio::ip::udp::v4()); _socket->connect(receiver_endpoint); _sock_fd = _socket->native(); @@ -161,10 +161,6 @@ public: } } - ~udp_zero_copy_asio_impl(void){ - delete _socket; - } - //get size for internal socket buffer template size_t get_buff_size(void) const{ Opt option; @@ -182,16 +178,24 @@ public: /******************************************************************* * Receive implementation: * - * Use select to perform a blocking receive with timeout. + * Perform a non-blocking receive for performance, + * and then fall back to a blocking receive with timeout. * Return the managed receive buffer with the new length. * When the caller is finished with the managed buffer, * the managed receive buffer is released back into the queue. ******************************************************************/ managed_recv_buffer::sptr get_recv_buff(double timeout){ udp_zero_copy_asio_mrb *mrb = NULL; - bool recv_ready = wait_for_recv(_sock_fd, timeout); - if (recv_ready and _pending_recv_buffs.pop_with_timed_wait(mrb, timeout)){ - return mrb->get_new(::recv(_sock_fd, mrb->cast(), _recv_frame_size, 0)); + if (_pending_recv_buffs.pop_with_timed_wait(mrb, timeout)){ + + #ifdef MSG_DONTWAIT //try a non-blocking recv() if supported + ssize_t ret = ::recv(_sock_fd, mrb->cast(), _recv_frame_size, MSG_DONTWAIT); + if (ret > 0) return mrb->get_new(ret); + #endif + + if (wait_for_recv_ready(_sock_fd, timeout)) return mrb->get_new( + ::recv(_sock_fd, mrb->cast(), _recv_frame_size, 0) + ); } return managed_recv_buffer::sptr(); } @@ -247,7 +251,7 @@ private: //asio guts -> socket and service asio::io_service _io_service; - asio::ip::udp::socket *_socket; + socket_sptr _socket; int _sock_fd; }; -- cgit v1.2.3 From 78a7cea143f6b0de3f6c0244acae296be7f1eef6 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 21 Feb 2011 04:20:10 -0800 Subject: usrp-e-mm-loopback : Works with GU fpga image. Cleaned up warnings. --- host/apps/omap_debug/usrp-e-mm-loopback.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c index b67eecd21..14f68a5c3 100644 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ b/host/apps/omap_debug/usrp-e-mm-loopback.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -7,6 +8,7 @@ #include #include #include +#include #include #include "usrp_e.h" @@ -72,7 +74,7 @@ static void *read_thread(void *threadid) struct pollfd pfd; pfd.fd = fp; pfd.events = POLLIN; - ssize_t ret = poll(&pfd, 1, -1); + poll(&pfd, 1, -1); } (*rxi)[rb_read].flags = RB_USER_PROCESS; @@ -95,7 +97,7 @@ static void *read_thread(void *threadid) printf("Sequence number fail, current = %d, previous = %d, pkt_count = %d\n", p->seq_num, prev_seq_num, pkt_count); printf("pkt received, rb_read = %d\n", rb_read); - printf("p = %X, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); + printf("p = %p, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); seq_num_failure ++; if (seq_num_failure > 2) @@ -135,7 +137,7 @@ static void *read_thread(void *threadid) // fflush(stdout); // printf("\n"); } - + return NULL; } static void *write_thread(void *threadid) @@ -171,7 +173,7 @@ static void *write_thread(void *threadid) struct pollfd pfd; pfd.fd = fp; pfd.events = POLLOUT; - ssize_t ret = poll(&pfd, 1, -1); + poll(&pfd, 1, -1); } memcpy(&(*tx_buf)[rb_write], tx_data, p->len * 2 + 12); @@ -188,18 +190,20 @@ static void *write_thread(void *threadid) // printf("Error returned from write: %d\n", cnt); // sleep(1); } + return NULL; } int main(int argc, char *argv[]) { pthread_t tx, rx; - long int t; + long int t = 0; struct sched_param s = { .sched_priority = 1 }; int ret, map_size, page_size; void *rb; + struct usrp_e_ctl16 d; if (argc < 2) { printf("%s data_size\n", argv[0]); @@ -211,6 +215,11 @@ int main(int argc, char *argv[]) fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); + d.offset = 14; + d.count = 1; + d.buf[0] = (1<<8) | (1<<9); + ioctl(fp, USRP_E_WRITE_CTL16, &d); + page_size = getpagesize(); ret = ioctl(fp, USRP_E_GET_RB_INFO, &rb_size); @@ -224,7 +233,7 @@ int main(int argc, char *argv[]) return -1; } - printf("rb = %X\n", rb); + printf("rb = %p\n", rb); rxi = rb; rx_buf = rb + (rb_size.num_pages_rx_flags * page_size); @@ -234,9 +243,11 @@ int main(int argc, char *argv[]) (rb_size.num_rx_frames * page_size >> 1) + (rb_size.num_pages_tx_flags * page_size); - printf("rxi = %X, rx_buf = %X, txi = %X, tx_buf = %X\n", rxi, rx_buf, txi, tx_buf); + printf("rxi = %p, rx_buf = %p, txi = %p, tx_buf = %p\n", rxi, rx_buf, txi, tx_buf); + + if ((ret = sched_setscheduler(0, SCHED_RR, &s))) + perror("sched_setscheduler"); - sched_setscheduler(0, SCHED_RR, &s); error = 0; #if 1 @@ -257,4 +268,6 @@ int main(int argc, char *argv[]) sleep(1000000000); printf("Done sleeping\n"); + + return 0; } -- cgit v1.2.3 From 7a786b4eca75ba844a8c79798a5b245b445527da Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 21 Feb 2011 04:20:50 -0800 Subject: usrp-e-crc-rw : Work with GU fpga image. Cleaned up warnings. --- host/apps/omap_debug/usrp-e-crc-rw.c | 37 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c index f91c4fa85..7f4ff0023 100644 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ b/host/apps/omap_debug/usrp-e-crc-rw.c @@ -97,7 +97,7 @@ static void *read_thread(void *threadid) struct pollfd pfd; pfd.fd = fp; pfd.events = POLLIN; - ssize_t ret = poll(&pfd, 1, -1); + poll(&pfd, 1, -1); } (*rxi)[rb_read].flags = RB_USER_PROCESS; @@ -136,7 +136,7 @@ static void *read_thread(void *threadid) } (*rxi)[rb_read].flags = RB_KERNEL; - + write(fp, NULL, 1); if (rx_crc != ck_sum) printf("Ck_sum eror, calc ck_sum = %lX, rx ck_sum = %X\n", @@ -176,6 +176,7 @@ static void *read_thread(void *threadid) bytes_transfered = 0; } } + return NULL; } static void *write_thread(void *threadid) @@ -185,6 +186,7 @@ static void *write_thread(void *threadid) unsigned long crc; unsigned long bytes_transfered; struct timeval start_time; + unsigned int pkt_seq = 0; __u8 *p; printf("Greetings from the write thread!\n"); @@ -228,19 +230,27 @@ static void *write_thread(void *threadid) struct pollfd pfd; pfd.fd = fp; pfd.events = POLLOUT; - ssize_t ret = poll(&pfd, 1, -1); + poll(&pfd, 1, -1); } // printf("Got space\n"); + for (i=8; i < tx_len-4; i++) { + p[i] = i & 0xFF; + } + + *(unsigned int *) &p[0] = tx_len-4; + *(unsigned int *) &p[4] = pkt_seq; + + pkt_seq++; + crc = 0xFFFFFFFF; for (i = 0; i < tx_len-4; i++) { - p[i] = i & 0xFF; // printf("%X ", p[i]); crc = ((crc >> 8) & 0x00FFFFFF) ^ crc_tab[(crc ^ p[i]) & 0xFF]; } - *(int *) &p[tx_len-4] = crc; + *(unsigned int *) &p[tx_len-4] = crc; // printf("\n crc = %lX\n", crc); (*txi)[rb_write].len = tx_len; @@ -273,13 +283,14 @@ static void *write_thread(void *threadid) // sleep(1); } + return NULL; } int main(int argc, char *argv[]) { pthread_t tx, rx; - long int t; + long int t=0; int fpga_config_flag ,decimation; int ret, map_size, page_size; void *rb; @@ -315,7 +326,7 @@ int main(int argc, char *argv[]) return -1; } - printf("rb = %X\n", rb); + printf("rb = %p\n", rb); rxi = rb; rx_buf = rb + (rb_size.num_pages_rx_flags * page_size); @@ -325,13 +336,13 @@ int main(int argc, char *argv[]) (rb_size.num_rx_frames * page_size >> 1) + (rb_size.num_pages_tx_flags * page_size); - fpga_config_flag = 0; + fpga_config_flag = (1<<8); if (strcmp(argv[1], "w") == 0) - fpga_config_flag |= (1 << 15); + fpga_config_flag |= (1 << 11); else if (strcmp(argv[1], "r") == 0) - fpga_config_flag |= (1 << 14); + fpga_config_flag |= (1 << 10); else if (strcmp(argv[1], "rw") == 0) - fpga_config_flag |= ((1 << 15) | (1 << 14)); + fpga_config_flag |= ((1 << 10) | (1 << 11)); fpga_config_flag |= decimation; @@ -344,7 +355,7 @@ int main(int argc, char *argv[]) sched_setscheduler(0, SCHED_RR, &s); - if (fpga_config_flag & (1 << 14)) { + if (fpga_config_flag & (1 << 10)) { if (pthread_create(&rx, NULL, read_thread, (void *) t)) { printf("Failed to create rx thread\n"); exit(-1); @@ -353,7 +364,7 @@ int main(int argc, char *argv[]) sleep(1); - if (fpga_config_flag & (1 << 15)) { + if (fpga_config_flag & (1 << 11)) { if (pthread_create(&tx, NULL, write_thread, (void *) t)) { printf("Failed to create tx thread\n"); exit(-1); -- cgit v1.2.3 From d7ae215814ab104be699d3f6d078ce84e6558330 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 21 Feb 2011 07:28:24 -0800 Subject: usrp-e-utils : Move loopback and timed test programs into utils directory for e100. --- host/usrp_e_utils/CMakeLists.txt | 1 + host/usrp_e_utils/usrp-e-loopback.c | 170 ++++++++++------ host/usrp_e_utils/usrp-e-timed.c | 382 ++++++++++++++++++++++++++++++++++++ 3 files changed, 489 insertions(+), 64 deletions(-) create mode 100644 host/usrp_e_utils/usrp-e-timed.c diff --git a/host/usrp_e_utils/CMakeLists.txt b/host/usrp_e_utils/CMakeLists.txt index 5123af592..1ecd2ac46 100644 --- a/host/usrp_e_utils/CMakeLists.txt +++ b/host/usrp_e_utils/CMakeLists.txt @@ -34,6 +34,7 @@ IF(ENABLE_USRP_E_UTILS) SET(usrp_e_utils_sources usrp-e-utility.cpp usrp-e-loopback.c + usrp-e-timed.c usrp-e-wb-test.cpp usrp-e-debug-pins.c usrp-e-i2c.c diff --git a/host/usrp_e_utils/usrp-e-loopback.c b/host/usrp_e_utils/usrp-e-loopback.c index 454d81ba7..a63882475 100644 --- a/host/usrp_e_utils/usrp-e-loopback.c +++ b/host/usrp_e_utils/usrp-e-loopback.c @@ -1,14 +1,18 @@ #include +#include #include +#include #include #include #include #include #include #include -#include +#include +#include +#include "linux/usrp_e.h" -#define MAX_PACKET_SIZE 1016 +// max length #define PKT_DATA_LENGTH 1016 static int packet_data_length; static int error; @@ -16,34 +20,16 @@ struct pkt { int len; int checksum; int seq_num; - short data[]; + short data[1024-6]; }; -static int length_array[2048]; -static int length_array_tail = 0; -static int length_array_head = 0; - -pthread_mutex_t length_array_mutex; //gotta lock the index to keep it from getting hosed - -//yes this is a circular buffer that does not check empty -//no i don't want to hear about it -void push_length_array(int length) { - pthread_mutex_lock(&length_array_mutex); - if(length_array_tail > 2047) length_array_tail = 0; - length_array[length_array_tail++] = length; - pthread_mutex_unlock(&length_array_mutex); -} - -int pop_length_array(void) { - int retval; - pthread_mutex_lock(&length_array_mutex); - if(length_array_head > 2047) length_array_head = 0; - retval = length_array[length_array_head++]; - pthread_mutex_unlock(&length_array_mutex); - return retval; -} +struct ring_buffer_info (*rxi)[]; +struct ring_buffer_info (*txi)[]; +struct pkt (*rx_buf)[200]; +struct pkt (*tx_buf)[200]; static int fp; +static struct usrp_e_ring_buffer_size_t rb_size; static int calc_checksum(struct pkt *p) { @@ -53,43 +39,56 @@ static int calc_checksum(struct pkt *p) sum = 0; for (i=0; i < p->len; i++) - sum ^= p->data[i]; + sum += p->data[i]; - sum ^= p->seq_num; - sum ^= p->len; + sum += p->seq_num; + sum += p->len; return sum; } static void *read_thread(void *threadid) { - char *rx_data; int cnt, prev_seq_num, pkt_count, seq_num_failure; struct pkt *p; unsigned long bytes_transfered, elapsed_seconds; struct timeval start_time, finish_time; - int expected_count; + int rb_read; printf("Greetings from the reading thread!\n"); + printf("sizeof pkt = %d\n", sizeof(struct pkt)); + + rb_read = 0; bytes_transfered = 0; gettimeofday(&start_time, NULL); - // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(2048); - p = (struct pkt *) ((void *)rx_data); - prev_seq_num = 0; pkt_count = 0; seq_num_failure = 0; while (1) { - cnt = read(fp, rx_data, 2048); - if (cnt < 0) - printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); + if (!((*rxi)[rb_read].flags & RB_USER)) { +// printf("Waiting for data\n"); + struct pollfd pfd; + pfd.fd = fp; + pfd.events = POLLIN; + poll(&pfd, 1, -1); + } + + (*rxi)[rb_read].flags = RB_USER_PROCESS; -// printf("p->seq_num = %d\n", p->seq_num); +// printf("pkt received, rb_read = %d\n", rb_read); + + cnt = (*rxi)[rb_read].len; + p = &(*rx_buf)[rb_read]; + +// cnt = read(fp, rx_data, 2048); +// if (cnt < 0) +// printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); + +// printf("p = %X, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); pkt_count++; @@ -97,17 +96,14 @@ static void *read_thread(void *threadid) if (p->seq_num != prev_seq_num + 1) { printf("Sequence number fail, current = %d, previous = %d, pkt_count = %d\n", p->seq_num, prev_seq_num, pkt_count); + printf("pkt received, rb_read = %d\n", rb_read); + printf("p = %p, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); seq_num_failure ++; if (seq_num_failure > 2) error = 1; } - expected_count = pop_length_array()*2+12; - if(cnt != expected_count) { - printf("Received %d bytes, expected %d\n", cnt, expected_count); - } - prev_seq_num = p->seq_num; if (calc_checksum(p) != p->checksum) { @@ -116,6 +112,12 @@ static void *read_thread(void *threadid) error = 1; } + (*rxi)[rb_read].flags = RB_KERNEL; + + rb_read++; + if (rb_read == rb_size.num_rx_frames) + rb_read = 0; + bytes_transfered += cnt; if (bytes_transfered > (100 * 1000000)) { @@ -135,12 +137,12 @@ static void *read_thread(void *threadid) // fflush(stdout); // printf("\n"); } - + return NULL; } static void *write_thread(void *threadid) { - int seq_number, i, cnt; + int seq_number, i, cnt, rb_write; void *tx_data; struct pkt *p; @@ -154,6 +156,7 @@ static void *write_thread(void *threadid) p->data[i] = i; seq_number = 1; + rb_write = 0; while (1) { p->seq_num = seq_number++; @@ -161,30 +164,46 @@ static void *write_thread(void *threadid) if (packet_data_length > 0) p->len = packet_data_length; else - p->len = (random()<<1 & 0x1ff) + (1004 - 512); - - push_length_array(p->len); + p->len = (random() & 0x1ff) + (1004 - 512); p->checksum = calc_checksum(p); - cnt = write(fp, tx_data, p->len * 2 + 12); - if (cnt < 0) - printf("Error returned from write: %d\n", cnt); + if (!((*txi)[rb_write].flags & RB_KERNEL)) { +// printf("Waiting for space\n"); + struct pollfd pfd; + pfd.fd = fp; + pfd.events = POLLOUT; + poll(&pfd, 1, -1); + } + + memcpy(&(*tx_buf)[rb_write], tx_data, p->len * 2 + 12); + + (*txi)[rb_write].len = p->len * 2 + 12; + (*txi)[rb_write].flags = RB_USER; + + rb_write++; + if (rb_write == rb_size.num_tx_frames) + rb_write = 0; + + cnt = write(fp, NULL, 0); +// if (cnt < 0) +// printf("Error returned from write: %d\n", cnt); // sleep(1); } + return NULL; } int main(int argc, char *argv[]) { pthread_t tx, rx; - pthread_mutex_init(&length_array_mutex, 0); - long int t; + long int t = 0; struct sched_param s = { .sched_priority = 1 }; + int ret, map_size, page_size; void *rb; - struct usrp_transfer_frame *tx_rb, *rx_rb; + struct usrp_e_ctl16 d; if (argc < 2) { printf("%s data_size\n", argv[0]); @@ -192,22 +211,43 @@ int main(int argc, char *argv[]) } packet_data_length = atoi(argv[1]); - if(packet_data_length > MAX_PACKET_SIZE) { - printf("Packet size must be smaller than %i\n", MAX_PACKET_SIZE); - exit(-1); - } fp = open("/dev/usrp_e0", O_RDWR); printf("fp = %d\n", fp); - rb = mmap(0, 202 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); - if (!rb) { - printf("mmap failed\n"); - exit; + d.offset = 14; + d.count = 1; + d.buf[0] = (1<<8) | (1<<9); + ioctl(fp, USRP_E_WRITE_CTL16, &d); + + page_size = getpagesize(); + + ret = ioctl(fp, USRP_E_GET_RB_INFO, &rb_size); + + map_size = (rb_size.num_pages_rx_flags + rb_size.num_pages_tx_flags) * page_size + + (rb_size.num_rx_frames + rb_size.num_tx_frames) * (page_size >> 1); + + rb = mmap(0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); + if (rb == MAP_FAILED) { + perror("mmap failed"); + return -1; } + printf("rb = %p\n", rb); + + rxi = rb; + rx_buf = rb + (rb_size.num_pages_rx_flags * page_size); + txi = rb + (rb_size.num_pages_rx_flags * page_size) + + (rb_size.num_rx_frames * page_size >> 1); + tx_buf = rb + (rb_size.num_pages_rx_flags * page_size) + + (rb_size.num_rx_frames * page_size >> 1) + + (rb_size.num_pages_tx_flags * page_size); + + printf("rxi = %p, rx_buf = %p, txi = %p, tx_buf = %p\n", rxi, rx_buf, txi, tx_buf); + + if ((ret = sched_setscheduler(0, SCHED_RR, &s))) + perror("sched_setscheduler"); - sched_setscheduler(0, SCHED_RR, &s); error = 0; #if 1 @@ -228,4 +268,6 @@ int main(int argc, char *argv[]) sleep(1000000000); printf("Done sleeping\n"); + + return 0; } diff --git a/host/usrp_e_utils/usrp-e-timed.c b/host/usrp_e_utils/usrp-e-timed.c new file mode 100644 index 000000000..06dfdf512 --- /dev/null +++ b/host/usrp_e_utils/usrp-e-timed.c @@ -0,0 +1,382 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "linux/usrp_e.h" + +// max length #define PKT_DATA_LENGTH 1016 +static int packet_data_length; + +struct ring_buffer_info (*rxi)[]; +struct ring_buffer_info (*txi)[]; +__u8 *rx_buf; +__u8 *tx_buf; +static struct usrp_e_ring_buffer_size_t rb_size; + +static int fp; +static u_int32_t crc_tab[256]; + +// CRC code from http://www.koders.com/c/fid699AFE0A656F0022C9D6B9D1743E697B69CE5815.aspx +// GPLv2 + +static u_int32_t chksum_crc32_gentab(void) +{ + unsigned long crc, poly; + unsigned long i, j; + + poly = 0x04C11DB7L; + + for (i = 0; i < 256; i++) { + crc = i; + for (j = 8; j > 0; j--) { + if (crc & 1) { + crc = (crc >> 1) ^ poly; + } else { + crc >>= 1; + } + } + crc_tab[i] = crc; +// printf("crc_tab[%d] = %X\n", i , crc); + } + + return 0; +} + +struct timeval delta_time(struct timeval f, struct timeval s) +{ + struct timeval d; + + if (f.tv_usec > s.tv_usec) { + d.tv_usec = f.tv_usec - s.tv_usec; + d.tv_sec = f.tv_sec - s.tv_sec; + } else { + d.tv_usec = f.tv_usec - s.tv_usec + 1e6; + d.tv_sec = f.tv_sec - s.tv_sec - 1; + } + + return d; +} + + +static void *read_thread(void *threadid) +{ + unsigned int cnt; + int rx_pkt_cnt, rb_read; + unsigned int i; + unsigned long crc, ck_sum; + unsigned int rx_crc, pkt_len, pkt_seq; + unsigned long bytes_transfered; + struct timeval start_time; + unsigned int prev_seq = 0; + int first = 1; + long tid; + __u8 *p; + + + tid = (long)threadid; + printf("Greetings from the reading thread(%ld)!\n", tid); + + // IMPORTANT: must assume max length packet from fpga + + rx_pkt_cnt = 0; + rb_read = 0; + + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + + while (1) { + + while (!((*rxi)[rb_read].flags & RB_USER)) { + struct pollfd pfd; + pfd.fd = fp; + pfd.events = POLLIN; + poll(&pfd, 1, -1); + } + (*rxi)[rb_read].flags = RB_USER_PROCESS; + + rx_pkt_cnt++; + cnt = (*rxi)[rb_read].len; + p = rx_buf + (rb_read * 2048); + + rx_crc = *(int *) &p[cnt-4]; + crc = 0xFFFFFFFF; + ck_sum = 0; + + pkt_len = *(unsigned int *) &p[0]; + pkt_seq = *(unsigned int *) &p[4]; + +// printf("Pkt len = %X, pkt seq = %X, driver len = %X\n", pkt_len, pkt_seq, cnt); + + if (pkt_len != (cnt - 4)) + printf("Packet length check fail, driver len = %ud, content = %ud\n", + cnt, pkt_len); + + if (!first && (pkt_seq != (prev_seq + 1))) + printf("Sequence number check fail, pkt_seq = %ud, prev_seq = %ud\n", + pkt_seq, prev_seq); + first = 0; + prev_seq = pkt_seq; + + for (i = 0; i < cnt-4; i++) { + ck_sum += p[i]; + + crc = ((crc >> 8) & 0x00FFFFFF) ^ + crc_tab[(crc ^ p[i]) & 0xFF]; +//printf("idx = %d, data = %X, crc = %X, ck_sum = %X\n", i, p[i], crc, ck_sum); +// crc = ((crc >> 8) & 0x00FFFFFF) ^ +// crc_tab[(crc ^ p[i+1]) & 0xFF]; +//printf("idx = %d, data = %X, crc = %X\n", i, p[i+1],crc); + } + + (*rxi)[rb_read].flags = RB_KERNEL; + write(fp, NULL, 1); + + if (rx_crc != ck_sum) + printf("Ck_sum eror, calc ck_sum = %lX, rx ck_sum = %X\n", + ck_sum, rx_crc); + +#if 0 + if (rx_crc != (crc & 0xFFFFFFFF)) { + printf("CRC Error, calc crc: %X, rx_crc: %X\n", + (crc & 0xFFFFFFFF), rx_crc); + } +#endif + + rb_read++; + if (rb_read == rb_size.num_rx_frames) + rb_read = 0; + + bytes_transfered += cnt; + + if (bytes_transfered > (100 * 1000000)) { + struct timeval finish_time, d_time; + float elapsed_seconds; + + gettimeofday(&finish_time, NULL); + + printf("sec = %ld, usec = %ld\n", finish_time.tv_sec, finish_time.tv_usec); + + d_time = delta_time(finish_time, start_time); + + elapsed_seconds = (float)d_time.tv_sec + ((float)d_time.tv_usec * 1e-6f); + + printf("Bytes transfered = %ld, elapsed seconds = %f\n", bytes_transfered, elapsed_seconds); + printf("RX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 4000); + + + start_time = finish_time; + bytes_transfered = 0; + } + } + return NULL; +} + +static void *write_thread(void *threadid) +{ + int i, tx_pkt_cnt, rb_write; + int tx_len; + unsigned long crc; + unsigned long bytes_transfered; + struct timeval start_time; + unsigned int pkt_seq = 0; + long tid; + __u8 *p; + + tid = (long)threadid; + printf("Greetings from the write thread(%ld)!\n", tid); + + rb_write = 0; + tx_pkt_cnt = 0; + + bytes_transfered = 0; + gettimeofday(&start_time, NULL); + + while (1) { + + tx_pkt_cnt++; + p = tx_buf + (rb_write * 2048); + +// printf("p = %p\n", p); + + if (packet_data_length > 0) + tx_len = packet_data_length; + else + tx_len = (random() & 0x1ff) + (2044 - 512); + +#if 0 + if (tx_pkt_cnt == 512) { + printf("."); + fflush(stdout); + } + if (tx_pkt_cnt == 1024) { + printf("'"); + fflush(stdout); + } + if (tx_pkt_cnt == 1536) { + printf(":"); + fflush(stdout); + tx_pkt_cnt = 0; + } +#endif + +// printf("Checking for space at rb entry = %d\n", rb_write); + while (!((*txi)[rb_write].flags & RB_KERNEL)) { + struct pollfd pfd; + pfd.fd = fp; + pfd.events = POLLOUT; + poll(&pfd, 1, -1); + } +// printf("Got space\n"); + + for (i=8; i < tx_len-4; i++) { + p[i] = i & 0xFF; + } + + *(unsigned int *) &p[0] = tx_len-4; + *(unsigned int *) &p[4] = pkt_seq; + + pkt_seq++; + + crc = 0xFFFFFFFF; + for (i = 0; i < tx_len-4; i++) { +// printf("%X ", p[i]); + crc = ((crc >> 8) & 0x00FFFFFF) ^ + crc_tab[(crc ^ p[i]) & 0xFF]; + + } + *(unsigned int *) &p[tx_len-4] = crc; +// printf("\n crc = %lX\n", crc); + + (*txi)[rb_write].len = tx_len; + (*txi)[rb_write].flags = RB_USER; + + rb_write++; + if (rb_write == rb_size.num_tx_frames) + rb_write = 0; + + bytes_transfered += tx_len; + + if (bytes_transfered > (100 * 1000000)) { + struct timeval finish_time, d_time; + float elapsed_seconds; + + gettimeofday(&finish_time, NULL); + + d_time = delta_time(finish_time, start_time); + + elapsed_seconds = (float)d_time.tv_sec - ((float)d_time.tv_usec * 1e-6f); + + printf("Bytes transfered = %ld, elapsed seconds = %f\n", bytes_transfered, elapsed_seconds); + printf("TX data transfer rate = %f K Samples/second\n", + (float) bytes_transfered / (float) elapsed_seconds / 4000); + + + start_time = finish_time; + bytes_transfered = 0; + } + +// sleep(1); + } + return NULL; +} + + +int main(int argc, char *argv[]) +{ + pthread_t tx, rx; + long int t=0; + int fpga_config_flag ,decimation; + int ret, map_size, page_size; + void *rb; + + struct usrp_e_ctl16 d; + struct sched_param s = { + .sched_priority = 1 + }; + + if (argc < 4) { + printf("%s r|w|rw decimation data_size\n", argv[0]); + return -1; + } + + chksum_crc32_gentab(); + + decimation = atoi(argv[2]); + packet_data_length = atoi(argv[3]); + + fp = open("/dev/usrp_e0", O_RDWR); + printf("fp = %d\n", fp); + + page_size = getpagesize(); + + ret = ioctl(fp, USRP_E_GET_RB_INFO, &rb_size); + + map_size = (rb_size.num_pages_rx_flags + rb_size.num_pages_tx_flags) * page_size + + (rb_size.num_rx_frames + rb_size.num_tx_frames) * (page_size >> 1); + + rb = mmap(0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); + if (rb == MAP_FAILED) { + perror("mmap failed"); + return -1; + } + + printf("rb = %p\n", rb); + + rxi = rb; + rx_buf = rb + (rb_size.num_pages_rx_flags * page_size); + txi = rb + (rb_size.num_pages_rx_flags * page_size) + + (rb_size.num_rx_frames * page_size >> 1); + tx_buf = rb + (rb_size.num_pages_rx_flags * page_size) + + (rb_size.num_rx_frames * page_size >> 1) + + (rb_size.num_pages_tx_flags * page_size); + + fpga_config_flag = (1<<8); + if (strcmp(argv[1], "w") == 0) + fpga_config_flag |= (1 << 11); + else if (strcmp(argv[1], "r") == 0) + fpga_config_flag |= (1 << 10); + else if (strcmp(argv[1], "rw") == 0) + fpga_config_flag |= ((1 << 10) | (1 << 11)); + + fpga_config_flag |= decimation; + + d.offset = 14; + d.count = 1; + d.buf[0] = fpga_config_flag; + ioctl(fp, USRP_E_WRITE_CTL16, &d); + + sleep(1); // in case the kernel threads need time to start. FIXME if so + + sched_setscheduler(0, SCHED_RR, &s); + + if (fpga_config_flag & (1 << 10)) { + if (pthread_create(&rx, NULL, read_thread, (void *) t)) { + printf("Failed to create rx thread\n"); + exit(-1); + } + } + + sleep(1); + + if (fpga_config_flag & (1 << 11)) { + if (pthread_create(&tx, NULL, write_thread, (void *) t)) { + printf("Failed to create tx thread\n"); + exit(-1); + } + } + + sleep(10000); + + printf("Done sleeping\n"); + + return 0; +} -- cgit v1.2.3 From 40f58d26c28adee8c8aebf93df25535e16050932 Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 21 Feb 2011 07:45:39 -0800 Subject: usrp-e-utils : Remove old files. --- host/apps/omap_debug/Makefile | 19 +- host/apps/omap_debug/usrp-e-crc-rw.c | 379 -------------------------- host/apps/omap_debug/usrp-e-loopback.c | 194 ------------- host/apps/omap_debug/usrp-e-mm-loopback.c | 273 ------------------- host/apps/omap_debug/usrp-e-random-loopback.c | 149 ---------- 5 files changed, 1 insertion(+), 1013 deletions(-) delete mode 100644 host/apps/omap_debug/usrp-e-crc-rw.c delete mode 100644 host/apps/omap_debug/usrp-e-loopback.c delete mode 100644 host/apps/omap_debug/usrp-e-mm-loopback.c delete mode 100644 host/apps/omap_debug/usrp-e-random-loopback.c diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index 46d4714a8..dd27ba657 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,27 +1,12 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 CXXFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 -all : usrp-e-spi usrp-e-i2c usrp-e-loopback usrp-e-mm-loopback usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-random-loopback usrp-e-timed usrp-e-lb-test usrp-e-crc-rw clkgen-config +all : usrp-e-spi usrp-e-i2c usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-lb-test usrp-e-crc-rw clkgen-config usrp-e-spi : usrp-e-spi.c usrp-e-i2c : usrp-e-i2c.c -usrp-e-loopback : usrp-e-loopback.c - gcc -o $@ $< -lpthread ${CFLAGS} - -usrp-e-mm-loopback : usrp-e-mm-loopback.c - gcc -o $@ $< -lpthread ${CFLAGS} - -usrp-e-timed : usrp-e-timed.c - gcc -o $@ $< -lpthread ${CFLAGS} - -usrp-e-random-loopback : usrp-e-random-loopback.c - gcc -o $@ $< -lpthread ${CFLAGS} - -usrp-e-crc-rw : usrp-e-crc-rw.c - gcc -o $@ $< -lpthread ${CFLAGS} - usrp-e-uart : usrp-e-uart.c usrp-e-uart-rx : usrp-e-uart-rx.c @@ -38,8 +23,6 @@ clkgen-config : clkgen-config.cc usrp-e-gpio : usrp-e-gpio.c -usrp-e-lb-test : usrp-e-lb-test.c - usrp-e-debug-pins : usrp-e-debug-pins.c clean : rm -f usrp-e-spi diff --git a/host/apps/omap_debug/usrp-e-crc-rw.c b/host/apps/omap_debug/usrp-e-crc-rw.c deleted file mode 100644 index 7f4ff0023..000000000 --- a/host/apps/omap_debug/usrp-e-crc-rw.c +++ /dev/null @@ -1,379 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "usrp_e.h" - -// max length #define PKT_DATA_LENGTH 1016 -static int packet_data_length; - -struct ring_buffer_info (*rxi)[]; -struct ring_buffer_info (*txi)[]; -__u8 *rx_buf; -__u8 *tx_buf; -static struct usrp_e_ring_buffer_size_t rb_size; - -static int fp; -static u_int32_t crc_tab[256]; - -// CRC code from http://www.koders.com/c/fid699AFE0A656F0022C9D6B9D1743E697B69CE5815.aspx -// GPLv2 - -static u_int32_t chksum_crc32_gentab(void) -{ - unsigned long crc, poly; - unsigned long i, j; - - poly = 0x04C11DB7L; - - for (i = 0; i < 256; i++) { - crc = i; - for (j = 8; j > 0; j--) { - if (crc & 1) { - crc = (crc >> 1) ^ poly; - } else { - crc >>= 1; - } - } - crc_tab[i] = crc; -// printf("crc_tab[%d] = %X\n", i , crc); - } - - return 0; -} - -struct timeval delta_time(struct timeval f, struct timeval s) -{ - struct timeval d; - - if (f.tv_usec > s.tv_usec) { - d.tv_usec = f.tv_usec - s.tv_usec; - d.tv_sec = f.tv_sec - s.tv_sec; - } else { - d.tv_usec = f.tv_usec - s.tv_usec + 1e6; - d.tv_sec = f.tv_sec - s.tv_sec - 1; - } - - return d; -} - - -static void *read_thread(void *threadid) -{ - int cnt; - int rx_pkt_cnt, rb_read; - int i; - unsigned long crc, ck_sum; - unsigned int rx_crc, pkt_len, pkt_seq; - unsigned long bytes_transfered; - struct timeval start_time; - unsigned int prev_seq = 0; - int first = 1; - - __u8 *p; - - - printf("Greetings from the reading thread!\n"); - - // IMPORTANT: must assume max length packet from fpga - - rx_pkt_cnt = 0; - rb_read = 0; - - bytes_transfered = 0; - gettimeofday(&start_time, NULL); - - while (1) { - - while (!((*rxi)[rb_read].flags & RB_USER)) { - struct pollfd pfd; - pfd.fd = fp; - pfd.events = POLLIN; - poll(&pfd, 1, -1); - } - (*rxi)[rb_read].flags = RB_USER_PROCESS; - - rx_pkt_cnt++; - cnt = (*rxi)[rb_read].len; - p = rx_buf + (rb_read * 2048); - - rx_crc = *(int *) &p[cnt-4]; - crc = 0xFFFFFFFF; - ck_sum = 0; - - pkt_len = *(unsigned int *) &p[0]; - pkt_seq = *(unsigned int *) &p[4]; - -// printf("Pkt len = %X, pkt seq = %X, driver len = %X\n", pkt_len, pkt_seq, cnt); - - if (pkt_len != (cnt - 4)) - printf("Packet length check fail, driver len = %ud, content = %ud\n", - cnt, pkt_len); - - if (!first && (pkt_seq != (prev_seq + 1))) - printf("Sequence number check fail, pkt_seq = %ud, prev_seq = %ud\n", - pkt_seq, prev_seq); - first = 0; - prev_seq = pkt_seq; - - for (i = 0; i < cnt-4; i++) { - ck_sum += p[i]; - - crc = ((crc >> 8) & 0x00FFFFFF) ^ - crc_tab[(crc ^ p[i]) & 0xFF]; -//printf("idx = %d, data = %X, crc = %X, ck_sum = %X\n", i, p[i], crc, ck_sum); -// crc = ((crc >> 8) & 0x00FFFFFF) ^ -// crc_tab[(crc ^ p[i+1]) & 0xFF]; -//printf("idx = %d, data = %X, crc = %X\n", i, p[i+1],crc); - } - - (*rxi)[rb_read].flags = RB_KERNEL; - write(fp, NULL, 1); - - if (rx_crc != ck_sum) - printf("Ck_sum eror, calc ck_sum = %lX, rx ck_sum = %X\n", - ck_sum, rx_crc); - -#if 0 - if (rx_crc != (crc & 0xFFFFFFFF)) { - printf("CRC Error, calc crc: %X, rx_crc: %X\n", - (crc & 0xFFFFFFFF), rx_crc); - } -#endif - - rb_read++; - if (rb_read == rb_size.num_rx_frames) - rb_read = 0; - - bytes_transfered += cnt; - - if (bytes_transfered > (100 * 1000000)) { - struct timeval finish_time, d_time; - float elapsed_seconds; - - gettimeofday(&finish_time, NULL); - - printf("sec = %ld, usec = %ld\n", finish_time.tv_sec, finish_time.tv_usec); - - d_time = delta_time(finish_time, start_time); - - elapsed_seconds = (float)d_time.tv_sec + ((float)d_time.tv_usec * 1e-6f); - - printf("Bytes transfered = %ld, elapsed seconds = %f\n", bytes_transfered, elapsed_seconds); - printf("RX data transfer rate = %f K Samples/second\n", - (float) bytes_transfered / (float) elapsed_seconds / 4000); - - - start_time = finish_time; - bytes_transfered = 0; - } - } - return NULL; -} - -static void *write_thread(void *threadid) -{ - int i, tx_pkt_cnt, rb_write; - int tx_len; - unsigned long crc; - unsigned long bytes_transfered; - struct timeval start_time; - unsigned int pkt_seq = 0; - __u8 *p; - - printf("Greetings from the write thread!\n"); - - rb_write = 0; - tx_pkt_cnt = 0; - - bytes_transfered = 0; - gettimeofday(&start_time, NULL); - - while (1) { - - tx_pkt_cnt++; - p = tx_buf + (rb_write * 2048); - -// printf("p = %p\n", p); - - if (packet_data_length > 0) - tx_len = packet_data_length; - else - tx_len = (random() & 0x1ff) + (2044 - 512); - -#if 0 - if (tx_pkt_cnt == 512) { - printf("."); - fflush(stdout); - } - if (tx_pkt_cnt == 1024) { - printf("'"); - fflush(stdout); - } - if (tx_pkt_cnt == 1536) { - printf(":"); - fflush(stdout); - tx_pkt_cnt = 0; - } -#endif - -// printf("Checking for space at rb entry = %d\n", rb_write); - while (!((*txi)[rb_write].flags & RB_KERNEL)) { - struct pollfd pfd; - pfd.fd = fp; - pfd.events = POLLOUT; - poll(&pfd, 1, -1); - } -// printf("Got space\n"); - - for (i=8; i < tx_len-4; i++) { - p[i] = i & 0xFF; - } - - *(unsigned int *) &p[0] = tx_len-4; - *(unsigned int *) &p[4] = pkt_seq; - - pkt_seq++; - - crc = 0xFFFFFFFF; - for (i = 0; i < tx_len-4; i++) { -// printf("%X ", p[i]); - crc = ((crc >> 8) & 0x00FFFFFF) ^ - crc_tab[(crc ^ p[i]) & 0xFF]; - - } - *(unsigned int *) &p[tx_len-4] = crc; -// printf("\n crc = %lX\n", crc); - - (*txi)[rb_write].len = tx_len; - (*txi)[rb_write].flags = RB_USER; - - rb_write++; - if (rb_write == rb_size.num_tx_frames) - rb_write = 0; - - bytes_transfered += tx_len; - - if (bytes_transfered > (100 * 1000000)) { - struct timeval finish_time, d_time; - float elapsed_seconds; - - gettimeofday(&finish_time, NULL); - - d_time = delta_time(finish_time, start_time); - - elapsed_seconds = (float)d_time.tv_sec - ((float)d_time.tv_usec * 1e-6f); - - printf("Bytes transfered = %ld, elapsed seconds = %f\n", bytes_transfered, elapsed_seconds); - printf("TX data transfer rate = %f K Samples/second\n", - (float) bytes_transfered / (float) elapsed_seconds / 4000); - - - start_time = finish_time; - bytes_transfered = 0; - } - -// sleep(1); - } - return NULL; -} - - -int main(int argc, char *argv[]) -{ - pthread_t tx, rx; - long int t=0; - int fpga_config_flag ,decimation; - int ret, map_size, page_size; - void *rb; - - struct usrp_e_ctl16 d; - struct sched_param s = { - .sched_priority = 1 - }; - - if (argc < 4) { - printf("%s r|w|rw decimation data_size\n", argv[0]); - return -1; - } - - chksum_crc32_gentab(); - - decimation = atoi(argv[2]); - packet_data_length = atoi(argv[3]); - - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); - - page_size = getpagesize(); - - ret = ioctl(fp, USRP_E_GET_RB_INFO, &rb_size); - - map_size = (rb_size.num_pages_rx_flags + rb_size.num_pages_tx_flags) * page_size + - (rb_size.num_rx_frames + rb_size.num_tx_frames) * (page_size >> 1); - - rb = mmap(0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); - if (rb == MAP_FAILED) { - perror("mmap failed"); - return -1; - } - - printf("rb = %p\n", rb); - - rxi = rb; - rx_buf = rb + (rb_size.num_pages_rx_flags * page_size); - txi = rb + (rb_size.num_pages_rx_flags * page_size) + - (rb_size.num_rx_frames * page_size >> 1); - tx_buf = rb + (rb_size.num_pages_rx_flags * page_size) + - (rb_size.num_rx_frames * page_size >> 1) + - (rb_size.num_pages_tx_flags * page_size); - - fpga_config_flag = (1<<8); - if (strcmp(argv[1], "w") == 0) - fpga_config_flag |= (1 << 11); - else if (strcmp(argv[1], "r") == 0) - fpga_config_flag |= (1 << 10); - else if (strcmp(argv[1], "rw") == 0) - fpga_config_flag |= ((1 << 10) | (1 << 11)); - - fpga_config_flag |= decimation; - - d.offset = 14; - d.count = 1; - d.buf[0] = fpga_config_flag; - ioctl(fp, USRP_E_WRITE_CTL16, &d); - - sleep(1); // in case the kernel threads need time to start. FIXME if so - - sched_setscheduler(0, SCHED_RR, &s); - - if (fpga_config_flag & (1 << 10)) { - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - } - - sleep(1); - - if (fpga_config_flag & (1 << 11)) { - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - } - - sleep(10000); - - printf("Done sleeping\n"); - - return 0; -} diff --git a/host/apps/omap_debug/usrp-e-loopback.c b/host/apps/omap_debug/usrp-e-loopback.c deleted file mode 100644 index d11cf7d09..000000000 --- a/host/apps/omap_debug/usrp-e-loopback.c +++ /dev/null @@ -1,194 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "usrp_e.h" - -// max length #define PKT_DATA_LENGTH 1016 -static int packet_data_length; -static int error; - -struct pkt { - int len; - int checksum; - int seq_num; - short data[]; -}; - -static int fp; - -static int calc_checksum(struct pkt *p) -{ - int i, sum; - - i = 0; - sum = 0; - - for (i=0; i < p->len; i++) - sum += p->data[i]; - - sum += p->seq_num; - sum += p->len; - - return sum; -} - -static void *read_thread(void *threadid) -{ - char *rx_data; - int cnt, prev_seq_num, pkt_count, seq_num_failure; - struct pkt *p; - unsigned long bytes_transfered, elapsed_seconds; - struct timeval start_time, finish_time; - - printf("Greetings from the reading thread!\n"); - - bytes_transfered = 0; - gettimeofday(&start_time, NULL); - - // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(2048); - p = (struct pkt *) ((void *)rx_data); - - prev_seq_num = 0; - pkt_count = 0; - seq_num_failure = 0; - - while (1) { - - cnt = read(fp, rx_data, 2048); - if (cnt < 0) - printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); - -// printf("p->seq_num = %d\n", p->seq_num); - - - pkt_count++; - - if (p->seq_num != prev_seq_num + 1) { - printf("Sequence number fail, current = %d, previous = %d, pkt_count = %d\n", - p->seq_num, prev_seq_num, pkt_count); - - seq_num_failure ++; - if (seq_num_failure > 2) - error = 1; - } - - prev_seq_num = p->seq_num; - - if (calc_checksum(p) != p->checksum) { - printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", - calc_checksum(p), p->checksum, pkt_count); - error = 1; - } - - bytes_transfered += cnt; - - if (bytes_transfered > (100 * 1000000)) { - gettimeofday(&finish_time, NULL); - elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - - printf("RX data transfer rate = %f K Samples/second\n", - (float) bytes_transfered / (float) elapsed_seconds / 4000); - - - start_time = finish_time; - bytes_transfered = 0; - } - - -// printf("."); -// fflush(stdout); -// printf("\n"); - } - -} - -static void *write_thread(void *threadid) -{ - int seq_number, i, cnt; - void *tx_data; - struct pkt *p; - - printf("Greetings from the write thread!\n"); - - tx_data = malloc(2048); - p = (struct pkt *) ((void *)tx_data); - - for (i=0; i < packet_data_length; i++) -// p->data[i] = random() >> 16; - p->data[i] = i; - - seq_number = 1; - - while (1) { - p->seq_num = seq_number++; - - if (packet_data_length > 0) - p->len = packet_data_length; - else - p->len = (random() & 0x1ff) + (1004 - 512); - - p->checksum = calc_checksum(p); - - cnt = write(fp, tx_data, p->len * 2 + 12); - if (cnt < 0) - printf("Error returned from write: %d\n", cnt); -// sleep(1); - } -} - - -int main(int argc, char *argv[]) -{ - pthread_t tx, rx; - long int t; - struct sched_param s = { - .sched_priority = 1 - }; - void *rb; - struct usrp_transfer_frame *tx_rb, *rx_rb; - - if (argc < 2) { - printf("%s data_size\n", argv[0]); - return -1; - } - - packet_data_length = atoi(argv[1]); - - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); - - rb = mmap(0, 202 * 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); - if (!rb) { - printf("mmap failed\n"); - exit; - } - - - sched_setscheduler(0, SCHED_RR, &s); - error = 0; - -#if 1 - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - - sleep(1); -#endif - - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - -// while (!error) - sleep(1000000000); - - printf("Done sleeping\n"); -} diff --git a/host/apps/omap_debug/usrp-e-mm-loopback.c b/host/apps/omap_debug/usrp-e-mm-loopback.c deleted file mode 100644 index 14f68a5c3..000000000 --- a/host/apps/omap_debug/usrp-e-mm-loopback.c +++ /dev/null @@ -1,273 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "usrp_e.h" - -// max length #define PKT_DATA_LENGTH 1016 -static int packet_data_length; -static int error; - -struct pkt { - int len; - int checksum; - int seq_num; - short data[1024-6]; -}; - -struct ring_buffer_info (*rxi)[]; -struct ring_buffer_info (*txi)[]; -struct pkt (*rx_buf)[200]; -struct pkt (*tx_buf)[200]; - -static int fp; -static struct usrp_e_ring_buffer_size_t rb_size; - -static int calc_checksum(struct pkt *p) -{ - int i, sum; - - i = 0; - sum = 0; - - for (i=0; i < p->len; i++) - sum += p->data[i]; - - sum += p->seq_num; - sum += p->len; - - return sum; -} - -static void *read_thread(void *threadid) -{ - int cnt, prev_seq_num, pkt_count, seq_num_failure; - struct pkt *p; - unsigned long bytes_transfered, elapsed_seconds; - struct timeval start_time, finish_time; - int rb_read; - - printf("Greetings from the reading thread!\n"); - printf("sizeof pkt = %d\n", sizeof(struct pkt)); - - rb_read = 0; - - bytes_transfered = 0; - gettimeofday(&start_time, NULL); - - prev_seq_num = 0; - pkt_count = 0; - seq_num_failure = 0; - - while (1) { - - if (!((*rxi)[rb_read].flags & RB_USER)) { -// printf("Waiting for data\n"); - struct pollfd pfd; - pfd.fd = fp; - pfd.events = POLLIN; - poll(&pfd, 1, -1); - } - - (*rxi)[rb_read].flags = RB_USER_PROCESS; - -// printf("pkt received, rb_read = %d\n", rb_read); - - cnt = (*rxi)[rb_read].len; - p = &(*rx_buf)[rb_read]; - -// cnt = read(fp, rx_data, 2048); -// if (cnt < 0) -// printf("Error returned from read: %d, sequence number = %d\n", cnt, p->seq_num); - -// printf("p = %X, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); - - - pkt_count++; - - if (p->seq_num != prev_seq_num + 1) { - printf("Sequence number fail, current = %d, previous = %d, pkt_count = %d\n", - p->seq_num, prev_seq_num, pkt_count); - printf("pkt received, rb_read = %d\n", rb_read); - printf("p = %p, p->seq_num = %d p->len = %d\n", p, p->seq_num, p->len); - - seq_num_failure ++; - if (seq_num_failure > 2) - error = 1; - } - - prev_seq_num = p->seq_num; - - if (calc_checksum(p) != p->checksum) { - printf("Checksum fail packet = %X, expected = %X, pkt_count = %d\n", - calc_checksum(p), p->checksum, pkt_count); - error = 1; - } - - (*rxi)[rb_read].flags = RB_KERNEL; - - rb_read++; - if (rb_read == rb_size.num_rx_frames) - rb_read = 0; - - bytes_transfered += cnt; - - if (bytes_transfered > (100 * 1000000)) { - gettimeofday(&finish_time, NULL); - elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - - printf("RX data transfer rate = %f K Samples/second\n", - (float) bytes_transfered / (float) elapsed_seconds / 4000); - - - start_time = finish_time; - bytes_transfered = 0; - } - - -// printf("."); -// fflush(stdout); -// printf("\n"); - } - return NULL; -} - -static void *write_thread(void *threadid) -{ - int seq_number, i, cnt, rb_write; - void *tx_data; - struct pkt *p; - - printf("Greetings from the write thread!\n"); - - tx_data = malloc(2048); - p = (struct pkt *) ((void *)tx_data); - - for (i=0; i < packet_data_length; i++) -// p->data[i] = random() >> 16; - p->data[i] = i; - - seq_number = 1; - rb_write = 0; - - while (1) { - p->seq_num = seq_number++; - - if (packet_data_length > 0) - p->len = packet_data_length; - else - p->len = (random() & 0x1ff) + (1004 - 512); - - p->checksum = calc_checksum(p); - - if (!((*txi)[rb_write].flags & RB_KERNEL)) { -// printf("Waiting for space\n"); - struct pollfd pfd; - pfd.fd = fp; - pfd.events = POLLOUT; - poll(&pfd, 1, -1); - } - - memcpy(&(*tx_buf)[rb_write], tx_data, p->len * 2 + 12); - - (*txi)[rb_write].len = p->len * 2 + 12; - (*txi)[rb_write].flags = RB_USER; - - rb_write++; - if (rb_write == rb_size.num_tx_frames) - rb_write = 0; - - cnt = write(fp, NULL, 0); -// if (cnt < 0) -// printf("Error returned from write: %d\n", cnt); -// sleep(1); - } - return NULL; -} - - -int main(int argc, char *argv[]) -{ - pthread_t tx, rx; - long int t = 0; - struct sched_param s = { - .sched_priority = 1 - }; - int ret, map_size, page_size; - void *rb; - struct usrp_e_ctl16 d; - - if (argc < 2) { - printf("%s data_size\n", argv[0]); - return -1; - } - - packet_data_length = atoi(argv[1]); - - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); - - d.offset = 14; - d.count = 1; - d.buf[0] = (1<<8) | (1<<9); - ioctl(fp, USRP_E_WRITE_CTL16, &d); - - page_size = getpagesize(); - - ret = ioctl(fp, USRP_E_GET_RB_INFO, &rb_size); - - map_size = (rb_size.num_pages_rx_flags + rb_size.num_pages_tx_flags) * page_size + - (rb_size.num_rx_frames + rb_size.num_tx_frames) * (page_size >> 1); - - rb = mmap(0, map_size, PROT_READ|PROT_WRITE, MAP_SHARED, fp, 0); - if (rb == MAP_FAILED) { - perror("mmap failed"); - return -1; - } - - printf("rb = %p\n", rb); - - rxi = rb; - rx_buf = rb + (rb_size.num_pages_rx_flags * page_size); - txi = rb + (rb_size.num_pages_rx_flags * page_size) + - (rb_size.num_rx_frames * page_size >> 1); - tx_buf = rb + (rb_size.num_pages_rx_flags * page_size) + - (rb_size.num_rx_frames * page_size >> 1) + - (rb_size.num_pages_tx_flags * page_size); - - printf("rxi = %p, rx_buf = %p, txi = %p, tx_buf = %p\n", rxi, rx_buf, txi, tx_buf); - - if ((ret = sched_setscheduler(0, SCHED_RR, &s))) - perror("sched_setscheduler"); - - error = 0; - -#if 1 - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - - sleep(1); -#endif - - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - -// while (!error) - sleep(1000000000); - - printf("Done sleeping\n"); - - return 0; -} diff --git a/host/apps/omap_debug/usrp-e-random-loopback.c b/host/apps/omap_debug/usrp-e-random-loopback.c deleted file mode 100644 index 5960b8fbd..000000000 --- a/host/apps/omap_debug/usrp-e-random-loopback.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "usrp_e.h" - -// max length #define PKT_DATA_LENGTH 1014 -static int packet_data_length; - -struct pkt { - int checksum; - int seq_num; - int len; - short data[]; -}; - -static int fp; - -static int calc_checksum(struct pkt *p) -{ - int i, sum; - - i = 0; - sum = 0; - - for (i=0; i < p->len; i++) - sum += p->data[i]; - - sum += p->seq_num; - - return sum; -} - -int randN(int n) -{ - long tmp; - - tmp = rand() % n; - - return tmp; -} - -static void *read_thread(void *threadid) -{ - int cnt, prev_seq_num; - struct usrp_transfer_frame *rx_data; - struct pkt *p; - - printf("Greetings from the reading thread!\n"); - - // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1014 * 2)); - rx_data = malloc(2048); - p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); - //p = &(rx_data->buf[0]); - printf("Address of rx_data = %p, p = %p\n", rx_data, p); - printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); - printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); - - prev_seq_num = 0; - - while (1) { - - cnt = read(fp, rx_data, 2048); -// printf("Packet received, status = %X, len = %d\n", rx_data->status, rx_data->len); -// printf("p->seq_num = %d\n", p->seq_num); - - if (p->seq_num != prev_seq_num + 1) - printf("Sequence number fail, current = %d, previous = %d\n", - p->seq_num, prev_seq_num); - prev_seq_num = p->seq_num; - - if (calc_checksum(p) != p->checksum) - printf("Checksum fail packet = %d, expected = %d\n", - calc_checksum(p), p->checksum); - printf("."); - fflush(stdout); -// printf("\n"); - } - -} - -static void *write_thread(void *threadid) -{ - int seq_number, i, cnt, pkt_cnt; - struct usrp_transfer_frame *tx_data; - struct pkt *p; - - printf("Greetings from the write thread!\n"); - - // Allocate max length buffer for frame - tx_data = malloc(2048); - p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); - printf("Address of tx_data = %p, p = %p\n", tx_data, p); - - printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); - - for (i=0; i < 1014; i++) -// p->data[i] = random() >> 16; - p->data[i] = i; - - tx_data->status = 0xdeadbeef; - tx_data->len = 8 + packet_data_length * 2; - - printf("tx_data->len = %d\n", tx_data->len); - - seq_number = 1; - - while (1) { - pkt_cnt = randN(16); - for (i = 0; i < pkt_cnt; i++) { - p->seq_num = seq_number++; - p->len = randN(1013) + 1; - p->checksum = calc_checksum(p); - tx_data->len = 12 + p->len * 2; - cnt = write(fp, tx_data, tx_data->len + 8); - } - sleep(random() >> 31); - } -} - - -int main(int argc, char *argv[]) -{ - pthread_t tx, rx; - long int t; - - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); - - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - - sleep(1); - - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - - sleep(1000000000); - - printf("Done sleeping\n"); -} -- cgit v1.2.3 From a7f9529f77700309dbaaa6250f6bd775bab7a70d Mon Sep 17 00:00:00 2001 From: Philip Balister Date: Mon, 21 Feb 2011 08:05:54 -0800 Subject: usrp-e-utils : Delete more old files. --- host/apps/omap_debug/Makefile | 13 +- host/apps/omap_debug/clkgen-config.cc | 296 -------------------------------- host/apps/omap_debug/fpga-downloader.cc | 253 --------------------------- host/apps/omap_debug/usrp-e-timed.c | 233 ------------------------- 4 files changed, 1 insertion(+), 794 deletions(-) delete mode 100644 host/apps/omap_debug/clkgen-config.cc delete mode 100644 host/apps/omap_debug/fpga-downloader.cc delete mode 100644 host/apps/omap_debug/usrp-e-timed.c diff --git a/host/apps/omap_debug/Makefile b/host/apps/omap_debug/Makefile index dd27ba657..f8b9f2bd9 100644 --- a/host/apps/omap_debug/Makefile +++ b/host/apps/omap_debug/Makefile @@ -1,7 +1,7 @@ CFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 CXXFLAGS=-Wall -I../../lib/usrp/usrp_e/ -march=armv7-a -mtune=cortex-a8 -mfpu=neon -O3 -all : usrp-e-spi usrp-e-i2c usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx fpga-downloader usrp-e-gpio usrp-e-debug-pins usrp-e-lb-test usrp-e-crc-rw clkgen-config +all : usrp-e-spi usrp-e-i2c usrp-e-uart usrp-e-led usrp-e-ctl usrp-e-button usrp-e-uart-rx usrp-e-gpio usrp-e-debug-pins usrp-e-spi : usrp-e-spi.c @@ -17,28 +17,17 @@ usrp-e-ctl : usrp-e-ctl.c usrp-e-button : usrp-e-button.c -fpga-downloader : fpga-downloader.cc - -clkgen-config : clkgen-config.cc - usrp-e-gpio : usrp-e-gpio.c usrp-e-debug-pins : usrp-e-debug-pins.c clean : rm -f usrp-e-spi rm -f usrp-e-i2c - rm -f usrp-e-loopback - rm -f usrp-e-mm-loopback - rm -f usrp-e-timed - rm -f usrp-e-rw-random rm -f usrp-e-uart rm -f usrp-e-uart-rx rm -f usrp-e-led rm -f usrp-e-ctl rm -f usrp-e-button - rm -f fpga-downloader rm -f usrp-e-gpio rm -f usrp-e-debug-pins rm -f usrp-e-lb-test - rm -f usrp-e-crc-rw - rm -f clkgen-config diff --git a/host/apps/omap_debug/clkgen-config.cc b/host/apps/omap_debug/clkgen-config.cc deleted file mode 100644 index e8279b4ae..000000000 --- a/host/apps/omap_debug/clkgen-config.cc +++ /dev/null @@ -1,296 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,2004,2008,2009 Free Software Foundation, Inc. - * - * This file is part of UHD - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - - -// Programming data for clock gen chip -static const unsigned int config_data[] = { - 0x000024, - 0x023201, - 0x000081, - 0x000400, - 0x00104c, - 0x001101, - 0x001200, - 0x001300, - 0x001414, - 0x001500, - 0x001604, - 0x001704, - 0x001807, - 0x001900, - //0x001a00,//for debug - 0x001a32, - 0x001b12, - 0x001c44, - 0x001d00, - 0x001e00, - 0x00f062, - 0x00f162, - 0x00f262, - 0x00f362, - 0x00f462, - 0x00f562, - 0x00f662, - 0x00f762, - 0x00f862, - 0x00f962, - 0x00fa62, - 0x00fb62, - 0x00fc00, - 0x00fd00, - 0x019021, - 0x019100, - 0x019200, - 0x019333, - 0x019400, - 0x019500, - 0x019611, - 0x019700, - 0x019800, - 0x019900, - 0x019a00, - 0x019b00, - 0x01e003, - 0x01e102, - 0x023000, - 0x023201, - 0x0b0201, - 0x0b0300, - 0x001fff, - 0x0a0000, - 0x0a0100, - 0x0a0200, - 0x0a0302, - 0x0a0400, - 0x0a0504, - 0x0a060e, - 0x0a0700, - 0x0a0810, - 0x0a090e, - 0x0a0a00, - 0x0a0bf0, - 0x0a0c0b, - 0x0a0d01, - 0x0a0e90, - 0x0a0f01, - 0x0a1001, - 0x0a11e0, - 0x0a1201, - 0x0a1302, - 0x0a1430, - 0x0a1580, - 0x0a16ff, - 0x023201, - 0x0b0301, - 0x023201, -}; - - -const unsigned int CLKGEN_SELECT = 145; - - -enum gpio_direction {IN, OUT}; - -class gpio { - public: - - gpio(unsigned int gpio_num, gpio_direction pin_direction, bool close_action); - ~gpio(); - - bool get_value(); - void set_value(bool state); - - private: - - unsigned int gpio_num; - - std::stringstream base_path; - std::fstream value_file; - std::fstream direction_file; - bool close_action; // True set to input and release, false do nothing -}; - -class spidev { - public: - - spidev(std::string dev_name); - ~spidev(); - - void send(char *wbuf, char *rbuf, unsigned int nbytes); - - private: - - int fd; - -}; - -gpio::gpio(unsigned int _gpio_num, gpio_direction pin_direction, bool close_action) -{ - std::fstream export_file; - - gpio_num = _gpio_num; - - export_file.open("/sys/class/gpio/export", std::ios::out); - if (!export_file.is_open()) ///\todo Poor error handling - std::cout << "Failed to open gpio export file." << std::endl; - - export_file << gpio_num << std::endl; - - base_path << "/sys/class/gpio/gpio" << gpio_num << std::flush; - - std::string direction_file_name; - - direction_file_name = base_path.str() + "/direction"; - - direction_file.open(direction_file_name.c_str()); - if (!direction_file.is_open()) - std::cout << "Failed to open direction file." << std::endl; - if (pin_direction == OUT) - direction_file << "out" << std::endl; - else - direction_file << "in" << std::endl; - - std::string value_file_name; - - value_file_name = base_path.str() + "/value"; - - value_file.open(value_file_name.c_str(), std::ios_base::in | std::ios_base::out); - if (!value_file.is_open()) - std::cout << "Failed to open value file." << std::endl; -} - -bool gpio::get_value() -{ - - std::string val; - - std::getline(value_file, val); - value_file.seekg(0); - - if (val == "0") - return false; - else if (val == "1") - return true; - else - std::cout << "Data read from value file|" << val << "|" << std::endl; - - return false; -} - -void gpio::set_value(bool state) -{ - - if (state) - value_file << "1" << std::endl; - else - value_file << "0" << std::endl; -} - -gpio::~gpio() -{ - if (close_action) { - std::fstream unexport_file; - - direction_file << "in" << std::endl; - - unexport_file.open("/sys/class/gpio/unexport", std::ios::out); - if (!unexport_file.is_open()) ///\todo Poor error handling - std::cout << "Failed to open gpio export file." << std::endl; - - unexport_file << gpio_num << std::endl; - - } - -} - -spidev::spidev(std::string fname) -{ - int ret; - int mode = 0; - int speed = 12000; - int bits = 24; - - fd = open(fname.c_str(), O_RDWR); - - ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); - ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); - ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); -} - - -spidev::~spidev() -{ - close(fd); -} - -void spidev::send(char *buf, char *rbuf, unsigned int nbytes) -{ - int ret; - - struct spi_ioc_transfer tr; - tr.tx_buf = (unsigned long) buf; - tr.rx_buf = (unsigned long) rbuf; - tr.len = nbytes; - tr.delay_usecs = 0; - tr.speed_hz = 12000000; - tr.bits_per_word = 24; - - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); - -} - -static void send_config_to_clkgen(gpio &chip_select, const unsigned int data[], unsigned int data_size) -{ - spidev spi("/dev/spidev1.0"); - unsigned int rbuf; - - for (unsigned int i = 0; i < data_size; i++) { - - std::cout << "sending " << std::hex << data[i] << std::endl; - chip_select.set_value(0); - spi.send((char *)&data[i], (char *)&rbuf, 4); - chip_select.set_value(1); - - }; -} - -int main(int argc, char *argv[]) -{ - - gpio clkgen_select(CLKGEN_SELECT, OUT, true); - - send_config_to_clkgen(clkgen_select, config_data, sizeof(config_data)/sizeof(unsigned int)); -} - diff --git a/host/apps/omap_debug/fpga-downloader.cc b/host/apps/omap_debug/fpga-downloader.cc deleted file mode 100644 index 4e475b5c1..000000000 --- a/host/apps/omap_debug/fpga-downloader.cc +++ /dev/null @@ -1,253 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,2004,2008,2009 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. -*/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -/* - * Configuration connections - * - * CCK - MCSPI1_CLK - * DIN - MCSPI1_MOSI - * PROG_B - GPIO_175 - output (change mux) - * DONE - GPIO_173 - input (change mux) - * INIT_B - GPIO_114 - input (change mux) - * -*/ - -const unsigned int PROG_B = 175; -const unsigned int DONE = 173; -const unsigned int INIT_B = 114; - -static std::string bit_file = "safe_u1e.bin"; - -const int BUF_SIZE = 4096; - -enum gpio_direction {IN, OUT}; - -class gpio { - public: - - gpio(unsigned int gpio_num, gpio_direction pin_direction); - - bool get_value(); - void set_value(bool state); - - private: - - std::stringstream base_path; - std::fstream value_file; -}; - -class spidev { - public: - - spidev(std::string dev_name); - ~spidev(); - - void send(char *wbuf, char *rbuf, unsigned int nbytes); - - private: - - int fd; - -}; - -gpio::gpio(unsigned int gpio_num, gpio_direction pin_direction) -{ - std::fstream export_file; - - export_file.open("/sys/class/gpio/export", std::ios::out); - if (!export_file.is_open()) ///\todo Poor error handling - std::cout << "Failed to open gpio export file." << std::endl; - - export_file << gpio_num << std::endl; - - base_path << "/sys/class/gpio/gpio" << gpio_num << std::flush; - - std::fstream direction_file; - std::string direction_file_name; - - if (gpio_num != 114) { - direction_file_name = base_path.str() + "/direction"; - - direction_file.open(direction_file_name.c_str()); - if (!direction_file.is_open()) - std::cout << "Failed to open direction file." << std::endl; - if (pin_direction == OUT) - direction_file << "out" << std::endl; - else - direction_file << "in" << std::endl; - } - - std::string value_file_name; - - value_file_name = base_path.str() + "/value"; - - value_file.open(value_file_name.c_str(), std::ios_base::in | std::ios_base::out); - if (!value_file.is_open()) - std::cout << "Failed to open value file." << std::endl; -} - -bool gpio::get_value() -{ - - std::string val; - - std::getline(value_file, val); - value_file.seekg(0); - - if (val == "0") - return false; - else if (val == "1") - return true; - else - std::cout << "Data read from value file|" << val << "|" << std::endl; - - return false; -} - -void gpio::set_value(bool state) -{ - - if (state) - value_file << "1" << std::endl; - else - value_file << "0" << std::endl; -} - -static void prepare_fpga_for_configuration(gpio &prog, gpio &init) -{ - - prog.set_value(true); - prog.set_value(false); - prog.set_value(true); - -#if 0 - bool ready_to_program(false); - unsigned int count(0); - do { - ready_to_program = init.get_value(); - count++; - - sleep(1); - } while (count < 10 && !ready_to_program); - - if (count == 10) { - std::cout << "FPGA not ready for programming." << std::endl; - exit(-1); - } -#endif -} - -spidev::spidev(std::string fname) -{ - int ret; - int mode = 0; - int speed = 12000000; - int bits = 8; - - fd = open(fname.c_str(), O_RDWR); - - ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); - ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); - ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); -} - - -spidev::~spidev() -{ - close(fd); -} - -void spidev::send(char *buf, char *rbuf, unsigned int nbytes) -{ - int ret; - - struct spi_ioc_transfer tr; - tr.tx_buf = (unsigned long) buf; - tr.rx_buf = (unsigned long) rbuf; - tr.len = nbytes; - tr.delay_usecs = 0; - tr.speed_hz = 48000000; - tr.bits_per_word = 8; - - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); - -} - -static void send_file_to_fpga(std::string &file_name, gpio &error, gpio &done) -{ - std::ifstream bitstream; - - std::cout << "File name - " << file_name.c_str() << std::endl; - - bitstream.open(file_name.c_str(), std::ios::binary); - if (!bitstream.is_open()) - std::cout << "File " << file_name << " not opened succesfully." << std::endl; - - spidev spi("/dev/spidev1.0"); - char buf[BUF_SIZE]; - char rbuf[BUF_SIZE]; - - do { - bitstream.read(buf, BUF_SIZE); - spi.send(buf, rbuf, bitstream.gcount()); - - if (error.get_value()) - std::cout << "INIT_B went high, error occured." << std::endl; - - if (!done.get_value()) - std::cout << "Configuration complete." << std::endl; - - } while (bitstream.gcount() == BUF_SIZE); -} - -int main(int argc, char *argv[]) -{ - - gpio gpio_prog_b(PROG_B, OUT); - gpio gpio_init_b(INIT_B, IN); - gpio gpio_done (DONE, IN); - - if (argc == 2) - bit_file = argv[1]; - - std::cout << "FPGA config file: " << bit_file << std::endl; - - prepare_fpga_for_configuration(gpio_prog_b, gpio_init_b); - - std::cout << "Done = " << gpio_done.get_value() << std::endl; - - send_file_to_fpga(bit_file, gpio_init_b, gpio_done); -} - diff --git a/host/apps/omap_debug/usrp-e-timed.c b/host/apps/omap_debug/usrp-e-timed.c deleted file mode 100644 index 3cb33ce2d..000000000 --- a/host/apps/omap_debug/usrp-e-timed.c +++ /dev/null @@ -1,233 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "usrp_e.h" - -// max length #define PKT_DATA_LENGTH 1016 -static int packet_data_length; - -struct pkt { - int checksum; - int seq_num; - short data[]; -}; - -static int fp; - -static int calc_checksum(struct pkt *p) -{ - int i, sum; - - i = 0; - sum = 0; - - for (i=0; i < packet_data_length; i++) - sum += p->data[i]; - - sum += p->seq_num; - - return sum; -} - -static void *read_thread(void *threadid) -{ - int cnt, prev_seq_num; - struct usrp_transfer_frame *rx_data; - struct pkt *p; - int rx_pkt_cnt; - int i; - unsigned long bytes_transfered, elapsed_seconds; - struct timeval start_time, finish_time; - - printf("Greetings from the reading thread!\n"); - - bytes_transfered = 0; - gettimeofday(&start_time, NULL); - - // IMPORTANT: must assume max length packet from fpga - rx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (1016 * 2)); - p = (struct pkt *) ((void *)rx_data + offsetof(struct usrp_transfer_frame, buf)); - //p = &(rx_data->buf[0]); - printf("Address of rx_data = %p, p = %p\n", rx_data, p); - printf("offsetof = %d\n", offsetof(struct usrp_transfer_frame, buf)); - printf("sizeof rx data = %d\n", sizeof(struct usrp_transfer_frame) + sizeof(struct pkt)); - - prev_seq_num = 0; - - rx_pkt_cnt = 0; - - while (1) { - - cnt = read(fp, rx_data, 2048); - if (cnt < 0) - printf("Error returned from read: %d\n", cnt); - rx_pkt_cnt++; - -#if 0 - if (rx_pkt_cnt == 512) { - printf("."); - fflush(stdout); - rx_pkt_cnt = 0; - } -#endif - - if (rx_data->status & RB_OVERRUN) - printf("O"); - - bytes_transfered += rx_data->len; - - if (bytes_transfered > (100 * 1000000)) { - gettimeofday(&finish_time, NULL); - elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - - printf("RX data transfer rate = %f K Samples/second\n", - (float) bytes_transfered / (float) elapsed_seconds / 4000); - - - start_time = finish_time; - bytes_transfered = 0; - } - } - -} - -static void *write_thread(void *threadid) -{ - int seq_number, i, cnt, tx_pkt_cnt; - struct usrp_transfer_frame *tx_data; - struct pkt *p; - unsigned long bytes_transfered, elapsed_seconds; - struct timeval start_time, finish_time; - - printf("Greetings from the write thread!\n"); - - bytes_transfered = 0; - gettimeofday(&start_time, NULL); - - tx_data = malloc(sizeof(struct usrp_transfer_frame) + sizeof(struct pkt) + (packet_data_length * 2)); - p = (struct pkt *) ((void *)tx_data + offsetof(struct usrp_transfer_frame, buf)); - printf("Address of tx_data = %p, p = %p\n", tx_data, p); - - printf("sizeof rp_transfer_frame = %d, sizeof pkt = %d\n", sizeof(struct usrp_transfer_frame), sizeof(struct pkt)); - - for (i=0; i < packet_data_length; i++) -// p->data[i] = random() >> 16; - p->data[i] = i; - - tx_data->status = 0; - tx_data->len = 8 + packet_data_length * 2; - - printf("tx_data->len = %d\n", tx_data->len); - - seq_number = 1; - tx_pkt_cnt = 0; - - while (1) { - - tx_pkt_cnt++; - -#if 0 - if (tx_pkt_cnt == 512) { - printf("."); - fflush(stdout); - } - if (tx_pkt_cnt == 1024) { - printf("'"); - fflush(stdout); - } - if (tx_pkt_cnt == 1536) { - printf(":"); - fflush(stdout); - tx_pkt_cnt = 0; - } -#endif - -// printf("tx status = %X, len = %d\n", tx_data->status, tx_data->len); - p->seq_num = seq_number++; - p->checksum = calc_checksum(p); - cnt = write(fp, tx_data, 2048); - if (cnt < 0) - printf("Error returned from write: %d\n", cnt); - - bytes_transfered += tx_data->len; - - if (bytes_transfered > (100 * 1000000)) { - gettimeofday(&finish_time, NULL); - elapsed_seconds = finish_time.tv_sec - start_time.tv_sec; - - printf("TX data transfer rate = %f K Samples/second\n", - (float) bytes_transfered / (float) elapsed_seconds / 4000); - - - start_time = finish_time; - bytes_transfered = 0; - } -// sleep(1); - } -} - - -int main(int argc, char *argv[]) -{ - pthread_t tx, rx; - long int t; - int fpga_config_flag ,decimation; - struct usrp_e_ctl16 d; - struct sched_param s = { - .sched_priority = 1 - }; - - if (argc < 4) { - printf("%s r|w|rw decimation data_size\n", argv[0]); - return -1; - } - - decimation = atoi(argv[2]); - packet_data_length = atoi(argv[3]); - - fp = open("/dev/usrp_e0", O_RDWR); - printf("fp = %d\n", fp); - - fpga_config_flag = 0; - if (strcmp(argv[1], "w") == 0) - fpga_config_flag |= (1 << 15); - else if (strcmp(argv[1], "r") == 0) - fpga_config_flag |= (1 << 14); - else if (strcmp(argv[1], "rw") == 0) - fpga_config_flag |= ((1 << 15) | (1 << 14)); - - fpga_config_flag |= decimation; - - d.offset = 14; - d.count = 1; - d.buf[0] = fpga_config_flag; - ioctl(fp, USRP_E_WRITE_CTL16, &d); - - sleep(1); // in case the kernel threads need time to start. FIXME if so - - sched_setscheduler(0, SCHED_RR, &s); - - if (fpga_config_flag & (1 << 14)) { - if (pthread_create(&rx, NULL, read_thread, (void *) t)) { - printf("Failed to create rx thread\n"); - exit(-1); - } - } - - sleep(1); - - if (fpga_config_flag & (1 << 15)) { - if (pthread_create(&tx, NULL, write_thread, (void *) t)) { - printf("Failed to create tx thread\n"); - exit(-1); - } - } - - sleep(10000); - - printf("Done sleeping\n"); -} -- cgit v1.2.3 From a8bb5ec900d8f2d3d2f274a921d19b564c668323 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 21 Feb 2011 19:03:13 -0800 Subject: uhd: replace header checks in cmake files with more robust compile checks for features implemented different ifdefs in the cpp files --- host/include/uhd/transport/if_addrs.hpp | 1 - host/lib/transport/CMakeLists.txt | 25 +++++++++++++------ host/lib/transport/if_addrs.cpp | 16 ++++++------ host/lib/utils/CMakeLists.txt | 43 ++++++++++++++++++++++++--------- host/lib/utils/load_modules.cpp | 14 +++++------ host/lib/utils/thread_priority.cpp | 10 +++++--- 6 files changed, 70 insertions(+), 39 deletions(-) diff --git a/host/include/uhd/transport/if_addrs.hpp b/host/include/uhd/transport/if_addrs.hpp index c831750d7..689aff42c 100644 --- a/host/include/uhd/transport/if_addrs.hpp +++ b/host/include/uhd/transport/if_addrs.hpp @@ -31,7 +31,6 @@ namespace uhd{ namespace transport{ std::string inet; std::string mask; std::string bcast; - if_addrs_t(void); }; /*! diff --git a/host/lib/transport/CMakeLists.txt b/host/lib/transport/CMakeLists.txt index e58957154..a5bf9c5f1 100644 --- a/host/lib/transport/CMakeLists.txt +++ b/host/lib/transport/CMakeLists.txt @@ -48,20 +48,31 @@ ENDIF(ENABLE_USB) ######################################################################## MESSAGE(STATUS "") MESSAGE(STATUS "Configuring interface address discovery...") - +INCLUDE(CheckCXXSourceCompiles) INCLUDE(CheckIncludeFileCXX) -CHECK_INCLUDE_FILE_CXX(ifaddrs.h HAVE_IFADDRS_H) + +CHECK_CXX_SOURCE_COMPILES(" + #include + int main(){ + struct ifaddrs *ifap; + getifaddrs(&ifap); + return 0; + } + " HAVE_GETIFADDRS +) + CHECK_INCLUDE_FILE_CXX(winsock2.h HAVE_WINSOCK2_H) -IF(HAVE_IFADDRS_H) +IF(HAVE_GETIFADDRS) MESSAGE(STATUS " Interface address discovery supported through getifaddrs.") - SET(IF_ADDRS_DEFS HAVE_IFADDRS_H) + SET(IF_ADDRS_DEFS HAVE_GETIFADDRS) ELSEIF(HAVE_WINSOCK2_H) MESSAGE(STATUS " Interface address discovery supported through SIO_GET_INTERFACE_LIST.") - SET(IF_ADDRS_DEFS HAVE_WINSOCK2_H) -ELSE(HAVE_IFADDRS_H) + SET(IF_ADDRS_DEFS HAVE_SIO_GET_INTERFACE_LIST) +ELSE() MESSAGE(STATUS " Interface address discovery not supported.") -ENDIF(HAVE_IFADDRS_H) + SET(IF_ADDRS_DEFS HAVE_IF_ADDRS_DUMMY) +ENDIF() SET_SOURCE_FILES_PROPERTIES( ${CMAKE_CURRENT_SOURCE_DIR}/if_addrs.cpp diff --git a/host/lib/transport/if_addrs.cpp b/host/lib/transport/if_addrs.cpp index 17cf8455b..b7c8ad844 100644 --- a/host/lib/transport/if_addrs.cpp +++ b/host/lib/transport/if_addrs.cpp @@ -20,14 +20,10 @@ #include #include -uhd::transport::if_addrs_t::if_addrs_t(void){ - /* NOP */ -} - /*********************************************************************** * Interface address discovery through ifaddrs api **********************************************************************/ -#if defined(HAVE_IFADDRS_H) +#ifdef HAVE_GETIFADDRS #include static boost::asio::ip::address_v4 sockaddr_to_ip_addr(sockaddr *addr){ @@ -59,10 +55,12 @@ std::vector uhd::transport::get_if_addrs(void){ return if_addrs; } +#endif /* HAVE_GETIFADDRS */ + /*********************************************************************** * Interface address discovery through windows api **********************************************************************/ -#elif defined(HAVE_WINSOCK2_H) +#ifdef HAVE_SIO_GET_INTERFACE_LIST #include std::vector uhd::transport::get_if_addrs(void){ @@ -98,13 +96,15 @@ std::vector uhd::transport::get_if_addrs(void){ return if_addrs; } +#endif /* HAVE_SIO_GET_INTERFACE_LIST */ + /*********************************************************************** * Interface address discovery not included **********************************************************************/ -#else /* HAVE_IFADDRS_H */ +#ifdef HAVE_IF_ADDRS_DUMMY std::vector uhd::transport::get_if_addrs(void){ return std::vector(); } -#endif /* HAVE_IFADDRS_H */ +#endif /* HAVE_IF_ADDRS_DUMMY */ diff --git a/host/lib/utils/CMakeLists.txt b/host/lib/utils/CMakeLists.txt index 743528189..a4d3b2db2 100644 --- a/host/lib/utils/CMakeLists.txt +++ b/host/lib/utils/CMakeLists.txt @@ -24,8 +24,8 @@ ######################################################################## MESSAGE(STATUS "") MESSAGE(STATUS "Configuring priority scheduling...") - INCLUDE(CheckCXXSourceCompiles) + CHECK_CXX_SOURCE_COMPILES(" #include int main(){ @@ -52,9 +52,10 @@ IF(HAVE_PTHREAD_SETSCHEDPARAM) ELSEIF(HAVE_WIN_SETTHREADPRIORITY) MESSAGE(STATUS " Priority scheduling supported through windows SetThreadPriority.") SET(THREAD_PRIO_DEFS HAVE_WIN_SETTHREADPRIORITY) -ELSE(HAVE_PTHREAD_SETSCHEDPARAM) +ELSE() MESSAGE(STATUS " Priority scheduling not supported.") -ENDIF(HAVE_PTHREAD_SETSCHEDPARAM) + SET(THREAD_PRIO_DEFS HAVE_THREAD_PRIO_DUMMY) +ENDIF() SET_SOURCE_FILES_PROPERTIES( ${CMAKE_CURRENT_SOURCE_DIR}/thread_priority.cpp @@ -66,21 +67,39 @@ SET_SOURCE_FILES_PROPERTIES( ######################################################################## MESSAGE(STATUS "") MESSAGE(STATUS "Configuring module loading...") +INCLUDE(CheckCXXSourceCompiles) -INCLUDE(CheckIncludeFileCXX) -CHECK_INCLUDE_FILE_CXX(dlfcn.h HAVE_DLFCN_H) -CHECK_INCLUDE_FILE_CXX(windows.h HAVE_WINDOWS_H) +SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS}) +CHECK_CXX_SOURCE_COMPILES(" + #include + int main(){ + dlopen(0, 0); + return 0; + } + " HAVE_DLOPEN +) +UNSET(CMAKE_REQUIRED_LIBRARIES) + +CHECK_CXX_SOURCE_COMPILES(" + #include + int main(){ + LoadLibrary(0); + return 0; + } + " HAVE_LOAD_LIBRARY +) -IF(HAVE_DLFCN_H) +IF(HAVE_DLOPEN) MESSAGE(STATUS " Module loading supported through dlopen.") - SET(LOAD_MODULES_DEFS HAVE_DLFCN_H) + SET(LOAD_MODULES_DEFS HAVE_DLOPEN) LIBUHD_APPEND_LIBS(${CMAKE_DL_LIBS}) -ELSEIF(HAVE_WINDOWS_H) +ELSEIF(HAVE_LOAD_LIBRARY) MESSAGE(STATUS " Module loading supported through LoadLibrary.") - SET(LOAD_MODULES_DEFS HAVE_WINDOWS_H) -ELSE(HAVE_DLFCN_H) + SET(LOAD_MODULES_DEFS HAVE_LOAD_LIBRARY) +ELSE() MESSAGE(STATUS " Module loading not supported.") -ENDIF(HAVE_DLFCN_H) + SET(LOAD_MODULES_DEFS HAVE_LOAD_MODULES_DUMMY) +ENDIF() SET_SOURCE_FILES_PROPERTIES( ${CMAKE_CURRENT_SOURCE_DIR}/load_modules.cpp diff --git a/host/lib/utils/load_modules.cpp b/host/lib/utils/load_modules.cpp index 623d31eb6..fa9b22438 100644 --- a/host/lib/utils/load_modules.cpp +++ b/host/lib/utils/load_modules.cpp @@ -29,9 +29,8 @@ namespace fs = boost::filesystem; /*********************************************************************** * Module Load Function **********************************************************************/ -#if defined(HAVE_DLFCN_H) +#ifdef HAVE_DLOPEN #include - static void load_module(const std::string &file_name){ if (dlopen(file_name.c_str(), RTLD_LAZY) == NULL){ throw std::runtime_error(str( @@ -39,10 +38,11 @@ static void load_module(const std::string &file_name){ )); } } +#endif /* HAVE_DLOPEN */ -#elif defined(HAVE_WINDOWS_H) -#include +#ifdef HAVE_LOAD_LIBRARY +#include static void load_module(const std::string &file_name){ if (LoadLibrary(file_name.c_str()) == NULL){ throw std::runtime_error(str( @@ -50,16 +50,16 @@ static void load_module(const std::string &file_name){ )); } } +#endif /* HAVE_LOAD_LIBRARY */ -#else +#ifdef HAVE_LOAD_MODULES_DUMMY static void load_module(const std::string &file_name){ throw std::runtime_error(str( boost::format("Module loading not supported: Cannot load \"%s\"") % file_name )); } - -#endif +#endif /* HAVE_LOAD_MODULES_DUMMY */ /*********************************************************************** * Load Modules diff --git a/host/lib/utils/thread_priority.cpp b/host/lib/utils/thread_priority.cpp index 40b74f655..18f372ec0 100644 --- a/host/lib/utils/thread_priority.cpp +++ b/host/lib/utils/thread_priority.cpp @@ -44,7 +44,7 @@ static void check_priority_range(float priority){ /*********************************************************************** * Pthread API to set priority **********************************************************************/ -#if defined(HAVE_PTHREAD_SETSCHEDPARAM) +#ifdef HAVE_PTHREAD_SETSCHEDPARAM #include void uhd::set_thread_priority(float priority, bool realtime){ @@ -67,11 +67,12 @@ static void check_priority_range(float priority){ int ret = pthread_setschedparam(pthread_self(), policy, &sp); if (ret != 0) throw std::runtime_error("error in pthread_setschedparam"); } +#endif /* HAVE_PTHREAD_SETSCHEDPARAM */ /*********************************************************************** * Windows API to set priority **********************************************************************/ -#elif defined(HAVE_WIN_SETTHREADPRIORITY) +#ifdef HAVE_WIN_SETTHREADPRIORITY #include void uhd::set_thread_priority(float priority, bool realtime){ @@ -93,13 +94,14 @@ static void check_priority_range(float priority){ if (SetThreadPriority(GetCurrentThread(), priorities[pri_index]) == 0) throw std::runtime_error("error in SetThreadPriority"); } +#endif /* HAVE_WIN_SETTHREADPRIORITY */ /*********************************************************************** * Unimplemented API to set priority **********************************************************************/ -#else +#ifdef HAVE_LOAD_MODULES_DUMMY void uhd::set_thread_priority(float, bool){ throw std::runtime_error("set thread priority not implemented"); } -#endif /* HAVE_PTHREAD_SETSCHEDPARAM */ +#endif /* HAVE_LOAD_MODULES_DUMMY */ -- cgit v1.2.3 From 9eb19bd9a006c47060b9d0913d2f9d4a49751275 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Mon, 21 Feb 2011 22:29:49 -0800 Subject: usrp2: cleanup clocks firmware stuff, removed unused code --- firmware/zpu/lib/clock_bits.h | 55 ------------- firmware/zpu/lib/clocks.c | 174 ++++-------------------------------------- firmware/zpu/lib/clocks.h | 71 +---------------- 3 files changed, 16 insertions(+), 284 deletions(-) delete mode 100644 firmware/zpu/lib/clock_bits.h diff --git a/firmware/zpu/lib/clock_bits.h b/firmware/zpu/lib/clock_bits.h deleted file mode 100644 index d2052e941..000000000 --- a/firmware/zpu/lib/clock_bits.h +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright 2010 Ettus Research LLC -// -/* - * Copyright 2008 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifndef INCLUDED_USRP2_CLOCK_BITS_H -#define INCLUDED_USRP2_CLOCK_BITS_H - -#define _MC_WE_LOCK 0x0001 -#define _MC_MIMO_CLK_INPUT 0x0002 // else SMA input - -/* - * Derived masks (use these): - * - * We get our input from 1 of three places: - * Our free running oscilator, our SMA connector, or from the MIMO connector - */ -#define MC_WE_DONT_LOCK 0x0000 -#define MC_WE_LOCK_TO_SMA (_MC_WE_LOCK | 0) -#define MC_WE_LOCK_TO_MIMO (_MC_WE_LOCK | _MC_MIMO_CLK_INPUT) - -/* - * Independent of the source of the clock, we may or may not drive our - * clock onto the mimo connector. Note that there are dedicated clock - * signals in each direction, so disaster doesn't occurs if we're - * unnecessarily providing clock. - */ -#define MC_PROVIDE_CLK_TO_MIMO 0x0004 - -#define MC_REF_CLK_MASK 0x0f - -#define MC_PPS_SOURCE_SMA (0x00 << 4) -#define MC_PPS_SOURCE_MIMO (0x01 << 4) - -#define MC_PPS_POLARITY_NEG (0x00 << 5) -#define MC_PPS_POLARITY_POS (0x01 << 5) - -#endif /* INCLUDED_USRP2_CLOCK_BITS_H */ diff --git a/firmware/zpu/lib/clocks.c b/firmware/zpu/lib/clocks.c index 2b352a385..c1e8ce827 100644 --- a/firmware/zpu/lib/clocks.c +++ b/firmware/zpu/lib/clocks.c @@ -1,4 +1,6 @@ -/* -*- c++ -*- */ +// +// Copyright 2010-2011 Ettus Research LLC +// /* * Copyright 2008 Free Software Foundation, Inc. * @@ -16,119 +18,39 @@ * along with this program. If not, see . */ -#ifdef HAVE_CONFIG_H -#include -#endif #include - +#include #include "memory_map.h" #include "ad9510.h" #include "spi.h" -#include "u2_init.h" -//USRP2PLUS clocks: -//Clock 0: testclk -//Clock 1: FPGA clk -//Clock 2: ADC clk -//Clock 3: DAC clk -//Clock 4: SER clk -//Clock 5: TX dboard clk -//Clock 6: EXP clk -//Clock 7: RX dboard clk +/*! + * \brief Lock Detect -- Return True if our PLL is locked + */ +bool clocks_lock_detect(); -//TODO: should have enough brains to init the FPGA clock for USRP2+. all others are suspect. -//note that without EEPROM support u2_hw_rev_major is going to be incorrect. +/*! + * \brief Enable or disable fpga clock. Disabling would wedge and require a power cycle. + */ +void clocks_enable_fpga_clk(bool enable, int divisor); void clocks_init(void) { // Set up basic clocking functions in AD9510 - ad9510_write_reg(0x45, 0x01); // CLK2 drives distribution + ad9510_write_reg(0x45, 0x01); //enable the 100MHz clock output to the FPGA for 50MHz CPU clock clocks_enable_fpga_clk(true, 1); spi_wait(); - // Set up PLL for 10 MHz reference - // Reg 4, A counter, Don't Care -// ad9510_write_reg(0x05, 0x00); // Reg 5, B counter MSBs, 0 -// ad9510_write_reg(0x06, 0x05); // Reg 6, B counter LSBs, 5 - // Reg 7, Loss of reference detect, doesn't work yet, 0 -// ad9510_write_reg(0x5A, 0x01); // Update Regs - - // Primary clock configuration -// clocks_mimo_config(MC_WE_DONT_LOCK); - - //wait for the clock to stabilize while(!clocks_lock_detect()); //issue a reset to the DCM so it locks up to the new freq output_regs->clk_ctrl |= CLK_RESET; - - // Set up other clocks - //clocks_enable_test_clk(false, 0); - //clocks_enable_tx_dboard(false, 0); - //clocks_enable_rx_dboard(false, 0); -// clocks_enable_eth_phyclk(false, 0); //PHY clk is separate now (u2r4, u2p) - - // Enable clock to ADCs and DACs - //clocks_enable_dac_clk(true, 1); - //clocks_enable_adc_clk(true, 1); -} - -/* -void -clocks_mimo_config(int flags) -{ - if (flags & _MC_WE_LOCK){ - // Reg 8, Charge pump on, dig lock det, positive PFD, 47 - ad9510_write_reg(0x08, 0x47); - } - else { - // Reg 8, Charge pump off, dig lock det, positive PFD - ad9510_write_reg(0x08, 0x00); - } - - // Reg 9, Charge pump current, 0x40=3mA, 0x00=650uA - ad9510_write_reg(0x09, 0x00); - // Reg A, Prescaler of 2, everything normal 04 - ad9510_write_reg(0x0A, 0x04); - // Reg B, R Div MSBs, 0 - ad9510_write_reg(0x0B, 0x00); - // Reg C, R Div LSBs, 1 - ad9510_write_reg(0x0C, 0x01); - // Reg D, Antibacklash, Digital lock det, 0 - - ad9510_write_reg(0x5A, 0x01); // Update Regs - - spi_wait(); - - // Allow for clock switchover - // The below masks include 0x10, which issues a reset to the DCM. - if (flags & _MC_WE_LOCK){ // WE LOCK - if (flags & _MC_MIMO_CLK_INPUT) { - // Turn on ref output and choose the MIMO connector - output_regs->clk_ctrl = 0x15; - } - else { - // turn on ref output and choose the SMA - output_regs->clk_ctrl = 0x1C; - } - } - else { // WE DONT LOCK - // Disable both ext clk inputs - output_regs->clk_ctrl = 0x10; - } - - // Do we drive a clock onto the MIMO connector? -// if (flags & MC_PROVIDE_CLK_TO_MIMO) -// clocks_enable_clkexp_out(true,10); -// else -// clocks_enable_clkexp_out(false,0); } -*/ bool clocks_lock_detect() @@ -188,79 +110,9 @@ clocks_enable_XXX_clk(bool enable, int divisor, int reg_en, int reg_div, int mod ad9510_write_reg(0x5A, 0x01); // Update Regs } -// Clock 0 -/*void -clocks_enable_test_clk(bool enable, int divisor) -{ - clocks_enable_XXX_clk(enable,divisor,0x3C,0x48,CLOCK_MODE_PECL); -}*/ - // Clock 1 void clocks_enable_fpga_clk(bool enable, int divisor) { clocks_enable_XXX_clk(enable,divisor,0x3D,0x4A,CLOCK_MODE_PECL); } -/* -// Clock 2 on Rev 3, Clock 5 on Rev 4, Clock 6 on USRP2+ -void -clocks_enable_clkexp_out(bool enable, int divisor) -{ - if(u2_hw_rev_major == 3) - clocks_enable_XXX_clk(enable,divisor,0x3E,0x4C,CLOCK_MODE_PECL); - else if(u2_hw_rev_major == 4) { - ad9510_write_reg(0x34,0x00); // Turn on fine delay - ad9510_write_reg(0x35,0x00); // Set Full Scale to nearly 10ns - ad9510_write_reg(0x36,0x1c); // Set fine delay. 0x20 is midscale - clocks_enable_XXX_clk(enable,divisor,0x41,0x52,CLOCK_MODE_LVDS); - } - else if(u2_hw_rev_major == 10) { - ad9510_write_reg(0x34, 0x00); - ad9510_write_reg(0x35, 0x00); - ad9510_write_reg(0x36, 0x1C); - clocks_enable_XXX_clk(enable, divisor, 0x42, 0x52, CLOCK_MODE_LVDS); - } - else - putstr("ERR (clocks_enable_clkexp_out): Invalid hw rev, don't know what to do!\n"); -} -*/ -/* -// Clock 5 on Rev 3, none (was 2) on Rev 4, none on USRP2+ -void -clocks_enable_eth_phyclk(bool enable, int divisor) -{ - if(u2_hw_rev_major == 3) - clocks_enable_XXX_clk(enable,divisor,0x41,0x52,CLOCK_MODE_LVDS); - else if(u2_hw_rev_major == 4) - clocks_enable_XXX_clk(enable,divisor,0x3E,0x4C,CLOCK_MODE_PECL); - else - putstr("(clocks_enable_eth_phyclk): no eth PHY clock or invalid hw rev\n"); //not really an error -} -*/ -// Clock 3 -/*void -clocks_enable_dac_clk(bool enable, int divisor) -{ - clocks_enable_XXX_clk(enable,divisor,0x3F,0x4E,CLOCK_MODE_PECL); -}*/ - -// Clock 4 -/*void -clocks_enable_adc_clk(bool enable, int divisor) -{ - clocks_enable_XXX_clk(enable,divisor,0x40,0x50,CLOCK_MODE_LVDS); -}*/ - -// Clock 6 -/*void -clocks_enable_tx_dboard(bool enable, int divisor) -{ - clocks_enable_XXX_clk(enable,divisor,0x42,0x54,CLOCK_MODE_CMOS); -}*/ - -// Clock 7 -/*void -clocks_enable_rx_dboard(bool enable, int divisor) -{ - clocks_enable_XXX_clk(enable,divisor,0x43,0x56,CLOCK_MODE_CMOS); -}*/ diff --git a/firmware/zpu/lib/clocks.h b/firmware/zpu/lib/clocks.h index 28d1d542f..7bc7a3cda 100644 --- a/firmware/zpu/lib/clocks.h +++ b/firmware/zpu/lib/clocks.h @@ -1,5 +1,5 @@ // -// Copyright 2010 Ettus Research LLC +// Copyright 2010-2011 Ettus Research LLC // /* * Copyright 2008 Free Software Foundation, Inc. @@ -21,75 +21,10 @@ #ifndef INCLUDED_CLOCKS_H #define INCLUDED_CLOCKS_H -/* - * Routines to configure our multitude of clocks - */ - -#include -#include "clock_bits.h" - - /*! - * One time call to initialize all clocks to a reasonable state. We - * come out of here using our free running 100MHz oscilator and not - * providing a clock to the MIMO connector (CMC_WE_DONT_LOCK) + * One time call to initialize the master clock to a reasonable state. + * We come out of here using our free running 100MHz oscillator. */ void clocks_init(void); - -/*! - * \brief MIMO clock configuration. - * - * Configure our master clock source, and whether or not we drive a - * clock onto the mimo connector. See MC_flags in usrp2_mimo_config.h. - */ -//void clocks_mimo_config(int flags); - -/*! - * \brief Lock Detect -- Return True if our PLL is locked - */ -bool clocks_lock_detect(); - -/*! - * \brief Enable or disable test clock (extra clock signal) - */ -//void clocks_enable_test_clk(bool enable, int divisor); - -/*! - * \brief Enable or disable fpga clock. Disabling would wedge and require a power cycle. - */ -void clocks_enable_fpga_clk(bool enable, int divisor); - -/*! - * \brief Enable or disable clock output sent to MIMO connector - */ -//void clocks_enable_clkexp_out(bool enable, int divisor); - -/*! - * \brief Enable or disable ethernet phyclk, should always be disabled - */ -//void clocks_enable_eth_phyclk(bool enable, int divisor); - -/*! - * \brief Enable or disable clock to DAC - */ -//void clocks_enable_dac_clk(bool enable, int divisor); - -/*! - * \brief Enable or disable clock to ADC - */ -//void clocks_enable_adc_clk(bool enable, int divisor); - -/*! - * \brief Enable or disable clock to Rx daughterboard - */ -//void clocks_enable_rx_dboard(bool enable, int divisor); - - -/*! - * \brief Enable or disable clock to Tx daughterboard - */ -//void clocks_enable_tx_dboard(bool enable, int divisor); - - #endif /* INCLUDED_CLOCKS_H */ -- cgit v1.2.3