summaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
authorJosh Blum <josh@joshknows.com>2010-04-28 11:10:50 -0700
committerJosh Blum <josh@joshknows.com>2010-04-28 11:10:50 -0700
commitcbd9e1da0866893d86320787a99cf4257478c539 (patch)
tree0b2515cd96d9c341795b91efed25df0616ea821c /host/include
parentf5b6776a0b642c0357fbecdead9d2b1ac6ece3d3 (diff)
parent8497eb2ac016f72e2b9a9028e5126bc73f5b0c9a (diff)
downloaduhd-cbd9e1da0866893d86320787a99cf4257478c539.tar.gz
uhd-cbd9e1da0866893d86320787a99cf4257478c539.tar.bz2
uhd-cbd9e1da0866893d86320787a99cf4257478c539.zip
Merge branch 'master' of git@ettus.sourcerepo.com:ettus/uhdpriv into usrp_e
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/types/CMakeLists.txt1
-rw-r--r--host/include/uhd/types/device_addr.hpp20
-rw-r--r--host/include/uhd/types/io_type.hpp1
-rw-r--r--host/include/uhd/types/metadata.hpp10
-rw-r--r--host/include/uhd/types/serial.hpp122
-rw-r--r--host/include/uhd/types/time_spec.hpp23
-rw-r--r--host/include/uhd/usrp/CMakeLists.txt1
-rw-r--r--host/include/uhd/usrp/dboard_eeprom.hpp60
-rw-r--r--host/include/uhd/usrp/dboard_iface.hpp40
-rw-r--r--host/include/uhd/usrp/dboard_manager.hpp1
-rw-r--r--host/include/uhd/usrp/dboard_props.hpp3
-rw-r--r--host/include/uhd/usrp/simple_usrp.hpp58
-rw-r--r--host/include/uhd/usrp/subdev_props.hpp8
-rw-r--r--host/include/uhd/utils/assert.hpp33
-rw-r--r--host/include/uhd/utils/props.hpp54
-rw-r--r--host/include/uhd/utils/safe_main.hpp3
16 files changed, 355 insertions, 83 deletions
diff --git a/host/include/uhd/types/CMakeLists.txt b/host/include/uhd/types/CMakeLists.txt
index e4cdf2cef..dbce21c98 100644
--- a/host/include/uhd/types/CMakeLists.txt
+++ b/host/include/uhd/types/CMakeLists.txt
@@ -25,6 +25,7 @@ INSTALL(FILES
metadata.hpp
otw_type.hpp
ranges.hpp
+ serial.hpp
stream_cmd.hpp
time_spec.hpp
tune_result.hpp
diff --git a/host/include/uhd/types/device_addr.hpp b/host/include/uhd/types/device_addr.hpp
index f5dd9371c..e8da2a1ab 100644
--- a/host/include/uhd/types/device_addr.hpp
+++ b/host/include/uhd/types/device_addr.hpp
@@ -32,13 +32,23 @@ namespace uhd{
*
* To narrow down the discovery process to a particular device,
* specify a transport key/value pair specific to your device.
- * Ex, to find a usrp2: my_dev_addr["addr"] = [resolvable_hostname_or_ip]
+ * - Ex, to find a usrp2: my_dev_addr["addr"] = [resolvable_hostname_or_ip]
*
* The device address can also be used to pass arguments into
* the transport layer control to set (for example) buffer sizes.
+ *
+ * An arguments string, is a way to represent a device address
+ * using a single string with delimiter characters.
+ * - Ex: addr=192.168.10.2
+ * - Ex: addr=192.168.10.2, rx_buff_size=1e6
*/
class UHD_API device_addr_t : public dict<std::string, std::string>{
public:
+ /*!
+ * Create a device address from an args string.
+ * \param args the arguments string
+ */
+ device_addr_t(const std::string &args = "");
/*!
* Convert a device address into a printable string.
@@ -52,14 +62,6 @@ namespace uhd{
* \return a string with delimiter markup
*/
std::string to_args_str(void) const;
-
- /*!
- * Make a device address from an args string.
- * The args string contains delimiter symbols.
- * \param args_str the arguments string
- * \return the new device address
- */
- static device_addr_t from_args_str(const std::string &args_str);
};
//handy typedef for a vector of device addresses
diff --git a/host/include/uhd/types/io_type.hpp b/host/include/uhd/types/io_type.hpp
index 930394d1b..5176374d6 100644
--- a/host/include/uhd/types/io_type.hpp
+++ b/host/include/uhd/types/io_type.hpp
@@ -23,6 +23,7 @@
namespace uhd{
/*!
+ * The Input/Output configuration struct:
* Used to specify the IO type with device send/recv.
*/
class UHD_API io_type_t{
diff --git a/host/include/uhd/types/metadata.hpp b/host/include/uhd/types/metadata.hpp
index d93b38b50..55add71cc 100644
--- a/host/include/uhd/types/metadata.hpp
+++ b/host/include/uhd/types/metadata.hpp
@@ -70,7 +70,10 @@ namespace uhd{
* Timed-out on receive?
*/
- //default constructor
+ /*!
+ * The default constructor:
+ * Sets the fields to default values (flags set to false).
+ */
rx_metadata_t(void);
};
@@ -103,7 +106,10 @@ namespace uhd{
bool start_of_burst;
bool end_of_burst;
- //default constructor
+ /*!
+ * The default constructor:
+ * Sets the fields to default values (flags set to false).
+ */
tx_metadata_t(void);
};
diff --git a/host/include/uhd/types/serial.hpp b/host/include/uhd/types/serial.hpp
new file mode 100644
index 000000000..c134725f5
--- /dev/null
+++ b/host/include/uhd/types/serial.hpp
@@ -0,0 +1,122 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_TYPES_SERIAL_HPP
+#define INCLUDED_UHD_TYPES_SERIAL_HPP
+
+#include <uhd/config.hpp>
+#include <boost/cstdint.hpp>
+#include <vector>
+
+namespace uhd{
+
+ /*!
+ * Byte vector typedef for passing data in and out of I2C interfaces.
+ */
+ typedef std::vector<boost::uint8_t> byte_vector_t;
+
+ /*!
+ * The i2c interface class:
+ * Provides i2c and eeprom functionality.
+ * A subclass should only have to implement the i2c routines.
+ * An eeprom implementation comes for free with the interface.
+ *
+ * The eeprom routines are implemented on top of i2c.
+ * The built in eeprom implementation only does single
+ * byte reads and byte writes over the i2c interface,
+ * so it should be portable across multiple eeproms.
+ * Override the eeprom routines if this is not acceptable.
+ */
+ class UHD_API i2c_iface{
+ public:
+ /*!
+ * Write bytes over the i2c.
+ * \param addr the address
+ * \param buf the vector of bytes
+ */
+ virtual void write_i2c(
+ boost::uint8_t addr,
+ const byte_vector_t &buf
+ ) = 0;
+
+ /*!
+ * Read bytes over the i2c.
+ * \param addr the address
+ * \param num_bytes number of bytes to read
+ * \return a vector of bytes
+ */
+ virtual byte_vector_t read_i2c(
+ boost::uint8_t addr,
+ size_t num_bytes
+ ) = 0;
+
+ /*!
+ * Write bytes to an eeprom.
+ * \param addr the address
+ * \param offset byte offset
+ * \param buf the vector of bytes
+ */
+ virtual void write_eeprom(
+ boost::uint8_t addr,
+ boost::uint8_t offset,
+ const byte_vector_t &buf
+ );
+
+ /*!
+ * Read bytes from an eeprom.
+ * \param addr the address
+ * \param offset byte offset
+ * \param num_bytes number of bytes to read
+ * \return a vector of bytes
+ */
+ virtual byte_vector_t read_eeprom(
+ boost::uint8_t addr,
+ boost::uint8_t offset,
+ size_t num_bytes
+ );
+ };
+
+ /*!
+ * The SPI configuration struct:
+ * Used to configure a SPI transaction interface.
+ */
+ struct UHD_API spi_config_t{
+ /*!
+ * The edge type specifies when data is valid
+ * relative to the edge of the serial clock.
+ */
+ enum edge_t{
+ EDGE_RISE = 'r',
+ EDGE_FALL = 'f'
+ };
+
+ //! on what edge is the mosi data valid?
+ edge_t mosi_edge;
+
+ //! on what edge is the miso data valid?
+ edge_t miso_edge;
+
+ /*!
+ * Create a new spi config.
+ * \param edge the default edge for mosi and miso
+ */
+ spi_config_t(edge_t edge = EDGE_RISE);
+ };
+
+} //namespace uhd
+
+#endif /* INCLUDED_UHD_TYPES_SERIAL_HPP */
diff --git a/host/include/uhd/types/time_spec.hpp b/host/include/uhd/types/time_spec.hpp
index f06d27118..25d9e41d0 100644
--- a/host/include/uhd/types/time_spec.hpp
+++ b/host/include/uhd/types/time_spec.hpp
@@ -28,10 +28,19 @@ namespace uhd{
* The time_spec_t can be used when setting the time on devices,
* and for dealing with time stamped samples though the metadata.
* and for controlling the start of streaming for applicable dsps.
+ *
+ * The fractional seconds are represented in units of nanoseconds,
+ * which provide a clock-domain independent unit of time storage.
+ * The methods "get_ticks" and "set_ticks" can be used to convert
+ * the fractional seconds to and from clock-domain specific units.
+ *
+ * The nanoseconds count is stored as double precision floating point.
+ * This gives the fractional seconds enough precision to unambiguously
+ * specify a clock-tick/sample-count up to rates of several petahertz.
*/
struct UHD_API time_spec_t{
- //! whole seconds count
+ //! whole/integer seconds count in seconds
boost::uint32_t secs;
//! fractional seconds count in nano-seconds
@@ -39,24 +48,26 @@ namespace uhd{
/*!
* Convert the fractional nsecs to clock ticks.
+ * Translation into clock-domain specific units.
* \param tick_rate the number of ticks per second
- * \return the number of ticks in this time spec
+ * \return the fractional seconds tick count
*/
boost::uint32_t get_ticks(double tick_rate) const;
/*!
* Set the fractional nsecs from clock ticks.
+ * Translation from clock-domain specific units.
* \param ticks the fractional seconds tick count
* \param tick_rate the number of ticks per second
*/
void set_ticks(boost::uint32_t ticks, double tick_rate);
/*!
- * Create a time_spec_t from seconds and ticks.
- * \param new_secs the new seconds (default = 0)
- * \param new_nsecs the new nano-seconds (default = 0)
+ * Create a time_spec_t from whole and fractional seconds.
+ * \param secs the whole/integer seconds count in seconds (default = 0)
+ * \param nsecs the fractional seconds count in nanoseconds (default = 0)
*/
- time_spec_t(boost::uint32_t new_secs = 0, double new_nsecs = 0);
+ time_spec_t(boost::uint32_t secs = 0, double nsecs = 0);
};
diff --git a/host/include/uhd/usrp/CMakeLists.txt b/host/include/uhd/usrp/CMakeLists.txt
index 4b880308e..ff2636d8c 100644
--- a/host/include/uhd/usrp/CMakeLists.txt
+++ b/host/include/uhd/usrp/CMakeLists.txt
@@ -26,6 +26,7 @@ INSTALL(FILES
#### dboard headers ###
dboard_base.hpp
+ dboard_eeprom.hpp
dboard_id.hpp
dboard_iface.hpp
dboard_manager.hpp
diff --git a/host/include/uhd/usrp/dboard_eeprom.hpp b/host/include/uhd/usrp/dboard_eeprom.hpp
new file mode 100644
index 000000000..108027b46
--- /dev/null
+++ b/host/include/uhd/usrp/dboard_eeprom.hpp
@@ -0,0 +1,60 @@
+//
+// Copyright 2010 Ettus Research LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+
+#ifndef INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP
+#define INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP
+
+#include <uhd/config.hpp>
+#include <uhd/usrp/dboard_id.hpp>
+#include <uhd/types/serial.hpp>
+#include <string>
+
+namespace uhd{ namespace usrp{
+
+struct UHD_API dboard_eeprom_t{
+ /*!
+ * The dboard id that was read from eeprom or will be set to eeprom.
+ */
+ dboard_id_t id;
+
+ /*!
+ * Create a dboard eeprom struct from the bytes read out of eeprom.
+ * The constructor will parse out the dboard id from a vector of bytes.
+ * To be valid, the bytes vector should be at least num_bytes() long.
+ * If the parsing fails due to bad checksum or incomplete length,
+ * the dboard id in this struct will be set to dboard_id::NONE.
+ * \param bytes the vector of bytes
+ */
+ dboard_eeprom_t(const uhd::byte_vector_t &bytes = uhd::byte_vector_t(0));
+
+ /*!
+ * Get the bytes that would be written to dboard eeprom.
+ * \return a vector of bytes
+ */
+ uhd::byte_vector_t get_eeprom_bytes(void);
+
+ /*!
+ * Get the number of bytes in the dboard eeprom segment.
+ * Use this value when reading out of the dboard eeprom.
+ * \return the number of bytes used by dboard eeprom
+ */
+ static size_t num_bytes(void);
+};
+
+}} //namespace
+
+#endif /* INCLUDED_UHD_USRP_DBOARD_EEPROM_HPP */
diff --git a/host/include/uhd/usrp/dboard_iface.hpp b/host/include/uhd/usrp/dboard_iface.hpp
index 71c7be200..1214a1a2f 100644
--- a/host/include/uhd/usrp/dboard_iface.hpp
+++ b/host/include/uhd/usrp/dboard_iface.hpp
@@ -19,39 +19,12 @@
#define INCLUDED_UHD_USRP_DBOARD_IFACE_HPP
#include <uhd/config.hpp>
+#include <uhd/types/serial.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/cstdint.hpp>
-#include <vector>
namespace uhd{ namespace usrp{
-//spi configuration struct
-struct UHD_API spi_config_t{
- /*!
- * The edge type specifies when data is valid
- * relative to the edge of the serial clock.
- */
- enum edge_t{
- EDGE_RISE = 'r',
- EDGE_FALL = 'f'
- };
-
- //! on what edge is the mosi data valid?
- edge_t mosi_edge;
-
- //! on what edge is the miso data valid?
- edge_t miso_edge;
-
- /*!
- * Create a new spi config.
- * \param edge the default edge for mosi and miso
- */
- spi_config_t(edge_t edge = EDGE_RISE){
- mosi_edge = edge;
- miso_edge = edge;
- }
-};
-
/*!
* The daughter board dboard interface to be subclassed.
* A dboard instance interfaces with the mboard though this api.
@@ -61,7 +34,6 @@ struct UHD_API spi_config_t{
class UHD_API dboard_iface{
public:
typedef boost::shared_ptr<dboard_iface> sptr;
- typedef std::vector<boost::uint8_t> byte_vector_t;
//tells the host which unit to use
enum unit_t{
@@ -123,19 +95,19 @@ public:
/*!
* Write to an I2C peripheral.
*
- * \param i2c_addr I2C bus address (7-bits)
- * \param buf the data to write
+ * \param addr I2C bus address (7-bits)
+ * \param bytes the data to write
*/
- virtual void write_i2c(int i2c_addr, const byte_vector_t &buf) = 0;
+ virtual void write_i2c(boost::uint8_t addr, const byte_vector_t &bytes) = 0;
/*!
* Read from an I2C peripheral.
*
- * \param i2c_addr I2C bus address (7-bits)
+ * \param addr I2C bus address (7-bits)
* \param num_bytes number of bytes to read
* \return the data read if successful, else a zero length string.
*/
- virtual byte_vector_t read_i2c(int i2c_addr, size_t num_bytes) = 0;
+ virtual byte_vector_t read_i2c(boost::uint8_t addr, size_t num_bytes) = 0;
/*!
* Write data to SPI bus peripheral.
diff --git a/host/include/uhd/usrp/dboard_manager.hpp b/host/include/uhd/usrp/dboard_manager.hpp
index 6de64b02d..007d85bb4 100644
--- a/host/include/uhd/usrp/dboard_manager.hpp
+++ b/host/include/uhd/usrp/dboard_manager.hpp
@@ -33,7 +33,6 @@ namespace uhd{ namespace usrp{
* Provide wax::obj access to the subdevs inside.
*/
class UHD_API dboard_manager : boost::noncopyable{
-
public:
typedef boost::shared_ptr<dboard_manager> sptr;
diff --git a/host/include/uhd/usrp/dboard_props.hpp b/host/include/uhd/usrp/dboard_props.hpp
index 3b290319f..0208a6c2c 100644
--- a/host/include/uhd/usrp/dboard_props.hpp
+++ b/host/include/uhd/usrp/dboard_props.hpp
@@ -29,7 +29,8 @@ namespace uhd{ namespace usrp{
DBOARD_PROP_NAME = 'n', //ro, std::string
DBOARD_PROP_SUBDEV = 's', //ro, wax::obj
DBOARD_PROP_SUBDEV_NAMES = 'S', //ro, prop_names_t
- DBOARD_PROP_USED_SUBDEVS = 'u' //ro, prop_names_t
+ DBOARD_PROP_USED_SUBDEVS = 'u', //ro, prop_names_t
+ DBOARD_PROP_DBOARD_ID = 'i' //rw, dboard_id_t
//DBOARD_PROP_CODEC //ro, wax::obj //----> not sure, dont have to deal with yet
};
diff --git a/host/include/uhd/usrp/simple_usrp.hpp b/host/include/uhd/usrp/simple_usrp.hpp
index c4e0338f7..c4142b4e6 100644
--- a/host/include/uhd/usrp/simple_usrp.hpp
+++ b/host/include/uhd/usrp/simple_usrp.hpp
@@ -39,20 +39,72 @@ namespace uhd{ namespace usrp{
class UHD_API simple_usrp : boost::noncopyable{
public:
typedef boost::shared_ptr<simple_usrp> sptr;
- static sptr make(const std::string &args);
+ /*!
+ * Make a new simple usrp from the device address.
+ * \param dev_addr the device address
+ * \return a new simple usrp object
+ */
+ static sptr make(const device_addr_t &dev_addr);
+
+ /*!
+ * Get the underlying device object.
+ * This is needed to get access to the streaming API and properties.
+ * \return the device object within this simple usrp
+ */
virtual device::sptr get_device(void) = 0;
+ /*!
+ * Get a printable name for this simple usrp.
+ * \return a printable string
+ */
virtual std::string get_name(void) = 0;
/*******************************************************************
* Misc
******************************************************************/
+ /*!
+ * Sets the time registers on the usrp immediately.
+ * \param time_spec the time to latch into the usrp device
+ */
virtual void set_time_now(const time_spec_t &time_spec) = 0;
+
+ /*!
+ * Set the time registers on the usrp at the next pps tick.
+ * The values will not be latched in until the pulse occurs.
+ * It is recommended that the user sleep(1) after calling to ensure
+ * that the time registers will be in a known state prior to use.
+ *
+ * Note: Because this call sets the time on the "next" pps,
+ * the seconds in the time spec should be current seconds + 1.
+ *
+ * \param time_spec the time to latch into the usrp device
+ */
virtual void set_time_next_pps(const time_spec_t &time_spec) = 0;
+
+ /*!
+ * Issue a stream command to the usrp device.
+ * This tells the usrp to send samples into the host.
+ * See the documentation for stream_cmd_t for more info.
+ * \param stream_cmd the stream command to issue
+ */
virtual void issue_stream_cmd(const stream_cmd_t &stream_cmd) = 0;
+
+ /*!
+ * Set the clock configuration for the usrp device.
+ * This tells the usrp how to get a 10Mhz reference and PPS clock.
+ * See the documentation for clock_config_t for more info.
+ * \param clock_config the clock configuration to set
+ */
virtual void set_clock_config(const clock_config_t &clock_config) = 0;
+ /*!
+ * Read the RSSI value from a usrp device.
+ * Or throw if the dboard does not support an RSSI readback.
+ * \return the rssi in dB
+ */
+ virtual float read_rssi(void) = 0;
+
/*******************************************************************
* RX methods
******************************************************************/
@@ -70,6 +122,8 @@ public:
virtual std::string get_rx_antenna(void) = 0;
virtual std::vector<std::string> get_rx_antennas(void) = 0;
+ virtual bool get_rx_lo_locked(void) = 0;
+
/*******************************************************************
* TX methods
******************************************************************/
@@ -86,6 +140,8 @@ public:
virtual void set_tx_antenna(const std::string &ant) = 0;
virtual std::string get_tx_antenna(void) = 0;
virtual std::vector<std::string> get_tx_antennas(void) = 0;
+
+ virtual bool get_tx_lo_locked(void) = 0;
};
}}
diff --git a/host/include/uhd/usrp/subdev_props.hpp b/host/include/uhd/usrp/subdev_props.hpp
index cd6b14ef5..1f8e91d68 100644
--- a/host/include/uhd/usrp/subdev_props.hpp
+++ b/host/include/uhd/usrp/subdev_props.hpp
@@ -35,13 +35,13 @@ namespace uhd{ namespace usrp{
SUBDEV_PROP_FREQ_RANGE = 'F', //ro, freq_range_t
SUBDEV_PROP_ANTENNA = 'a', //rw, std::string
SUBDEV_PROP_ANTENNA_NAMES = 'A', //ro, prop_names_t
- //SUBDEV_PROP_ENABLED = 'e', //rw, bool //---> dont need, we have atr
+ SUBDEV_PROP_LO_LOCKED = 'L', //ro, bool
SUBDEV_PROP_QUADRATURE = 'q', //ro, bool
SUBDEV_PROP_IQ_SWAPPED = 'i', //ro, bool
SUBDEV_PROP_SPECTRUM_INVERTED = 's', //ro, bool
- SUBDEV_PROP_USE_LO_OFFSET = 'l' //ro, bool
- //SUBDEV_PROP_RSSI, //ro, float //----> not on all boards, use named prop
- //SUBDEV_PROP_BANDWIDTH //rw, double //----> not on all boards, use named prop
+ SUBDEV_PROP_USE_LO_OFFSET = 'l', //ro, bool
+ SUBDEV_PROP_RSSI = 'R', //ro, float
+ SUBDEV_PROP_BANDWIDTH = 'B' //rw, double
};
}} //namespace
diff --git a/host/include/uhd/utils/assert.hpp b/host/include/uhd/utils/assert.hpp
index 842ed8dfa..01beed757 100644
--- a/host/include/uhd/utils/assert.hpp
+++ b/host/include/uhd/utils/assert.hpp
@@ -18,27 +18,27 @@
#ifndef INCLUDED_UHD_UTILS_ASSERT_HPP
#define INCLUDED_UHD_UTILS_ASSERT_HPP
+#include <uhd/config.hpp>
#include <uhd/utils/algorithm.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/current_function.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/exception/info.hpp>
#include <stdexcept>
+#include <string>
namespace uhd{
- class assert_error : public std::logic_error{
- public:
- explicit assert_error(const std::string& what_arg) : logic_error(what_arg){
- /* NOP */
- }
- };
+ //! The exception to throw when assertions fail
+ struct UHD_API assert_error : virtual std::exception, virtual boost::exception{};
- #define ASSERT_THROW(_x) if (not (_x)) { \
- throw uhd::assert_error(str(boost::format( \
- "Assertion Failed:\n %s:%d\n %s\n ---> %s <---" \
- ) % __FILE__ % __LINE__ % BOOST_CURRENT_FUNCTION % std::string(#_x))); \
- }
+ //! The assertion info, the code that failed
+ typedef boost::error_info<struct tag_assert_info, std::string> assert_info;
+
+ //! Throw an assert error with throw-site information
+ #define UHD_ASSERT_THROW(_x) if (not (_x)) \
+ BOOST_THROW_EXCEPTION(uhd::assert_error() << uhd::assert_info(#_x))
/*!
* Check that an element is found in a container.
@@ -58,17 +58,18 @@ namespace uhd{
){
if (std::has(iterable, elem)) return;
std::string possible_values = "";
- BOOST_FOREACH(T e, iterable){
- if (e != iterable.begin()[0]) possible_values += ", ";
+ size_t i = 0;
+ BOOST_FOREACH(const T &e, iterable){
+ if (i++ > 0) possible_values += ", ";
possible_values += boost::lexical_cast<std::string>(e);
}
- throw uhd::assert_error(str(boost::format(
+ boost::throw_exception(uhd::assert_error() << assert_info(str(boost::format(
"Error: %s is not a valid %s. "
"Possible values are: [%s]."
)
% boost::lexical_cast<std::string>(elem)
% what % possible_values
- ));
+ )));
}
}//namespace uhd
diff --git a/host/include/uhd/utils/props.hpp b/host/include/uhd/utils/props.hpp
index 6be0b2ce5..516102a5f 100644
--- a/host/include/uhd/utils/props.hpp
+++ b/host/include/uhd/utils/props.hpp
@@ -21,27 +21,63 @@
#include <uhd/config.hpp>
#include <uhd/wax.hpp>
#include <boost/tuple/tuple.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/exception/info.hpp>
+#include <stdexcept>
#include <vector>
#include <string>
namespace uhd{
- //typedef for handling named properties
+ //! The type for a vector of property names
typedef std::vector<std::string> prop_names_t;
- typedef boost::tuple<wax::obj, std::string> named_prop_t;
+
+ /*!
+ * A named prop struct holds a key and a name.
+ * Allows properties to be sub-sectioned by name.
+ */
+ struct UHD_API named_prop_t{
+ wax::obj key;
+ std::string name;
+
+ /*!
+ * Create a new named prop from key and name.
+ * \param key the property key
+ * \param name the string name
+ */
+ named_prop_t(const wax::obj &key, const std::string &name);
+ };
/*!
* Utility function to separate a named property into its components.
* \param key a reference to the prop object
* \param name a reference to the name object
+ * \return a tuple that can be used with boost::tie
+ */
+ UHD_API boost::tuple<wax::obj, std::string> extract_named_prop(
+ const wax::obj &key,
+ const std::string &name = ""
+ );
+
+ //! The exception to throw for property errors
+ struct UHD_API prop_error : virtual std::exception, virtual boost::exception{};
+
+ //! The property error info (verbose or message)
+ typedef boost::error_info<struct tag_prop_info, std::string> prop_info;
+
+ /*!
+ * Throw when getting a not-implemented or write-only property.
+ * Throw-site information will be included with this error.
+ */
+ #define UHD_THROW_PROP_GET_ERROR() \
+ BOOST_THROW_EXCEPTION(uhd::prop_error() << uhd::prop_info("cannot get this property"))
+
+ /*!
+ * Throw when setting a not-implemented or read-only property.
+ * Throw-site information will be included with this error.
*/
- inline UHD_API named_prop_t //must be exported as part of the api to work (TODO move guts to cpp file)
- extract_named_prop(const wax::obj &key, const std::string &name = ""){
- if (key.type() == typeid(named_prop_t)){
- return key.as<named_prop_t>();
- }
- return named_prop_t(key, name);
- }
+ #define UHD_THROW_PROP_SET_ERROR() \
+ BOOST_THROW_EXCEPTION(uhd::prop_error() << uhd::prop_info("cannot set this property"))
} //namespace uhd
diff --git a/host/include/uhd/utils/safe_main.hpp b/host/include/uhd/utils/safe_main.hpp
index b682aa540..a4e4e06e8 100644
--- a/host/include/uhd/utils/safe_main.hpp
+++ b/host/include/uhd/utils/safe_main.hpp
@@ -19,6 +19,7 @@
#define INCLUDED_UHD_UTILS_SAFE_MAIN_HPP
#include <uhd/config.hpp>
+#include <boost/exception/diagnostic_information.hpp>
#include <iostream>
#include <stdexcept>
@@ -33,6 +34,8 @@
int main(int argc, char *argv[]){ \
try { \
return _main(argc, argv); \
+ } catch(const boost::exception &e){ \
+ std::cerr << "Error: " << boost::diagnostic_information(e) << std::endl; \
} catch(const std::exception &e) { \
std::cerr << "Error: " << e.what() << std::endl; \
} catch(...) { \