LabVIEW for LimeSDR

通过OpenUSRP插件可以将LimeSDR设备模拟成USRP

可以通过这个方法实现matlab、gnuradio、labview等原生支持

模拟成USRP可以运行LabVIEW Communications System Design Software软件
模拟成USRP可以运行LabVIEW Communications System Design Software软件

由于LabVIEW编译比较复杂,这里直接提供64bit的OpenUSRP二进制编译文件

直接下载附件内文件即可支持

安装方法

1、下载编译完成的OpenUSRP.dll文件:[download id=”10″]

1、下载NI-USRP 16.1支持: http://www.ni.com/download/ni-usrp-16.1/6525/en/

2、添加系统环境变量UHD_MODULE_PATH,路径就是OpenUSRP.dll的目录

LabVIEW 2016 x64和LabVIEW Communications System Design Software 2.0下测试成功

 

OpenUSRP项目介绍

USRP是美国Ettus Research公司出款的用于学习软件无线电的硬件,基本被所有SDR软件所支持

USRP的价格也相对比较贵,国内一款B210的设备基本要过万,给学习软件无线电带来压力

不过由于USRP的驱动UHD是开源的项目,所以可以使用自己做的第三方接口模拟USRP设备

目前可以使用LimeSDR设备,模拟成USRP B210设备使用,减少代码的多次移植问题

OpenUSRP提供两种安装模式,一个是LIBUHD模式,可以在编译驱动的时候自己打包进去

还有一个是MODULE模式,可以变成附加模块,实现USRP设备的模拟

Gnuradio支持

Linux和MacOS可以直接使用module模式

windows下建议直接替换UHD.dll文件使用,module模式需要配置UHD_MODULE_PATH环境变量及自己编译

 

Matlab支持

windows下替换C:\MATLAB\SupportPackages\R2016a\toolbox\shared\sdr\sdru\bin\win64下面的UHD.dll文件,可让Matlab支持limeSDR设备了

LabVIEW的UHD文件为不开源版本,暂时不支持。

注意:

UHD有版本区别,有时候替换无法工作,就需要自己编译重新安装

附件Windows二进制文件,基于matlab的uhd-1543f56编译完成

[download id=”3″]

[download id=”4″]

项目地址:https://github.com/jocover/OpenUSRP

BLE物理层的开源SDR实现

BLESDR可以使用SDR实现BLE的物理层和链路层的工作,软件完全开源

目前可以在limesdr硬件上实现实现BLE的嗅探,重放,以及广播包

其他SDR设备也可以运行

嗅探模式:

blesdr -S

可以嗅探BLE包,BLE包通过一个callback函数返回

广播模式:

blesdr -b B9407F30F5F8466EAFF925556B57FE6D -m 1.2

发送一个UUID16为B9407F30F5F8466EAFF925556B57FE6D的iBeacon包,可被苹果设备接受,要自定义发送包可以用sample_for_ADV_IND去实现

重放模式:

blesdr -R

从RX chan接受到的BLE数据包发送到TX chan

 

windows二进制地址:[download id=”6″]

项目地址:https://github.com/jocover/BLESDR

参考文档

Bletooth 4.0 core文档

https://www.bluetooth.org/docman/handlers/downloaddoc.ashx?doc_id=229737

S9-C SDR宽频接收机 WebSDR、openwebrx支持插件

8_72270_53e00880d6d5724

此插件支持s9-c在linux环境下运行websdr、openwebrx等软件
可以运行在树莓派环境或ubuntu、debian环境
安装教程

前期工作:
使用putty或者直接登录linux系统

1:更新依赖包

sudo apt-get update
sudo apt-get install build-essential cmake libftdi-dev

 

2:编译s9c linux驱动

cd driver
mkdir build
cd build
cmake ..
make
sudo make install
sudo ldconfig

 

3:配置驱动

sudo rmmod ftdi_sio
sudo cp driver/libs9c/s9c.rules /etc/udev/rules.d/s9c.rules
sudo udevadm control --reload-rules

 

4:配置接收程序

cd s9cwebsdr
nano s9cwebsdr.c

 

配置定义如下
CHANNEL_NUM为接收通道数,最大支持8个,最小1个
CH_X_FREQ为接收通道的频率,单位hz
AMP_GAIN 为总体的AMP增益设置,支持范围0-30
CH_X_GAIN为每个通道的单独增益

配置完成后按crtl+X退出,选择Y保存

编译接收机程序
make

运行
./s9cwebsdr

5:配置websdr方法
wedsdr获取方法参见
http://www.websdr.org/faq.html

websdr.cfg文件添加如下配置

#band名字
band ch1
#输入数据来源,ch1代表第一通道
device /tmp/s9c-fifo-ch1
#采样率 目前都是192000
samplerate 192000
#中心频率 根据之前的CH_X_FREQ设置对应填写
centerfreq 1000
#是否交换IQ
swapiq

6:配置openwebrx方法
获取方法参见
https://github.com/simonyiszk/openwebrx

config_webrx.py配置中添加

#输入数据来源,ch2代表第二通道,可以自己选择
start_rtl_command=”cat /tmp/s9c-fifo-ch2″
format_conversion=”csdr convert_s16_f”

修改默认配置
#采样率,默认250000改成192000
samp_rate = 192000
#中心频率,根据CH_X_FREQ 填写
center_freq = 145525000
如果在远程连接中配置,会导致远程连接断开后后来接收程序也自动断开,可以使用nohup或者screen工具反正后台终止

 

下载地址:s9c-websdr 0.01

pine64环境下架设websdr服务器

架设环境如下:pine64 @2GB版,S9-C 8通道短波无线电接收器

首先由于pine64运行在aarch64环境,由于websdr-rpi只支持32位环境,需要安装armhf支持

sudo dpkg --add-architecture armhf

sudo apt-get update

sudo apt-get install libc6:armhf libfftw3-3:armhf  libpng12-0:armhf libasound2:armhf libssl1.0.0:armhf

另外由于S9-C没有音频接口,需要将IQ文件转换为S16LE的音频编码输入到websdr,需要编辑websdr.cfg文件,添加如下参数

device /tmp/s9c-fifo-ch1
samplerate 192000
centerfreq 1000
swapiq

然后使用linxu的mkfifo建立命名管道,可以成功使32位程序与64位程序进行数据沟通

最终成功运行websdr,地址:http://websdr.jiangwei.org:8901

websdr

 

 

limesdr介绍

今天发现limesdr项目在crowdsupply开启众筹活动,裸板售价299美元,目前活动优惠价格249美元,邮递至中国快加15美元运费。

limesdr是一款完全开源的SDR产品,和HackRF一样,包括PCB设计图,FPGA代码,HOST代码完全公开,方便研究和学习SDR系统原理,比较值得一提的是,limesdr支持100kHz-3.8GHz的工作频率,已经可以不需外置上变频器,即可完成短波应用的使用。另外limesdr包含了2×2 MIMO的支持。

limesdr-bothsides_jpg_project-body

相比hackrf的299美元,bladerf的420美元,和USRP的价格来说,这款SDR已经是目前市面上能买到性价比最好的产品了

ARMv8 SHA256指令集测试

ARMv8指令集新增了crypto加密指令集,支持包括AES、SHA1、SHA256
SHA256指令集支持128bit的寄存器
1

PINE 64 aarch64环境下测试
速度对比:10000000次计算SHA256测试

CPU C CODE : time:14872734 ns

ARMv8 HW : time:1567756 ns

下面是aarch64下的部分汇编代码

    ld1       {v5.16b-v8.16b}, [x1], #64
    mov       v2.16b, v0.16b
    mov       v3.16b, v1.16b

    rev32     v5.16b, v5.16b
    rev32     v6.16b, v6.16b
    add       v9.4s, v5.4s, v16.4s
    rev32     v7.16b, v7.16b
    add       v10.4s, v6.4s, v17.4s
    mov       v4.16b, v2.16b
    sha256h   q2, q3, v9.4s
    sha256h2  q3, q4, v9.4s
    sha256su0 v5.4s, v6.4s
    rev32     v8.16b, v8.16b
    add       v9.4s, v7.4s, v18.4s
    mov       v4.16b, v2.16b
    sha256h   q2, q3, v10.4s
    sha256h2  q3, q4, v10.4s
    sha256su0 v6.4s, v7.4s
    sha256su1 v5.4s, v7.4s, v8.4s
    add       v10.4s, v8.4s, v19.4s
    mov       v4.16b, v2.16b
    sha256h   q2, q3, v9.4s
    sha256h2  q3, q4, v9.4s
    sha256su0 v7.4s, v8.4s
    sha256su1 v6.4s, v8.4s, v5.4s
    add       v9.4s, v5.4s, v20.4s
    mov       v4.16b, v2.16b
    sha256h   q2, q3, v10.4s
    sha256h2  q3, q4, v10.4s
    sha256su0 v8.4s, v5.4s


完整测试代码:github

ARMv8 CRC32指令集测试

在PINE 64上测试了一下ARMv8的 CRC32加速代码,大约可以获得6倍的加速,可以用于压缩和以太网校验算法的加速

测试代码如下,来自linux kernel arch/arm64/crypto/crc32-arm64.c

使用CRC32指令集需要在编译参数加入-mcpu=generic+crc

#define CRC32X(crc, value) __asm__("crc32x %w[c], %w[c], %x[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32W(crc, value) __asm__("crc32w %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32H(crc, value) __asm__("crc32h %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32B(crc, value) __asm__("crc32b %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CX(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CW(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CH(crc, value) __asm__("crc32ch %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
#define CRC32CB(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))

uint32_t crc32_arm64_le_hw(uint32_t crc, const uint8_t *p, unsigned int len)
{
	int64_t length = len;

	while ((length -= sizeof(uint64_t)) >= 0) {
		CRC32X(crc, *((uint64_t *)p));
		p += sizeof(uint64_t);
	}

	if (length & sizeof(uint32_t)) {
		CRC32W(crc, *((uint32_t *)p));
		p += sizeof(uint32_t);
	}
	if (length & sizeof(uint16_t)) {
		CRC32H(crc, *((uint16_t *)p));
		p += sizeof(uint16_t);
	}
	if (length & sizeof(uint8_t))
		CRC32B(crc, *p);

	return crc;
}

uint32_t crc32c_arm64_le_hw(uint32_t crc, const uint8_t *p, unsigned int len)
{
	int64_t length = len;

	while ((length -= sizeof(uint64_t)) >= 0) {
		CRC32CX(crc, *((uint64_t *)p));
		p += sizeof(uint64_t);
	}

	if (length & sizeof(uint32_t)) {
		CRC32CW(crc, *((uint32_t *)p));
		p += sizeof(uint32_t);
	}
	if (length & sizeof(uint16_t)) {
		CRC32CH(crc, *((uint16_t *)p));
		p += sizeof(uint16_t);
	}
	if (length & sizeof(uint8_t))
		CRC32CB(crc, *p);

	return crc;
}