如何搭配USRP在安卓设备上搭建GNU Radio

作者:媒体转发 时间:2018-03-23 01:52

字号

在这篇文章中,我们会使用安卓设备通过USB连接USRP。所以就需要USRP B2xx(B200, B210, 或者是 B200mini),这些都是经过全面测试的。除了这些,我们还需要一个OTG(USB On-the-Go)线缆,它可以插入安卓设备的USB端口。准备好这些,就可以按照下图所示接线方法连接。

Android_usrp_connection-annotated.png

点击这里查看已经被测试证明可以正常工作的设备列表。

具有网络连接的USRP似乎更容易在使用安卓设备的情况下正常工作。B2xx系列的USRP最大的问题在于每次开机时都必须对其固件和FPGA图像进行编程,而N200/N210这样的的USRP是预编程的,所以不需要面临某些USB设备的权限问题,联网的USRP所需的权限只有“android.permission.INTERNET”,该权限用于访问ControlPort。

RTL-SDR也可以用于安卓设备上的GNU Radio,与USRP B2xx差不多,这些设备也需要USB权限的替代办法,不过不需要编程。我们可以将RTL-SDR库和gr-osmosdr对其的支持构建到Android依赖包的GR中。此外,增加对其他基于USB的设备(如BladeRF,HackRF,Airspy等)的支持也将是比较直接的。

点击这里查看Github上完整的GrTemplateUSRP示例。

开始

我们现在要构建一个新的应用程序,首先,按照GRAndWalkthroughCP概述中的步骤创建一个新的应用程序项目,不过这次暂且命名为GrTemplateUSRP,这为我们设置了一个支持ControlPort且有一个基本流图的项目。在进行下一步之前,确保应用程序的构建和运行就像GrTemplateCP一样。

其次,克隆并构建GrHardwareService应用程序,并将此应用安装到你的安卓设备上,如果你第一次启动时没有连接USRP,应用可能会崩溃。加载完成后,它会为B2xx设备安装USRP固件和FPGA图像,并开始侦听USB连接。如果插入了供应商和生产ID与任何已知的USRP匹配的设备,则开始对设备进行编程。它会要求你授权两次以使用该设备,一次对固件进行编程,另一次是对FPGA图像进行编程。一旦完成,硬件即准备就绪。

如果你在第一次插入USRP时导致了程序崩溃,则可能是权限问题。在Marshmallow(安卓6.0)上,需要进入设置中的应用程序部分,找到GrHardwareService,然后启用存储权限。这是安卓6.0中的新“功能”。

添加对USB设备的支持

我们必须与安卓设备交互才可以在Java应用程序中获取信息并将其传递给C++流图,值得一提的是,安卓并不会将USB权限交给本地应用程序,所以我们需要在Java中获取文件描述符(fd)和USB文件系统路径(usrpfs_path),并将其通过GNU Radio传递给libUHD,最终通过libUSB访问。

接下来,我们需要添加一些支持以获得USB许可,并找到我们需要连接到USRP的fd和usbfs_path信息。

首先,将这些变量添加到MainActivity类中:

 public static Intent intent = null;     private String usbfs_path = null;     private int fd = -1;     private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";     private static final String DEFAULT_USBFS_PATH = "/dev/bus/usb";     private UsbManager mUsbManager;     private UsbDevice mUsbDevice;

在我们收发无线电之前,我们需要确保已经拥有USB权限。因此,和我们之前一直在OnCreate中做事情不同,我们会将其分成不同部分,首先在OnCreate中,我们需要获取USB设备,设置无线电接收器,然后询问用户是否允许使用该设备。当用户同意时,无线电接收器启动。 即完成对USB设备的访问,现在我们可以对USB设备进行操作,以便我们从中获取需要的信息。这就是OnCreate函数:

@Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         // Create the seekBar to move update the amplitude         SeekBar ampSeekBar = (SeekBar) findViewById(R.id.seekBar);         ampSeekBar.setMax(100);      // max value -> 1.0         ampSeekBar.setProgress(50);  // match 0.5 starting value         ampSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {             @Override             public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {                 Double amp = progress / 100.0; // rescale by 100                 RPCConnection.KnobInfo _k =                         new RPCConnection.KnobInfo(mult_knob_name, amp,                                 BaseTypes.DOUBLE);                 HashMap _map = new HashMap<>();                 _map.put(mult_knob_name, _k);                 postSetKnobMessage(_map);             }             @Override             public void onStartTrackingTouch(SeekBar seekBar) {             }             @Override             public void onStopTrackingTouch(SeekBar seekBar) {             }         });         // Start setting up for USB permission request         intent = getIntent();         mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);         IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);         registerReceiver(mUsbReceiver, filter);         mUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);         if (mUsbDevice == null) {             Log.d("GrTemplateUSRP", "Didn't get a device; finding it now.");             final HashSet allowed_devices = getAllowedDevices(this);             final HashMap usb_device_list = mUsbManager.getDeviceList();             for (UsbDevice candidate : usb_device_list.values()) {                 String candstr = "v" + candidate.getVendorId() + "p" + candidate.getProductId();                 if (allowed_devices.contains(candstr)) {                     // Need to handle case where we have more than one device connected                     mUsbDevice = candidate;                 }             }         }         Log.d("GrTemplateUSRP", "Selected Device: " + mUsbDevice);         PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0,                 new Intent(ACTION_USB_PERMISSION), 0);         // Launch dialog to ask for permission.         // If use hits OK, the broadcast receiver will be launched.         mUsbManager.requestPermission(mUsbDevice, permissionIntent);     }

需要注意的是,我们仍要在此处创建Seek Bar作为GUI设置。

责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接