diff options
| author | Martin Braun <martin.braun@ettus.com> | 2017-06-03 01:33:54 -0700 | 
|---|---|---|
| committer | Martin Braun <martin.braun@ettus.com> | 2017-12-22 15:03:59 -0800 | 
| commit | 40235b8c5aba6acec2acdc4135b828b1d9785a96 (patch) | |
| tree | 6570aa9f99872979e51106f5249fe82080c611dc /mpm/python | |
| parent | 0d659863da607acaaf15ab69a662af2da006f65e (diff) | |
| download | uhd-40235b8c5aba6acec2acdc4135b828b1d9785a96.tar.gz uhd-40235b8c5aba6acec2acdc4135b828b1d9785a96.tar.bz2 uhd-40235b8c5aba6acec2acdc4135b828b1d9785a96.zip  | |
mpm/mpmd: Call init() during UHD session init, not on hwd spawn
Diffstat (limited to 'mpm/python')
| -rwxr-xr-x | mpm/python/usrp_hwd.py | 3 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/base.py | 3 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/dboard_manager/eiscat.py | 27 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/base.py | 9 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/periph_manager/n310.py | 3 | ||||
| -rw-r--r-- | mpm/python/usrp_mpm/rpc_server.py | 42 | 
6 files changed, 66 insertions, 21 deletions
diff --git a/mpm/python/usrp_hwd.py b/mpm/python/usrp_hwd.py index 27c2870df..8abc89923 100755 --- a/mpm/python/usrp_hwd.py +++ b/mpm/python/usrp_hwd.py @@ -115,8 +115,8 @@ def main():          "type": mgr._get_device_info()["type"],          "serial": mgr._get_device_info()["serial"]      } -    mgr.init(args.default_args) # TODO really this should be called by the UHD session      if args.init_only: +        mgr.init(args.default_args)          log.info("Terminating on user request before launching RPC server.")          mgr.deinit()          return True @@ -130,7 +130,6 @@ def main():      signal.signal(signal.SIGTERM, kill_time)      signal.signal(signal.SIGINT, kill_time)      signal.pause() -    mgr.deinit() # TODO Really this should be called when a device is unclaimed      return True  if __name__ == '__main__': diff --git a/mpm/python/usrp_mpm/dboard_manager/base.py b/mpm/python/usrp_mpm/dboard_manager/base.py index 724558445..56655f946 100644 --- a/mpm/python/usrp_mpm/dboard_manager/base.py +++ b/mpm/python/usrp_mpm/dboard_manager/base.py @@ -52,6 +52,7 @@ class DboardManagerBase(object):          device_args -- Arbitrary dictionary of info, typically user-defined          """          return [] +    ### End of overridables #################################################      def __init__(self, slot_idx, **kwargs):          self.log = get_logger('dboardManager') @@ -82,7 +83,7 @@ class DboardManagerBase(object):          Run the dboard initialization. This typically happens at the beginning          of a UHD session. -        Must be overridden. +        Must be overridden. Must return True/False on success/failure.          args -- A dictionary of arbitrary settings that can be used by the                  dboard code. Similar to device args for UHD. diff --git a/mpm/python/usrp_mpm/dboard_manager/eiscat.py b/mpm/python/usrp_mpm/dboard_manager/eiscat.py index dc4ee1cac..980a64fcc 100644 --- a/mpm/python/usrp_mpm/dboard_manager/eiscat.py +++ b/mpm/python/usrp_mpm/dboard_manager/eiscat.py @@ -17,10 +17,10 @@  """  EISCAT rx board implementation module  """ -from builtins import range -from builtins import object  import time +from builtins import range +from builtins import object  from ..mpmlog import get_logger  from ..uio import UIO  from . import lib @@ -28,8 +28,6 @@ from .base import DboardManagerBase  from .lmk_eiscat import LMK04828EISCAT  from usrp_mpm.cores import ClockSynchronizer -N_CHANS = 8 # Chans per dboard -  def create_spidev_iface_sane(dev_node):      """      Create a regs iface from a spidev node (sane values) @@ -410,6 +408,12 @@ class EISCAT(DboardManagerBase):          self.clock_synchronizer = None          self._spi_ifaces = None +    def is_initialized(self): +        """ +        Returns True if the daughterboard is a usable state and ready to stream +        """ +        return self.initialized +      def init(self, args):          """          Execute necessary actions to bring up the daughterboard: @@ -425,6 +429,9 @@ class EISCAT(DboardManagerBase):          For operation (streaming), the ADCs and deframers still need to be          initialized. + +        Note that this function will do nothing if the device was previously +        initialized.          """          def _init_dboard_regs():              " Create a UIO object to talk to dboard regs " @@ -493,6 +500,12 @@ class EISCAT(DboardManagerBase):                  adc.reset()              return adcs          # Go, go, go! +        if self.initialized and not args.get("force_init", False): +            self.log.info( +                "Dboard was previously initialized; skipping init. " \ +                "Specify force_init=1 to force initialization." +            ) +            return True          self.log.info("init() called with args `{}'".format(              ",".join(['{}={}'.format(x, args[x]) for x in args])          )) @@ -534,6 +547,7 @@ class EISCAT(DboardManagerBase):              self._spi_ifaces['adc0'], self._spi_ifaces['adc1'],          ))          self.log.trace("ADC Reset Sequence Complete!") +        return True      def send_sysref(self): @@ -582,12 +596,13 @@ class EISCAT(DboardManagerBase):      def shutdown(self):          """ -        Safely turn off the daughterboard +        Safely turn off the daughterboard. This will take away power to the +        components; a re-initialization will be necessary after calling this.          """          self.log.info("Shutting down daughterboard") +        self.initialized = False          self._deinit_power(self.radio_regs) -      def _init_power(self, regs):          """          Turn on power to the dboard. diff --git a/mpm/python/usrp_mpm/periph_manager/base.py b/mpm/python/usrp_mpm/periph_manager/base.py index 89282265f..c0e64ade3 100644 --- a/mpm/python/usrp_mpm/periph_manager/base.py +++ b/mpm/python/usrp_mpm/periph_manager/base.py @@ -302,6 +302,12 @@ class PeriphManagerBase(object):          passed to the daughterboard's init calls.  For additional features,          this needs to be overridden. +        The main requirement of this function is, after calling it successfully, +        all RFNoC blocks must be reachable via CHDR interfaces (i.e., clocks +        need to be on). + +        Return False on failure, True on success. +          args -- A dictionary of args for initialization. Similar to device args                  in UHD.          """ @@ -312,8 +318,7 @@ class PeriphManagerBase(object):          self.log.info("Identifying available network interfaces...")          self._init_interfaces()          self.log.debug("Initializing dboards...") -        for dboard in self.dboards: -            dboard.init(args) +        return all((dboard.init(args) for dboard in self.dboards))      def deinit(self):          """ diff --git a/mpm/python/usrp_mpm/periph_manager/n310.py b/mpm/python/usrp_mpm/periph_manager/n310.py index 7b43aec38..537f43ee8 100644 --- a/mpm/python/usrp_mpm/periph_manager/n310.py +++ b/mpm/python/usrp_mpm/periph_manager/n310.py @@ -141,13 +141,14 @@ class n310(PeriphManagerBase):          Calls init() on the parent class, and then programs the Ethernet          dispatchers accordingly.          """ -        super(n310, self).init(args) +        result = super(n310, self).init(args)          self._eth_dispatchers = {              x: EthDispatcherTable(self.eth_tables.get(x))              for x in list(self._chdr_interfaces.keys())          }          for ifname, table in iteritems(self._eth_dispatchers):              table.set_ipv4_addr(self._chdr_interfaces[ifname]['ip_addr']) +        return result      def _allocate_sid(self, sender_addr, port, sid, xbar_src_addr, xbar_src_port, new_ep):          """ diff --git a/mpm/python/usrp_mpm/rpc_server.py b/mpm/python/usrp_mpm/rpc_server.py index 43843cff5..982e94c91 100644 --- a/mpm/python/usrp_mpm/rpc_server.py +++ b/mpm/python/usrp_mpm/rpc_server.py @@ -153,12 +153,13 @@ class MPMServer(RPCServer):      def claim(self, session_id):          """ -        claim `token` - tries to claim MPM device and provides a human readable session_id -        This is a safe method which can be called without a claim on the device +        claim `token` - tries to claim MPM device and provides a human readable +        session_id.          """          self._state.lock.acquire()          if self._state.claim_status.value: -            return "" +            self.log.warning("Someone tried to claim this device again") +            raise RuntimeError("Double-claim")          self.log.debug(              "Claiming from: %s, Session ID: %s",              self.client_host, @@ -169,11 +170,34 @@ class MPMServer(RPCServer):          ), 'ascii')          self._state.claim_status.value = True          self._state.lock.release() -        self.session_id = session_id +        self.session_id = session_id + " ({})".format(self.client_host)          self._reset_timer() -        self.log.debug("giving token: %s to host: %s", self._state.claim_token.value, self.client_host) +        self.log.debug( +            "giving token: %s to host: %s", +            self._state.claim_token.value, +            self.client_host +        )          return self._state.claim_token.value + +    def init(self, token, args): +        """ +        Initialize device. See PeriphManagerBase for details. This is forwarded +        from here import to give extra control over the claim release timeout. +        """ +        if not self._check_token_valid(token): +            self.log.warning( +                "Attempt to init without valid claim from {}".format( +                    self.client_host +                ) +            ) +            raise RuntimeError("init() called without valid claim.") +        self._timer.kill() # Stop the timer, inits can take some time. +        result = self.periph_manager.init(args) +        self.log.debug("init() result: {}".format(result)) +        self._reset_timer() +        return result +      def reclaim(self, token):          """          reclaim a MPM device with a token. This operation will fail @@ -203,8 +227,8 @@ class MPMServer(RPCServer):          """          unconditional unclaim - for internal use          """ -        self.log.debug("Releasing claim on session `{}' by `{}'".format( -            self.session_id, self.client_host +        self.log.debug("Releasing claim on session `{}'".format( +            self.session_id          ))          self._state.claim_status.value = False          self._state.claim_token.value = b'' @@ -213,12 +237,12 @@ class MPMServer(RPCServer):          self.periph_manager.deinit()          self._timer.kill() -    def _reset_timer(self): +    def _reset_timer(self, timeout=TIMEOUT_INTERVAL):          """          reset unclaim timer          """          self._timer.kill() -        self._timer = spawn_later(TIMEOUT_INTERVAL, self._unclaim) +        self._timer = spawn_later(timeout, self._unclaim)      def unclaim(self, token):          """  | 
