当前位置: 首页 > news >正文

Linux内核编程(二十一)USB应用及驱动开发

       

一、基础知识 

1. USB接口是什么?

        USB接口(Universal Serial Bus)是一种通用串行总线,广泛使用的接口标准,主要用于连接计算机与外围设备(如键盘、鼠标、打印机、存储设备等)之间的数据传输和电力供应。它旨在简化计算机与外部设备之间的连接方式,同时提供更高的传输速度和更好的兼容性。

         在1990年代初,计算机外围设备通常使用专用接口,如鼠标和键盘常见的PS/2接口,打印机使用的LPT接口(并口)等。这些接口虽然在当时各自具有一定的专用性和高效性,但也存在很多问题,随着技术的发展,通用性更强的接口逐渐成为主流,USB(Universal Serial Bus)便是这一发展潮流的代表。 

        1996年,由Intel微软康柏DECIBMNEC北方电信公司等七家业界巨头组成的非盈利组织USB标准化组织(USB Implementers Forum,简称USB-IF)开始推动USB(Universal Serial Bus)接口的标准化工作。USB的诞生标志着计算机外围设备连接方式的革命性转变。

USB 1.0/1.1最早的版本,传输速度为12 Mbps。
USB 2.0

提供更高的传输速度(最高480 Mbps),广泛应用于各种设备。

USB 3.0/3.1提供更高的数据传输速率,最高可达5 Gbps及以上,支持更大的电流供电。
USB 4.0最新的USB版本,支持更高的传输速率,最高可达40 Gbps,并且兼容Thunderbolt 3协议。

2. USB命名规则

        在2013年,USB 3.0USB 3.1推出后,USB实现了更高的传输速度和更多功能,但随着技术的进步和市场的需求,USB-IF(USB Implementers Forum)为了更清晰地区分不同的版本和性能,进行了命名上的调整。

第一次命名改变:

                USB 3.0 改名为 USB 3.1 Gen 1

                USB 3.1 改名为 USB 3.1 Gen 2

第二次命名改变:

                USB 3.1 Gen1 = USB 3.2 Gen1
                USB 3.1 Gen2 = USB 3.2 Gen2
                USB 3.2 = USB 3.2 Gen2x2

        其本质上就是, USB 3.0 就是 USB 3.2 Gen1 ,USB 3.1是USB 3.2 Gen2,USB 3.2是USB 3.2 Gen2x2。

3. USB HOST和USB OTG

        USB Host(主设备):是指具备控制和管理USB总线的设备。它负责控制所有USB连接的设备,发起数据传输,并管理设备间的通信。USB Host的核心功能是控制和调度USB数据的流向。典型的USB Host设备包括:计算机(台式机、笔记本电脑等)、打印机(具有USB接口的)等。在USB通信中,Host设备通过发送命令来请求从设备发送或接收数据。Host设备管理USB总线上的电源供给和数据传输。

        USB Slave(从设备):是指依赖于主设备控制的设备。USB从设备由主设备管理,它没有独立的数据传输能力,所有的数据传输都必须经过主设备发起或协调。USB从设备通常是外设设备,例如:键盘、鼠标、U盘等。

        USB OTG(On-The-Go):是一项功能,使得USB设备在需要时可以切换角色,既可以作为主设备,也可以作为从设备,从而直接与其他USB设备进行通信。USB OTG标准通常适用于移动设备,如智能手机、平板电脑等。它允许用户无需通过传统的主设备(如计算机)即可实现设备间的直接连接和数据交换。例如,一台支持OTG的手机可以在连接U盘时充当主设备,而在连接键盘时又可以充当从设备。

4. USB集线器(hub)

        USB Hub(集线器)是一种设备,允许多个USB设备通过一个USB端口与计算机进行连接。它实际上是一个多端口的USB接口扩展器,可以将计算机的一个USB端口扩展为多个端口,方便用户连接多个USB设备。 集线器是为了扩展更多的接口。但是并不是可以无休止的可以扩展,USB2.0协议中最多扩展七层。每一层所有设备相加不能超过127个(包括集线器) 。

        所有从机都必须经过集线器(hub)才能与主机连接,也就是设备不能直接和主机相连接。根集线器:与主机直接连接的集线器叫做根集线器,用户外接的叫做普通集线器。

下图的集线器就是普通集线器。

下图中集线器就是根集线器, 例如U盘的插入就是连接到根集线器上。

     

5. USB描述符

        描述符通常是一种数据结构,在 Linux里面就是一个结构体,使用结构体来描述当前的设备有哪些特征,用于描述某个对象或设备的属性和特征。在USB和其他通信协议中,描述符扮演着重要的角色,它们包含了设备的基本信息,如设备类别、供应商ID、产品ID等,这些信息对于主机来说至关重要,因为主机需要依靠这些信息来识别和管理连接的设备。例如下述内容。

/* USB Device Descriptor */
struct usb_device_descriptor {uint8_t  bLength;              // 描述符的长度(以字节为单位),对于设备描述符来说总是18字节uint8_t  bDescriptorType;      // 描述符类型,对于设备描述符来说总是0x01uint16_t bcdUSB;               // USB规范版本号,以二进制编码的十进制数表示uint8_t  bDeviceClass;         // 设备类别代码uint8_t  bDeviceSubClass;      // 设备子类代码uint8_t  bDeviceProtocol;      // 设备协议代码uint8_t  bMaxPacketSize0;      // 端点0的最大数据包大小(以字节为单位)uint16_t idVendor;             // 供应商IDuint16_t idProduct;            // 产品IDuint16_t bcdDevice;            // 设备版本号,以二进制编码的十进制数表示uint8_t  iManufacturer;        // 供应商字符串描述符的索引uint8_t  iProduct;             // 产品字符串描述符的索引uint8_t  iSerialNumber;        // 序列号字符串描述符的索引uint8_t  bNumConfigurations;   // 支持的配置数量
} __attribute__((packed));

        USB 描述符主要有:设备描述符,配置描述符,接口描述符,端点描述符。这些描述符共同构建了USB设备的特征和功能,通过读取这些描述符,系统可以配置驱动和参数,使得操作系统可以正确识别设备和通信。

(1)设备描述符:是USB设备中最重要的描述符之一,它包含了设备的基本信息,如设备类型、供应商ID、产品ID、设备版本等。这个描述符通常位于设备的EEPROM或闪存中,并在设备枚举过程中被主机读取。通过读取设备描述符,主机可以了解设备的基本属性,并决定如何与设备进行通信。设备描述符是设备连接到主机时第一个被请求和返回的信息。它提供了设备的本特征。

(2)配置描述符:描述设备支持的不同配置。

(3)接口描述符:描述了配置中的一个接口。

(4)端点描述符:描述接口中的一个端点。端点是数据在设备和主机之间传输的终点。一个具体的端点只能属于四种传输模式中的一种。

注意:
        一个USB设备有1个设备描述符。
        一个USB设备有1个或多个配置描述符。
        一个USB配置有1个或多个接口描述符。
        一个USB接口有0个或多个点描述符(不括端点0)。

6. 传输模式

 USB有四种传输模式:批量传输、中断传输、实时传输、控制传输。

(1)批量传输:适用于大数据量传输,且对实时性要求不高。主要用于传输不需要定时保证的数据,传输时没有时间限制,可以在空闲带宽下传输数据。常见应用:U盘、外部硬盘等。

(2)中断传输:用于传输少量、具有时间限制的数据,主机定期请求数据,传输间隔由设备和主机协商。实时性要求较高,但数据量较小,且数据传输频率是固定的。常见应用:鼠标、键盘、游戏手柄等输入设备。

(3)实时传输:适用于需要固定传输速率的场景,实时性要求高,但允许一定程度的丢包或误差。一般用于音频、视频等流式数据传输,确保数据能够以固定速率传输,尽管可能会丢失一些数据。常见应用:音视频设备、USB音响、摄像头等。

(4)控制传输(Control Transfer):用于设备配置、查询和命令的传输,数据量较小,且是双向传输。常用于 USB 设备的初始化和命令交换,传输的内容通常较为简单。常见应用:设备配置、读取设备状态、设置设备功能等。控制传输分为三个阶段:①建立阶段。②数据阶段。③确认阶段。

7. USB数据格式

        US8通信数据格式由域、包、事务、传输组成。多个域组成包,多个包组成事务,多个事务组成传输。所以域是 USB 数据传输中最小的单位。事务是最基本的单位,对于我们开发人员来说关注事务和传输就可以了。

(1)域(Domain)

  • 是 USB 数据传输中的最小单位。每个域有特定的作用和格式,可以包含一个或多个字段。
  • 七种类型的域
    • 同步域(SYNC):用于同步传输时钟,确保数据传输的时序性。
    • 地址域(ADDR):标识 USB 设备的地址,通常用于指定数据的目标设备。
    • 端点域(ENDPT):指定数据的目标端点,用于区分设备的不同数据流。
    • 帧号域(FRAME):用于标识当前传输的帧号,在多帧传输中起到区分作用。
    • 标识域(ID):用于标识不同的传输或者数据包。
    • 数据域(Data):实际的数据内容区域,是传输的核心部分。
    • 校验域(CRC):包含用于检验数据完整性的校验码,确保数据传输过程中没有错误。

(2)包(Packet)

        包是由多个域组成的数据单元。根据包的不同类型,域的结构会有所不同。USB 包有四种主要类型:

令牌包(Token Packet):用于向设备发送请求或命令,包含地址和端点等信息。

数据包(Data Packet):用于传输实际的数据,包含数据域和校验域。

握手包(Handshake Packet):用于确认数据传输的结果,常见的有 ACK(确认)和 NAK(未确认)等。

特殊包(Special Packet):用于特殊的控制或管理操作,例如 RESET 或 SOF(帧开始信号)。

        

        在 USB 中,PID 代表 Packet ID,即 数据包标识符。它用于标识 USB 数据包的类型,并且是在令牌包(Token Packet)和握手包(Handshake Packet)中必不可少的字段。常见的 PID 类型:

  • 令牌包(Token Packet)

    • OUT:用于主机向设备传输数据。
    • IN:用于设备向主机传输数据。
    • SETUP:用于设置设备的控制传输。
  • 数据包(Data Packet)

    • DATA0:表示数据包的第一个数据包,常用于控制传输。
    • DATA1:表示数据包的第二个数据包。
  • 握手包(Handshake Packet)

    • ACK:确认数据包传输成功。
    • NAK:表示数据包传输失败。
    • STALL:表示设备在处理数据时发生错误,无法完成请求。
  • 特殊包(Special Packet)

    • PRE:预留包(用于扩展等特殊用途)。

(3)事务(Transaction)

  • 事务是 USB 数据传输的基本单位,是由令牌包、数据包和握手包组成的。事务是传输过程中最小的可操作单元。
  • 事务的结构
    • 令牌包(Token Packet):发起事务,标识目标设备、端点等信息。
    • 数据包(Data Packet):可选,用于传输实际的数据。
    • 握手包(Handshake Packet):可选,用于确认数据传输是否成功。
  • 对开发者而言,事务是关注的重点,因为它直接影响数据的传输成功与否。

(4)传输(Transfer)

  • 传输是更高层次的概念,通常由多个事务组成,多个事务之间在时间上有一定的顺序。
  • 一个完整的传输可能涉及多个包、事务和域,最终确保数据从主机到设备(或反向)成功传送。

举例:

8. USB枚举

        USB枚举(USB Enumeration)是指USB设备连接到计算机时,操作系统对该设备进行识别和配置的过程。这个过程包括一系列步骤,确保计算机能够正确识别设备、安装必要的驱动程序并为设备分配资源。

        在USB枚举过程中主要使用控制传输模式。通常用于设备和主机之间的命令和状态交换。它的工作流程分为三个阶段:建立阶段(Setup)数据阶段(Data)确认阶段(Status)

(1)建立阶段。

        由USB主机发起,该阶段使用的是一个SETUP数据包,其结构包含了请求的命令、参数、设备的目标等信息。通过SETUP数据包,主机向设备发送命令,或者设备准备接收或发送数据。

        如果是输入请求(例如获取设备信息),则设备会准备好数据供主机接收。如果是输出请求(例如配置设备),则设备会准备好数据接收主机发出的命令。

(2)数据阶段。

        如果建立阶段是输入请求,则数据阶段由设备向主机传输数据。如果建立阶段是输出请求,则数据阶段由主机向设备传输数据。如果没有实际的数据传输需求(即请求的长度为零),此阶段依然会发送一个长度为0的数据包来表示数据传输完成。

(3)确认阶段。

        确认阶段刚好跟建立阶段相反。如果数据阶段是输入请求(即主机接收设备数据),那么确认阶段是设备向主机发送一个输出数据包。如果数据阶段是输出请求(即主机向设备发送数据),那么确认阶段是主机向设备发送一个输入数据包。

        确认阶段的主要目的是验证数据是否已经正确传输。如果传输成功,确认阶段不会包含任何数据;它只是作为一种状态确认,以告知数据传输是否正常完成。通常,成功的确认阶段只包含一个零长度数据包,这意味着数据传输完成且没有错误。

查看USB枚举过程中的数据内容,如下所示:

(1)传输。

(2) 传输和事务。

(3) 传输、事务、包和域。

 

 ★举例USB枚举过程:

二、应用编程 

1. libusb库安装

  libusb 是一个用 C 语言编写的开源库,主要用于简化 USB 设备的操作。通过 libusb,开发者可以方便地与 USB 设备进行通信,而不需要深入了解 USB 协议的底层细节。

  libusb 提供了跨平台的 API,可以在 Linux、macOS 和 Windows 等操作系统中使用,极大地提升了应用的可移植性。libusb 提供了一套简洁的 API,支持从 USB 1.0 到 USB 3.1 等不同版本的 USB 协议。无论是在传输数据、控制 USB 设备还是处理设备的其他操作时,API 接口保持一致,使用起来非常方便。

(1)下载。

        下载地址:libusb官网。如下图所示,下载最新的版本即可。

(2)编译安装(X86下)。

        我们下载所得到的就是libusb库的源码包,我们需要对源码包进行编译操作。在不同平台上使用的编译器不同,例如X86使用gcc,ARM使用交叉编译器。

<1> 安装依赖包。

sudo apt install -y libudev-dev

<2> 指定编译环境,这里为x86_64-linux 架构。

./configure --build=x86_64-linux

<3> 编译和安装。

make
sudo make install

<4> 验证:进入/usr/local/lib查看。

(3)编译安装(ARM下)。 

 <1> 安装依赖包。

sudo apt install -y libudev-dev

<2> 指定编译环境,这里为ARM架构。(先在源码包路径下新建install文件夹,用于存放编译后的libusb库)

//--build:编译平台
//--host:目标平台
//--prefix:安装路径
//CC: 编译器
//CXX:g++编译器
//--disable-udev:用于禁用对 udev 的支持
./configure --build=x86_64-linux --host=arm-linux --prefix=/home/qjl/libusb/libusb-1.0.27/install CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ --disable-udev

<3> 编译和安装。

make
sudo make install

<4> 使用验证。

        将源码目录下的example中的一个测试源码(例如listdevs.c)拷贝到install文件夹中。然后使用交叉编译器编译这个源码生成可执行文件。如下所示。将生产的可执行文件使用命令file来查看格式是否正确。将可执行文件传至开发板运行。

//-I ./include/libusb-1.0 :头文件路径
//-L ./lib :静态库路径
//-lusb-1.0 -lpthread -static 连接usb静态库 和线程thread库arm-linux-gnueabihf-gcc listdevs.c -o listdevs -I ./include/libusb-1.0  -L ./lib  -lusb-1.0 -lpthread -static

相关文章:

Linux内核编程(二十一)USB应用及驱动开发

一、基础知识 1. USB接口是什么&#xff1f; USB接口&#xff08;Universal Serial Bus&#xff09;是一种通用串行总线&#xff0c;广泛使用的接口标准&#xff0c;主要用于连接计算机与外围设备&#xff08;如键盘、鼠标、打印机、存储设备等&#xff09;之间的数据传输和电…...

什么是数据仓库?

什么是数据仓库&#xff1f; 数据仓库&#xff08;Data Warehouse&#xff0c;简称DW&#xff09;是一种面向分析和决策的数据存储系统&#xff0c;它将企业中分散的、异构的数据按照一定的主题和模型进行集成和存储&#xff0c;为数据分析、报表生成以及商业智能&#xff08;…...

计算机网络 (48)P2P应用

前言 计算机网络中的P2P&#xff08;Peer to Peer&#xff0c;点对点&#xff09;应用是一种去中心化的网络通信模式&#xff0c;它允许设备&#xff08;或节点&#xff09;直接连接并共享资源&#xff0c;而无需传统的客户端-服务器模型。 一、P2P技术原理 去中心化架构&#…...

SK海力士(SK Hynix)是全球领先的半导体制造商之一,其在无锡的工厂主要生产DRAM和NAND闪存等存储器产品。

SK海力士&#xff08;SK Hynix&#xff09;是全球领先的半导体制造商之一&#xff0c;其在无锡的工厂主要生产DRAM和NAND闪存等存储器产品。以下是SK海力士的一些主要产品型号和类别&#xff1a; DRAM 产品 DDR4 DRAM 特点: 高速、低功耗&#xff0c;广泛应用于PC、服务器和移…...

FunASR 在Linux/Unix 平台编译

第一步拉取镜像并生成容器&#xff1a; ### 镜像启动 通过下述命令拉取并启动FunASR软件包的docker镜像&#xff1a; shell sudo docker pull \ registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-online-cpu-0.1.12 mkdir -p ./funasr-runtime-…...

git操作(Windows中GitHub)

使用git控制GitHub中的仓库版本&#xff0c;并在Windows桌面中创建与修改代码&#xff0c;与GitHub仓库进行同步。 创建自己的GitHub仓库 创建一个gen_code实验性仓库用来学习和验证git在Windows下的使用方法&#xff1a; gen_code仓库 注意&#xff0c;创建仓库时不要设置…...

物联网网关Web服务器--Boa服务器移植与测试

1、Boa服务器介绍 BOA 服务器是一个小巧高效的web服务器&#xff0c;是一个运行于unix或linux下的&#xff0c;支持CGI的、适合于嵌入式系统的单任务的http服务器&#xff0c;源代码开放、性能高。 Boa 嵌入式 web 服务器的官方网站是http://www.boa.org/。 特点 轻量级&#x…...

vue3学习日记8 - 一级分类

最近发现职场前端用的框架大多为vue&#xff0c;所以最近也跟着黑马程序员vue3的课程进行学习&#xff0c;以下是我的学习记录 视频网址&#xff1a; Day2-17.Layout-Pinia优化重复请求_哔哩哔哩_bilibili 学习日记&#xff1a; vue3学习日记1 - 环境搭建-CSDN博客 vue3学…...

前端实习第二个月小结

时间飞快&#xff0c;第一次实习已经过去两个多月&#xff0c;作一些简单的总结和分享。 注&#xff1a;文章整体会比较轻松&#xff0c;提及的经历、经验仅作参考。 一、关于实习/工作内容 1、工作内容 近期做的是管理后台方面的业务&#xff0c;技术栈&#xff1a;前端re…...

深入了解卷积神经网络(CNN):图像处理与深度学习的革命性技术

深入了解卷积神经网络&#xff08;CNN&#xff09;&#xff1a;图像处理与深度学习的革命性技术 导语 卷积神经网络&#xff08;CNN&#xff09;是现代深度学习领域中最重要的模型之一&#xff0c;特别在计算机视觉&#xff08;CV&#xff09;领域具有革命性的影响。无论是图…...

b站视频(网页加客户端)+本地视频 生成回链

b站视频(网页加客户端)本地视频 生成回链 引言 基于上一篇博客方案 本地视频进度加入笔记根据进度快速锁定视频位置 我想着只有本地的话, 那b站上的视频, 不是每次都得下载下来吗? 如果是一套课程, 直接下载, 然后视频处理成mp3,还好, 如果只是一个视频, 每次这样处理就有点…...

3.数据库系统

3.1数据库的基本概念 3.1.1:数据库体系结构 3.1.1.1集中式数据库系统 数据是集中的 数据管理是集中的 数据库系统的素有功能(从形式的用户接口到DBMS核心)都集中在DBMS所在的计算机 3.1.1.2C/S结构 客户端负责数据表示服务服务器主要负责数据库服务 数据库系统分为前端和后端…...

红米k40s设备驱动设备驱动树

github地址# 链接https://github.com/autoandroida/vendor_xiaomi_munch...

Linux-C/C++--文件 I/O 基础

在 Linux 中&#xff0c;文件 I/O 是指通过系统调用或命令对文件进行的输入输出操作。Linux 操作系统提供了强大的文件操作功能&#xff0c;使得用户和程序可以方便地对文件进行读取、写入、修改和管理。文件 I/O 指的是对文 件的输入/输出操作&#xff0c;说白了就是对文件的读…...

HarmonyOS NEXT开发进阶(六):HarmonyOS NEXT实现嵌套 H5 及双向通信

文章目录 一、前言二、鸿蒙应用加载Web页面2.1 加载网络地址页面2.2 加载本地H5页面 三、实现Web组件 H5 层与鸿蒙应用层进行相互通讯3.1 鸿蒙应用向 H5 页面发送数据3.2 H5页面向鸿蒙应用发送数据 四、拓展阅读 一、前言 随着HarmonyOS NEXT的快速发展&#xff0c;越来越多的…...

【Flink系列】4. Flink运行时架构

4. Flink运行时架构 4.1 系统架构 Flink运行时架构——Standalone会话模式为例 1&#xff09;作业管理器&#xff08;JobManager&#xff09; JobManager是一个Flink集群中任务管理和调度的核心&#xff0c;是控制应用执行的主进程。也就是说&#xff0c;每个应用都应该被…...

动态主机配置协议 (DHCPv4)介绍,详细DHCP协议学习笔记

定义 动态主机配置协议 (DHCP) 是一种用于集中对用户 IPv4 地址进行动态管理和配置的技术。为与 IPv6 动态主机配置协议 (DHCPv6) 进行区分&#xff0c;本文统一将动态主机配置协议称为 DHCPv4。 DHCPv4 协议由 RFC 2131 定义&#xff0c;采用客户端/服务器通信模式&#xff…...

Vue.js组件开发-如何处理跨域请求

在Vue.js组件开发中&#xff0c;处理跨域请求&#xff08;CORS&#xff0c;即跨来源资源共享&#xff09;通常不是直接在Vue组件中解决的&#xff0c;而是需要后端服务器进行相应的配置&#xff0c;以允许来自不同源的请求。不过&#xff0c;前端开发者也需要了解一些基本的COR…...

【C++】构造函数与析构函数

写在前面 构造函数与析构函数都是属于类的默认成员函数&#xff01; 默认成员函数是程序猿不显示声明定义&#xff0c;编译器会中生成。 构造函数和析构函数的知识需要建立在有初步类与对象的基础之上的&#xff0c;关于类与对象不才在前面笔记中有详细的介绍&#xff1a;点我…...

Agent区别于MOE和RAG的核心; Agent(智能体)、RAG和MOE区别

Agent区别于MOE(专家混合模型)和RAG(检索增强生成)的核心 目录 Agent区别于MOE(专家混合模型)和RAG(检索增强生成)的核心自主性与决策能力环境交互与学习能力多模态感知与处理能力Agent(智能体)、RAG(检索增强生成)和MOE(专家混合模型)区别Agent(智能体)RAG(检…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...