2. 使用DOCA SDK编译第一个程序
任务目标
编写一个基于DOCA SDK的最小C程序,调用DOCA核心API读取当前DPU的设备信息(如PCIe地址、固件版本),并编译运行验证DOCA开发环境可用。本案例聚焦于从源码到可执行文件的完整编译链路,不涉及DPU业务功能开发。
环境与依赖
- 硬件:NVIDIA BlueField-3 DPU(或兼容的BlueField-2/3平台)
- 操作系统:Ubuntu 22.04(DPU内置或Host交叉编译环境)
- DOCA SDK 2.x(已安装并配置环境变量)
- 编译工具:gcc、make、pkg-config
确认环境就绪:
doca_version # 应输出DOCA版本号
pkg-config --modversion libdoca # 应输出库版本
完整实现代码
创建文件 print_dpu_info.c:
#include <stdio.h>
#include <string.h>
#include <doca_dev.h>
#include <doca_error.h>
#include <doca_log.h>
DOCA_LOG_REGISTER(PRINT_DPU_INFO);
int main(int argc, char *argv[]) {
doca_error_t result;
struct doca_dev *dev = NULL;
const char *pci_addr;
const char *flavor;
uint32_t pcie_vendor_id, pcie_device_id;
/* 初始化DOCA日志系统 */
result = doca_log_init();
if (result != DOCA_SUCCESS) {
fprintf(stderr, "日志初始化失败: %s\n", doca_error_get_descr(result));
return EXIT_FAILURE;
}
/* 打开第一个可用DPU设备 */
result = doca_dev_open(NULL, &dev);
if (result != DOCA_SUCCESS) {
DOCA_LOG_ERR("无法打开DPU设备: %s", doca_error_get_descr(result));
doca_log_destroy();
return EXIT_FAILURE;
}
/* 获取设备信息 */
result = doca_dev_get_pci_addr(dev, &pci_addr);
if (result != DOCA_SUCCESS) {
DOCA_LOG_ERR("获取PCIe地址失败: %s", doca_error_get_descr(result));
goto cleanup;
}
result = doca_dev_get_flavor(dev, &flavor);
if (result != DOCA_SUCCESS) {
DOCA_LOG_ERR("获取设备型号失败: %s", doca_error_get_descr(result));
goto cleanup;
}
result = doca_dev_get_pcie_vendor_id(dev, &pcie_vendor_id);
if (result != DOCA_SUCCESS) {
DOCA_LOG_ERR("获取厂商ID失败: %s", doca_error_get_descr(result));
goto cleanup;
}
result = doca_dev_get_pcie_device_id(dev, &pcie_device_id);
if (result != DOCA_SUCCESS) {
DOCA_LOG_ERR("获取设备ID失败: %s", doca_error_get_descr(result));
goto cleanup;
}
/* 打印信息 */
DOCA_LOG_INFO("=== DPU 设备信息 ===");
DOCA_LOG_INFO("PCIe地址: %s", pci_addr);
DOCA_LOG_INFO("设备型号: %s", flavor);
DOCA_LOG_INFO("PCIe Vendor ID: 0x%04x", pcie_vendor_id);
DOCA_LOG_INFO("PCIe Device ID: 0x%04x", pcie_device_id);
cleanup:
doca_dev_close(dev);
doca_log_destroy();
return (result == DOCA_SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE;
}
编译与运行
创建Makefile(或直接使用命令行编译):
# Makefile
CFLAGS = $(shell pkg-config --cflags libdoca)
LDLIBS = $(shell pkg-config --libs libdoca)
print_dpu_info: print_dpu_info.c
gcc -o $@ $< $(CFLAGS) $(LDLIBS)
clean:
rm -f print_dpu_info
编译并运行:
make
sudo ./print_dpu_info
需要sudo权限以访问DPU设备节点。
验证方法与通过标准
- 编译通过:make无报错,生成可执行文件
print_dpu_info。 - 运行成功:程序退出码为0,日志输出包含以下字段:
=== DPU 设备信息 ===
PCIe地址: 03:00.0
设备型号: BlueField-3
PCIe Vendor ID: 0x15b3
PCIe Device ID: 0xa2d2
以上为预期输出示例,实际值取决于具体硬件。判定通过条件:程序能正常打开设备并打印出非空的PCIe地址和设备型号,且退出码为0。
常见问题
- 设备打开失败:确认已安装DOCA驱动(
doca_device_list命令能看到设备),且当前用户有/dev/doca*访问权限。 - pkg-config找不到库:执行
export PKG_CONFIG_PATH=/opt/mellanox/doca/lib/pkgconfig:$PKG_CONFIG_PATH。 - 编译警告:若提示隐式函数声明,检查DOCA头文件路径是否正确包含
doca_dev.h。