# udi **Repository Path**: xdevices/udi ## Basic Information - **Project Name**: udi - **Description**: Universal Device Interface 通用设备接口 - **Primary Language**: C++ - **License**: BSD-3-Clause - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2019-01-27 - **Last Updated**: 2026-02-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 通用设备接口 > Universal Device Interface(udi)v1.00 ## 介绍 通用设备接口主要对`AD+IF+RF`模式的采集设备进行统一的接口定义,方便应用程序根据统一的接口进行调用,减少应用程序对不同厂商采集设备API的依赖。 ## 硬件结构 ### 1. 通道连接 ```mermaid graph LR; RF1(射频通道1)-->IF1; IF1(中频通道1)--通道1-->AD(AD采集卡); RF2(射频通道2)--通道2-->AD(AD采集卡); IF3(中频通道3)--通道3-->AD(AD采集卡); ANT1(天线)-->RF1; ANT2(天线)-->RF2; ANT3(天线)-->IF3; ANT4(天线)--通道4-->AD(AD采集卡); ``` + 该接口支持多通道AD采集卡,每个通道可支持:`中频卡+射频卡`, `中频卡`,`射频卡`或不连接 + 每个中频通道可配置不同的中频卡,可独立设置中频频率、滤波带宽、增益控制等 + 每个射频通道可配置不同的射频卡,可独立设置射频频点、增益控制等 ### 2. DDC连接 目前仅支持所有DDC通道具备同样的能力,且和所有AD通道是全连接的,如下图所示: ![DDC和AD连接图](img/ad_ddc.png) ## 接口定义 ### 1. 接口版本 > 加载器根据版本号来加载不同版本的接口库,因此,不允许更改版本号 ```c float udiGetApiVer() ``` + 函数说明 用于返回当前设备实现的接口版本,该版本通过宏`UDI_API_VERSION`进行定义,实现时直接返回该值即可 + 参考实现 ```c float udiGetApiVer() { return UDI_API_VERSION; } ``` ### 2. 设备发现 该部分的接口用于发现设备、获取设备信息、创建设备和销毁设备等 #### 2.1 获取设备数量 ```c int udiGetDeviceCount() ``` + 函数说明 用于获取当前系统连接的设备数量,如果返回0或负数则认为没有检测到设备 + 调用说明 调用程序通过该方法来检测设备是否正常连接且正确安装!!!**重要** #### 2.2 获取设备类型 > 可选实现,仅在该接口同时支持不同类型的设备时使用,默认使用udi动态库的名称 ```c udi_status_t udiGetDeviceType(int index, char devType[UDI_MAX_DEVICE_TYPE_LEN]) ``` + 函数说明 用于获取指定序号设备的设备类型,设备类型为字符串,最大长度由`UDI_MAX_DEVICE_TYPE_LEN`宏定义 #### 2.3 获取设备序列号 > 可选实现,仅在同时有多个设备连接时使用,默认使用设备序号 ```c udi_status_t udiGetDeviceSerial(int index, char devSn[UDI_MAX_DEVICE_SN_LEN]) ``` + 函数说明 用于获取指定序号设备的设备型号,该型号应与设备硬件进行绑定来区分不同的设备,一般固化在设备上的存储芯片内 #### 2.4 创建设备 ```c udi_device_t udiCreateDevice(int index, const char* config) ``` + 函数说明 用于创建指定索引的设备实例 - index:设备索引 - config:配置信息,json格式,具体格式由实现者定义 + 实现说明 该API仅用于创建设备,不打开设备 ```c udi_device_t udiCreateDeviceBySerial(const char* devSn, const char* config) ``` + 函数说明 用于创建指定序列号的设备实例 - devSn:设备SN编号 - config:配置信息,json格式,具体格式由实现者定义 + 实现说明 该API仅用于创建设备,不打开设备 #### 2.5 销毁设备 ```c udi_status_t udiDestroyDevice(udi_device_t dev) ``` + 函数说明 用于销毁由`udiCreateDevice`创建的设备对象 + 调用说明 设备销毁后,对应的设备对象不可再次使用 ### 3. 设备打开关闭 该部分的接口用于控制设备的打开、重置和关闭等操作 #### 3.1 打开设备 ```c udi_status_t udiOpenDevice(udi_device_t dev) ``` + 函数说明 用于打开指定的设备 + 实现说明 必须支持设备在关闭后再次打开使用 #### 3.2 重置设备 ```c udi_status_t udiResetDevice(udi_device_t dev) ``` + 函数说明 用于重置指定的设备,重置后设备的所有状态清零,且支持继续使用 #### 3.3 关闭设备 ```c udi_status_t udiCloseDevice(udi_device_t dev) ``` + 函数说明 用于关闭指定的设备,关闭后设备不再允许使用,但支持再次通过`udiOpenDevice`打开后使用 ### 4. 采集卡AD 该部分接口用于控制AD卡,包括:能力查询、参数设置、回调注册、启动停止等 #### 4.1 是否具备AD > 可选实现 ```c bool udiHasAd(udi_device_t dev) ``` + 函数说明 用于指示当前设备是否具备AD功能 + 实现说明 未实现该函数或返回`false`时,认为该设备不具备AD功能 > 注: AD为采集设备的核心功能,每个完整的采集设备必须具备AD功能,仅在单独封装中频卡和射频卡接口时才不实现该函数或返回`false` #### 4.1 查询AD能力 > 仅在具备AD功能时实现 ```c typedef struct { int channelCount; //!< 通道数目 udi_clock_source_t clockSources; //!< 支持的时钟源类型,当多个时钟源时,用|来连接 udi_stream_format_t streamFormats; //!< 支持的数据流格式 udi_i64_t minClockRate; //!< 最高时钟速率 udi_i64_t maxClockRate; //!< 最低时钟速率 }udi_ad_capability_t; udi_status_t udiQueryAdCapability(udi_device_t dev, udi_ad_capability_t& capability) ``` + 函数说明 用于查询当前设备AD卡的能力,包括以下信息: + 通道数目 + 时钟源类型 + 数据流格式 + 最大和最小采样时钟 具体请参考`udi_ad_capability_t` + 调用说明 调用方根据该接口获取AD卡的能力,并依此作为用户设置AD卡的参数约束 > 注: 当前只支持所有AD通道同样的能力配置,不支持每个通道不同配置 #### 4.2 设置AD参数 > 仅在具备AD功能时实现 ```c typedef struct { udi_clock_source_t clockSource; //!< AD时钟源 udi_i64_t clockRate; //!< 时钟速率,Hz }udi_ad_params_t; udi_status_t udiSetAdParams(udi_device_t dev, const udi_ad_params_t& params) ``` + 函数说明 用于设置AD通道的参数 > 注: 目前所有AD通道只支持统一参数设置,不支持对每个AD通道单独设置 #### 4.3 获取AD状态 > 仅在具备AD功能时实现 ```c typedef struct { udi_clock_source_t clockSource; //!< AD时钟源 udi_i64_t clockRate; //!< 时钟速率,Hz int mtu; //!< AD数据回调时的最大传输单元,按样点计 }udi_ad_status_t; udi_status_t udiGetAdStatus(udi_device_t dev, udi_ad_status_t& status) ``` + 函数说明 用于获取AD状态,主要是AD卡当前生效的参数值、回传的最大传输单元 + 调用说明 调用方根据回传的最大传输单元来优化接收缓冲区的申请 #### 4.4 注册AD回调 > 仅在具备AD功能时实现 ```c udi_status_t udiRegAdCallback(udi_device_t dev, udi_callback_t callback, void* userData) ``` + 函数说明 用于注册AD数据的回调函数,`userData`用于传递用户数据,在回调时,用户根据该数据进行相应的处理 + 实现说明 实现方需保存`userData`值,在回调时将`userData`值回传给用户,由用户进行处理 + 调用说明 目前只支持注册单个回调函数,所有AD通道共用同一个回调函数,重复注册时会替换掉之前注册的回调函数和`userData` #### 4.5 打开AD通道 > 仅在具备AD功能时实现 ```c udi_status_t udiOpenAdChannel(udi_device_t dev, int channel) ``` + 函数说明 用于打开指定的AD通道。 #### 4.6 关闭AD通道 > 仅在具备AD功能时实现 ```c udi_status_t udiCloseAdChannel(udi_device_t dev, int channel) ``` + 函数说明 用于关闭指定的AD通道。 #### 4.7 启动AD传输 > 仅在具备AD功能时实现 ```c udi_status_t udiStartAd(udi_device_t dev) ``` + 函数说明 用于启动AD传输。 + 实现说明 所有AD通道只有在启动AD传输后才会真正开始数据回传 #### 4.8 停止AD传输 > 仅在具备AD功能时实现 ```c udi_status_t udiStopAd(udi_device_t dev) ``` + 函数说明 用于停止AD传输 ### 5. 信道化DDC #### 5.1 是否具备DDC > 可选实现 ```c bool udiHasDdc(udi_device_t dev) ``` + 函数说明 用于指示当前设备是否具备DDC功能,当不具备DDC功能时,DDC接口集中的其他方法不需要实现 + 实现说明 + 不实现该方法或返回`false`时,认为不具备DDC功能 + DDC功能和AD功能在同一个库上实现,如果当前封装库未实现AD功能,则也不应具备DDC功能 #### 5.2 查询DDC能力 > 仅在支持DDC时实现 ```c typedef struct { int channelCount; //!< DDC通道数 bool supportDuc; //!< 是否支持数字上变频 udi_stream_format_t streamFormats; //!< 支持的数据流格式,多种流格式用|连接 int minExtractRate; //!< 最小抽取系数 int maxExtractRate; //!< 最大抽取系数 }udi_ddc_capability_t; udi_status_t udiQueryDdcCapability(udi_device_t dev, udi_ddc_capability_t& capability) ``` + 函数说明 用于查询DDC通道的能力,包括以下信息: + DDC通道数 + 是否支持数字上变频 + 数据流传输格式 + 最小和最大抽取系数 具体请参见`udi_ddc_capability_t` + 实现说明 DUC是指将DDC后的基带复信号上变频到`fs/4`的实信号,以减少数据传输量 #### 5.3 设置DDC参数 > 仅在支持DDC时实现 ```c typedef struct { int adSource; //!< 源AD通道号,0~(AD通道数-1) double centerFreq; //!< 中心频点, Hz double sampleFreq; //!< 输出采样率, Sps double bandWidth; //!< 输出带宽, Hz bool duc; //!< 是否进行数字上变频 }udi_ddc_params_t; udi_status_t udiSetDdcParams(udi_device_t dev, int ddcChannel, const udi_ddc_params_t& params) ``` + 函数说明 用于设置指定DDC通道的参数。每个DDC通道的参数可单独设定,需要设定的参数如下: + 源AD通道号。用于指示当前DDC通道的数据从哪个AD通道来源,取值范围为:0~AD通道数-1 + 中心频点。用于设置当前DDC抽取信号的频点,取值范围为:`0~fs/2` + 输出采样率。用于设置抽取信号的输出采样率,取值范围为:`fs/maxExtractRate~fs/minExtractRate`,其中`minExtractRate`和`maxExtractRate`为`udi_ddc_capability_t`中指示的值 + 输出带宽。用于设置抽取信号的滤波带宽,实现方可根据该值选择合适的滤波器 + 数字上变频。用于设置是否对抽取后的信号进行数字上变频,上变频后输出信号为实信号。该值仅在DDC支持DUC功能时有效。如果设置DUC为true但DDC不支持DUC功能,函数应返回错误指示。 #### 5.4 获取DDC状态 > 仅在支持DDC时实现 ```c typedef struct { int adSource; //!< 源AD通道号 double centerFreq; //!< 中心频点, Hz double sampleFreq; //!< 采样率, Sps double bandWidth; //!< 带宽, Hz udi_stream_format_t streamFormat; //!< 数据流格式 int mtu; //!< 最大传输单元,按样点计 bool duc; //!< 数字上变频 }udi_ddc_status_t; udi_status_t udiGetDdcStatus(udi_device_t dev, int ddcChannel, udi_ddc_status_t& status) ``` + 函数说明 用于获取指定DDC通道的当前状态,主要为当前生效的参数等 + 调用说明 调用方需在设置指定DDC通道参数后才能获取对应的状态,否则状态不可用 #### 5.5 注册DDC回调 > 仅在支持DDC时实现 ```c udi_status_t udiRegDdcCallback(udi_device_t dev, udi_callback_t callback, void* userData) ``` + 函数说明 用于注册DDC数据的回调函数,`userData`用于传递用户数据,在回调时,用于根据该数据进行相应的处理 + 实现说明 实现方需保存`userData`值,在回调时将`userData`值回传给用户,由用户进行处理 + 调用说明 目前只支持注册单个回调函数,所有DDC通道共用同一个回调函数,重复注册时会替换掉之前的回调函数和`userData` #### 5.6 打开DDC通道 > 仅在支持DDC时实现 ```c udi_status_t udiOpenDdcChannel(udi_device_t dev, int ddcChannel) ``` + 函数说明 用于打开指定的DDC通道。通道打开后,DDC数据将通过回调函数进行回传 #### 5.7 关闭DDC通道 > 仅在支持DDC时实现 ```c udi_status_t udiCloseDdcChannel(udi_device_t dev, int ddcChannel) ``` + 函数说明 用于关闭指定的DDC通道 ### 6. 中频卡IF 该部分接口为可选实现接口,仅在采集卡配置中频卡时实现 #### 6.1 是否具备IF > 可选实现 ```c bool udiHasIf(udi_device_t dev, int channel) ``` + 函数说明 用于指示当前设备的给定通道是否配置有中频卡 + 实现说明 函数未实现时,则认为所有通道均未配置中频卡 返回`false`时,则认为给定通道未配置中频卡 #### 6.2 查询IF频档 > 仅在支持IF时实现 ```c udi_status_t udiQueryIfFreqCount(udi_device_t dev, int channel, int& freqCount) ``` + 函数说明 用于查询当前中频卡支持的中频频率档数。 如果只支持70M或140M中频,则freqCount返回1 如果同时支持70M和140M中频,则freqCount返回2 如果同时支持更多的中频,则freqCount返回实际支持的中频个数 #### 6.2 查询IF能力 > 仅在支持IF时实现 ```c typedef struct { udi_i64_t freq; //!< 中频频率, Hz udi_i64_t minBandWidth; //!< 最小滤波带宽, Hz udi_i64_t maxBandWidth; //!< 最大滤波带宽, Hz udi_gain_mode_t gainModes; //!< 支持的增益模式,多种模式可用|连接 float minGain; //!< 最小增益, dB float maxGain; //!< 最大增益, dB float minAttenuation; //!< 最小衰减, dB float maxAttenuation; //!< 最大衰减, dB }udi_if_capability_t; udi_status_t udiQueryIfCapability(udi_device_t dev, int channel, //!< AD通道号, int freqIdx, //!< 中频频档序号, 0 ~ freqCount-1 udi_if_capability_t& capability) ``` + 函数说明 用于查询指定通道和指定频档的中频卡能力,包括: + 中频频率 + 最小和最大带宽 + 增益控制模式 + 最小和最大增益值 + 实现说明 当中频卡支持多种中频频率时,通过freqIdx指示要查询的中频频档,函数返回给定频档的能力参数 > freq用于指示当前频档的中频频率,如:70,000,000表示70M中频 > > minBandWidth和maxBandWidth表示当前频档下滤波器的带宽范围 + 调用说明 调用方根据该接口获取中频卡的能力,并依此作为设置中频参数的约束 #### 6.3 设置IF参数 > 仅在支持IF时实现 ```c typedef struct { udi_i64_t freq; //!< 中频频点,Hz udi_i64_t bandWidth; //!< 中频带宽,Hz udi_gain_mode_t gainMode; //!< 增益模式 float gainValue; //!< 增益值,dB。仅在手动增益模式下有效 float attenuation; //!< 衰减值, dB }udi_if_params_t; udi_status_t udiSetIfParams(udi_device_t dev, int channel, const udi_if_params_t& params) ``` + 函数说明 用于设置中频卡的参数 #### 6.4 获取IF状态 > 仅在支持IF时实现 ```c typedef struct { udi_i64_t freq; //!< 中频频点 udi_i64_t bandWidth; //!< 中频带宽 udi_gain_mode_t gainMode; //!< 增益模式 float gainValue; //!< 增益值, dB float attenuation; //!< 衰减值, dB int powerLevel; //!< 能量级别,为负值时表示溢出 }udi_if_status_t; udi_status_t udiGetIfStatus(udi_device_t dev, int channel, udi_if_status_t& status) ``` + 函数说明 用于获取指定通道中频卡的状态 + 调用说明 调用方需在设置指定中频通道参数后才能获取对应的状态,否则状态不可用 ### 7. 射频卡RF 该部分接口为可选实现接口,仅在采集卡配置射频卡时实现 #### 7.1 是否具备RF > 可选实现 ```c bool udiHasRf(udi_device_t dev, int channel) ``` - 函数说明 用于指示当前设备的给定通道是否配置有射频卡 - 实现说明 函数未实现时,则认为所有通道均未配置射频卡 返回`false`时,则认为给定通道未配置射频卡 #### 7.2 查询RF能力 > 仅在支持RF时实现 ```c typedef struct { udi_i64_t minInFreq; //!< 最小输入频率, Hz udi_i64_t maxInFreq; //!< 最大输入频率, Hz udi_i64_t minOutFreq; //!< 最小输出频率, Hz udi_i64_t maxOutFreq; //!< 最大输出频率, Hz udi_i64_t minBandWidth; //!< 最小滤波带宽, Hz udi_i64_t maxBandWidth; //!< 最大滤波带宽, Hz udi_gain_mode_t gainModes; //!< 支持的增益模式,多种模式可用|连接 float minGain; //!< 最小增益, dB float maxGain; //!< 最大增益, dB float minAttenuation; //!< 最小衰减, dB(不支持衰减时填0) float maxAttenuation; //!< 最大衰减, dB(不支持衰减时填0) }udi_rf_capability_t; udi_status_t udiQueryRfCapability(udi_device_t dev, int channel, udi_rf_capability_t& capability) ``` - 函数说明 用于查询指定通道的射频卡能力,包括: - 最小和最大输入频率 - 最小和最大输出频率 - 增益控制模式 - 最小和最大增益值 - 调用说明 调用方根据该接口获取射频卡的能力,并依此作为设置射频卡参数的约束 #### 7.3 设置RF参数 > 仅在支持RF时实现 ```c typedef struct { udi_i64_t inFreq; //!< 输入频点,Hz udi_i64_t outFreq; //!< 输出频点,Hz udi_i64_t bandWidth; //!< 滤波带宽, Hz udi_gain_mode_t gainMode; //!< 增益模式 float gainValue; //!< 增益值,dB(仅在手动增益模式下有效) float attenuation; //!< 衰减值, dB }udi_rf_params_t; udi_status_t udiSetRfParams(udi_device_t dev, int channel, const udi_rf_params_t& rfParams) ``` + 函数说明 用于设置指定射频通道的参数 #### 7.4 获取RF状态 > 仅在支持RF时实现 ```c typedef struct { udi_i64_t inFreq; //!< 输入频点,Hz udi_i64_t outFreq; //!< 输出频点,Hz udi_i64_t bandWidth; //!< 滤波带宽, Hz udi_gain_mode_t gainMode; //!< 增益模式 float gainValue; //!< 增益值 float attenuation; //!< 衰减值, dB }udi_rf_status_t; udi_status_t udiGetRfStatus(udi_device_t dev, int channel, udi_rf_status_t& rfStatus) ``` + 函数说明 用于获取指定射频通道的状态 + 调用说明 调用方必须在设置指定射频通道参数后再进行查询,否则状态不可用 ### 8. 错误信息查询 > 必须实现 ```c const char* udiGetLastError(udi_device_t dev) ``` + 函数说明 用于获取最后一次调用失败对应的错误信息 + 实现说明 实现方必须在内部保存最后一次调用错误时对应的错误信息 + 调用说明 调用方只能在函数返回错误或警告(返回值不等于`udiStatusOk`)时,才能调用该方法,否则返回的错误信息不可用 ## 使用方式 ### 1. 独立使用模式 该模式针对实现了AD功能的封装库,可独立作为采集设备使用 ### 2. 组合使用模式 该模式通过配置文件,对单独的AD、IF、RF封装库进行组装,实现完整的采集设备。 ![组合使用图示](img/combined_udi.png) + 组合配置文件 每个组合通过udi配置文件进行定义,udi配置文件定义**待定** ## 注意事项 射频卡和中频卡在配合使用时,需要注意频率的一致性,即:射频卡的输出频率必须和中频卡的输入频率一致