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): """ |