1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
#!/usr/bin/env python
#
# Copyright 2017 Ettus Research (National Instruments)
#
# 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/>.
#
"""
Main executable for the USRP Hardware Daemon
"""
from __future__ import print_function
import sys
import argparse
from gevent import signal
import usrp_mpm as mpm
from usrp_mpm.mpmtypes import SharedState
from usrp_mpm.periph_manager import periph_manager
_PROCESSES = []
def setup_arg_parser():
"""
Create an arg parser
"""
parser = argparse.ArgumentParser(description="USRP Hardware Daemon")
parser.add_argument(
'--daemon',
help="Run as daemon",
action="store_true",
)
parser.add_argument(
'--init-only',
help="Don't start the RPC server, terminate after running initialization",
action="store_true",
)
parser.add_argument(
'--override-db-pids',
help="Provide a comma-separated list of daughterboard PIDs that are " \
"used instead of whatever else the code may find",
default=None
)
parser.add_argument(
'--default-args',
help="Provide a comma-separated list of key=value pairs that are" \
"used as defaults for device initialization.",
default=None
)
return parser
def parse_args():
"""
Return a fully parse args object
"""
args = setup_arg_parser().parse_args()
if args.override_db_pids is not None:
args.override_db_pids = [int(x, 0) for x in args.override_db_pids.split(",")]
args.default_args = args.default_args or ''
try:
args.default_args = {
x.split('=')[0].strip(): x.split('=')[1].strip() if x.find('=') != -1 else ''
for x in args.default_args.split(',')
if len(x)
}
except IndexError:
log.error("Could not parse default device args: `{}'".format(args.default_args))
return args
def kill_time(sig, frame):
"""
kill all processes
to be used in a signal handler
If all processes are properly terminated, this will exit
"""
log = mpm.get_main_logger().getChild('kill')
for proc in _PROCESSES:
proc.terminate()
log.info("Terminating pid: {0}".format(proc.pid))
for proc in _PROCESSES:
proc.join()
log.info("System exiting")
sys.exit(0)
def main():
"""
Go, go, go!
Main process loop.
"""
log = mpm.get_main_logger().getChild('main')
args = parse_args()
shared = SharedState()
# Create the periph_manager for this device
# This call will be forwarded to the device specific implementation
# e.g. in periph_manager/n310.py
# Which implementation is called will be determined during configuration
# with cmake (-DMPM_DEVICE).
# mgr is thus derived from PeriphManagerBase (see periph_manager/base.py)
log.info("Spawning periph manager...")
mgr = periph_manager(args)
discovery_info = {
"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:
log.info("Terminating on user request before launching RPC server.")
mgr.deinit()
return True
log.info("Spawning discovery process...")
_PROCESSES.append(
mpm.spawn_discovery_process(discovery_info, shared))
log.info("Spawning RPC process...")
_PROCESSES.append(
mpm.spawn_rpc_process(mpm.mpmtypes.MPM_RPC_PORT, shared, mgr))
log.info("Processes launched. Registering signal handlers.")
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__':
exit(not main())
|