如何使用libiio C/C++在ADALM-Pluto中实现数据传输?
libiio中AD9361数据传输逻辑及Matlab等效实现
核心数据传输代码定位
你怀疑的这段代码确实是libiio实现AD9361数据收发的核心逻辑,其中实际触发数据传输的关键函数是循环内的两行:
iio_buffer_push(txbuf):将填充好IQ数据的TX缓冲区推送到硬件,完成信号发送,对应Matlab的transmitRepeat或sdrTransmitter(txWaveForm)iio_buffer_refill(rxbuf):从硬件获取新的RX数据填充缓冲区,完成信号接收
与Matlab传输函数的对应逻辑
Matlab的sdrTransmitter(txWaveForm)或transmitRepeat是高度封装的API,而libiio需要手动完成完整的数据流配置与传输流程,对应步骤如下:
- 设备配置:设置采样率、射频频率、带宽、端口等参数(对应Matlab中SDR对象的属性配置)
- 通道初始化:获取并使能RX/TX的I/Q通道
- 缓冲区创建:创建用于数据暂存的IIO缓冲区(Matlab内部自动管理缓冲区)
- 数据填充/读取:向TX缓冲区写入IQ数据,从RX缓冲区读取IQ数据
- 触发传输:调用
iio_buffer_push/iio_buffer_refill完成实际硬件收发
核心代码片段详解
以下是你提供的代码中关键部分的作用说明:
1. 设备与配置初始化
// 创建IIO上下文,连接到AD9361设备 ctx = iio_create_context_from_uri("ip:192.168.2.1"); // 获取TX/RX设备 get_ad9361_stream_dev(TX, &tx); get_ad9361_stream_dev(RX, &rx); // 配置TX/RX流参数(采样率、频率等) cfg_ad9361_streaming_ch(&rxcfg, RX, 0); cfg_ad9361_streaming_ch(&txcfg, TX, 0); // 获取并使能I/Q通道 iio_channel_enable(rx0_i); iio_channel_enable(rx0_q); iio_channel_enable(tx0_i); iio_channel_enable(tx0_q);
这部分对应Matlab中创建SDR对象并配置参数的步骤,完成硬件的基础配置与通道激活。
2. 缓冲区创建
// 创建非循环缓冲区,大小为1MiS(1024*1024采样点) rxbuf = iio_device_create_buffer(rx, 1024 * 1024, false); txbuf = iio_device_create_buffer(tx, 1024 * 1024, false);
缓冲区是用户空间与硬件之间的数据交互区域,false表示非循环模式(循环模式可用于连续发送固定数据,类似transmitRepeat)。
3. 主循环中的数据收发
while (!stop) { // 推送TX缓冲区,触发硬件发送数据 nbytes_tx = iio_buffer_push(txbuf); // 填充RX缓冲区,从硬件获取接收数据 nbytes_rx = iio_buffer_refill(rxbuf); // 读取RX缓冲区中的IQ数据(示例中交换I/Q) p_inc = iio_buffer_step(rxbuf); p_end = iio_buffer_end(rxbuf); for (p_dat = (char*)iio_buffer_first(rxbuf, rx0_i); p_dat < p_end; p_dat += p_inc) { const int16_t i = ((int16_t*)p_dat)[0]; const int16_t q = ((int16_t*)p_dat)[1]; ((int16_t*)p_dat)[0] = q; ((int16_t*)p_dat)[1] = i; } // 向TX缓冲区写入IQ数据(示例中填充0,替换为你的txWaveForm即可) p_inc = iio_buffer_step(txbuf); p_end = iio_buffer_end(txbuf); for (p_dat = (char*)iio_buffer_first(txbuf, tx0_i); p_dat < p_end; p_dat += p_inc) { // 替换这里的0为你的IQ数据,注意AD9361是12位采样,需要左移4位对齐MSB ((int16_t*)p_dat)[0] = your_i_sample << 4; ((int16_t*)p_dat)[1] = your_q_sample << 4; } // 统计采样数 nrx += nbytes_rx / iio_device_get_sample_size(rx); ntx += nbytes_tx / iio_device_get_sample_size(tx); }
- 若要实现Matlab
sdrTransmitter(txWaveForm)的效果,只需将示例中填充0的部分替换为你的IQ波形数据即可 - 若要实现
transmitRepeat的连续发送,可创建循环缓冲区(将iio_device_create_buffer的第三个参数改为true),填充一次数据后重复推送
内容的提问来源于stack exchange,提问作者Count Zero
相关产品推荐
相关产品推荐

