HID协议详解 - Report Descriptor报告描述符构建与解析

news2024/11/28 2:29:21

USB相关基础知识简述

报告描述符是HID协议里比较复杂的一部分,在理解报告描述符之前,可以对USB协议数据传输的一些基础知识做一些了解,更方便理解后续内容。

报告是USB协议里数据传输(Data Transfer)的一种,而报告描述符是对这些传输的数据作用途(Usage)上的说明。

USB协议规范1ms产生一个USB帧(Frame),USB设备可以每一帧中交换(Transaction)一次数据[发送/接收],交换通常由数个包(Packet)组成,而一次传输事务则又由一个或几个交换来完成。

传输事务解决了主机、设备之间交互一次数据的问题,但是有些端点是需要进行多次双向传输或者多次单向传输的,同时因为设备的功能不同,所需要的带宽和传输特性也不同,那么就需要一个更上层的机制解决以上问题,四大各有专场的传输应运而生。

控制传输(Control Transfers)

突发性、非周期性、主机软件发起的请求/响应通信,组态、命令和状态的通讯都可以使用控制型传输,常用于消息型数据(message-type data),控制型传输是当需要时才执行传输要求,是最一般的传输方式。

中断传输(Interrupt Transfers)
中断传输是使用中断事务(Interrupt Transactions)来传输数据的,通常用于低频、有限制的延迟通信,使用在有周期流数据上报的场景,即重复数据更新(Recurring data),在每个有限周期内(Bounded period)作至少一次的小量数据发送或接收,所以适用于流数据(stream-type data),注意这里所谓的周期时间只是在端点描述符中的轮询间隔时间。input,output,和Feature。

批量传输(Bulk Transfers)

批量传输是一种可靠的单向传输,传输延迟没有保证,它会尽可能的利用可以利用的带宽完成传输,适合数据量比较大的传输,当总线上只有批量传输,延迟也是能保证的,毕竟没人和它竞争带宽。U盘就是采用批量传输,因为它对时间延迟不是那么严格,只要可靠的完成大量数据的传输即可。

同步传输(Isochronous Transfers)

同步传输属于不可靠传输,其好处是可以保证带宽,没有延迟,因为不可靠传输,所以没有握手包,也不支持 PID 翻转(传输失败重复发送3次),同步传输拥有最高的优先级。

假如总线中有四类数据需要传输,那么主机将在每帧开始发送SOF包,然后优先安排同步传输,之后安排中断传输,其次是控制传输,最后才是批量传输(大容量传输)

四种传输方式,初接触一般只要了解控制型传输和中断型传输即可。

中断型输入管线(interrupt in pipe)仅可以传送input报告;中断型输出管线(interrupt out pipe)仅可以传送output报告;但是控制型管线(control pipe)可以传送input,output和feature报告。端点描述符有声明所使用的端点为何种管线。

最后,数据本身没有任何意义,而协议是赋予它们意义的GOD;

为了尽可能的描述清楚,后文内容比较长,建议反复咀嚼。

报告描述符(Report Descriptor)

报告描述符(Report Descriptor),由设备端(Device)描述给主机端(Host),后续设备端通过中断端点发送的数据的用途(Usage)说明或称描述数据格式及意义。它在连接建立初期就发送给主机端,主机端依据报告描述符去解析来自中断端点的数据。

通俗的讲,报告描述符就是描述连接建立之后设备端发送给主机端的数据,每一字节(bytes)每一位(bits)所代表的意义。

要更详细全面了解报告描述符,可以查阅下述两个官方文档:

《Device Class Definition for human interface device (HID)》

《Universal Serial Bus HID Usage Tables》

一份是HID 协议,另一个是HID报表描述符(USAGE_PAGE & USAGE)的内容定义。

报告描述符分两种:短条目(Short items)、长条目(long items)

报告描述符的组成:

官方报告描述符组成结构示意图

 一个报告描述符可以由多个Report组成,当超过1个report时,需要用collection去组合,collection可以嵌套collection,每个report都可以有多个用途(Usage),其它Main item/Report size/Report count/Logical minium等都是用于修饰usage。

案例简析 

下述代码段提供了一个基于官方鼠标案例改的实用示例,对照该示例可以做一个总体的分析。

Report Description通常表现形式是设为一个大数组,数组内容可分两部分组成:条目标签(item tag) + 条目数据(item data)。

其中Tag大小固定,短条目(short item)为1Byte,长条目(long item tag)为3Byte。示例中是一个短条目(short item),其Tag组成又分两个部分:标签(Tag)、数据大小(DataSize),bSize(2bits) + bType(2bits) + bTag(4bits) = 1byte

bSize = 数据大小

bType = 标签(Tag)类型

bTag = 标签(Tag)

上述定义在后文有详细提供,这里只先给个总体的概念。

如上,可以得出一个简单的解析报告描述符的方式,即数组第一个字节肯定为Item,从其中能解析出标签和数据大小,数据大小就是标签后跟着的连续数据。例如item = 0x05,我们能解析出Tag =B(0),Type=B(01),Size=B(01),其中数据长度为1byte,所以后面的0x01是0x05的数据内容。然后就是下一个item,依旧按照前面的分析方式,就能将整个描述符给解析出来。

uint8_t report_desc[] = 
{
    0x05, 0x01, //USAGE_PAGE (Generic Desktop)
    0x09, 0x02, //USAGE (Mouse)
    0xa1, 0x01, //COLLECTION (Application)
    0x85, 0x01, //REPORT_ID (1)
    0x09, 0x01, //USAGE (Pointer)
    0xa1, 0x00, //COLLECTION (Physical)
    0x05, 0x09, //Usage Page (Buttons)
    0x19, 0x01, //Usage Minimum (01)
    0x29, 0x03, //Usage Minimum (03)
    0x15, 0x00, //Logical Minimum (0)
    0x25, 0x01, //Logical Minimum (1)
    0x95, 0x03, //Report Count (3)
    0x75, 0x01, //Report Size (1)
    0x81, 0x02, //Input (Data, Variable, Absolute)
    0x95, 0x01, //Report Count (1)
    0x75, 0x05, //Report Size (5)
    0x81, 0x01, //Input (Constant)
    0x05, 0x01, //USAGE_PAGE (Generic Desktop)
    0x09, 0x30, //USAGE (x)
    0x09, 0x31, //USAGE (y)
    // 0x09, 0x38, //USAGE (wheel)
    0x15, 0x00, //Logical Minimum (0)
    0x26, 0x38, 0x04, //Logical Minimum (1080)
    0x75, 0x10, //Report Size (16)
    0x95, 0x03, //Report Count (2)
    0x81, 0x02, //Input (Data, Variable, Relative)
    0xc0,       //END_COLLECTION
    0xc0       //END_COLLECTION
};

 下文将对报告描述符的类型(bType)和标记(bTag)做一个详细的描述。

短条目(Short items)

短条目格式将条目大小(bSize)、类型(bType)和标记(bTag)打包到第一个字节中。第一个字节后面可以跟着0、1、2或4个可选数据字节(byte),这取决于数据的大小。Host主要依据【bSize + bType + bTag】去了解其后面所跟的数据的意义。

 bSize:描述数据内容的大小,占2bit,共4个选项

b00 = 0 bytes
b01 = 1 byte
b10 = 2 bytes
b11 = 4 bytes

bType:描述条目类型(可以理解为命令类型),占2bit,共3个选项以及1个保留项

b00 = Main (主要类型)
b01 = Global (全局类型)
b10 = Local (局部类型)
b11 = Reserved (保留)

 bTag:描述各条目类型下的各细分条目(可以理解为命令),占4bit,最多15个选项,具体后文列表描述。

长条目(long items)

长条目的条目大小(bSize)、类型(bType)和标记(bTag)固定为0xFE(B11111110),表明该条目为长条目类型。

bDataSize:描述长条目数据大小,占1byte,最大255。

bLongItemTag:描述长条目标签,占2byte,但是官方暂时没有对其有做定义(截止hid1_11.pdf),但其中0xF0~0xFF提供给厂商做自定义。

data:长条目具体数据最大255个字节。

长条目较少用到,只在一些专门设备领域有用到,暂时不做了解,后文主讲短条目。

短条目bTag选项 - Main项标签

Main Item Tag表
Main item tag
(bType=0)

Tag Code

(bTag)

Item code

if(bSize=1)

Description
Input
0x80x81 Input、Output、Collection项可选值表
Output
0x90x91 Input、Output、Collection项可选值表
Feature
0xB0xB1 Input、Output、Collection项可选值表
Collection
0xA0xA1

 Collection项可选值表

Collection 和 End Collection。以鼠标而言,在实体上是一个指针(pointer),只是应用为计算机鼠标﹔而这个指针含有三个按键和二个平移轴X 和Y。所以指针的报告是由不同格式的数据所构成,因而需要用到Collection 和End Collection 将几个Input 项目集结成一组,其用途为指针,再用Collection 和End Collection 将指针括起来说明其应用为鼠标。标签End Collection 没有跟随任何数据。标签Collection 会跟随一个字节的数据,例如指针的数据名为Physical,而鼠标的为Application,参考下文collection项可选值表。

End Collection
0xC0xC0集合项结束符,End Collection 不跟随任何数据,仅0xC0
Reserved
0xD~0xF\保留
bSize = x; itemCode = (tagCode<<4)|x;

Input/Output/Feature具有相通的选项数据定义

input/output都是相对主机端而言的。

Input(e.g. 0x81 , 0x**),输入报告 ,是设备端将设备操作发送到主机,这种报告通常通过中断端点发送到主机,以此保障一个固定周期的输入报告,它也可以控制端点的get report(input)来传输。

Output(e.g. 0x91, 0x**),输出报告,是主机端将软件需求发送给设备,输出报告通常以控制端点的set report(output)来传输,只需要响应软件的实际需求既可,它也可以使用中断端点来传输数据。

Feature(e.g.0xb1, 0x**),特征报告,是主机端发送到设备端的数据组态格式,特征报告只能以get report()/set report()来获取或设置设备的特征值。

Input、Output、Feature项可选值表

Main (后面带的数据格式以及含义)中Input,Output和Feature三个标签,产生报告数据的格式具有共通的数据定义: 

Bit 0

{Data (0) | Constant (1)}

主项目之数据为可变值(设为Data),或为固定不可变值(设为Constant)。Constant 都用于Feature 的报告,或是用于填充位(padding),使报告长度以字节为单位。

Bit 1

{Array (0) | Variable (1)}

主项目之数据的每个字段可以表示几个不同的操作的其中一个被触发(设为Array),或是每个字段仅表示一个操作(设为Variable)。如果是Variable,则Report Count 的数据值等于报告数据的字段数。若是Array,则Report Count 的数据值表示可以同时被触发的最多操作数目。

Bit 2

{Absolute (0) | Relative (1)}

主项目的数据是以相对于固定的基准点方式提供绝对数值(设为Absolute),或是提供相对于前次报告的相对值(设为Relative)。

Bit 3

{No Wrap (0) | Wrap (1)}

主项目的数据值达到极值后会转为极低值,反之亦同,称作卷绕(设为Wrap)。例如一个转钮可以做360°旋转,输出值从0 至10,若设定为Wrap,则值达10 后,在同方向旋转则值变为0,反之若达到0,再转就得到10。

Bit 4

{Linear (0) | Non Linear (1)}

主项目的数据与操作刻度为线性关系(设为Linear),或为非线性(设为Nonlinear)。

Bit 5

{Preferred State (0) | No Preferred (1)}

主项目对应的操作再不被触发时会自动恢复到初始状态(设为Preferred State),或是不会恢复原状(设为No Preferred)。例如键盘的按键和会自动置中(self-centering)的游戏杆,皆为Preferred State。

Bit 6

{No Null position (0) | Nullstate(1)}

主项目对应的操和有一个状态,其不会送出有意义的数据,即数据将不在Logical Minimum 和Logical Maximum 之间,这种操控要标注Null State,否则为No Null Position。例如几个按键,而无键被按下的用途没有声明在Usage 之列,则可以在主项目的数据中设Null State,将无键被按下的状态排除在Logical Minimum 和Logical Maximum区间之外,进一步请参看Universal Serial Bus HID Usage Tables 文件的Appendix A.3 节中范例。

Bit 7

Reserved (0)

主项目Feature 的数据不允许被主机改变(设为Non Volatile),或是允许被主机改变(设为Volatile)。注意主项目Input 和Output,此标注设定无意义,所以bit 7 的代码必须为0。

Bit 8

{Bit Field (0) | Buffered Bytes (1)}

主项目的数据格式要以字节为单位,不足构成字节时自动填充成字节则设Buffered Bytes。

Bit 31-9Reserved (0)

 

Collection/End Collection组合

项目实际应用中,一个设备通常不止一个功能点,以上述鼠标示例为例,具有3个按钮(左键、右键、中键),X/Y轴方向位移,滚轮等,它们各自具有不同的数据格式,聚集组成鼠标各个功能,此时我们需要Collection/End Collection去集合组织这些数据格式。某些设备还可能具有多组Collection,表明它有多方面的功能集合,例如某些手绘板同时具有触摸板、键鼠功能或某些键盘上有触摸功能。

Collection选项数据定义在下文有表格详细列出说明,size为1个字节。

End Collection通常不跟随数据,0xC0既可,表明Collection作用域的结束。

 Collection项可选值表

Collection 的数据名称很难有一个准则来给定,《Universal Serial Bus HID Usage Tables档中将各种用途的用途种类(usage type)列出,使用者必须依据用途种类来指定Collection 的数据名称,例如鼠标,键盘和游戏杆的用途种类为CA,所以要用Collection (Application),而指针为CP,所以用Collection (Physical)。 

0x00
Physical (group of axes)
0x01Application (mouse, keyboard)
0x02Logical (interrelated data)
0x03Report
0x04Named Array
0x05Usage Switch
0x06Usage Modifier
0x07-0x7FReserved
0x80-0xFFVendor-defined

 

短条目bTag选项 -  Global项标签

 Global item tag表及其意义理解描述 

Global Item Tag表
Global item tag
(bType=1)
Tag Code

(bTag)

Item code

if(bSize=1)

Description
Usage Page
0x00x05

HID Usage Pages Tables(Usage选项表文档)

Logical Minimum
0x10x15以逻辑单位表示的区段值。这是变量或数组项将报告的最小值。例如鼠标移动XY轴的最小值为-127
Logical Maximum
0x20x25以逻辑单位表示的区段值。这是变量或数组项将报告的最大值。例如鼠标移动XY轴的最大值为127
Physical Minimum
0x30x35变量项的物理范围的最小值。这表示逻辑最小值加上单位

当 Physical  == UNDEFINED;

则 Physical  = Logical;

Physical Minimum和Physical Maximum 一定要同时定义,否则任何一个没定义就会被Logical替代

Physical Maximum
0x40x45变量项的物理范围的最大值。
Unit Exponent
0x50x55

以10为底的单位指数的值。

未定义时默认为0

Unit表中列出常用单位,包括长度、质量、时间、温度、电流和光强,大多数复杂单位都可以由这些基本单位推导出来
Unit
0x60x65单位值
Report Size
0x70x75无符号整数,以比特(Bit)为单位指定报表字段的大小。这允许解析器构建供报表处理程序使用的项映射。

Size*Count = UsageDataSize;

注意的是,size的单位是Bit,这里涉及到不满一个字节场景下的常量填充问题,例如,前面鼠标示例中Usage Page(buttons),三个按键只需3bits,此时没有其它合适的有效数据字段时可以选择填充5bits常量:

Report Count (1)
Report Size (5)
Input (Constant)

Report Count
0x90x95无符号整数,指定该项的数据字段数;确定报告中为此特定项包含了多少个字段
(以及因此有多少位被添加到报告中)。
Report ID
0x80x85

当一个报告数据被分成数个部分单独上报时,需要为各部分添加一个ID前缀。例如,一个数据部分,其长为3字节,定义Report ID为01,则该设备将生成一个4字节的数据报告,其中第一个字节是01。

设备还可能生成其他报告,每个报告都有唯一的ID,ID值从1起始,不允许应用0作为ID值,0被保留给未赋值ID的报告使用。

Push
0xA0xA5当遇到 Push 项目时,项目状态表被复制并放置在堆栈上供以后检索。

Unit (Meter), 
Unit Exponent (-3), 
Push, 
Unit Exponent (0)
pop,
input()

上述在push之后,将毫米(10^-3)压栈,重定义米单位,在后面pop,单位重新恢复成毫米单位,input时单位是毫米

Pop
0xB0xB5当找到一个 Pop 项目时,项目状态表被堆栈中的顶部表替换。
Reserved
0xC~0xF\保留
bSize = x; itemCode = (tagCode<<4)|(0x01<<2)|x;

Unit

Unit指示实际单位项,理解如下:

Unit的数据取值使用7个Nibbe(半字节4位)来描述所有可能的单位,包括6种基础单位及其可以组合出的复杂单位。

7种国际基础单位:长度(米)、质量(千克)、时间(秒)、电流(安培)、热力学温度(开尔文)、物质的量(摩尔)和发光强度(坎德拉/Candela)

Nibbe:

7

6

5

4

3

2

1

0

Unit:

保留

 光亮

Luminous Intensity

电流
Current

温度
Temperature

时间
Time

质量
Mass

长度
Length

系统
System

 7个Nibbe中最低的4bits用于描述该Unit属于哪个单位系统

NibbleSystem

None

SI Linear

SI Rotation

English Linear

English Rotation

0

Lowest Nibble(4bits)

0x0

0x1

0x2

0x3

0x4

0x05~0x0E 为保留值,0x0F提供给厂商作为自定义选项

其它的高Nibble描述各物理量单位,

物理量单位表
Nibble

None

SI Linear

SI Rotation

English Linear

English Rotation

1

Length

None

公分(cm)

弧度(Radians)

英寸(Inch)

角度(Degrees)

2

Mass

None

公克(g)

公克

Slug ①

Slug

3

Time

None

秒(s)

4

Temperature

None

开尔文(Kelvin)

开尔文

华氏(Fahrenheit)

华氏

5

Current

None

安培(Ampere)

安培

安培

安培

6

Luminous intensity

None

Candela

Candela

Candela

Candela

 ① Slug(英制质量单位),1Slug=32.174049lbs(磅)=14.593904kg(千克)

report descriptor通过一个指数(Exponent),去将各基础单位组合出复杂单位,7个Nibble中除了最低4bits外,其它6Nibble都将以Exponent次方去相乘(当Exponent小于0时,既是相除),由此可以乘除出大部分单位。后文有一个示例表,可以对照验证理解。

各基础单位Nibble指数(Exponent)-代码,取值为4位补码(补码:首位表示符号),对照参考下表

Codes - Exponent 对照表

-8

-7

-6

-5

-4

-3

-2

-1

01234

5

6

7

0x08

0x09

0x0A

0x0B

0x0C

0x0D

0x0E 

0x0F 

0x000x010x020x030x04

0x05

0x06

0x07

 下面贴一个官方示例常见复杂单位表

把上表理解一下,Codes - Exponent 对照表配合物理量单位表,换算成下表

Nibbe:

7

6

5

4

3

2

1

0

Unit:

保留

 光亮

Luminous Intensity

电流
Current

温度
Temperature

时间
Time

质量
Mass

长度
Length

系统
System

距离 = Distance(cm) = Unit(0x0011) = cm^1 = cm11
质量 = Mass(g) = Unit(0x0101) = g^1 = g0101
时间 = Time(s) = Unit(0x1001) = s^1 = s1001

速度 = Velocity(cm/s)

        = Unit(0xF011)

        = F(s^-1)*1(cm^1)

        = cm/s

F011

动量 = Momentum(kg·m/s)

        = Unit(0xF111)

        = F(s^-1)*1(g^1)*1(cm^1)

        = g*cm/s

F111

加速度 = Acceleration(m/s²)

            = Unit(0xE011)

            = E(s^-2)*1(cm^1)

            = cm/s^2

E011

力 = Force(kg·m/s²)

     = Unit(0xE111)

     = E(s^-2)*1(g^1)*1(cm^1)

     = g*cm/s^2

E111

能量 = Energy

        = Unit(0xE121)

        = E(s^-2)*1(g^1)*1(cm^2)

        = cm^2*g/s^2

E121

角加速度 = Angular Acceleration

               = Unit(0xE012)

               = E(s^-2)*1(r^1)

               = r/s^2

E012

电压 = Voltage

        = Unit(x00F0D121)

        = F(a^-1)*D(s^-3)*1(g^1)*2(cm^2)

        = g*cm^2/a*s^3

F0D121

Unit Exponent 

当Unit Exponent被定义时,表示换算最终单位时还需要乘一个10的指数,其数值为4位补码(补码:首位表示符号),代表10的指数范围从-7~+8,如下:

UnitExponent00H01H02H03H04H05F06H07H08H09H0AH0BH0CH0DH0EH0FH
数值01234567-8-7-6-5-4-3-2-1

 

 Unit Exponent/ Unit 的关系

Unit Exponent牵扯到两组Tag:逻辑范围(LogicalMaximum /LogicalMinimum),实际范围(PhysicalMaximum/PhysicalMinimum)。

单位分辨率 = (逻辑范围/实际范围)*10^UnitExponent = (LogicalMaximum - LogicalMinimum) /((PhysicalMaximum - PhysicalMinimum) * 10^UnitExponent)

if ((Physical Maximum == UNDEFINED)
|| (Physical Minimum == UNDEFINED)
|| ((Physical Maximum == 0) && (Physical Minimum == 0)))
{
    Physical Maximum = Logical Maximum;
    Physical Minimum = Logical Minimum;
}
If (Unit Exponent == UNDEFINED)
Unit Exponent = 0;
Resolution = (Logical Maximum – Logical Minimum) / ((Physical Maximum – Physical Minimum) * (10^Unit Exponent))

示例理解

 以一个400DPI的鼠标为例,理解一下Unit Exponent/Unit的关系,下表描述了鼠标X/Y轴的移动单位:

参数
Logical Minimum-127
Logical Maximum127
Physical Minimum-3175
Physical Maximum3175
Unit Exponent-4
UnitInches

Resolution = (127-(-127)) / ((3175-(-3175)) * 10^-4) = 400 counts per inch

对上述公式及单位的理解

DPI是dots per inch的缩写,意思是每英寸的像素数,CPI是count per inch的缩写,意思是每英寸的采样率。DPI和CPI都可以用来表示鼠标的分辨率,但是DPI反应的是个静态指标,用在打印机或扫描仪上显得更为合适。由于鼠标移动是个动态的过程,用CPI来表示鼠标的分辨率更为恰当。
上述单位设定,当我们把鼠标向左移动一英寸时,400cpi的鼠标会向计算机发出400次“左移”信号,而如果是800cpi的鼠标就会发送800次。做个假设,我们把鼠标移动1/800英寸,那么800cpi的鼠标会向计算机传送一次移动信号,而400cpi的鼠标却没有反应,我们必须再移动1/800英寸它才会传送移动信号。

 

短条目bTag选项 - Local项标签

Local item tag(bType=2)
Tag Code

(bTag)

Item code

if(bSize=1)

Description
Usage
0x00x09

HID Usage Pages Tables(Usage选项表文档)

Usage Minimum
0x10x19定义Usage实例的起始值。
Usage Maximum
0x20x29

定义Usage实例的结束值。

起始值 - 结束值定义了一个连续范围,这个范围内都是实例,举例:

Usage Minimum(1),Usage Minimum(3)等效于Usage(1),Usage(2),Usage(3),

这样在定义多个同属性Usage时便利。

Designator Index
0x30x39确定控件使用的主体部分。Index 指向Physical描述符中的一个指示符。
Designator Minimum
0x40x49定义与数组或位图关联的开始指示符的索引
Designator Maximum
0x50x59定义与数组或位图关联的结束指示符的索引。
String Index
0x70x79String描述符的String索引;允许将字符串与特定项或控件关联。
String Minimum
0x80x89指定将一组连续字符串分配给数组或位图中的控件时的第一个字符串索引。
String Maximum
0x90x99指定将一组连续字符串分配给数组或位图中的控件时的最后一个字符串索引
Delimiter
0xA0xA9定义一组局部项的开始或结束(1 = open set, 0 = close set).
Reserved
0xB~0xF\保留
bSize = x; itemCode = (tagCode<<4)|(0x10<<2)|x;

 

参考链接

 1、​​​​​​HID 官方手册

 2、USB HID报告描述符教程 - 知乎

3、USB 协议分析之 HID 设备

4、HID Usage Pages Tables(Usage选项表文档)

5、HID官方描述符工具

6、USB中文网-HID介绍

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android正确使用资源res文件

观看此文注意首先有的UI改颜色&#xff0c;没用&#xff0c;发现无法更改按钮背景颜色。我的AS下载的是最新版本&#xff0c;Button按钮的背景颜色一直都是亮紫色&#xff0c;无法更改。为什么呢&#xff1f;首先在你的清单文件中看你应用的是哪个主题。我现在用的是这个可能你…

PYthon组合数据类型的简单使用

Python的数据类型有两种&#xff0c;基本数据类型和组合数据类型&#xff0c;组合数据类型在Python的使用中特别重要。 1.组合数据类型的分类&#xff1a; 2.序列类型 序列类型中元素存在顺序关系&#xff0c;可以存在数值相同但位置不同的元素。序列类型支持成员关系操作符&…

计算机编程基础

0与1的世界 计算机是由晶体管和电路板组成的电子设备。 不论是我们微信信息的呈现、图像的储存和数字之间的运算本质上都是0和1的信息。 0、1便可以代表电压的高低、开关的闭合以及电阻的导电和不导电。 0、1表示的数字便是“逢二进一”。计算机的最小的储存单位是位&#…

Java如何String字符串带括号转成List

问题现象 今天在做一个需求&#xff1a;将存入数据库中的数据读到后解析成list遍历分析 数据格式&#xff1a; "[1677660600000, 1677660900000, 1677661200000]" "[5, 4, 4,3,2&#xff0c;0,0]" 我一开始想到的就是使用逗号分割即可 结果变成了这样的…

电容笔和Apple pencil有什么区别?开学季电容笔排行榜

与苹果的 Pencil相比&#xff0c;市面上常见的电容笔在压感上是没有具备重力压感&#xff0c;只具备着一种倾斜压感。对于绘画没有过高要求的话&#xff0c;其实一支普通的平替电容笔&#xff0c;就能为我们解决日常很多问题。它不仅可以用在办公上&#xff0c;也可以用在笔记、…

算法小抄3-理解使用Python容器之列表

引言 首先说一个概念哈,程序算法数据结构,算法是条件语句与循环语句组成的逻辑结构,而数据结构也就是容器. 算法决定数据该如何处理,而容器则决定如何数据如何存储. 不同的语言对容器有不同的实现方式, 但他们的功能都是相似的, 打好容器基础,你就可以在各式各样的语言中来回横…

1.Spring Cloud (Hoxton.SR10) 学习笔记—基础知识

本文目录如下&#xff1a;一、Spring Cloud基础知识什么是微服务架构&#xff1f;服务拆分 有哪些注意事项&#xff1f;什么是分布式集群?分布式的 CAP 原则&#xff1f;组件 - Spring Cloud 哪几个组件比较重要&#xff1f;组件 - 为什么要使用这些组件&#xff1f;组件 - Na…

有关白盒加密

白盒密码技术白皮书 有关白盒的概念 其实白盒黑盒之类概念其实是软件保护方面的概念&#xff0c;在很多方面都有应用&#xff0c;例如 黑盒&#xff1a; 传统的加密技术是默认假定处于黑盒中的&#xff0c;也就是假定攻击者无法获得密钥。具体而言&#xff0c;认为攻击者并…

PMP证书含金量如何,打算以后从事项目管理这一行业的有没有必要考这个证书?

建议考一个&#xff0c;虽然说这一纸证书实际不能带来多少利益&#xff0c;只是一个资格证书&#xff0c;项目管理行业入门证书&#xff0c;但是现在很多企业招聘要求中写了“有 PMP 证书”优先录取&#xff0c;还是考一个有备无患。含金量问题一直备受关注&#xff0c;总结了一…

操作系统(1.1)--引论

目录 一、操作系统的目标和作用 1.操作系统的目标 2.操作系统的作用 2.1 OS作为用户与计算机硬件系统之间的接口 2.2 OS作为计算机系统资源的管理者 2.3 0S实现了对计算机资源的抽象 3. 推动操作系统发展的主要动力 二、操作系统的发展过程 1.无操作系统的计算机系统…

Web3中文|日本元宇宙经济“狂飙”

2月27日&#xff0c;三菱、富士通和其它科技公司发布关于建立“日本元宇宙经济区”的协议&#xff0c;表示将联手从角色扮演游戏的角度创建开放的元宇宙基础设施&#xff0c;以推动日本的Web3战略。据了解&#xff0c;日本一直在努力将Web3技术纳入其国家议程&#xff0c;去年1…

规范哈夫曼编码和Deflate算法

经过常规的哈夫曼编码以后&#xff0c;我们需要将每个符号对应的码字记录下来&#xff0c;比较容易想到的是按照字母序记录每个字母的编码&#xff0c;这样的好处是字母与码字的映射关系被隐式记录&#xff1a; 假设字母表 A{a1,a2,a3,a4,a5}\mathcal{A}\{a_1,a_2,a_3,a_4,a_5\…

基于数据驱动的电动车电池数据分析(一)

基于数据驱动的电动车电池数据分析&#xff08;一&#xff09; 欢迎关注笔者的微信公众号 笔者过去一年多的时间都在国内一家头部新能源企业实习&#xff0c;主要参与一些数据分析和平台研发的工作。在工作中积累了一些数据分析的经验&#xff0c;其中新能源领域比较多的是一…

曾经被人们看成是异想天开的产业互联网,或许终将会实现

一波还未平息&#xff0c;一波又起。元宇宙的热度还未彻底散去&#xff0c;ChatGPT已经成为了名符其实的新风口。如果用一个概念来定义现在这样一个热点和风口频出的时代的话&#xff0c;我想&#xff0c;用产业互联网或许是再合适不过的了。对此&#xff0c;可能有人并不认同。…

【设计模式】21.访问者模式

概述 定义&#xff1a; 封装一些作用于某种数据结构中的各元素的操作&#xff0c;它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。 结构 访问者模式包含以下主要角色: 抽象访问者&#xff08;Visitor&#xff09;角色&#xff1a;定义了对每一个元素&a…

Outlook邮箱登录不上?被阻止?这些方法教你解决

Outlook是微软的一款备受欢迎的应用软件&#xff0c;可以用来收发电子邮件、管理联系人信息、记日记、安排日程、分配任务等。然而最近就有很多朋友向东哥反映&#xff0c;有的时候没有办法正常登录outlook 邮箱&#xff0c;这是怎么回事呢&#xff1f;不用担心&#xff0c;今天…

揭秘可视化图探索工具 NebulaGraph Explore 是如何实现图计算的

前言 在可视化图探索工具 NebulaGraph Explorer 3.1.0 版本中加入了图计算工作流功能&#xff0c;针对 NebulaGraph 提供了图计算的能力&#xff0c;同时可以利用工作流的 nGQL 运行能力支持简单的数据读取&#xff0c;过滤及写入等数据处理功能。 本文将简单分享下 NebulaGr…

学习记录 --- Pytorch优化器

文章目录参考文献什么是优化器optimizer的定义optimizer的属性defaultsstateparam_groupsoptimizer的方法zero_grad()step()add_param_group()state_dict()、load_state_dict()优化一个网络同时优化多个网络当成一个网络优化当成多个网络优化只优化网络的某些指定的层调整学习率…

总结对Dva数据流向的简单理解

在刚刚接触Dva时&#xff0c;我最想知道的第一个问题就是&#xff1a; 1. Dva是什么&#xff1f; Dva官网文档的介绍是&#xff1a; dva 是体验技术部开发的 React 应用框架&#xff0c;将上面三个 React 工具库包装在一起&#xff0c;简化了 API&#xff0c;让开发 React 应…

[Datawhale][CS224W]图神经网络(八)

目录一、图神经网络1.1 为什么卷积神经网络 (CNN) 在图形上失败&#xff1f;1.2 一个GNN网络的结构如图&#xff1a;![在这里插入图片描述](https://img-blog.csdnimg.cn/20210606150918449.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cH…