微知-DOCA ARGP参数模块的相关接口和用法(config单元、params单元,argp pipe line,回调)

文章目录

  • 1. 背景
  • 2. 设置参数的主要流程
    • 2.1 初始化
    • 2.2 注册某个params的处理方式以及回调函数
    • 2.4 定义好前面的params以及init指定config地点后start处理argv
  • 3. 其他
  • 4. DOCA ARGP包相关
    • 4.1 主要接口
    • 4.2 DOCA ARGP的2个rpm包
      • 4.2.1 doca-sdk-argp-2.9.0072-1.el8.x86_64.rpm
      • 4.2.2 doca-sdk-argp-devel-2.9.0072-1.el8.x86_64.rpm
      • 4.2.3 头文件和so库
  • 5. 综述

1. 背景

DOCA: Data Center-on-a-Chip Architecture,片上数据中心架构。是NVIDIA针对DPU的软件框架。DOCA之于DPU,就相当于CUDA之于GPU。本文介绍的是DOCA SDK中的DOCA ARGP模块的机制原理,他是DOCA程序的一个标准参数处理框架。

DOCA ARGP (DOCA Arg Parser)是doca中给用户程序提供的一个处理用户参数的模块。基本原理是提供一个后端处理服务,将-v -vv这种参数以及遇到这种参数给一个回调函数(该回调函数用户提供),然后在回调函数中将用户输入数据存入正确的config数据中。
在doca argp中主要有2种内存,一个是config内存(就是用户在整个模块中的config参数);另一个是params内存,这个内存是用来给argp用的,它定义了多个参数匹配模式元组的表示,也就是后面提到的params的多个接口设置的目的。
然后doca argp使用多个API接口,注册用户期望的多个params,然后根据用户输入的多个参数一一的进入用户定制的处理函数将数据存入用户config空间。
要真正理解本文的流程建议拿一个实际的DOCA samples进行查看。本文使用的源码是doca sapmle中的\doca\samples\doca_devemu\devemu_pci_device_dma\dpu\devemu_pci_device_dma_dpu_main.c

全局关键点预览:
在这里插入图片描述

2. 设置参数的主要流程

  • 先创建一个 param的句柄: doca_argp_param_createstruct doca_argp_param *param。 doca_argp后端提供这个服务,让后端创建相关资源。这里doca后端应该仅仅是使用类似malloc创建资源,后面整整reg才会初始化。可以看到这些params的的本质是KV的方式,key就是前面几个set的key,v是存在通过param_create的内存中。
  • 然后设置参数的几件套:包括-x,–xxx这些指定方式。其中 -x短模式用:doca_argp_param_set_short_name,长模式用:doca_argp_param_set_long_name
  • 然后设置这个参数的description:doca_argp_param_set_description
  • 指定函数处理的调用函数:毁掉函数中从params中指定的参数,送到config中去。也就可以直接从输入参数拷贝到创建的params的资源中去。
  • 设置param的参数类型
  • 指定这些参数后,就能够使用doca_argp_register_param将指定的几个参数赋值到create的资源里面去。并且应该后台有一个-和–的全局链,然后给后面匹配的时候遍历对比。

那么接下来的问题是,在argp后端创建了资源,也给资源进行了赋值。用户程序如何将运行时刻的参数赋值到这些资源上呢?
答案是:doca_argp_start(argc, argv);
当程序运行后,指定了类似–vuid之后,doca_argp_start会从argc和argv中获取这些参数,然后判断比如和前面register的-或者–的参数对比,如果对比上了,就会调用对应的param注册的callback,然后callback中将参数给到用户程序的config里面。这里callback的函数调用的时候,因为有指定param的参数类型,会作为参数传入callback的第二个参数,另外就是前面

那么用户程序的config里面是如何存储到用户参数的呢?

doca_argp_param_create
doca_argp_param_set_short_name
doca_argp_param_set_long_name
doca_argp_param_set_description
doca_argp_param_set_callback
doca_argp_param_set_type
doca_argp_init
将定义的buf注册到argp后端
后端在遍历回调的时候config内存点
doca_argp_register_param
指定参数-x或者--xx
doca_argp_start
将数据给argp后端
memory
【param】test_reg_params1
参数kv结构化表示数据
主要目的是通过-等找到callback
经过callback设置到config
short
-u
long
--vuid
desc
this is a test vuid
callback
function_xxx(params, config)
type
string
argp_backend
argp后端的大概结构
test_reg_params2
test_reg_params1
【config】全局配置数据
参数结构:struct devemu_pci_cfg
APP
APP被调用
argc_argv
将用户输入argc argv的值从params匹配后
配置到config中
回调函数中使用config的结构转义出来

也就是说当doca_argp_start执行后,从用户-等参数就设置到init指定的地址里面。

2.1 初始化

使用doca_argp_init会创建argp的资源
用法:

	result = doca_argp_init("doca_devemu_pci_device_dma_dpu", &devemu_pci_cfg);
	if (result != DOCA_SUCCESS) {
		DOCA_LOG_ERR("Failed to init ARGP resources: %s", doca_error_get_descr(result));
		goto sample_exit;
	}

定义:

struct devemu_pci_cfg {
	char devemu_manager_pci_address[DOCA_DEVINFO_PCI_ADDR_SIZE]; /* Emulated device manager PCI address */
	char dma_dev_name[DOCA_DEVINFO_IBDEV_NAME_SIZE];	     /* DMA device name */
	char vuid[DOCA_DEVINFO_REP_VUID_SIZE];			     /* VUID of emulated device */
	uint64_t host_dma_mem_iova;				     /* IOVA of host DMA memory */
	char write_data[MEM_BUF_LEN];				     /* Data to write to host memory */
};

2.2 注册某个params的处理方式以及回调函数

	result = register_vuid_param("DOCA Devemu emulated device VUID.", vuid_callback);
	if (result != DOCA_SUCCESS)
		return result;

doca_error_t register_vuid_param(const char *description, doca_argp_param_cb_t vuid_callback)
{
	struct doca_argp_param *param;
	doca_error_t result;

	/* Create and register VUID param */
	result = doca_argp_param_create(&param);
	if (result != DOCA_SUCCESS) {
		DOCA_LOG_ERR("Failed to create ARGP param: %s", doca_error_get_descr(result));
		return result;
	}
	doca_argp_param_set_short_name(param, "u");
	doca_argp_param_set_long_name(param, "vuid");
	doca_argp_param_set_description(param, description);
	doca_argp_param_set_callback(param, vuid_callback);
	doca_argp_param_set_type(param, DOCA_ARGP_TYPE_STRING);
	result = doca_argp_register_param(param);
	if (result != DOCA_SUCCESS) {
		DOCA_LOG_ERR("Failed to register program param: %s", doca_error_get_descr(result));
		return result;
	}

	return DOCA_SUCCESS;
}

## 2.3 回调函数:
static doca_error_t vuid_callback(void *param, void *config)
{
	struct devemu_pci_cfg *conf = (struct devemu_pci_cfg *)config;
	const char *vuid = (char *)param;

	return parse_vuid(vuid, conf->vuid);
}

2.4 定义好前面的params以及init指定config地点后start处理argv

从入参中直接赋值到定义的参数中:

	result = doca_argp_start(argc, argv);
	if (result != DOCA_SUCCESS) {
		DOCA_LOG_ERR("Failed to parse sample input: %s", doca_error_get_descr(result));
		goto argp_cleanup;
	}

	if (*devemu_pci_cfg.vuid == 0) {
		DOCA_LOG_ERR("The VUID parameter is missing");
		goto argp_cleanup;
	}

3. 其他

该文章中主要的主要流程的全流程代码

/*
 * Sample main function
 *
 * @argc [in]: command line arguments size
 * @argv [in]: array of command line arguments
 * @return: EXIT_SUCCESS on success and EXIT_FAILURE otherwise
 */
int main(int argc, char **argv)
{
	struct devemu_pci_cfg devemu_pci_cfg;
	doca_error_t result;
	struct doca_log_backend *sdk_log;
	int exit_status = EXIT_FAILURE;

	/* Set the default configuration values (Example values) */
	strcpy(devemu_pci_cfg.devemu_manager_pci_address, "0000:03:00.0");
	strcpy(devemu_pci_cfg.dma_dev_name, "");
	strcpy(devemu_pci_cfg.vuid, "");
	strcpy(devemu_pci_cfg.write_data, "This is a sample piece of data from DPU!");
	devemu_pci_cfg.host_dma_mem_iova = 0x1000000;

	/* Register a logger backend */
	result = doca_log_backend_create_standard();
	if (result != DOCA_SUCCESS)
		goto sample_exit;
	/* Register a logger backend for internal SDK errors and warnings */
	result = doca_log_backend_create_with_file_sdk(stderr, &sdk_log);
	if (result != DOCA_SUCCESS)
		goto sample_exit;
	result = doca_log_backend_set_sdk_level(sdk_log, DOCA_LOG_LEVEL_WARNING);
	if (result != DOCA_SUCCESS)
		goto sample_exit;

	DOCA_LOG_INFO("Starting the sample");

#ifdef DOCA_ARCH_DPU
	result = doca_argp_init("doca_devemu_pci_device_dma_dpu", &devemu_pci_cfg);
	if (result != DOCA_SUCCESS) {
		DOCA_LOG_ERR("Failed to init ARGP resources: %s", doca_error_get_descr(result));
		goto sample_exit;
	}
	result = register_devemu_pci_params();
	if (result != DOCA_SUCCESS) {
		DOCA_LOG_ERR("Failed to register sample command line parameters: %s", doca_error_get_descr(result));
		goto argp_cleanup;
	}
	result = doca_argp_start(argc, argv);
	if (result != DOCA_SUCCESS) {
		DOCA_LOG_ERR("Failed to parse sample input: %s", doca_error_get_descr(result));
		goto argp_cleanup;
	}

	if (*devemu_pci_cfg.vuid == 0) {
		DOCA_LOG_ERR("The VUID parameter is missing");
		goto argp_cleanup;
	}

	result = devemu_pci_device_dma_dpu(devemu_pci_cfg.devemu_manager_pci_address,
					   devemu_pci_cfg.dma_dev_name,
					   devemu_pci_cfg.vuid,
					   devemu_pci_cfg.host_dma_mem_iova,
					   devemu_pci_cfg.write_data);
	if (result != DOCA_SUCCESS) {
		DOCA_LOG_ERR("devemu_pci_device_dma_dpu() encountered an error: %s", doca_error_get_descr(result));
		goto argp_cleanup;
	}

	exit_status = EXIT_SUCCESS;

argp_cleanup:
	doca_argp_destroy();

#else // DOCA_ARCH_DPU
	(void)argc;
	(void)argv;

	DOCA_LOG_ERR("PCI Emulated Device DMA DPU can run only on the DPU");
	exit_status = EXIT_FAILURE;

#endif // DOCA_ARCH_DPU

sample_exit:
	if (exit_status == EXIT_SUCCESS)
		DOCA_LOG_INFO("Sample finished successfully");
	else
		DOCA_LOG_INFO("Sample finished with errors");
	return exit_status;
}


# 定义params的地方:
/*
 * Register the command line parameters for the sample
 *
 * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
 */
static doca_error_t register_devemu_pci_params(void)
{
	doca_error_t result;

	result = register_devemu_manager_pci_address_param(pci_callback);
	if (result != DOCA_SUCCESS)
		return result;

	result = register_dma_device_name_param(device_name_callback);
	if (result != DOCA_SUCCESS)
		return result;

	result = register_vuid_param("DOCA Devemu emulated device VUID.", vuid_callback);
	if (result != DOCA_SUCCESS)
		return result;

	result = register_mem_address_param(mem_address_callback);
	if (result != DOCA_SUCCESS)
		return result;

	result = register_write_data_param(write_data_callback);
	if (result != DOCA_SUCCESS)
		return result;

	return DOCA_SUCCESS;
}

# 将parmas存入到config中的回调函数(config是init函数的时候存入的)
/*
 * ARGP Callback - Handle VUID parameter
 *
 * @param [in]: Input parameter
 * @config [in/out]: Program configuration context
 * @return: DOCA_SUCCESS on success and DOCA_ERROR otherwise
 */
static doca_error_t vuid_callback(void *param, void *config)
{
	struct devemu_pci_cfg *conf = (struct devemu_pci_cfg *)config;
	const char *vuid = (char *)param;

	return parse_vuid(vuid, conf->vuid);
}

4. DOCA ARGP包相关

4.1 主要接口

在这里插入图片描述

4.2 DOCA ARGP的2个rpm包

4.2.1 doca-sdk-argp-2.9.0072-1.el8.x86_64.rpm

在这里插入图片描述

4.2.2 doca-sdk-argp-devel-2.9.0072-1.el8.x86_64.rpm

在这里插入图片描述

4.2.3 头文件和so库

参考doca_argp.h

5. 综述

本文拆解了argp的编程模式。本质就是一个用户态命令输入流的pipe line。并且提出了2个内存块param和config,在pipe line里面通过param中的callback进入每个param的处理流程,处理流程中就是把用户输入的param存入config中

参考:
https://docs.nvidia.com/doca/api/2.9.0/pdf/doca-libraries-api.pdf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/918902.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux之vim模式下全选命令

在Linux系统中,使用Vim编辑器进行全选操作可以通过以下几种方式实现: 1.使用键盘快捷键 按下 ”ggVG”(先按下”g”,再按下”g”,再按下”V”,最后按下”G”)可以全选当前文件内容。其中 ”g…

SQL复杂数据类型处理

背景 数据处理中,经常碰到复杂数据类型,需要将他们进行解析才能利用。 复杂数据类型 1、MAP结构转为列 WITH tmp AS ( SELECT {"Users":{"4418":{"UserId":4418,"Score":0,"IsStudent":true},&q…

下一代以区域为导向的电子/电气架构

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所有人的看法和评价都是暂时的,只有自己的经历是伴随一生的,几乎所有的担忧和畏惧…

CSS盒子的定位>(上篇)#定位属性#相对定位-附练习

一、定位属性 1.定位方式 position属性可以选择4种不同类型的定位方式。 语法格式:position:relation | absolute | fixed参数:①relative生成相对定位的元素,相对于其正常位置进行定位。 ②absolute生成绝对定位的…

Matlab信号处理:短时傅里叶变换

短时傅里叶变换(简称STFT)是傅里叶变换在时频域的扩展,它是为分析频域随时间变化的非平稳信号。本文模拟一个啁啾信号(一个线性调频的信号),借助matlab的短时傅里叶变换函数stft,分析其时频特性…

Linux网络:基于文件的网络架构

Linux网络:基于文件的网络架构 网络架构TCP全连接队列 网络架构 在Linux中提供了多种系统调用,完成网络操作。比如TCP连接的建立,各种报文的收发等等。但是所有的Linux网络操作,都源于系统调用socket, 在Linux的man手…

【SpringBoot】23 文件预览(kkFileView)

Gitee仓库 https://gitee.com/Lin_DH/system 介绍 文件预览功能是指在不打开或编辑文件的情况下,通过某种方式查看文件的内容、格式或者部分内容的功能。该功能通常用于文件管理系统、办公工具、在线教育平台、企业协作平台、电子邮件客户端等领域,能…

Android笔记(三十七):封装一个RecyclerView Item曝光工具——用于埋点上报

背景 项目中首页列表页需要统计每个item的曝光情况,给产品运营提供数据报表分析用户行为,于是封装了一个通用的列表Item曝光工具,方便曝光埋点上报 源码分析 核心就是监听RecyclerView的滚动,在滚动状态为SCROLL_STATE_IDLE的时…

关于Java合并多个Excel中的数据【该数据不是常规列表】,并入库保存的方案

1. 背景 最近在使用RPA(机器人流程自动化)做数据采集的时候。发现那个RPA采集,一次只能采集相同格式的数据,然后入到Excel或者库中。由于院内系统的业务限制,导致采集的数据是多个Excel,并且我们这边的需求…

Robot | 用 RDK 做一个小型机器人(更新中)

目录 前言架构图开发过程摄像头模型转换准备校准数据使用 hb_mapper makertbin 工具转换模型 底版开发 结语 前言 最近想开发一个小型机器人,碰巧看到了 RDK x5 发布了,参数对于我来说非常合适,就买了一块回来玩。 外设也是非常丰富&#xf…

NPOI 实现Excel模板导出

记录一下使用NPOI实现定制的Excel导出模板&#xff0c;已下实现需求及主要逻辑 所需Json数据 对应参数 List<PurQuoteExportDataCrInput> listData [{"ItemName": "电缆VV3*162*10","Spec": "电缆VV3*162*10","Uom":…

TCP/IP--Socket套接字--JAVA

目录 一、概念 二、分类 1.流套接字 2.数据报套接字 三、UDP数据报套接字编程 1.API介绍 2.基于UDP实现简单回显服务器 一、概念 Socket套接字&#xff0c;是由系统提供⽤于⽹络通信的技术&#xff0c;是基于TCP/IP协议的⽹络通信的基本操作单元。 基于Socket套接字的⽹络…

从大数据到大模型:现代应用的数据范式

作者介绍&#xff1a;沈炼&#xff0c;蚂蚁数据部数据库内核负责人。2014年入职蚂蚁&#xff0c;承担蚂蚁集团的数据库架构职责&#xff0c;先后负责了核心链路上OceanBase&#xff0c;OceanBase高可用体系建设、NoSQL数据库产品建设。沈炼对互联网金融、数据库内核、数据库高可…

2024雪浪小镇·京东科技上海产业对接会

11月15日下午对接会由京东科技主办在上海南翔温德姆酒店顺利召开,来自上海本地的AIoT及工业互联网优秀企业、投资人、京东生态合作伙伴齐聚一堂,共同探讨技术赋能和产业协同之路,加速企业发展和促进产业升级。 无锡经开区是无锡最年轻、最具创新动力、产业张力、宜居魅力和开放…

Vue3踩坑记录

目录 一、定义常变量 1.1、ref和reactive到底用谁&#xff1f; 二、双向绑定 2.1、直接改变表格该行数据 2.1、在弹窗改变表格该行数据 一、定义常变量 1.1、ref和reactive到底用谁&#xff1f; 已知&#xff1a;使用ref定义基础类型数据&#xff1b;使用reactive定义复…

ROM修改进阶教程------安卓14去除修改系统应用后导致的卡logo验证步骤 适用安卓13 14 安卓15可借鉴参考

上期的博文解析了安卓14 安卓15去除系统应用签名验证的步骤解析。我们要明白。修改系统应用后有那些验证。其中签名验证 去卡logo验证 与可降级安装应用验证等等的区别。有些要相互结合使用。今天的博文将对修改系统应用后卡logo验证做个步骤解析。 通过博文了解💝💝�…

2024.11.18晚Linux复习课笔记

第一章 cat -n显示行号 -b不显示空行号 pwd 打印当前的工作目录 cd ls 打印当前工作的所有文件 -a -A -l:显示当前文件的详细信息 -r:递归显示 passwd:修改密码 ip a 查看ip地址 poweroff shutdown -h 关机 reboot shutdown -r 第二章 man --help …

数据可视化如何帮助企业提升数据洞察力?

数据驱动时代&#xff0c;企业每天都在面对数据的洪流。一方面&#xff0c;拥有海量数据意味着蕴藏着无尽的机会&#xff1b;另一方面&#xff0c;如果无法提炼这些数据背后的价值&#xff0c;它们只会成为业务发展的负担。例如&#xff0c;许多企业手握丰富的销售数据&#xf…

报错java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not ...解决方法

在运行项目时出现java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field com.sun.tools.javac.tree.JCTree qualidzz这样的报错 解决方法 1.第一步&#xff1a;在pom文件中将lombok的版本改成最新的 此时1.18.34是新…