dwc3 gadget

gadget 框架如下,代码都在 drivers/usb/gadget下面

USB gadget 驱动剖析

dwc3 封装了usb_gadget 和usb_gadget_driver,dwc3 代表了最底层的设备控制器驱动

composite 框架是composite.c

struct dwc3 {
	struct usb_ctrlrequest	*ctrl_req;
	struct dwc3_trb		*ep0_trb;
	void			*ep0_bounce;
	void			*scratchbuf;
	u8			*setup_buf;
	dma_addr_t		ctrl_req_addr;
	dma_addr_t		ep0_trb_addr;
	dma_addr_t		ep0_bounce_addr;
	dma_addr_t		scratch_addr;
	struct dwc3_request	ep0_usb_req;

	/* device lock */
	spinlock_t		lock;

	struct device		*dev;

	struct platform_device	*xhci;//child dev
	struct resource		xhci_resources[DWC3_XHCI_RESOURCES_NUM];

	struct dwc3_event_buffer **ev_buffs;
	struct dwc3_ep		*eps[DWC3_ENDPOINTS_NUM];//ep0,ep1... for device mode

	struct usb_gadget	 gadget;//udc.gadget point this 
	struct usb_gadget_driver *gadget_driver;//point to composite_driver_template @composite.c
	。。。。。。。。。。。。。。。。。
	}
struct usb_gadget_driver {//提供一个通用的usb gadget driver 模板,向下注册到udc,向上给functions driver提供bind 回调等
	char			*function;
	enum usb_device_speed	max_speed;
	int			(*bind)(struct usb_gadget *gadget,
					struct usb_gadget_driver *driver);
	void			(*unbind)(struct usb_gadget *);
	int			(*setup)(struct usb_gadget *,
					const struct usb_ctrlrequest *);
	void			(*disconnect)(struct usb_gadget *);
	void			(*suspend)(struct usb_gadget *);
	void			(*resume)(struct usb_gadget *);
	void			(*reset)(struct usb_gadget *);

	/* FIXME support safe rmmod */
	struct device_driver	driver;
};

 usb_gadget_driver 的一个实例 定义在composite.c

static const struct usb_gadget_driver composite_driver_template = {
	.bind		= composite_bind, //bind usb_gadget and usb_gadget_driver
	.unbind		= composite_unbind,

	.setup		= composite_setup,
	.reset		= composite_disconnect,
	.disconnect	= composite_disconnect,

	.suspend	= composite_suspend,
	.resume		= composite_resume,

	.driver	= {
		.owner		= THIS_MODULE,
	},
};

struct usb_gadget {//represents a usb slave device
	struct work_struct		work;//usb_gadget_state_work
	struct usb_udc			*udc;//udc 控制器
	/* readonly to gadget driver */
	const struct usb_gadget_ops	*ops;//udc ops
	struct usb_ep			*ep0;
	struct list_head		ep_list;	/* of usb_ep */
	enum usb_device_speed		speed;
	enum usb_device_speed		max_speed;
	enum usb_device_state		state;
	const char			*name;
	struct device			dev;// this abstract device.
	unsigned			out_epnum;
	unsigned			in_epnum;

    unsigned			is_dualspeed:1;
	unsigned			sg_supported:1;
	unsigned			is_otg:1;
	unsigned			is_a_peripheral:1;
	unsigned			b_hnp_enable:1;
	unsigned			a_hnp_support:1;
	unsigned			a_alt_hnp_support:1;
	unsigned			quirk_ep_out_aligned_size:1;
	unsigned			is_selfpowered:1;
};

usb_udc 封装了usb gadget和usb_gadget_driver 

struct usb_udc {
    struct usb_gadget_driver    *driver;// define @composite.c
    struct usb_gadget        *gadget;//device,define @udc
    struct device            dev;//the child device to the actual controller
    struct list_head        list;
    bool                vbus;
};
 

 

upper layer上面是复合设备和复合驱动

struct usb_composite_dev {//represents one composite usb gadget
	struct usb_gadget		*gadget;//read-only, abstracts the gadget's usb peripheral controller
	struct usb_request		*req;
	struct usb_request		*os_desc_req;//ep0 request

	struct usb_configuration	*config;

	/* OS String is a custom (yet popular) extension to the USB standard. */
	u8				qw_sign[OS_STRING_QW_SIGN_LEN];
	u8				b_vendor_code;
	struct usb_configuration	*os_desc_config;
	unsigned int			use_os_string:1;

	/* private: */
	/* internals */
	unsigned int			suspended:1;
	struct usb_device_descriptor	desc;
	struct list_head		configs;//配置描述符的list head
	struct list_head		gstrings;
	struct usb_composite_driver	*driver;//对应的驱动
	u8				next_string_id;
	char				*def_manufacturer;

	/* the gadget driver won't enable the data pullup
	 * while the deactivation count is nonzero.
	 */
	unsigned			deactivations;

	/* the composite driver won't complete the control transfer's
	 * data/status stages till delayed_status is zero.
	 */
	int				delayed_status;

	/* protects deactivations and delayed_status counts*/
	spinlock_t			lock;

	unsigned			setup_pending:1;
	unsigned			os_desc_pending:1;
};
struct usb_composite_driver {
	const char				*name;
	const struct usb_device_descriptor	*dev;//设备描述符
	struct usb_gadget_strings		**strings;//字符串描述符
	enum usb_device_speed			max_speed;
	unsigned		needs_serial:1;
	
	 // 用于分配整个设备共享的资源,使用usb_add_config添加配置,必须实现
	int			(*bind)(struct usb_composite_dev *cdev);//用于和复合设备绑定
	int			(*unbind)(struct usb_composite_dev *);

	void			(*disconnect)(struct usb_composite_dev *);

	/* global suspend hooks */
	void			(*suspend)(struct usb_composite_dev *);
	void			(*resume)(struct usb_composite_dev *);
	struct usb_gadget_driver		gadget_driver;//向udc层提供的接口变量,composite_driver_template@composite.c
	//Gadget driver controlling this driver,父类,struct usb_composite_driver 是子类
};

 

dwc3 gadget 如何初始化并添加到udc系统中

dwc3_probe---dwc3_core_init_mode---dwc3_gadget_init

 

mass_storage legacy的复合设备驱动和注册

static struct usb_composite_driver msg_driver = {
	.name		= "g_mass_storage",
	.dev		= &msg_device_desc,//设备描述符
	.max_speed	= USB_SPEED_SUPER,
	.needs_serial	= 1,
	.strings	= dev_strings,//字符串描述符
	.bind		= msg_bind,
	.unbind		= msg_unbind,
};
static int __init msg_init(void)
{
	return usb_composite_probe(&msg_driver);
}
module_init(msg_init);
/**
 * usb_composite_probe() - register a composite driver
 * @driver: the driver to register
 *
 * Context: single threaded during gadget setup
 *
 * This function is used to register drivers using the composite driver
 * framework.  The return value is zero, or a negative errno value.
 * Those values normally come from the driver's @bind method, which does
 * all the work of setting up the driver to match the hardware.
 *
 * On successful return, the gadget is ready to respond to requests from
 * the host, unless one of its components invokes usb_gadget_disconnect()
 * while it was binding.  That would usually be done in order to wait for
 * some userspace participation.
 */
int usb_composite_probe(struct usb_composite_driver *driver)//register a composite driver,向上提供的接口
{
	struct usb_gadget_driver *gadget_driver;

	if (!driver || !driver->dev || !driver->bind)
		return -EINVAL;

	if (!driver->name)
		driver->name = "composite";

	driver->gadget_driver = composite_driver_template;//基类驱动赋值
	gadget_driver = &driver->gadget_driver;//ptr to composite_driver_template

	gadget_driver->function =  (char *) driver->name;
	gadget_driver->driver.name = driver->name;
	gadget_driver->max_speed = driver->max_speed;//fill field

	return usb_gadget_probe_driver(gadget_driver);
}
int usb_gadget_probe_driver(struct usb_gadget_driver *driver)//@udc-core.c
{
	struct usb_udc		*udc = NULL;
	int			ret;

	if (!driver || !driver->bind || !driver->setup)
		return -EINVAL;

	mutex_lock(&udc_lock);
	list_for_each_entry(udc, &udc_list, list) {//udc 就是控制器驱动
		/* For now we take the first one */
		if (!udc->driver)//no driver ,so need find the right one
			goto found;
	}

	pr_debug("couldn't find an available UDC\n");//udc 控制器注册的时候就注册到链表上了udc gadget就指向了实际的已经填充的gadget结构体
	mutex_unlock(&udc_lock);
	return -ENODEV;
found:
	ret = udc_bind_to_driver(udc, driver);//关键
	mutex_unlock(&udc_lock);
	return ret;
}
static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *driver)
{
	int ret;

	dev_dbg(&udc->dev, "registering UDC driver [%s]\n",
			driver->function);

	udc->driver = driver;
	udc->dev.driver = &driver->driver;//driver 地址赋值
	udc->gadget->dev.driver = &driver->driver;

	ret = driver->bind(udc->gadget, driver);//composite_bind @composite.c
	if (ret)
		goto err1;
	ret = usb_gadget_udc_start(udc);//dwc3_gadget_start
	if (ret) {
		driver->unbind(udc->gadget);
		goto err1;
	}
	usb_udc_connect_control(udc);//会回调到usb_gadget的pillup函数,配置上拉,连接到host

	kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);//send event
	return 0;
}

 composite_bind中会创建复合设备,复合设备和复合驱动会绑定到一起。

 

 

 

 

 

 

### LlamaIndex 多模态 RAG 实现 LlamaIndex 支持多种数据类型的接入与处理,这使得它成为构建多模态检索增强生成(RAG)系统的理想选择[^1]。为了实现这一目标,LlamaIndex 结合了不同种类的数据连接器、索引机制以及强大的查询引擎。 #### 数据连接器支持多样化输入源 对于多模态数据的支持始于数据收集阶段。LlamaIndex 的数据连接器可以从多个异构资源中提取信息,包括但不限于APIs、PDF文档、SQL数据库等。这意味着无论是文本还是多媒体文件中的内容都可以被纳入到后续的分析流程之中。 #### 统一化的中间表示形式 一旦获取到了原始资料之后,下一步就是创建统一而高效的内部表达方式——即所谓的“中间表示”。这种转换不仅简化了下游任务的操作难度,同时也提高了整个系统的性能表现。尤其当面对复杂场景下的混合型数据集时,良好的设计尤为关键。 #### 查询引擎助力跨媒体理解能力 借助于内置的强大搜索引擎组件,用户可以通过自然语言提问的形式轻松获得所需答案;而对于更复杂的交互需求,则提供了专门定制版聊天机器人服务作为补充选项之一。更重要的是,在这里实现了真正的语义级关联匹配逻辑,从而让计算机具备了一定程度上的‘认知’功能去理解和回应人类意图背后所蕴含的意义所在。 #### 应用实例展示 考虑到实际应用场景的需求多样性,下面给出一段Python代码示例来说明如何利用LlamaIndex搭建一个多模态RAG系统: ```python from llama_index import GPTSimpleVectorIndex, SimpleDirectoryReader, LLMPredictor, PromptHelper, ServiceContext from langchain.llms.base import BaseLLM import os def create_multi_modal_rag_system(): documents = SimpleDirectoryReader(input_dir='./data').load_data() llm_predictor = LLMPredictor(llm=BaseLLM()) # 假设已经定义好了具体的大型预训练模型 service_context = ServiceContext.from_defaults( chunk_size_limit=None, prompt_helper=PromptHelper(max_input_size=-1), llm_predictor=llm_predictor ) index = GPTSimpleVectorIndex(documents, service_context=service_context) query_engine = index.as_query_engine(similarity_top_k=2) response = query_engine.query("请描述一下图片里的人物表情特征") print(response) ``` 此段脚本展示了从加载本地目录下各类格式文件开始直到最终完成一次基于相似度排序后的top-k条目返回全过程。值得注意的是,“query”方法接收字符串参数代表使用者想要询问的内容,而在后台则会自动调用相应的解析模块并结合先前准备好的知识库来进行推理计算得出结论。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值