一文搞懂 USB 设备端驱动框架

strongerHuang 2021-06-06 10:02

关注+星标公众,不错过精彩内容

转自 | 漫谈嵌入式


hello 大家好,今天带领大家学习一下USB 设备端驱动 

内核版本:4.4.94

1. Linux USB 子系统

在介绍设备端驱动前,我们先来看看 Linux USB子系统。这里的子系统是相对于整个Linux kernel 来说的,而非单一设备。从整体概括了USB主机端和设备端的通信框架。

Linux kernel 中早已集成了较为完善的USB协议栈,由于其规模庞大,包含多个类别的设备驱动,所以Linux系统中的USB协议栈也被称为USB子系统。

1.1 主机端

主机端,简化抽象三层:

  • 各种类设备驱动:mass sotrage, CDC, HID等
  • USB 设备驱动:USB 核心处理
  • 主机控制器驱动:不同的USB主机控制器(OHCI/EHCI/UHCI),抽象为HDC。

1.2 设备端

设备端,也抽象为三层:

  • 设备功能驱动:mass sotage , CDC, HID 等,对应主机端的类设备驱动
  • Gadget 设备驱动:中间层,向下直接和UDC通信,建立链接;向上提供通用接口,屏蔽USB请求以及传输细节。
  • 设备控制器驱动:UDC驱动,直接处理USB设备控制器。

2. USB 设备驱动

2.1 gadget 驱动框架拆解1

我们将USB 设备端驱动拆解一下,其驱动框架如下:

上文提到,Gadget 设备层起着至关重要的作用。为上层提供通用的驱动框架,与下层UDC通过Gadget Interface 建立联系。

其中Compsite Framwork 提供了一个通用的usb_gadget_driver 模板,包括各种方法供上层Function driver 使用。(driver/usb/gadget/compsite.c)

从上图我们可以看出,对于USB设备端驱动开发而言,更多的关注的是Function driver这层。USB 控制相关过程,内核提供了一个中间层帮我们屏蔽掉了。

2.2 gadget 驱动框架拆解2

内核版本:Linux Kernel 4.4.94,我们以这个版本进行拆解分析

4.x 的内核相对于3.x的内核在gadget 驱动上分解的更加完善,显得目录结构,层次分明,分工合理,更便于理解。

相对于3.x 的版本,4.4.94这个内核,将原来的、driver/usb/gadget目录进行拆分。通用接口保持不变,比如compsite.c以及functions.c。将usb function driver 进行细分,分为legacy和functions。

有了这些背景,我们再看4.4.94这版内核,gadget驱动框架,如图所示(下图笔者按自己的理解绘制的):

  • legacy:整个Gadget 设备驱动的入口。位于driver/usb/gadget/legacy下,里面给出了常用的usb类设备的驱动sample。其作用就是配置USB设备描述符信息,提供一个usb_composite_driver, 然后注册到composite层。
  • functions:各种usb 子类设备功能驱动。位于driver/usb/gadget/functions,里面也给出了对应的sample。其作用是配置USB子类协议的接口描述以及其他子类协议,比如uvc协议,hid等。
  • 注意:对于一个compsite 设备一个有一个或者多个function,对应的也就有多个functions driver

从这张图上,有没有发现,设备端驱动开发似乎越来越简单了。没错,事实上,我们只需要根据legacy的源码,添加对应的usb设备描述符信息,以及其他若干配置即可。

换言之,我们只需要关心 legacy 这一丢丢就行,对于functions这层会根据业务需要略微调整,不过整体变动不大。

usb 驱动框架之所以复杂,除了需要研究各种复杂的协议,还融合了各种驱动,对于初学者来说,理解起来有点困难。事实上,光是legacy这里也包含其他驱动,比如webcam里有大名鼎鼎的 v4l2 驱动框架。

所以当我学习USB驱动框架的时候,一定要抓大放小,【把握主要脉络,忽略细节】。当我们把一个复杂的驱动逐一拆解的话,其实发现,就没有那么可怕了。

2.3 usb compsite 设备构建

为了便于理解,我们来简单了解一个usb compsite 设备的构建过程:

假设构建一个usb 复合设备,需要支持uac, uac, hid 三个功能 其驱动框架如下:

  • 首先,我们需要一个驱动入口 legacy,用来配置设备描述信息,支持的协议等
  • 然后添加一个配置支持多种接口,这里支持uvc uac hid, 每个接口对应一个functions driver
  • 最后我们把它注册到compsite 层
  • 对于functions driver 有个usb function driver list,在内核注册function driver 时会自动添加到一个链表上。functions.c 就是用来管理所有的function drivers

3. USB gadget 驱动剖析

3.1 相关数据结构

在梳理整个框架前我们先梳理一下几个重要的数据结构,从下到上依次介绍:

usb_udc:

udc 使用,内嵌usb_gadget_driver 和 usb_gadget

struct usb_udc {
 struct usb_gadget_driver *driver;
 struct usb_gadget  *gadget;
 struct device   dev;
 struct list_head  list;
 bool    vbus;
};

usb gadget:

usb 底层操作,包括udc,端点请求等。

struct usb_gadget {
 struct work_struct  work;         /* 工作队列 */
 struct usb_udc   *udc;          /* udc */
 /* readonly to gadget driver */
 const struct usb_gadget_ops *ops; /*gadget 设备操作函数集*/
 struct usb_ep   *ep0;           /* 控制端点,只对setup包响应*/
 struct list_head  ep_list;      /* 将设备的所有端点连成链表,ep0不在其中 */
 enum usb_device_speed  speed; /* 高速、全速和低速 */
 enum usb_device_speed  max_speed; /* 最大速度 */
 enum usb_device_state  state;
 const char   *name;
 struct device   dev;
 unsigned   out_epnum;       /* out ep number */
 unsigned   in_epnum;         /* in ep number */
 struct usb_otg_caps  *otg_caps;

 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   quirk_altset_not_supp:1;
 unsigned   quirk_stall_not_supp:1;
 unsigned   quirk_zlp_not_supp:1;
 unsigned   is_selfpowered:1;
 unsigned   deactivated:1;
 unsigned   connected:1;
};

usb_gadget_driver:

usb_gadget_driver - driver for usb 'slave' devices. usb 从设备驱动通用结构。

  • 作用:提供一个通用的usb gadget driver 模板,向下注册到udc,向上给functions driver提供bind 回调等。

  • 关注:bind 回调、function 驱动名、setup 处理请求

struct usb_gadget_driver {
 char   *function;    /* String describing the gadget's function */
 enum usb_device_speed max_speed; /* Highest speed the driver handles */
 int   (*bind)(struct usb_gadget *gadget, /* the driver's bind callback */
     struct usb_gadget_driver *driver);
 void   (*unbind)(struct usb_gadget *);
 int   (*setup)(struct usb_gadget *, /* 处理ep0 request */
     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_composite_driver:

usb_composite_driver ,设备驱动的入口,用来管理设备配置信息,保存设备描述符。 

重点:关注 bind 方法。

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;

 int   (*bind)(struct usb_composite_dev *cdev); /* bind 方法 */
 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;     /* usb gadget driver */
};

usb_composite_dev:

内嵌gadget对象,以及usb 设备的一些配置和请求,主要用于初始化。

struct usb_composite_dev {
 struct usb_gadget  *gadget;
 struct usb_request  *req;
 struct usb_request  *os_desc_req;

 struct usb_configuration *config; /* usb 配置信息 */

 /* 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;
 struct list_head  gstrings;
 struct usb_composite_driver *driver; /* composite 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;
};

3.2 驱动剖析

如图为一个通用的usb gadget 驱动剖析,框图中只列出了两个function,如果有多个function可以继续添加。关于udc控制器部分,,没有继续画下去,注意我们始终保持一个原则,【抓大放小】,把握重要的脉络即可。

有关 usb 设备端驱动,比较复杂图片包含内容比较多,如果觉得不清楚,后台回复【gadget 驱动】获取高清图

分层分块

上下分层,左右分离的思想。

  • 设备功能驱动
    • legacy 驱动入口
    • functions 驱动实现
  • Gadget 设备层:最重要的是compsite_bind 方法,承上启下的作用。
  • udc 设备控制器层。usb 协议的真正处理。

驱动走向

  • 向下:usb_composite_driver -> usb_gadget_driver->usb_udc
  • 向上回调:udc_bind_to_driver -> composite_bind -> webcam_bind 其中其主要作用的两个结构就是usb_gadget_driver 和 usb_compsite_dev。前者向下注册到udc list 里面,与udc控制器建立绑定关系;后者向上提供接口,供上层配置usb 设备的各种functions 和其他配置信息。

代码分析

  1. 注册usb_composite_driver
module_usb_composite_driver(webcam_driver)
     module_driver(webcam_driver, usb_composite_probe, \
         usb_composite_unregister)
  1. usb_composite_probe
usb_composite_probe(webcam_driver);
        driver->gadget_driver = composite_driver_template;
        gadget_driver = &driver->gadget_driver;
        ...
        usb_gadget_probe_driver(composite_driver_template);
                udc_bind_to_driver(udc, driver);
                        composite_driver_template->bind(udc->gadget, composite_driver_template);
                        usb_gadget_udc_start(udc);
  1. composite_bind
composite_bind(udc->gadget,composite_driver_template);
        cdev->gadget = gadget;
        composite_dev_prepare(webcam_driver,cdev);
                cdev->req = usb_ep_alloc_request(gadget->ep0, GFP_KERNEL); /* 申请端点0 */
                cdev->req->complete = composite_setup_complete;
                cdev->driver = webcam_driver;
                usb_ep_autoconfig_reset(gadget);
        webcam_driver->bind(cdev);
  1. webcam_bind
webcam_bind(cdev);
        usb_get_function_instance("uvc");
                try_get_usb_function_instance("uvc");
                        uvc_alloc_inst();
        usb_add_config();
                webcam_config_bind();
                        usb_get_function();
                        usb_add_function();
                others_config_bind();

其他

关于function driver 我们这里没有详细介绍,这个框图只是一个通用的usb 设备驱动框架图,对于具体的usb function driver 我们这里没有做具体分析。

以f_uvc简单举例,详细过程见内核源码。

DECLARE_USB_FUNCTION_INIT(uvc, uvc_alloc_inst, uvc_alloc);

DECLARE_USB_FUNCTION_INIT(uvc, uvc_alloc_inst, uvc_alloc);
        usb_function_register(&uvcusb_func);
                list_for_each_entry(fd, &func_list, list)
                list_add_tail();

DECLARE_USB_FUNCTION_INIT 

一个通用的驱动模板,用来注册usb_function_driver,并添加到func_list上。

#define DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc)  \
 static struct usb_function_driver _name ## usb_func = {  \
  .name = __stringify(_name),    \
  .mod  = THIS_MODULE,     \
  .alloc_inst = _inst_alloc,    \
  .alloc_func = _func_alloc,    \
 };        \
 MODULE_ALIAS("usbfunc:"__stringify(_name));


#define DECLARE_USB_FUNCTION_INIT(_name, _inst_alloc, _func_alloc) \
 DECLARE_USB_FUNCTION(_name, _inst_alloc, _func_alloc)  \
 static int __init _name ## mod_init(void)   \
 {        \
  return usb_function_register(&_name ## usb_func); \
 }        \
 static void __exit _name ## mod_exit(void)   \
 {        \
  usb_function_unregister(&_name ## usb_func);  \
 }        \
 module_init(_name ## mod_init);     \
 module_exit(_name ## mod_exit)

4. 总结

本文以拆解的方式,逐步剥离 usb 设备端驱动框架,带领大家来重新认识usb 设备端驱动,同时给出了一个 compsite 设备的通用驱动框架模型,并从源码层次分析整个驱动流程。

有关USB 或者 其他类似的高级驱动,笔者有个建议,在初学时一点更要【把握主次,忽略细节】。

比如一个复合的usb 设备可能包含,uvc,uac,hid,等等,视频有uvc function驱动和v4l2驱动,uac也有相应的驱动,衍生展开会非常复杂。

所以当我们先掌握设备端驱动框架以及流程,等后面需要加入其他usb function 驱动再去研究其协议或者驱动,以及衍生驱动。

------------ END ------------


后台回复『USB』『Linux』阅读更多相关文章。


欢迎关注我的公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

欢迎关注我的视频号:


点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

strongerHuang 作者黄工,高级嵌入式软件工程师,分享嵌入式软硬件、物联网、单片机、开发工具、电子等内容。
评论 (1)
游客_12403 2021-06-06 10:08
讲的还行,建议增加demo演示
  • Python DevOps运维开发实战集训营(中级班+高级班)
    今天给大家分享2套课程,《Python DevOps运维开发实战集训营(中级班)》+《Python DevOps运维开发实战集训营(高级班)》,视频+源码+课件文档下载,资料齐全!价值4K的资源!

    Python能够取得如此出色的成绩,与他自身特点及发展密不可分,Python能够大展头角的领域涵盖方方面面,例如系统运维、网站开发、人工智能、网络编程、数学处理、爬虫等。现阶段,掌握一门开发语言已经是高薪运维工程师的必备技能,不会开发,你就不能提高运维工作效率!就不能充分理解公司业务流程!就不能帮助调试、优化!

    对于DevOps领域来说,Python是你首选的开发语言, 因为它易学易用,能够满足大部分自动化需求,快速开发出高大上的运维管理平台,是目前系统运维应用最广泛的语言,没有之一!为此,推出这]课程,帮助你快速提升运维开发能力。只要你跟着老师坚持学习2个月,就能掌握Python+ Django开发Web系统、背后设计思想、代码实现,并通过上手实战理解”自动化运维"在实际工作中的应用,独立开发运维系统。


    中级班大纲:
    第1周 开班仪式
    第2周 第一阶段:Python 快速入门(上)
    第3周 第一阶段:Python 快速入门(下)
    第4周 第二阶段:Django 入门与进阶(上)
    第5周 第二阶段:Django 入门与进阶(下)
    第6周 第三阶段:前端基础 HTML-CSS-JS-Layui
    第7周 第三阶段:前端基础 HTML-CSS-JS-Layui
    第8周 第四阶段:项目案例:K8s管理平台(1)
    第9周 第四阶段:项目案例:K8s管理平台(2)
    第10周 第四阶段:项目案例:K8s管理平台(3)
    代码+课件


    高级班大纲:
    第1周、开班仪式
    第2周、第一阶段:Django REST Framework框架(上)
    第3周、第一阶段:Django REST Framework框架(下)
    第4周、第二阶段:Vue 前端开发
    第5周、第二阶段:Vue前端开发
    第6周、第三阶段:CMDB项目实战(API平台开发)
    第7周、第三阶段:CMDB项目实战(API平台开发)
    第8周、第三阶段:CMDB项目实战(前端开发)
    第9周、第四阶段:应用自动发布项目实战(服务端)
    第10周、第四阶段:应用自动发布项目实战(前端)
    第11周、第四阶段:应用自动发布项目实战(前端)
    第12周、第四阶段:应用自动发布项目实战(前端)
    课程配套代码和文档

  • 统计学习方法-李航-清华大学出版社
    统计学习方法-李航-清华大学出版社
  • 华普物联16路IO串口继电器 HP-IO0016

    HP-IO0016 系列产品是采用标准 Modbus- RTU 协议的继电器设备,支持 RS485/232 或网络通 信。HP-IO0016 产品具备 2 路 IN 输入接口、2 路继电器输出接口、2 路 AI 模拟量输入和一路 RS485 接口,支持宽电压供电,多路输入输出控制,可广泛应用于工业生产、农业、智慧城市、写字楼等 各类应用场景。

  • 线性系统理论与设计
    线性系统理论与设计 陈启宗1988
  • 华普物联两路IO串口继电器 HP-IO222

    HP-IO222 系列产品是采用标准 Modbus- RTU 协议的继电器设备,支持 RS485/232 或网络通信。HP-IO222 产品具备 2 路 IN 输入接口、2 路继电器输出接口、2 路 AI 模拟量输入和一路 RS485 接口,支持宽电压供电,多路输入输出控制,可广泛应用于工业生产、农业、智 慧城市、写字楼等各类应用场景

  • 高效程序员的45个习惯 - 敏捷开发修炼之道
    高效程序员的45个习惯 - 敏捷开发修炼之道(epub格式,附阅读器安装程序)
  • 华普物联HP-ERS-GW120 RS485/以太网网关

    HP-ERS-GW120是一款高性能的modbus网关,采用了高性能工业处理器ARM926E),主频达到300MHZ,具有出色的数据处理能力和响应速度。

    该产品支持4路干接点输入和2RS485接口,可以实现设备之间的稳定通信和管理。用户可以通过网页配置添加自定义modbus DI输入和modbus DO输出,灵活添加场景列表,通过自定义输入控制自定义输出。HP-ERS-GW120适用于一些需要灵活配置的场景,如工业自动化和智能酒店等。它具有高可靠性、高稳定性、高性能和易用性,可以满足各种应用场景的需求,提高生产效率和管理水平,降低成本和风险。

  • 赋能三板斧:让天下没有难做的培训-安秋明
    赋能三板斧:让天下没有难做的培训-安秋明
  • 电气设备安装工(初级)(第2版)-朱照红
    电气设备安装工(初级)(第2版)-朱照红
  • 游戏数据分析的艺术-于洋-余敏雄-吴娜-师胜柱
    游戏数据分析的艺术-于洋-余敏雄-吴娜-师胜柱(mobi格式,附阅读器安装程序)
  • 射频电路设计与仿真实例[徐兴福著]2014年版
    本书主要介绍使用ADS2011进行射频电路的设计和仿真,书中包含大量的工程实例
  • 零静态功耗理想二极管介绍
    零静态功耗的理想二极管介绍
  • 统计学习方法(第2版)-课件-李航
    统计学习方法(第2版)-课件-李航
  • 万亿级流量转发:BFE核心技术与实现
    万亿级流量转发:BFE核心技术与实现(epub格式,附阅读器安装程序)
  • 2020 年, 世界上最大的CTD 传感器生产商——美国 Seabird 公司对我国用户限制采购, 其产品不得用于“军事最终用途”或“军事最终用户”,导致我国几乎所有的水下移动平台均无法采购到该公司 CTD 传感器产品, 短期内又无法获得相应的替代仪器, 严重影响了产品应用, “卡脖子”之痛油然而生。据2020年由传感器国家工程研究中心等四个行业核心机构,联合发布的权威报告《中国传感器发展蓝皮书》,特别写到中国高端传感器的应用市场几乎被国外垄断,其中列举了汽车传感器、智能气体传感器、光
    传感器专家网 2023-06-01 19:36 121浏览
  • “七天制作新游戏”、“AI全自动完成所有游戏!”......继各种AI绘画、AI合成照片、视频之后,AI在游戏领域开启了新一场狂欢。长久以来,游戏和AI一直有着“相互扶持”的亲密关系——一边是游戏充当AI科研基地,正向拉动AI技术进步;一边是AI定位为先进的技术工具,为游戏体验带来更多可能性。如今,ChatGPT彻底引爆AI领域,与人工智能有所关联的行业深受影响,游戏和AI之间的关系亦有了更深层次的连接。AI是游戏的活水源伴随着AI绘画、AI合成图片视频接连爆火,AI技术应用的重要性愈加突出,“
    刘旷 2023-06-02 10:27 153浏览
  • 过电压保护器采用放电间隙给氧化锌阀片分压的方法,降低产品的操作冲击保护残压,来实现对操作过 电压的保护;与此同时采用四星型接法,也叫做三叉戟式接法,设置公共中性点,实现对相间过电压的 快速响应,有效的防止三相负载出现相间绝缘击穿。 针对ZB-TBP-35kV/310型过电压保护器的型式试验报告都检测哪些项目呢? 先要对最为直观的项目进行检查,就是过电压保护器的外观。 检测内容:1、外观表面单个缺陷面积不能超过5mm²    &nb
    保定众邦电气 2023-06-02 14:17 247浏览
  • 一、去年在调试MARVELL 88E6320,交换机功能调通。剩下SMI通讯去访问芯片寄存器,这个功能可有可无,调不通的话就当作傻瓜交换机用。所幸调通,也是迷迷糊糊,自己太菜鸡了~二、下面分享一下调试过程第一篇 port 操作 只有2个寄存器可以直接访问,命令寄存器(0x00)和数据寄存器(0x01),其他寄存器要通过这两个寄存器访问。 读写流程 读写某一个功能寄存器的时候,必须通过命令寄存器(0x00)和数据寄存器(0x01)实现 读指令 先往命令
    LIN 2023-06-02 10:00 193浏览
  • 探针台可以按照使用类型与功能来划分,也可以按照操作方式来划分成:手动探针台、半自动探针台、全自动探针台。手动探针台系统顾名思义是手动控制的,这意味着晶圆载物台、显微镜以及定位器/操纵器都是由使用者手动移动的。因此一般是在没有很多待测器件需要测量或数据需要收集的情况下使用手动探针台。该类探针台的优点之一是只需要很少的培训,易于配置环境和转换测试环境,并且不需要涉及额外培训和设置时间的电子设备、PC或软件。由于其灵活和可变性高的特点,非常适合研发人员使用。全自动探针台相比上述两种添加了晶圆材料处理搬
    锦正茂科技 2023-06-02 11:49 200浏览
  •          2020年初,作为ICT的老兵,无可意外的遇到了“安可”和“信创”,而在琶洲听了倪光南院士的网信安全讲座,更是燃起了中国人的民族自尊心,我想既然工作可以为国家的战略贡献一点点力量,就扎根信创,做出点样子。      随后的事情,华为一次制裁,曙光制裁,华为二次加严制裁,飞腾被制裁,长存被制裁,更多更长的实体清单,给信创的发展带来了巨大的障碍,也严重的冲击了从业者的信心。    &
    天涯书生 2023-06-03 10:17 256浏览
  • RKNN(Rockchip Neural Network)是一种用于嵌入式设备的深度学习推理框架,它提供了一个端到端的解决方案,用于将训练好的深度学习模型转换为在嵌入式设备上运行的可执行文件。使用RKNN框架可以在嵌入式设备上高效地运行深度学习模型,这对于需要在资源受限的设备上进行实时推理的应用场景非常有用。例如,可以将RKNN用于智能摄像头、机器人、无人机等嵌入式设备中,实现物体检测、人脸识别、图像分类等人工智能功能。RKNN-Toolkit2是为用户提供在 PC、 Rockchip NPU
    飞凌嵌入式 2023-06-02 11:23 207浏览
  • 目前已知WDM波分复用技术有很多种,如:FBT (熔融拉锥,Fused Biconical Taper)、FBG(光纤布拉格光栅,Fiber Bragg Grating)、TFF (薄膜滤波, Thin Film Filter)、AWG (阵列波导光栅, Arrayed Waveguide Grating)、EDG (刻蚀衍射光栅,Etched Diffraction Grating)、MZI (马赫-曾德干涉,Mach-Zehnder Interferometers)、MRR (微环谐振器型,
    hycsystembella 2023-06-02 11:11 214浏览
  • 一、前言在这个数字化时代,物联网HMI已成为连接人与设备之间的关键纽带,为用户提供直观、智能的交互体验,背后强大的关键驱动力扮演着至关重要的角色,其中SCADA级功能库和控件库的引入成为了物联网HMI设计和开发的核心要素。SCADA级功能库为物联网HMI带来了出色的数据可视化和边缘计算能力,能够实现对复杂系统和设备的实时监测与控制,协助用户快速制定和执行生产决策;SCADA级控件库为物联网HMI提供了丰富的交互元素和可视化控件,创建出直观、个性化的可视化界面,满足不同应用场景的需求,提供更好的用
    工业物联网技术 2023-06-01 21:46 174浏览
  • 5月24日至26日,第十六届(2023)国际太阳能光伏与智慧能源展览会(SNEC)在上海举行,“新能源人”齐聚一堂。时隔两年,SNEC展会吸引了超过50万人注册,3100多家企业出席,吸引大批海内外观众前来,展览规模创世界之最,无疑把新能源的市场热度再次推向一个制高点。 势能资本创始人黄俊受邀出席 SNEC 第七届国际储能技术和装备及应用(上海)大会。会上,黄俊发表题为《储能领域的资本市场和创新机会》主题报告,分享势能资本对当前全球储能产业复杂竞争格局的思考,并探讨国内储能产业未来的
    势能资本 2023-06-02 10:48 305浏览
  • 电车怎么充电最省钱跟燃油车相比,纯电动车充电费用确实比加油要便宜很多。但是老话说的好“吃不穷穿不穷,算计不到就受穷”,其实在充电这件事上还是有很多省钱小窍门儿的。比如说:充电站所在的停车场停车费贵不贵?在公共充电站充电时,充电费用是否执行峰谷电价?别看这些都是小钱,但是积少成多之后,可能就是一笔可观的费用。今天四川英特丽小编就来给大家介绍一些充电时比较省钱的方法。我们的电费都由哪些费用组成?其实,在纯电动车的日常充电中,我们最后的“充电费用”可能由三部分组成:电费、服务费和停车费。前两种费用在公
    四川英特丽科技有限公司 2023-06-02 08:40 160浏览
  • 软件介绍Vayo-Stencil DesignerVayo-Stencil Designer(简称VSD)是一款面向企业的专业钢网设计软件,可以为企业高效构建适合企业自身产品和工艺know-how的数字化开口规范,解决钢网开口审查、局部开口设计、完整钢网设计、PIP焊料填充率计算等场景需求。场景介绍First Frost场景一:工艺数字化开口库构建和管理专利技术智能学习功能,将企业量产验证的钢网自动学习到钢网开口数据库,绝大部分企业1~3天即可完成企业数字化钢网开口库的构建,将企业钢网开口Kno
    望友科技 2023-06-02 13:16 246浏览
  • 汽车电子电气架构(E/E架构)的升级主要体现在三大层面:硬件架构从分布式向域控制/中央集中式方向发展,软件架构从高耦合向分层解耦方向发展,通信架构由LIN/CAN 总线向以太网方向发展。在汽车智能化趋势下,立足于E/E架构,将功能安全和信息安全的方案融入整车架构、系统需求与软硬件设计,同时基于实际运行,持续验证和迭代功能安全和信息安全设计,从而进一步保障智能汽车全生命周期的安全。现阶段主要处于域集中式阶段,各主机厂量产的E/E架构方案主要分为三种:功能域、跨域融合、中央计算平台+区控制器。201
    可可盖世大学堂 2023-06-02 10:48 254浏览
  • 黄世勋 | 生成式AI |COMPUTEX2023英伟达 | 大模型 | 台北电脑展 |GH2002023年是大语言模型、生成式AI、ChatGPT、AIGC大爆发的一年。GPU是大规模深度学习、高性能计算的重要硬件基础,而大语言模型,如生成式AI、ChatGPT等,则借助GPU的计算能力快速地训练和推理,获得更高的模型效果和更广泛的应用场景。尤其在游戏开发领域,运用大语言模型可以加强游戏的情节推进、人工智能角色表现等方面的体验,而加速训练的英伟达GPU则
    蓝海大脑GPU 2023-06-02 11:55 235浏览
我要评论
1
33
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦