大家好,我是集海 ae 工程师同辉谷,今天由我来给大家讲解集海 apm 三二 f 四系列 usb 二点零外设以及其通信应用讲解。 通信应用就是我们针对 f 四零七的 usb 外设专门制作的 sdk, 下面我们给大家讲解一下 f 四零七的 usb 外是模块。 usb 的外设模块一共有三个,一个是全速模块,还有两个高速模块。其中这两个高速模块,高速模块一和二是同属于 一个 usb 控制器,在本质上的话,他四零七是拥有两个 usb 控制器。全速模块做主机时支持全速和低速, 作为同机时只支持全速。高速模块,两个高速模块的话,做主机时支持高速,全速和低速,作为同机时顶支持高速和全速。下面我给大家讲解一下两个高速模块他们之间的区别。 通常我们的阴间设计中,我们 usb 的后期均内合是通过 usb i 接口外沿高速坏,然后才到达,就是用户的应用。但是 ipn 三二二四零七他的内核他可以拥有两个接口,通过文件去切换,其中一个就是常用的 uipia 接口,可以外接高速快。 然后另外一个是我们集成在今天内部的高速模块二,它是由 utananxj 口来内建一个高速快,最后在客户使用的时候就不需要自己设计一个高速快。 有关于应用历程呢?我们制作了一个 spksdk, 里面有重击的历程,我们介绍一下重击的历程大概有哪些。一共有三个历程, 分别是鼠标、虚拟窗口和优盘。鼠标的话就是通过 usb 丢电脑将可以识别为鼠标,通过我们的迷你版按键一和按键二可以抖抖音中光标 去你创口的话,就是将其他用电脑后将识别成为一个创口,通过创口助手的话,我们可以发送数据给芯片,今天会回传同样的信息。 u 盘是将 id o 美举,可以美举上于可用的一个 u 盘或者一个虚拟 u 盘来去测试它的传输速度。 下面讲解一下红机用户层接口,用户层就是我们拿到了我们的 apk 部,我们第一步就是 是对 usb 进行一些度数化,度数化的话我们只要调用这个函数,然后将以输入参数给配置完全,就可以实现基本的理解,其中输入参数包括就是基本的设备描述图控制,请求 助理回到函数控制状态回到函数啊,工作助理回到函数等,就是在肚子化的时候就能配置好这些输入参数,比如这个肉肉毒所示,这是 hid, 也就是我们鼠标的一个历程, 调用了这个函数之后,将进行入仓数给配置完全,然后我们就可以就是直接按他的枚取。下面是同期的用户乘 接口,第二个用户层,也就是用户层的回到函数,在每个同机历程中都有 usb 点优色点击文件,这个文件呢会存放一些用户的回到函数,这些函数可以就属于应用成, 可以进行一些创口打印等操作,这个用的比较少,主要还是前面第一步的速度化函数, 在内行数中我们调用 usb 的住宿化函数就可以实现他的媒体,比如说下图这是 hip, 也就是鼠标的住宿化。 对于做手画的参数的话,先做一个介绍,我们给大概分为五类,第一类的话就是,呃, 我们的描述服务成员描述服务呢就是存放设备描述服务等信息,比如说这种配置描述服务都不算描述服务,厂商描述服务等信息。成员的类型是一个结构体, 结构体当然是有一个速度指针和它的长度,这是一个视力。 下面是第二部分,就是设备的请求成员,设备请求,这些都是回到函数, 这位请求是指的是由主席发送设备接收并处理的请求,比如获取描述符,设置地址等请求。相关的结构体成员都是回到函数,用户只需要传递函数名及 那个产生数的指针。这个请求可以分为三类,标准请求、类请求和厂商制定请求。比如说这里这个是标准请求, 这是一个回掉函数的一个指针,这是一个回掉函数数组的一个指针,这是不能标准请求处理的一个错误处理函数,这是我们的三十请求处理,然后这是厂商请求处理。 我们以这个 ps 请求成员为例,这个成员类型是函数指针指针,他的返回词是外的,也就是空类,嗯,然后他的输入参数是这个请求数 据指称,比如这是 hid 的一个失利。通过这个回到函数的定义,我们可以对这个顶球 他的数据进行一个点击,然后进行特别的一个操作,每个不同的类,不同的 plus, 他会有不同的助理,具体的话可以看对应的手册。 下面是状态过程回到函数,也就是一般我们是用于控制传输才会有这个状态过程,一般先执行此回到函数,再执行状态过程 常用于 df, 由比如在数据传输后,先不回复状态和边用传输来编成 fresh, 再回复状态。传言的类型也 是函数,指称输入和反位置都是空类型。下面第四部分是端点盘输回掉函数,这是服务于端点零之外的传输, 在数据传输成功后会指行此回调函数。通常端点零是作为控制端点使用的,端点零之外的端点,比如说可能会 a 是中段短点,控制短点或者是同步短点等。他成年人类型的话也是一个函数指针,反位置是空,他的输入是一个短点号, 下面是一个鼠标的一个视力。我们调这个回调函数之后,我们就知道他是哪个观点触发了,然后我们给自己相应的标准 出位。下面是最后一部分是我将其归类为其他回调函数,一个是部位回调函数,一个是中段回调函数, 会回到函数,顾名思义,也就是说在 usb 在进行复位的时候,我们会调用它。还有中段回到函数是用户可以作为一些补充,也就是说对一些中段的额外来处理。 关于同机的三个历程,我们可以对他结构进行一个说明,我们找到其中的共同点 之后,我们就可以更清晰的了解这个这个 sdk。 不,他的大致的结构,我们用他的时候应该去怎么用,哪些是该动的,哪些是不该动的。首先是第一部分,第 一部分是我们的应用成就,不同类的时候需要编辑相应的应用,比如说以这个鼠标,鼠标的话,我们先用它的 pass 处理,然后这个是虚拟窗口,虚拟窗口的话我们也是对应电容器相应的 pass 处理, 他内容会更丰富一些,他用他可能应用成没有,包括传输成有一些额外的对比。 第二部分就是三个立场,一起公用的一套代理,也就是说包含了协议代码和一些驱动代码 拥护,原则上不需要对这些内容进行改动。也就是说比如说我们要拟定一个自己的应用,我们可以保留这一部分第二部分,然后我们在 自行构建第一部分,这样子就可以快速的构建我们自己的应用。 下面是主机历程的介绍,我们主要实现了三个历程,这三个历程其实是对标的,是我们上一部分的从基历程,也就是也都有鼠标档口和优盘。 鼠标的话我们可以接入一个鼠标真实的鼠标或者是上一节的鼠标立场,鼠标的移动会使芯片打印信号,模拟鼠标的卫衣 去窗口,窗口主机就是说我们给接入我们的窗口的同机组建这个窗口,这些数据的收发优盘,我们给接入一个真实的一个优盘, 我们动作安安全可以保存一个文件的,他另一个安全可以扫描优盘里面的文件。 首先我们介绍一下主机用户接口中的出口话,在用住手话函数时需要配置输入参数,输入参数包含比较合金的回调函数,包括中单处理理由处理的函数,需要在住手话的时候就配合完成。 另一部分是用户的回调函数,在每个主题历程中都有 usb 优势点吸引文件 也就和我们的同级历程类似,但这里主机的话,我们这个优秀点击的回答人数会更丰富一些。再比如说在连接的时候,断开连接的时候,或者是 是获取一些做端描述服务的媒体的时候,这些都会有对应的用户回答函数。 在灭函数中,我们给调用 usb 出手化函数,也就是说先进行主机的出手化。 在 y 二一循环中,我们应当就是保持这部分内容不变,也就是说我们在构建自己应用的时候,需要就是在保留这个的基础之上,再添加我们自己的应用。 ufb 这个触手或函数的话,和乘机历程类似,将我们构建好的函数,将题指针配置为数参数就可以了。但是我们介绍一下,在刚才说 y 二说话 环中主人形使用人形函数,我们对函数内部的运作流程做一个说明,也就是我们将回到函数工装等一个速度 通过边移,就是说我们通过房的速度成员来实现不同的微量函数的切换, 不同的回答完数意味着不同的主机状态,不同成员需要用户定义,也就是说我们一般是写好了,写好了之后用户只需要定要用应用上即可。 右图是我们的主人选里面这个横竖内部结构,比如说在这里是我们的回条函数的一个数组,通过这个数组的成员标,也就是我们数组的标 好的改变而切换不同的状态。下面我们介绍一下粗俗化的一些参数,我将其分为三类。第一类是类状态函数,比如说克拉斯粗俗化这个回调函数成员在 usb 媒体之后 可以进入 pass 阶段的初始化人数负责。 pass 的初始化,大幅是一个私立, 我们出手画的时候,我们会出手画 hid 所使用的一个通告,并将状态记忆的状态跳转至 plus 的请求状态。 第二个是 pass 的反粗手法回调函数,我们一般在 usb 论台连接之后,会对 卡死的进行一个反复手腕也就是一个复位。第三个是卡死的请求回到函数,使函数负责卡死请求的处理。 下面这些代码是 hid 对请求的一个处理,包装的也是一个回到函数的一个数组,跟我们的人群状态类似。 第四个是 boss 是左奥的处理函数,在 sid 的数据传输中,我们可以对其左边的位移进行一些处理。 这部分是 usb 的挂起和唤醒魔函数,挂起回到函数成员就是在 usb 挂起的时候会直行持 回到函数,因为我可以编辑一些逼工号模式的,嗯,唤醒你,顾名思义就是在 usb 唤醒的时候咨询。 第三部分就是 usb 的中段尾调函数,在中段符函数的结尾跟用户可以做一些补充的一些处理。 之后我们再讲解一下主机的三个历程的大的结构, 他们共同点就是第二部分拥有批重和协议代码,这一部分不需要任务去改变。 第一部分是应用层,应用层也就是说我们在不同的裂的时候,我们可以对其进行一些编辑,比如说这个在 u 盘的时候我们添加 还有一个文件餐园的文件系统,我们可以对特殊的类进行一些特殊的一些处理。 以上就是我对西海 fm 三二二四零七系列的 usb 外设集体应用的讲解,谢谢大家。
粉丝2417获赞2.1万

大家好,这节课呢,我们给大家推荐一款稍写调试工具 pw 二下载调试器,这款下载调试器呢,目前的话价格比较便宜,感兴趣的同学呢可以去入手。在某宝当中搜索创新工坊 pw 零刻二就可以找到这款下载调试器, 目前的价格的话呢是九块九,感兴趣的同学可以去入手一个。那比我们呢介绍的其他的下载调试器,比如说 st link 或者解胎壳之动的话要便宜很多, 这样的话呢,大家拿一杯奶茶的钱呢,就可以买一款下的调制器,对于我们学习这种单面机的编程会有很大的一个帮助。 那他除了支持 stm 三二之外的话呢,还支持一些行顺啊,华大啊等等芯片,这样的话呢,我们有这一款下载调制器呢,就可以完成很多芯片的一个 烧血,那除了支持调试烧血之外,他还支持串口,所以呢用起来的话还是比较方便的。那我们接下来的话呢,给大家演示一下如何用, 我们需要呢做一下硬件接线,那硬件接线的话,我们还是使用 swd 的接口,那所以呢,我们还是用了这么几个银角,就是它这个里面的话提供了这么几个银角,那我们用到这个时钟数据,还有一个精英地,还有一个 vdd, 那当然了,如果说你需要用到串口通信,那你还可以把这个地方呢和你的板当中的串口做一个连接,这样的话呢,这一个东西既支持下载,还能够做一些串形通信的一个调试这个功能这边你接到电脑吗?他他就可以做一个电瓶的一个转换, 那你的 uirt 的信号可以直接和他进行连接,这样的话呢,你烧了程序之后还可以借助他呢,借助创口助手来 做一些信息的打印啊,信息的观察等等各种各样的工作,大家感兴趣的可以去了解一下。那这个调试器的话呢,他还支持在线调试,我们后面的话呢,也会给大家介绍,包括用 s t 内阁做在线调试,或者这款 下载器做在线调试,这样的话呢,你在程序当中出现了问题,你可以去借助于调试的方式来找到相关的一些逻辑问题,这个大家感兴趣的话可以去看一下。 那接下来的话呢,我们演示一下这个下载调试器如何用,我们借助于我们上次课的代码,上次课呢我们讲外部中断的时候呢,用的这个代码,我们上节课下载的时候呢,是用的 st 立刻下载,这节课的话呢,我们就用 这个下载器来进行下载。在下载之前的话呢,我们需要先把硬件连好,硬件的话连接非常简单,那就是这个下载调试器它里面的四根线,对吧? 两个电源线,一定的时钟线,一个数据线,和我们这边的 swd 的接口呢,做一个连接,这个和 s 七立刻的连接方式是一样的。这个连好了之后的话呢,我们需要做一下设置,在第八个这个位置,我们要选中这个 cmsrsdip, 第八个我们原来用的是 st link, 我们上节课用的是这是 strink, 那这节课呢,我们用这个, 然后的话点击赛特,赛特之后这个时候你可以看到他这个时候呢,已经找到了这款下载调制器,对吧?他的 id 已经读出来了,这个地方的话呢,你可以选这个,你也可以呢去选 这个都是没有问题的。然后的话需要注意的,如果说我们在 car 当中,我们要把这个地方要改成这个,如果说你默认的他默认的是这个,如果说是你没有去改的话,默认的时候我们可以去编一 下载看一下,如果说你是默认的,他下载的时候的话呢,会爆这么一个错误,这个呢我也是看他的文档当中的说明,我们大家一定要去修改,那这个时候呢,你要把 这个位置给他改成选中这个选项,就在 reset 这个位置要选这个选项,选这个选项之后其他的我们就不用管了,那这边的话我们把这个 reset 撞勾上, 当然了这个地方的话呢啊,这个编程的这个一个犯法的话,他我们原来就有,当然了如果说没有的话,你可以去点击按的去添加选择,根据你的芯片的类型去选择,那我们这边直接点 okok, 然后的话呢我就可以直接去下载, 这个时候呢就可以下载完成了,这个时候下载完成之后的话呢,我们实现的功能呢还是上节课这个功能,按键按下小灯 点亮,就是用外部中断的方式实现这么一个点灯,这个呢就是用这个下载调试器可以进行这么一个程序的下载。大家这个是在开耳环境下,如果说你是其他的环境,比如说啊啊,那也可以,他也有一个相关的文档,大家感兴趣的话呢,可以去看一下, 那除了我们在开始当中进行下载之外的话呢,他还提供了一个上一级的工具叫做 power right 这么一个工具,我们接触这个工具的话呢,也可以完成这个程序的一个下载, 这个工具的使用的话呢也很简单。那我们这边的话呢,因为有了这个工具之后的话呢,我们以后就不用打开 car 了, 但是需要注意的就是说你如果说要想借助这个工具来稍写,那我们呢在这个地方要设置声称 hack 的文件,我们要把 hack 的文件生成。然后的话呢我们用这个工具的话呢,可以加载 hack 的啊,加进来,当然了这个呢 主要是用在这种批量烧血的时候,当你批量烧血的话,也可以去买相关的离线烧血器,更方便一点啊,这个呢,呃也可以用,对吧?也可以用,那这样的话呢,就说你如果说你的产品已经做好了,需要去批量烧血,这个时候呢,你用开尔的话,一个一个的就比较慢,那用这种工具的话呢,相对来说会更快一点, 当然了他还支持其他的一些功能,比如说可以读出来序列号,然后呢可以做一些加密的一些工作,这个呢大家感兴趣的可以自己去研究一下,我们这边就不给大家介绍了,就说感兴趣的呢,你也可以去看一下,他支持一些加密啊,包括一些其他的处理。那我们这边给大家简简单的演示一下如何用它进行稍写。 如果说进行稍写的话呢,首先你要选择芯片,那我们这边是选择 atm 三二的,然后呢我是选择的是 f 幺,然后的话我们这边是 c 八 t 六,可以找到 f 幺零三 c, 然后呢点击 ok, 然后的话呢这个芯片选好之后的话,我们要点这个 program memory, 我们要添加固件,添加固件的话呢,比如说我们就用我们刚才这个固件, 我们这刚才这个呢是外部中断的,这个部件,我们可以把它呢给它加载进来,加载进来之后,然后点击确定, 那这个时候呢他已经到边缘区,你可以点击用户键,这个时候呢他会把它更新到他的数据缓冲区,下次如果说你还是稍写这么同样一个固件的话,你就不需要去反复的加载了, 然后的话呢你你如果说下次想用的话,你还可以把这个呢给他项目另存,这样的话你下次再稍写的时候直接把这个项目打开就可以直接去稍写了,就不需要啊去 反复的去打开开耳软件,然后用开耳一个一个的去烧,那这样的话就更方便一点。那烧血的话呢,他这边提供了比如说你这个全自动的方式在线烧血,那我们可以点击这个,他会自动去烧血,这个时候呢他会啊烧血完成,对吧?烧血完成,烧血完成之后, 同样呢可以完成我们原来的这个功能,那当然你要按下复位,按下复位键, 那这个时候呢同样的去把这个程序呢下载进去了,这个呢就是借助这个工具来进行下载,当然了你也可以去读出来你的序列号,比如说你可以去点击这边,你可以把这个程序读出来,你可以读取你的 memory, 那这个呢你可以去读取,这个我就不掩饰了。那你还可以读取呢,你的这个芯片的一个啊, 一号我们来看一下,是在 这个你可以读取了你的目标芯片的阿迪号,我们点击它,这个时候呢可以把你的芯片的阿迪可以读出来, 然后的话这边还有其他的功能,对吧?还有其他功能,你可以就是说读取芯片任意位置的数据,比如说弗莱斯 rem 或者计算器。然后呢你还可以打开串口助手,打开串口助手,这个时候呢,你他本身也是 带了一个串口,对吧?那你可以和你的单片低的串口连到一起,这样的话呢就可以做一些串口的工具的一个调试,这样的话就也比较方便。那其他的功能的话呢?大家感兴趣的可以呢自己去研究。


哈喽,大家好,我是齐海啊,今天我想来分享一个线上问题的排查,顺便也带出一下我们是什么去看原码啊,包括怎么去深入了学习框架。我先简单介绍一下这个问题的背景,我们项目当中用的分影去完成 r、 b、 c 的一个调用, 那这个底层其实就是封装了 http 的一个请求跟响应,使用起来其实跟大波这种 rpc 框架也就类似,先定一个二方包,那这种二方包他有一个训练化跟反训练化的一个过程,那这次的问题是怎样一个问题啊?这次遇到的问题就是我新添加了一个接口的调用,然后这一行就报错了 啊,就是报读取这个瑞斯胖斯里面的包底去做转换的时候报错了。大家可能不知道为什么要定义这么一个 decode 啊?啊?其实这是有一些历史背景的啊,这个 dcode 他实现了 fin, 他原生自带的这个接口,那 fin 在解析的时候,他就会找到这个接口的一个时间内复印,他在解析这个请求的时候,他就会类似于 spi 这种机制去调用这个 dq 等我们可以看这个对战啊,他是在处理这个请求响应的时候 会去调用这个抵扣点,这个抵扣点默认是有病的一个视线的,但是我们是自定义了之后,他会优先用我们自定义的这个抵扣点。为什么不用默认的抵扣点啊?主要是因为一些历史原因啊,这里不去展开讲,我们直接就在看这里,他到了这一步之后,这里他 body twisty 拿到的是什么东西啊?他是直接拿到了一个对象的一个地址,这个就可以简单理解成就是他的一个地址,那正常掉其他人的接口就不会有这个问题啊。我们再来看一下掉其他接口是怎样的?这里就掉另外一个接口 kiss drink, 看一下他打赢,哎,他打赢出来为什么就是一个节省的支付串呢?刚才那一个为什么就是一个地址呢?一个读出来的是地址啊,另外一个读出来的是节省支付串。那为什么会有这种差异性呢?我们都是调到同样的复印接口,那作为提供这个二方包的同事,我去问了一下他这个问题, 他就跟我讲可以用另外一种方式去读取这个 body 就没有问题了。我问他这两种读取有什么差异呢?自己也讲不出来原因啊,个是推视镜,另外一个是 body, 然后再把它读取出来, 这两种方式到底有什么不一样吗?那我们再明确一下问题,同样是调分接口,为什么有一些接口?他 tree stream 打印的是节省另外一些接口,他 tree string 他打印的就是一个对象的地址。那接下来我们就开始分析这个圆码,这就是我调别人 服务,他提供了一个份接口,这个接口他返回了对象,他打印出来就是一个地址,而不是一个街审,我们就从这里开始去第八个,嗯,大家看一下,进来了之后这就是份他的一个汉德伦,他是有一个封装的, 直接去银墨口进行一个吊用,这里是一个请求的转发啊,吊,哪一个接口,哪一个参数啊?银墨口我们继续进去,直接通过名字可以到这里来,这里就是执行,并且解析,这里还在对请求进行一个封装,我们继续走 啊,这里就是去执行这个请求,拿到的是一个 spose, 所以继续调用进去。这里拿到的也是一个地址啊,这里就是通过复载均衡注册中心去拿到对应的一个指定地址,这里拿到客户端去执行这个请求。我们进这个方法啊,这里就通过一种命令模式啊,去执行这个请, 他这里面就是一个回调函数,这个杀不灭他,他去封装了一些命令,他的一些出手法的操作啊,再去执行里面这个回调函数的啊。执行体上明确这个 t 就是返回了 spose, 所以我们直接到这个请求题这里来,然后 excuse? 执行 到这里,然后继续进去啊。 internel, htb, 克莱特,我们看一下他是怎样一种事情啊。这个已经是跟 fin 不相关的阿帕奇里面的发送网络请求的客户端,所以这里面就没必要去进行第八个了,直接看 fin, 他做了一个后置的处理,他这里用了一个建造者模式啊, 去对这个 sposs 进行一个 bude, 这里的是 poss, 拿到了之后我们可以去执行一下,看一下他得到了这个巴蒂提示军人之后是不是一个节省,他这里打印的就是一个对象。好,我们继续走 这里,他其实掉到底层的一些框架里面,嗯,可能很容易迷路,那我们直接看这里的对战,直接走到飞人这里,跳出来,跑到这里,然后跳到这里之后,我们继续往下走, 我们看这里啊,他在处理这个 response, 我们进去啊,呃,到这里之后,哎,看一下这里有个 logo 的级别 啊,不等于浪的话,他就会去处理这个 response, 继续进去啊,看一下这里是在处理什么东西好,这里他没有去做任何处理,然后直接 respose 这里出来之后这个 respose, 他继续往下面走,这里判断他要返回的是什么类型,这里就会去调用我们自定义的这个抵扣点 去拿到这个最大额头,所以这里提示君的话就会有问题的。看一下这里的巴蒂提斯君拿到的就是这样一个对象的地址, 所以这里肯定是有问题的,他应该是一个节省,然后到这里来,所以走我们自定义的 dcode, 走我们自定义的 dcode, 到这里来肯定就会报错了, 然后要走到这里,然后这一行代码去进行一个兼容啊,但是我们以前的很多代码的确是走这一行也可以去正常解析啊,所以我们来看一个正常。呃,所以我们来看一个老接口,他为什么就能打印出来一个接审 好,我们就通过这样一个接口啊,进去啊,这是以前他们钓鱼的一个接口,我们来看一下啊,跟刚才一样的,到这个迪斯帕去这里 去进行一个调用,继续走前面的代码都没什么区别,我们就直接看他对于这是 pose 的一个处理啊,直接跳到这里来,继续进来到这里来,进去。哎,大家也没发现, 大家有没有发现前面那种情况,他没有走到这里来,所以他没有去对这个的 pose 去做一个处理, 那我们看一下这个位置 pose 里面到底在做什么事情啊?继续走啊。咦?大家有没有发现他对这个保底有做一个读取,留的一个读取, 这里推八 d, 这里八 d, 他把它转成一个字节的一个数组,这个字节数组他是重写了这个题数据的,重写的这个题数数他就能够把里面的字节数组转化成一个 啊。我们想要的这个巴迪的节省,所以关键一点就是他重写的这个 tus tune, 我们这个 dcode 他就是这个,这个巴迪去 tishrin, 如果说走了刚才那个逻辑的话,他就能够把他的巴底去以节省的形式去给他打印出来,而不是用 oppo 机在里面的 tst 君,所以这是导致 有差异的一个直接原因。那我们继续回到刚才的代码啊,关键就是在这里。那我们再来第八个看一下直接打印地址的这一次请求,他为什么 respons 没有走这里啊? 好,那我们继续进来啊,我们直接跳到,我们刚才看到哪里啊?就到这里来,到这里来啊,继续进去,所以我们来看一下,我们来执行一下 啊 fouse, 所以说他不会进去处理这个 spose, 那我们看一下他,他为什么是 forse 啊?为什么其他请求他是去呢?我们来看一下他怎么判断这个是不是在第八个开启的。走,继续走,这就是默认第八个的一个印特优先级的一个值啊, 他跟这个去做一个比较,这个他是一万,那这个他的一个出租值是两万,所以说他不满足这个条件,他就 然后返回一个 fuse, 那我们再来看一下这个值他是怎么去设置的,我们看一下这个注视啊,这个值如果是为空的话,他会继承 param logan, 那我们就来看一下这个 logan, 他的 parent logan 是什么 logan? 我们再来看啊,往上走,这里也是两万,那继续往上走,这里也是两万,往上走,这里继续往上走,往上走。 然后一直追溯到这个 rut logo root logo 它的是两万,它上面就没有帕瑞特了,所以说这里的日字 logo, 所以这里的原因就是 logo 他的一个打印日字的级别没有匹配到,所以导致他没有去处理这个 response, 没有去重写这个 street string, 那为什么其他接口会处理这个接口他就不会去处理了?那我们看一下项目里面他对包打印的这个包明有没有什么配置好,大家可以看一下 这里他默认配置的是第八个,那在根部落下 com 包下面,他其实是没有去配置的,所以说他是用的一个默认值啊,他是 inford 一个级别的啊,大家记好啊,这个包路径啊, come 露他是点 dm, 那我们再来看一下我们新调的这个接口, 哎,这个报名他是没有去匹配到的,他是没有去匹配到的,所以到这里基本上结论就已经有了,因为我们调用的这个二方包,他定义的这个报路径跟其他的 api 的接口,他的报路径是不匹配的,所以他这里不会开启这个第八个的状态, 然后他就没有去对这个 respose 的 two string 去进行一个重写,导致我们这里的 spose body twiston 直接去调音的 oppo 七个人去打印内的一个地址的一个方法,所以会报错,所以问 题就在这里。那明确的问题了之后,我们就知道怎么去解决啊?第一个解决方案就是让提供这个二方包的人去改,把这个报名前面加一个后缀,跟我们配置的这个是去匹配的,或者我们在调用方的这边直接把这个路径改一下,也能匹配到他的这个接口, 也能走到瑞士胖斯那个处理逻辑。但是我认为这两种解决方案都不太好,因为你整个请求跟响应的处理不应该依赖于任何日制的这种框架,而应该直接去对他的巴底去进行一些流失的处理。所以说我认为直接用这种方法去替换掉这个方法就好了,所以说这里就改成这样, 直接这样处理就行了。原先这种驱使菌本身就是不太合理的,这本身就是 rpc 的奖励了,一个解析不应该去依赖任何日制的这种框架,这种藕和性是完全没 必要的。好,这个圆码的分析就到这里啊。最开始反馈这个问题,虽然同时给了这种解决方案,但是至于根本的原因他也不清楚。在工作当中很多人都会遇到这种情况,就是遇到一个问题,你可能改一下写的方式,或者说百度一下,马上就能够查到一个解决方案啊,的确也能解决, 但是你没有刨根问底去深究,那下一次遇到类似的问题,你还是去百度吗?关键是有些问题,他可能一方面这个技术比较新,另外一方面他是有很多前置条件的,比如说这个场景,为什么这两种方式在复印的这种情况下 有些不一样,你就算去搜索也很难去描述啊,所以说如果你有分析原码的这种能力,你完全可以去刨根问底去深究一下,而且最后你发现我们最后改动其实非常小,就改了银行代码,但是你在分析这个问题的过程当中 去熟悉了整个 rpc 调用他的一个请求的处理的一个过程,你能看到他很多内部的一些设计在里面,好的不好的你都能学习到很多东西,这种潜移默化的学习就逐渐能够拉开你跟别人的一些差距, 长期下来他就会量变引起质变,那逐渐你就会变成别人眼中的大神了。今天就通过这么一个小的问题啊去分享给大家,如果对你有帮助的话,也希望能够一线上联多多点赞转发,没关注的小伙伴也麻烦点一下关注,好,谢谢大家,拜拜!

开箱即海半导体的低压电机评估版,这是在 icez 的微信公众号申请的,大家可以去关注一下,经常有很多白嫖活动。 打开可以看到包装非常精美。该版支持十二到七二 v 电压输入,支持 bldc 和 pmsm 电机支持霍尔光电核磁编码器 有塞 s、 p、 i、 r、 c 看接口和多种电流采样方式。主控采用极海半导体的 f m 三二 f 零三五 c 八 t 七,驱动是风翘的 f d 六二八七高压三项驱动串口芯片是庆恒的 c h 三四零一, mouse 是一零零 v 七三 r 的。整体做工很好,而且相应的测试点都有,群里资料也很丰富,支持。

市场主流的厂家有,北京赵毅创新 gd 三二系列、珠海极海半导体 apm 三二系列、上海移动微电子 mm 三二系列、庆恒微电子、 c h 三二系列、华达半导体 hc 三二系列、中科星 cetc 的 cks 三二系列、亚特力的 at 三二系列、 中微半导体的 cms 三二系列。有的是拼图片兼容代码需要做一定的修改,有的甚至能做到从银角到计存器的全面兼容,代码几乎不需要修改就可以直接替换。

哈喽,大家好,我是季海,之前分享了一期内存合并的这个解决方案有很多问题啊,大家都在问,的确那一期的视频信息的密度非常高,我建议反复的去观看,针对大家问的比较多的一些点,我也在评论区答应大家去写一个 demo 出来,所以接下来我打算不定期的去更新, 我们一起来写这个 demo。 如果你是没有看过那一期分享视频的小伙伴,我强烈建议你去看一下,否则我们接下来讲的一些东西你可能听不懂。这一期我们既然就写一个点啊,就是用户请求过来,我怎么去进行合并,合并完了之后怎么去通知用户 啊,我们就来写这么一个逻辑啊。至于这个并发预知的判断,对联的创建,还有宣传安全的一些东西,这一期的戴墨就先不去写,后面有时间我再去分几期来完善。那我们就开始吧,我们首先创建了一个戴墨的项目啊,就在这个包下面 去建一个类。我们先来梳理一下我们的思路,比如说我们起十个县城,库存只有六个,每个用户能拿到自己的请求响应。首先第一步我们先来构造一些领域对象 啊,比如说用户的请求,那每个用户的话,他是有一个订单号,用户 id, 还有他要扣减的数量,然后给他 ct 直接生成,这里为了创建方便,直接给他生成一个构造器, 然后我们再来定义每一个用户,他进行库存扣减的一个方法。当然这里的返回词肯定是需要定义的,因为每个用户他要知道自己到底有没有扣减成功,那我们再来定义这个返回值, 那这个布尔就代表说到底有没有课件成功,这个麦赛季就有一定的文案,比如说他课件失败的话,到底是什么原因?是等待超时了还是 库存不够了?这个要给他一个具体的信息。好,那我们再来玩上这个方法,所以这个方法就是一个用户他进行库存扣减的操作,然后我们再来定一下库存这个变量,这里库存是有六个, 当然在我们前面的分享当中啊,这其实是数据库里面一行记录,但是我们这里只是一个 demo, 所以我们就定一个变量去摸你数据库一行用户进来之后就会有一些预值的判断,然后会去生成这么一个对列,进入到对列里面。 但这一期我们不写这个逻辑,我们只关注县城的合并和这种通知,这里我们直接就定一个对联。这里大家要想一下用户县城的一个主色跟换起你首先想到的是什么方法, 那肯定就是奥布杰克特里面的啊, weight 跟 note five, 那我们在这里去注册每一个用户现成,那到底主色在哪一个对象上面呢?因为这个 witter 跟 note five 他是 定义在对象上面的呀。很多小伙伴可能就会想用 every quest 去做这个事情,但是这里有一个问题啊, every quest, 那你这个每一个请求他都有一个瑞扎尔特,那这个瑞扎尔特你怎么去进行传递呢? 所以说这里我们需要再定一个对象, request promise, 那这个类的话,他就包含了请求跟响应,我们再去通过这个对象去进行一个主色跟唤醒啊,这样就能够完成现成这样的一个通信了,所以他是有指向用户请求跟响应的一个指针的, 给他一个初始的构造方法 dat set, 所以我们这个主色对列,它主色的就是这样一个类,我们这个对列就定义好了,当然在实际场景肯定是要给它限制一个长度的。嗯,比如说这里有十个用户,那我们就给这个对列设置一个九,那另外多了这一个用户的话,他可能就要等待一下, 等待这个对列里面有空间释放给他,这里我们就开始进对列的一个操作,创建这个 pro 迷时的对象,这里创建的时候他是没有 redout 的,所以我们再给他添加一个构造方法, 像主色堆里面添加元素,其实有好几个方法,有 offer, 有 pot, 有 a 的,他们最大的一个差异就是当这个对象满的时候,他们是泡异常还是主色,还是说直接返回出还是 boss over, 这个方法他就会比较灵魂一点,可以等待一定的时间,比如说这里我就给他设置一百号秒, 等待一百毫秒,如果进对联没有成功,那就直接返回一个啊,异常 系统繁忙,那进对列成功了之后,那当前的用户先生就要开始主设了,开始主设这个对象了,但是我们也不可能一直主设在这里,所以要设置一个时间,比如说就是两百毫秒。 我不知道你会不会有小伙伴疑问,为什么这里要先获取到这个对象的锁,因为胃的方法他要释放锁呀,那你不先获取锁,那你怎么去释放呢?你可以简单这么理解,如果这里主塞超时了,那就要告诉上有这里等待超时了,你要抛出一个错误, 那走到下面的话就是正常情况了,那直接就返回这个请求的一个 read, 这样就行了。好,这一块就是入对列的一个操作,那这个定时任务我们就可以模拟一个一步的线程去进行一个轮巡。我们来定义这个定时任务啊, 首先先启动一个异步相乘,给他起一个名字吧,叫莫尔吉瘦的,这里别忘了要启动这里我们就开始写这个合并的逻辑, 首先最外面是一个循环,一个不断的轮巡,然后判断这个对立是不是空的,如果是空的,但是我们也不可能让 cpu 不断的去空转,那我们还是要简单的等待一下,比如说等待十毫秒, 等待完了之后去继续轮巡。那下面就是对联里面有合并先成,那我们就把这些用户先成批量拿出来 啊,定一个数组,这个力士特他每次用完了之后可以去清空就好了,没必要每次都溜,那就把它移上去,因为这个队列你在合并的时候也有可能有新的用户请求把它放进来,所以我们用这样去进进行一个判断,然后就直接把它放进来, 我们再累加一下这些用户现成的到底要扣多少库存,这个剩余的库存是够他们合并的这个数量,但是另外一种情况的话是不够的,所以说两 种情况你都要去考虑到,那我们这里首先写第一种情况啊,那这里就要先来判断一下,当然如果是这种共享的数据库啊,你肯定是没法这样去判断的,因为你上面有多个实力都判断有库存够的话,你这个扣钱肯定是有问题的, 但是这里模拟的情况是在内存里面,所以说也不会有这种病发的情况啊,整个这个脚步的请求,他是一个单线程在跑,他不会有病发的情况,所以这里判断的话比真实的情况要相对简单一点。但是我们这一期的电摩的话,只是讲这个多线程的一个通信跟主色,我们这一期的话关注这一个点就行了, 然后就判断这个库存是够的,那直接进行剪就行了,然后这里再通知所有的用户,这里通知就很简单了,对吧?直接利斯特 fore request promise。 同样你要先获取到这个对象的锁,然后去 进行一个通知啊,结束了之后继续下一个轮巡。当然这里还热了一点,就是你只是换取了这个用户现成,但是用户他的一个结果还没有拿到的,所以这里还要先把结果给他塞了进去。 那第二种情况就是库存不足的情况,那我们就会把它退化成一个循环,然后获取到每一个请求他要扣减的数量,然后去判断当前的数量够不够,如果够的话,那我们就可以去唤醒这个对象了, 唤醒这个对象同样的这里也要把结果给他塞进去,那库存不够的话,那我们也要给一个响应,就是告诉他库存不够了。 好,大概的逻辑都写的差不多了,然后我们就在主线层里面来模拟这十个用户线层,我们先来构造一个线层词,这里模拟十个用户线层, 我们给他生成一个跟用户 id, 跟订单 id, 订单 id 就是这个序号,加个一百吧。嗯,用户 id 就是这个序号,好了,订单 id 用户 id, 那每个扣减的数量那就是一,我们要用户要拿到结果 就是一个 feel 球的一个对象,这球我们把它都保存起来。当然如果大家想模拟一个并发的效果也是可以的,当浪起,然后这样的话去进行并发这样一个模拟的操作,然后最后我们再去拿每一个响应的一个结果, 每个用户的话最多让他等三百毫秒吧。我们为了更直观的看到这个程序到底怎么运行呢?我们来加一些日字,首先对于用户段来说,他肯定是要知道请求跟响应是什么东西的,然后这些模型都要提示均匀方法去给他进重新定义。 好,我们在这里打印客户端请求响应,前面加上一个现成名称, 然后这里也加一个日字,就这个合并先成里面,然后打印一下他到底合并了哪些用户先成。这里是有六个库存,所以响应结果最多只有六个能够成功抢到库存,为什么说是六个呢?因为他这里等待的话是有两百毫秒,可能到这里的话会有卡顿,会有部分请求失败, 那我们就来运行一下啊, 哎,这里都没拿到结果,看一下到底是什么原因 啊?这里有一个系统繁忙,哎,刚才哪里打赢的系统繁忙啊?就是入对列的时候是吧?啊,所以这个对列只设置了九,嗯,那我们先把这个九改一下,改成十, 让所有请求都能够放进去,这里为什么还是浪啊?这个定时任务我们还没有启动定时任务 胶布胶布启动一下,当然这里启动一不想整可能有一个时间啊,我们先让他睡眠一下,等待这个启动,比如说等个两秒钟吧。嗯,好,我们再来。 好,这里就打印出来了,主线层的响应就是这样,最多只有六个能够拿到库存扣减成功,其中有四个库存是扣减不足的,所以他们就是走到这个逻辑了啊,这个逻辑应该是没有走到 这个批次,运行完了之后也别忘了把这个数组进行一个清空。那我们再来试一 一下库存全都够的情况,现在有十个用户现成,我库存就设十个, 这样所有请求都是成功的,而且合并课件也只有一个县城,就降低了这个数据库 l 的这个性能上的压力啊。所以前面那一些很多小伙伴在问这个县城间应该怎么去进行合并跟通信通知 啊?主要就是定义了这么一个 promise, 它包含了用户的请求跟响应,根据这个对象的一个锁去进行一个呃,主色位特,然后跟 note five 这一期的戴墨我们就写到这里啊,主要就是用户现成了一个请求跟响应,对于用户来说他还是同步的,大家可能看我写下比较轻松啊,但是我强烈建议大家动手亲自去写一下,还是有一定难度的啊,你这样写了之后也能做一个小小的练习,这样你能够 加深整个县城间通信的一个方式。这期视频就到这里啊,也希望大家多多少年点赞转发,没关注的小伙伴也希望点一下关注哦面有时间的话我们会继续现在的这个呆默,继续去进行一个迭代,即使订阅的话就不会错过这种精彩的内容了。 好,谢谢大家,拜拜。

哈喽,大家好,我是吉海,之前很多粉丝说想让我来分享一些具体的案例,这次我就想来分享一下之前做的一个订单的切换,这里面涉及到了一些场景和解决方案,我认为还是比较有参考价值的。先简单介绍一下背景, 我们当时最开始的系统,他是有很多订单的来源的,他每一种订单类型他都单独去建了一张订单表, 所以导致后面订单表的维护成本非常高。看每张表的结构大部分是一样的,但是有一些具体的字段可能跟具体的场景有关系。出于这样一个背景,我们后面在做重构的时候,就要把这多个订单表合并为一商表。这里面就有几个难点, 第一就是我们当时这个服务是 tc 的,他是不能去停机的,所以你要做到一个平滑的迁移。第二个难点是这个项目他还在单独的业务迭代当中,所以你没办法单独的去改数据员的一个访问,因为业务开发的 小伙伴他也在不断的写新的 dio 的访问层,所以在同样一个代码里,你要保证对别人访问数据库,他是一个透明的效果。第三个难点就是你在做数据切换的这个过程当中,你怎么去规避这个风险,因为这个订单表它是属于核心经络, 所以他的自断的一些完整性、一致性,这个是要求非常高的。背景跟几个挑战都介绍清楚了之后,我们就来分析一下这个解决方案应该怎么去做。虽然在公司层面有一些成熟的分库分表的解决方案,但是我们不是单纯的分库分表,我们是把多个独立的表合并为一张表, 这个表的结构其实也是有变化的。但是值得欣慰的一点就是这些表都是一个应用在进行访问,我不知道你们系统会不会有存在这种情况。同样是存储一张表,可能是多个应用在访问,比如说商品要去查库存的系统,那库存的系统他可能是把库存存在 瑞丽纸的 ky 牛里面的,那商品要去访问库存,其实就有两种方式,第一种就是商品直接去访问这个 ky 牛访问瑞丽纸,另外一种就是商品去掉库存的接口库存,再去掉瑞丽纸。大家觉得这两种方案哪一种好一点? 从联络上来说,商品直接去访问瑞丽字好像更快一点,但是这个其实是违背为服务的一个原则的,相当于库存他把自己的数据结构、存储结构暴露给了外部,这样就会导致一些问题,比如说库存我哪天不想用瑞丽字了,我想改成 es 搜索引擎,那我是不是还要去找商品去改他的代码? 可能上游不只是商品,其他很多应用他都直接去访问了瑞迪斯,那是不是所有应用都要去改?或者说库存他塞到瑞迪斯里面一个 k y 值,他哪天要排查问题,不知道这个 k v 被哪个应用删掉了,那这个时候就非常难排查了。因为很多应用都在访问这个数据,所以作为没服务问题, 就尽量把对外吐出的数据都是定义在 api 的层面,不要暴露太多自己内部封装的细节,这个其实也是符合面相对象里面的依赖倒置的思想。我们继续回答解决方案。其实整个过程大致分为几步,第一步就是先双写, 然后再确认这个双喜的数据没问题,最后再把独的流量切换到这个新表的数据去,他可能通过几次发布去完成切换了这么一个过程,也可以一次性的把代码发上去,通过一些开关的配置让他走不同的逻辑, 这样就能够解决第一个问题,平滑的去迁移。那第二个问题就是你怎么去跟业务团队去进行一个节偶式的开发?我们是用的麦贝丽斯框架,我们在定义数据和访问的时候,只定义了这个迈跑的接口, 他这个接口的生成是动态的,通过查明文件去进行生成的。在 c 外十层都是通过 dio 的接口去进行一个注入的, 那如果说我把这个 dio 的生成进行一层代理,那这个代理里面去完成双鞋还有切换的这些逻辑,那是不是上有了十二十层就完全能够做到无感知了?所以我当时通过这种方式去解决了,跟业务去进行一个协调的开发,这样就能够双方进行一个结偶。另外一个问题就是把多张表 合并为一张表之后,你原先有没有通过其他场景通过 id 来进行查询,那多个表他原先可能是用的制成 id, 他原先不同的订单表,他的 id 可能是一样的,那这个问题怎么去解决?所以我们订单表在最开始生成的时候,我们都没有用他的制成 id, 都是去生成一个全局的流水号,所以这里就避免了这个 id 冲突的这个问题, 如果说每个表的 id 都是用了自身,并且他会有一些外界,那这个方案的话可能会变得更加的复杂,感兴趣的小伙伴可以思考一下 这个问题应该怎么去解决。那针对于第三个问题,怎么去保证新表表数据的写入的一次性?这个写入老表的时候,你要去写入新表,这两个操作应该是在一个事物里面,针对 inter 这种情况可能比较简单,但是针对啊不对头,这种情况你可能老表有数据,新表还没有数据,可能是一些历史数据, 可能你啊不对的这个数据在新表里面还不存在先增量同步,在新老表都去写。对于历史数据,我们还会有一个同步的逻辑,把老数据给迁移到新表来,那这里可能存在一些极端情况,比如说你在更新的时候,正常应该是先更新老表,再更新新表啊,可能同步的这个程序先读了老表的这个数据 还在同步的过程当中,你这个时候去更新了老表,然后又更新新表,发现新表还没有数据,那这个时候同步的这个程序又把老表老的数据给他,印制了他的新表,那这个时候新老表的数据就不一 一致了。所以对于历史数据的一个同步完了之后,你还要有一个定时任务,去进行双边的一个对账,对账的过程当中可能还要去发一些告警, 那这个告警出来之后,你看是需要程序他自动去进行一个双方数据的校证,还是你人工介入去进行一个定证啊,所以做好这几步之后,你会发现在整个同步完了之后,可能有一些告警就处理完了,后面逐渐告警就会变得越来越少,你两边的数据就基本能够达到一致, 虽然这么多还是写入的一个过程,那对于切换流量其实还是要有一个挥度的过程的,你不可能一把说把所有用户一下都切换到新表了, 因为这个表设计的制度还非常多,然后又是属于核心电路,我们还是要尽量做一些风险控制,我们还是要去做灰度的切流,比如说按百分比,比如说我用某个用户的 id 对一百取模等于一,我才进行 走心表,这样逐渐去放大这个流量。同时我还单独设计一个娇艳的模块,就是你在读的过程当中,先读老表,再读心表。还有一个比较的逻辑,你这个比较逻辑就是对比心表跟老表的数据,他是一致的,通过你的娇艳的,你才返回心表,否则还是走老表。 但是在这个过程当中,如果教练没有通过,你还是要发一个告警出来,看一下这到底是什么情况。基于这些步骤结束了之后,然后确认没问题,你再把这个灰度的流量逐渐给他打开,运行一阵之后,你会发现这些告警逐渐就变少了啊,系统也逐渐变稳定了之后, 你就可以把老表写入的流量也停掉,老表就可以下线了,那这个时候就完成了整个切换的过程,大概的思路就是这样,这里面设计的知识点还是比较多,最大的挑战还是怎么去做了一个无缝切换,怎么跟业务去并行,怎么去保证 两边数据新老表的一致性啊?其实这些思想在分分表啊,还有一些其他的存储有状态的,这些服务的分片迁移的过程当中可能都会涉及到我今天就分享你们多, 大家觉得讲的还不错耶,欢迎一键三连,没关注的小伙伴也麻烦点一下关注,拜拜。

给大家整理了一份单片机的资料,使用国产芯片替代进口货已经成为了一种趋势,我们国产的三十二位微处理器是完全可以替代 sm 三二单片机的, 这里我罗列了八个主流的国产三摄位单片机生产厂家,这几天我通过各种渠道整合了他们的相关资料,现在整理打包分享给大家,需要的朋友可以进群领取,或者是私信我都可以。 资料内容包括他们相应的数据手册、技术手册、芯片的选型指南,同时还给大家附上了他们的芯片资料原网址或者是技术支持的网址,大家可以进去根据需求自行下载。 基地三二单面机还给大家提供了他的程序移植指南。这里所罗列的三十二位微处理器生产 厂家,他们的产品基本上和 sm 三饵是高度相似的,他们都使用了阿玛克泰克斯顿盒, 只不过使用的版本不一样,比如 m 零、 m 一、 m 三、 m 四、 m 七档芯片的新闻参数、片仔资源也略有不同,而这正是我们程序移植所需要注意的事项。 如果你以前使用的是 sm 三二单片机,现在有上手国产芯片,难度是不大的。 目前北京召集创新的基地三二单片机资料比较丰富,使用的人也比较多,所以学习起来比较方便,大家可以根据自己的实际情况选择相应的单片机进行替换。

各位观众大家好,我是捷尔半导体的 f 一王宫,接下来我要向大家介绍一下我们捷尔半导体展会上的一些应用场景,像我手右边的这个是我们那个高性能四伏电机的一个控制系统, 他的呃采用的控制方案是主战是我们的四零七贼机芯片,而通过网口也有是伊斯凯的来控制这边的两个四伏控制器来驱动这边两个四伏电机,像这个电机中间连的是几根铅笔芯 啊,通过我们的师傅控制能够让这个铅笔芯在高速运动急停急动的状态下都不会断裂,就是两个师傅控制是一直是一个同步运动的一个状态,这个是一个可以在机器人, 那个数控机床以及工业领域都有很好的应用。而我这边的话是还有一个通用的电机控制平台,这边的话是一个控制板,这边是一个泳池同步电机 可以通过板子控制来对他进行一个呃加速减速、正反转的一个控制,能支持的算法包括有感、无感,有那个无感方波以及有感史料等多种控制方案, 其实也有很好的那个硬件检测以及那个安全防护,有过流过压以及堵钻的那个保障措施,来保证整个平台的一个安全运转。而这边还有一些方案板,就是我们的变为 s 空调以及一些车身 控制的一些方案版,嗯,可以呃,我们产品的介绍就差不多是这些,想具体的了解的话,我们的呃产品系列包括我们的通用 mcu 有幺零三零三零 以及我们有过车规认证的幺零三 rct 七和我们的零七二 bt 七他们都过了 acq 一百的车规认证啊,详细情况请到我们官网上面下载我们的数据手册和质量手册,谢谢。