How-to: Get and Set Paths in UHD and the State Tree

This how-to guide explains how to get and set arbitrary paths in UHD; these are the values that are written to the state tree of the server in your SDR unit for a particular parameter (i.e. gain, IQ balance, FPGA version, etc.). Here we discuss how you would accomplish get or set paths if you want to manually configure these paths from the command line or if you are writing your own UHD program.


IMPORTANT!! It is not recommended that the user directly access the state tree in our SDR devices; this how-to guide should be used with caution.

1. Manually Using the Command Line for Get/Set Paths in UHD of the state tree

  1. Figure out what property in the state tree in the unit you want to change.

  2. Go to the C++ implementation file on your SDR device. For Crimson TNG, this crimson_tng_impl.cpp. On Cyan, this would be the one corresponding to your unit (for example, cyan_4r4t_impl.cpp is a 4R4T 1GSPS SDR unit). For Crimson TNG, this would be located in the following directory on the host system:

    $ uhd/host/lib/usrp/crimson_tng/crimson_tng_impl.cpp
  3. Step 3 is to find the UHD macro that corresponds to the state tree path in the crimson_tng_impl.cpp file or the one corresponding to Cyan. To figure out which UHD path corresponds to the state tree path you want to access, look in the implementation file for instances of the macro TREE_CREATE_ST and TREE_CREATE_RW. The first argument in the macro is the path used within UHD programs, and the second argument is the path it corresponds to on the server. The third and fourth arguments are the datatypes.

    For example, the following line of code:

    TREE_CREATE_RW(mb_path / "clock_source" / "value",      "time/source/ref",  std::string, string);

    is the macro that will create a state tree path. Once again, in this macro, the first argument is the UHD path, the second is the path in the server, and the third and fourth argument are the data types.

  4. To get the value of the state tree, you need to use the following command (you can find out the arguments with the –help flag):

    $ uhd_manual_get

    For example, the following command would get the current state tree value for DSP gain:

    $ uhd_manual_get --path /mboards/0/rx_codecs/A/gains --type int


    The valid data types are string, int and double in the above argument.


    For finding the “–path” argument in the above and below command, you need to go into the crimson_tng_impl.cpp file and locate the TREE_CREATE_RW or TREE_CREATE_ST that create the path binding in the state tree. Then, you will need to find in this file the variables associated with the UHD path argument of the TREE_CREATE_RW or TREE_CREATE_ST, and plug these into the “–path” argument of the uhd_manual_set/get command.

  5. To manually set paths in the state tree, you need to use following command (you can find out the arguments with the –help flag):

    $ uhd_manual_set 

    For instance, to change the DSP gain value in the state tree, use the following command:

    $ uhd_manual_set --path /mboards/0/rx_codecs/A/gains --type int --value 15

2. Get/Set In a UHD Program

  1. Same as Step 1 above.

  2. Same as Step 2 above.

  3. Same as Step 3 above.

  4. If you’re trying to write a program, you will need to include the get/set functions. This is included when you initialize the device; already done in most UHD programs. The code to initialize the usrp device is:

    uhd::usrp::multi_usrp::sptr usrp = uhd::usrp::multi_usrp::make(std::string(""));
  5. Step 5 is to use the USRP device created in Step 4 to call the get_tree_value and set_tree_value functions. The code looks like this:

    //gets the old value from the state tree
    std::string old_value;
    usrp->get_tree_value(path, old_value);
    std::cout << "Old value: " << old_value << std::endl;
    std::string = "some path";
    std::string = "some value";
    usrp->set_tree_value(path, value);
    std::cout << "Set to: " << value << std::endl;
    std::string new_value;
    usrp->get_tree_value(path, new_value);
    std::cout << "The value is now: " << new_value << std::endl;
  6. The first argument in the get_tree_value(path,old_value) and set_tree_value(path, new_value) functions is the UHD path you figured out in Step 3 (not the path of the server, i.e. it’s the first argument, not the second). In the case of get_tree_value, the second argument is the current value of the state tree written to that variable, and in the case of set_tree_value, it is the value you are trying to set the state tree to.


IMPORTANT: It is essential that the argument in that tree (the data type), is the same data type as the variable you’re trying to pass to the set/get_tree_value. If you do not adhere to the datatype, this will write a garbage value, and not immediately throw out an error.