diff options
author | Josh Blum <josh@joshknows.com> | 2010-04-28 11:10:50 -0700 |
---|---|---|
committer | Josh Blum <josh@joshknows.com> | 2010-04-28 11:10:50 -0700 |
commit | cbd9e1da0866893d86320787a99cf4257478c539 (patch) | |
tree | 0b2515cd96d9c341795b91efed25df0616ea821c /host/include | |
parent | f5b6776a0b642c0357fbecdead9d2b1ac6ece3d3 (diff) | |
parent | 8497eb2ac016f72e2b9a9028e5126bc73f5b0c9a (diff) | |
download | uhd-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.txt | 1 | ||||
-rw-r--r-- | host/include/uhd/types/device_addr.hpp | 20 | ||||
-rw-r--r-- | host/include/uhd/types/io_type.hpp | 1 | ||||
-rw-r--r-- | host/include/uhd/types/metadata.hpp | 10 | ||||
-rw-r--r-- | host/include/uhd/types/serial.hpp | 122 | ||||
-rw-r--r-- | host/include/uhd/types/time_spec.hpp | 23 | ||||
-rw-r--r-- | host/include/uhd/usrp/CMakeLists.txt | 1 | ||||
-rw-r--r-- | host/include/uhd/usrp/dboard_eeprom.hpp | 60 | ||||
-rw-r--r-- | host/include/uhd/usrp/dboard_iface.hpp | 40 | ||||
-rw-r--r-- | host/include/uhd/usrp/dboard_manager.hpp | 1 | ||||
-rw-r--r-- | host/include/uhd/usrp/dboard_props.hpp | 3 | ||||
-rw-r--r-- | host/include/uhd/usrp/simple_usrp.hpp | 58 | ||||
-rw-r--r-- | host/include/uhd/usrp/subdev_props.hpp | 8 | ||||
-rw-r--r-- | host/include/uhd/utils/assert.hpp | 33 | ||||
-rw-r--r-- | host/include/uhd/utils/props.hpp | 54 | ||||
-rw-r--r-- | host/include/uhd/utils/safe_main.hpp | 3 |
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(...) { \ |