`
insertyou
  • 浏览: 905684 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

【我所認知的BIOS】—>SMM (SYSTEM MANAGEMENT INTERRUPT )

阅读更多

【我所認知的BIOS—>SMM

System management mode 学习笔记)

By LightSeed

2009-9-11

1System management mode综述

这篇文章里面我主要是谈谈对IA32的了解,而且也纯粹是笔记而已,没有太多的组织语言。

1.1 什么是SMM

SMM是一种特殊用途的运行模式,他是用来处理影响整个系统功能的模式。影响整个系统功能的东东大致有:电源管理,系统硬件的控制等,或者也可用用这个模式来处理专有OEM designed代码。这种模式的运行只面向系统固件,而不是由软件来申请使用的。SMM的好处有很多后主要有,它提供了一个比较清楚的,容易孤立的处理的环境。这种模式对于系统或应用软件是透明的(我的理解呀,透明就是没有任何影响的意思^^,如果不正确还往高手不吝指教)。

1.2 SMM能够完成的事情

SMM通过SMI而被调用(或者说进入更合适点吧),处理器就会保存处理器的当前状态(处理器的上下文,发觉英文翻译过来真别扭,还是建议大家看E文原版比较好。-_-<),然后切换到SMRAM中这个独立的运行环境中来。当CPU的模式是SMM的时候,CPU去执行SMI handler代码,来完成相应的操作。比如:

①关闭未使用的磁盘驱动器或显示器,执行专有的代码;

②将整个系统进入挂起状态(suspended state)。

③处理DOS下的USB等等相关的东东。

④相关的定时器的刷新(在DOS下有Go Stop grant,的选择它也是通过SMI来计时的。)

⑤等等,,,用SMI来处理的相关操作真是太多了。这里例举不完。

当在SMI处理程序已完成其规定的操作后,它会执行恢复(RSM)指令。这指令会使处理器重新加载处理器之前已经保存了的上下文,切换到之前的保护模式或实模式下,恢复(应该说是进入SMM之前的程序,继续执行此程序)去执行中断应用程序(ISR)或操作系统程序(program)或任务(task)。

1.3 SMM的特点

SMM的以下机制(也许翻译成“特点”更加有味道),使之对于应用程序和操作系统而言都是透明的:

①进入SMM的唯一途径是触发了SMI信号。

②处理器执行SMM代码的时候是在一个单独的地址空间(SMRAM)下完成的,并且这段地址空间在其他模式下是绝对不能被访问的(inaccessible)。

③在进入SMM的时候,处理器保存了中断程序(interrupted program)或者任务(task)的上下文。

④通常由OS来处理的所有中断,在进入SMM后都会被disabled。(当然这里说的是通常,其实在后面我们会进一步探讨,这些中断也是可以打开的,只是要考虑的情况就比较多,比较复杂罢了。)

RSM指令只能在SMM里执行。(有人会问,那如果在其他模式下执行RSM,结果会怎样呢?笔者觉得你可以尝试一下,结果你自然就知道了。^^

SMM是类似于实地址模式中,不存在任何权限级别或地址映射。一个SMM的程序可以处理多达4G内存且可以执行所有I / O和指令。


2SMMSMI

2.1 SYSTEM MANAGEMENT INTERRUPT (SMI)系统管理中断

进入SMM的唯一途径是产生了SMI信号。这个信号会通过处理器的SMI# pin产生,或者直接从APIC bus上收到了SMI信号。SMI是一个不可屏蔽的外部中断,SMI的运作独立于处理器的其他中断,异常处理机制,本地(localAPICSMI的优先级要高于NMI(不可屏蔽中断)和可屏蔽中断。SMM是不可重入的,这就是说,当处理器在SMM里的时候,SMI是被disabled了的。

2.2 SMM和其他模式之间的联系

2.2.1 SMM和其他模式之间的切换

1显示了SMM与其他处理器运行模式(保护模式,实模式和虚拟- 8086)之间的切换过程。SMI信号产生后,不管处理器是实模式,还是保护模式,甚至虚拟8086模式都会导致处理器切换到SMM。执行指令(RSM)后,处理器总是回到进入到SMM模式之前的那个模式。

1 处理器各种模式之间的切换示意图

2.2.2 进入SMM

当处理器收到一个SMI信号,它会等待所有指令就绪,同时等待所有保存完成。处理器会保存它的上下文到SMRAM(后面小节会介绍),然后进入SMM的,并开始执行SMI handler(处理程序)。

当处理器在进入SMM的时候,它会通知处理器的外部硬件说:“SMM已经开始了”(或者SMI pin会呈三态。或者SMIACT#会被访问等等,只是各种处理器的表达方式不太一样罢了,但是宗旨都是一样的。这和我们人的语言比较相像,虽然我们和外国都说不同的语言,但是我们的目的都是相互交流。)。

SMI的优先级高于调试异常(debug exceptions)和外部中断。因此,如果NMI,可屏蔽硬件中断,或出现调试指令,和SMI同时向CPU发送信号的时候,只有SMI会被处理。随后CPU不再会响应SMI请求,因为处理器已经在SMM里面了。当处理器已经在SMM里面的时候,第一个SMI请求将会被锁存,并且当处理器执行RSM指令退出SMM后,马上会响应这个SMI(就是再一次进入SMM。)。不过需要说的是,当处理器在SMM中时它只能,仅仅只能锁存一个SMI信号。

2.2.3 退出SMM

退出SMM的唯一方法是执行RSM指令。RSM指令只能是在SMI的处理程序中有效;如果处理器没有处于SMM,而试图执行RSM指令,那么这将会导致操作码异常。

RSM指令可以恢复处理器的上下文,这些上下文的信息被做成镜像存入到SMRAM里面了。RSM就是通过加载这个镜像,恢复处理器的寄存器从而恢复状态的。然后处理器返回SMIACK信息到系统总线,并把控制权交还给被中断的程序。

RSM指令成功完成后,处理器会通知外部硬件SMM已经退出。对于不同的CPU有不同的反应这个和进入SMM的时候是相对应的。

如果处理器检测到无效的状态信息保存在SMRAM,它将会进入关闭状态并生成一个特殊的总线周期表明它已经关闭。这种关闭状态只发生在下列情况下:

①在写CR4的时候,控制寄存器CR4的预留位被设置为1。这种错误一般来说是不会发生的,除非SMI处理程序的代码修改了SMRAM保存处理器上下文区域的保存状态,从而修改了CR4的保存所在的位置。不过值得注意的是,它所在的位置也是无法读取或修改其保存状态的。

②一个非法的位组合写入到控制寄存器CR0,特别是PG设置为1PE设置为0,或NW1CD设置为0

③(仅对于奔腾处理器和英特尔486处理器)当执行RSM的时候,如果存入SMBASE地址寄存器的地址不是32Kbyte边界对齐。这条限制不适用P6系列处理器。

在关闭状态,英特尔处理器停止执行指令,直到RESET#,或NMI#INT#是有效。然而在关闭状态,奔腾系列处理器可以识别SMI#信号,P6系列的处理器和Intel486处理器却不行。英特尔的任何系列的CPU均不支持使用SMI#把CPU从关闭状态恢复。处理器在这种情况下的反应是不明确的。在奔腾4和后来处理器上,关闭将抑制INTRA20M,但不会改变任何其他抑制。在这些处理器上,如果在SMM的处理程序中没有做任何动作去解除对NMI的抑制,那么NMI将被一直抑制。


3SMRAM

3.1 SMRAM的综述

当处理器在SMM里的时候,处理器执行代码和存储数据都是在SMRAM空间里发生的。SMRAM空间映射到处理器的物理地址空间,它可多达4GBytes。处理器使用这个空间来保存处理器的上下文和存储SMI的处理程序代码,数据和堆栈。它也可以用来存储系统管理信息(如系统配置和关闭设备的具体信息)和OEM的具体信息。

默认SMRAM大小为64Kbytes,并且它的开始会有一个物理基地址(又叫做SMBASE)。当然这一切都是在物理内存上的。SMBASE的默认值是30000H(硬件复位就是这个值。)。处理器会到[SMBASE+8000H]处去找SMI处理程序的第一条指令。 [SMBASE + FE00H][SMBASE + FFFFH]存储着处理器的状态。(见后面3.2的详细说明。)

该系统的逻辑是需要解码的SMRAM最低限度物理地址范围,自[SMBASE + 8000H][SMBASE + FFFFH]。如果需要的话,处理器可以解码更大的地址空间。SMRAM大小最小可是32 KB(笔者:知道这里是怎么来的么?其实就是8000H~FFFFH)最大可以是 4 Gbytes

SMRAM位置可以通过改变SMBASE值来改变(后面会说。)。应当指出,在一个多处理器的系统中,所有处理器初始时SMBASE值相同(30000H)。初始化软件必须按顺序让每个处理器进入SMM并改变其SMBASE,以便它不和其他的处理器重叠。(笔者:在这里只是这么说而已,其实在后面的探讨中,我们会发现也不是说一定不能重叠,在某些情况下是可以重叠的。)

实际SMRAM的物理位置,可以在系统内存中,或在一个单独的RAM存储器里。当处理器收到一个SMI后,它产生一个SMI确认信号。(这和之前说的是同一回事。)

系统的逻辑可以使用SMI确认或SMIACT#引脚有效,来解码SMRAM重定向并访问他们(如果需要)。如果一个单独的RAM内存用于SMRAM,当处理器没有在SMM的时候,系统的逻辑应提供能映射到系统内存的SMRAM可编程方法。当处理器进入SMM后,并执行SMI处理程序之前,上句提的机制将使能启动程序来初始化SMRAM空间(因为它是load SMI处理程序的地方),

3.1 SMRAM State Save Map

IA - 32处理器最初进入SMM,它会写入自己的状态到SMRAM的相应区域。([SMBASE + 8000H + 7FFFH]~[SMBASE + 8000H +7E00H])。存在这些地方的有些寄存器是只读的,并不得修改(修改这些寄存器将导致不可预知的行为,比如正如之前说的CR4)。SMI处理程序不应依赖任何存储在这个区域的数据的值。图2SMRAM的大致描述。

2 SMRAM的用处

3是寄存器被保存示意图

3 寄存器被保持的示意图

需要说明的是后面的这些寄存器也被保存了,但是是不可读的,并且他们在退出SMM后同样会被恢复:

①控制寄存器CR4(在SMM中是,这个寄存器被全部清零。)

②段选择子的隐藏部分被保存到了CS,DS,ES,FS,GS,SS中。

下面的这些状态是不会自动保存和恢复的。他们是

①调试寄存器DR0~DR3

②在x87 FPU的寄存器。

MTRRs

④控制寄存器CR2

MSRP6系列处理器和Pentium处理器)TR3~TR7(奔腾和Intel486处理器)。

⑥陷阱控制器的状态。

The machine-check architecture registers(不知道该怎么翻译>.<)。

APIC内部中断状态(ISRIRR等)。

microcode(微代码)更新状态。

3.2 SMI HANGDLER的执行环境

保存完处理器的当前上下文后,处理器开始初始化其核心寄存器的value,正如表1所示。

1

在处理器进入SMM的时候,PEPG在控制寄存器CR0的标志(flag)被清除,这使的处理器是在一个类似的实模式的环境中。不过他们之间又有不少的差异,如下:

SMRAM的寻址可以从从0 FFFFFFFFH4 Gbytes)不等。(在SMM下,物理地址扩展(使能CR4PAE)不支持。)

②正常的64Kbyte实模式段界限提高到4 Gbytes。(直观去理解其实就是进入了Big real mode的模式了或者说Flat mode。)

③默认的操作数和地址大小为16位,这就限制了SMRAM地址空间的1Mbyte实地址模式界限。然而,操作数大小和地址大小可以通过覆盖前缀来访问超过1Mbyte的地址空间。(笔者:我的理解起是就是Big real mode的原理啦。只是这里表达的比较含蓄不好理解而已,起是就是指段选择子的隐藏部分,这是确定段基地址的。)

④如果使用32位操作数大小覆盖前缀,那么可以用近jmp或者call跳向可向4 GByte地址空间的任何地方。(CS:EIP去访问,理解其原理哦。)

⑤数据和堆栈可以被放在4 GByte的地址空间的任何地方。但如果他们被放在了1Mbyte以上的地方,那么他们只能被32位地址的寻址方式访问。同代码段一样,数据或堆栈段基址不能超过20位。(笔者:其实我想一般都会设成是0,这样比较方便访问和计算地址,Big real mode不也就是这样么?)

段寄存器CS的值是自动设置为30000H(它是默认将SMBASE左移4位得到的)。EIP寄存器设置为8000H。当EIP的值加到CS上后产生了一个线性地址,这个线性地址就是SMI处理程序的第一条指令所在。

其他段寄存器(DSSSESFSGS)均被清除为0,且他们的段界限设置为4 Gbytes。在这种情况下,SMRAM地址空间可被视为一个平坦的4 GByte的线性地址空间。(笔者:这不就是Flat mode的定义么,呵呵。。。)如果一个段寄存器被加载16位的值,该值被左移4位后加载到段基地址(段寄存器的隐藏部分)(笔者:前面个括号可是原文里面出现了的哦,再一次印证了我说的,确实是Flat mode)。段的属性和解析那都不会被修改。(笔者:这里也是Flat mode的一个强调,因为在flat mode中如果显示地修改段选择子,那么段的基地址会被重新加载。)


4、中断在SMM里的特殊情况

4.1 SMM里的中断处理

之前我们一直都说在SMM这种模式下CPU是不会再响应其他中断的,其实呀这也是有特殊情况的。容我慢慢道来。

当处理器进入SMM了后,所有的硬件中断都被disabled,如下面的动作:

EFLAGS寄存器的IF标志被清除,这样可以屏蔽硬件产生的中断。

EFLAGS寄存器的TF标志被清除,这样可以disabled单步陷阱(Single-step traps)。

③调试寄存器DR7被清除,这样可以disabled断点陷阱(Breakpoint traps)。

NMISMIA20M中断被内部SMM的逻辑封锁。(见后面小节有叙述。)

软件调用中断和异常仍有可能发生,屏蔽硬件中断可以通过设置IF标志而被使能。英特尔建议,SMM的代码尽量写的不调用软件中断(如INT NINTOBOUND 指令)或产生异常。

如果SMM的处理程序需要中断和异常处理,那么必须要在SMM内部创建和初始化SMM的中断表以及必要的异常和中断处理程序。在中断表是正确初始化(使用LIDT指令)完成之前,任何异常和软件中断将导致不可预知的处理器行为。

4.2 SMM里中断的限制

我们在设计SMM的中断和异常(exception)处理机制的时候有以下的限制:

①中断表应被设置于线性地址0,必须是实模式的中断向量表类型。(4bytes包含CSIP)。

②由于是实模式类型的基地址信息,中断或异常不能控制段的基地址位数超过20位的的段基地址。

③中断或异常无法控制一个段偏移超过16位(64Kbyte)的子程序。

④当异常或中断发生时,返回地址的EIP只有最低16位会作为有效位被压入了堆栈。如果中断程序的偏移大于64Kbytes,那么当CPU执行完中断子程序后就不能正确返回到中断发生前的中断点。(在这种情况下的话,我们有一种解决方法就是,手动去修改在堆栈中的返回地址。)

⑤当SMI handler正在执行的时候(CpuSMM下的另一种说法),SMBASE的重定位这种特性会影响处理器中断或者异常的返回。例如,如果SMBASE重定位的地址高于1MByte的时候,但是异常处理程序却在低于1 MByte的内存中,一个正常的SMI handler的返回就会出问题了。不过到是有一种解决方案:提供一个计算异常处理子程序的机制,这种机制可以计算当子程序的返回地址是在1Mbyte以上,而返回地址是16位的情况下的子程序的返回地址。当然了,这种修改返回地址的机制肯定是修改堆栈中的相应位置来实现的。修改完这个地址后,我们就可以通过far callreturn到中断前的程序了。

⑥如果SMI handler需要进入调试陷阱机制,必须确保SMM访问调试处理程序可行,并且保存了当前内容调试寄存器DR0~DR3(为了等下好恢复)。调试寄存器DR0~DR3的和DR7必须初始化为适当的值。

⑦如如果需要单步的机制,我们必须要保证SMM访问调试处理程序可用。且设置EFLAGSTF标志位。

⑧同样如果CPUSMM的时候,我们还要求CPU能响应可屏蔽的硬件中断或者软件触发的中断。(笔者:当然这种SMI设计是可以实现的)。那么我们必须确保SMM访问中断处理程序可行的(笔者:为什么要特别加上这句,就是应该SMBASE的重定位有可能会让ISR不能正常访问到。),然后将EFLAGS寄存器的IF标志置1(用STI指令)。软件中断其实并没有被阻止,所以他们不需要被特别的使能(enabled)。(笔者:这里有两点要说明一下,如果不说明估计很多人会头晕了。首先,软件中断本身就属于OS的范畴,那么SMM本身对它来说就是透明的,就是不存在的。再次,我们要理解软件中断的概念,它是直接到中断向量表中取相应地址然后call的。基于这两点,我想应该比较清楚了。)

5NMI HANDLING WHILE IN SMM

SMI Handler中,NMI(不可屏蔽中断)都将被屏蔽。如果在SMI handler里有NMI(不可屏蔽中断)请求发生,那么它将被锁存,待处理器退出SMM后再来处理这个被锁存的中断。需要提醒的是,当CPU进入SMM后可以且仅仅可以锁存一个NMI(不可屏蔽中断)请求。有这样一种情况比较特殊,假如CPU正在执行RSM指令的时候,同时又有NMI的请求发生,那么这种情况的话NMI的请求将会等待,并且当CPU执行完RSM后会优先响应NMI的请求(换言之,原本CPU会中断已经在指令预取队列中的指令顺序,先响应NMI。)。当然这一切都是我们首先假设在SMI发生之前NMI均没有被阻止。如果在SMI发生之前NMI均被阻止,那么CPU在执行RSM的时候全部NMI也均会被阻止。(笔者:聪明的你肯定会觉得这里怪怪的,那你知道这个地方哪里怪了么?在5.2中找答案。)

5.1 IRET

虽然处理器进入SMM后,NMI(不可屏蔽中断)请求会被阻止,但是他们可能会通过软件被enabled,比如说执行IRET这条指令。如果SMM handler需要使用NMI(不可屏蔽中断),那么它应该先调用一个虚拟(dummy)中断服务来处理IRET指令的目的地址。一旦执行了IRET指令,NMI(不可屏蔽中断)的中断服务就会像在实模式下面的行为一样去执行ISR。可以这么说,这就已经不再是SMM了。(不知道大家理解了没有?)(笔者:后来我认真研究了一下,为什么CPU会有这种机制,一旦执行IRET这条指令的话,那么NMI的阻止状态就会被打开。这其实是和NMI的中断机制决定的。因为当CPU在处理NMI handler的时候,会disable另外的NMI handlercall,知道CPU执行了IRET这条指令后,CPU才会把这个disable打开。这种阻止的机制其实就是为了防止NMI的嵌套调用而做的处理。)

5.2 一种更特殊的情况(也得考虑进去哦)

还有一种更特殊的情况可能会发生:本身SMI handler就已经嵌套了一个NMI,恰好在处理NMI的时候,另外一个NMI也同时发生了。一般来说,当我们在处理NMI的时候,我们会关掉NMI中断,所以一般情况下而言当NMI发生后CPU就能完整的去处理这个NMI中断,并且通过IRET返回。(笔者:而且一次只能处理一个NMI中断哦。)

当正常执行NMI handler 的时候,CPU进入了SMMCPU此时会保存上下文到SMRAM,但是不会保存继续关闭NMI的这种属性。所以潜在地,当CPU还在SMM里面或者正在执行RSM的时候,就会有可能有一个NMI被锁存,并且根据SMM的特性,当CPU退出SMM后不会执行之前预取队列里的指令,优先执行这个被锁存的NMI handler。(要知道,纵使进入SMM之前的那个NMI还没有被处理完。)所以,有可能就会有一个甚至更多的NMI被嵌套进了第一个NMI handler。当我们在设计NMI 中断服务子程序(ISR)的时候应该把这种可能考虑进去。(笔者:归根结底,其实这样还是由于CPUSMM特性造成。如果SMM 不会锁存NMI的话,那么就不会有这些事情发生了。呵呵,,,但是intelCPU就是有这个特性呢,故我们应该考虑的全面点。)

6SMBASE RELOCATION(重定位)

6.1 SMBASE重置综述

SMRAM默认的基地址是30000H。此值被存在处理器一个内部寄存器中,被称为SMBASE register。操作系统或可执行程序可以重置的SMRAM里的相应位置来改变SMBASE(这个位置就是SMRAM偏移量7EF8H)从而得到一个新的值(见图4)。

4 SMBASESMRAM中的位置

在执行RSM指令的时候会重新加载CPU内部的SMBASE register。而这个值就是offset 7EF8H处的值,然后退出SMM。所有后续SMI请求都会使用这个新的SMBASE的值来作为基地址去搜索SMI handler的第一条指令。(这条指令会在 SMBASE+8000H处。)并且SMRAM的状态保存区域会从SMBASE + FE00HSMBASE + FFFFH处。(当RESET的时候,处理器重置内部SMBASE register的值,复位成30000H,但执行CPU initial的时候不会改变它。)

在多处理器系统,初始化软件必须为每个处理器设置SMBASE一个合适的值,让SMRAM保存各自的上下文的时候不会重叠。(对于奔腾处理器和Intel486处理器,SMBASE值必须在32Kbyte的边界。否则,在执行RSM指令的时候,处理器将进入关闭状态。)

当然了,要让SMBASE重置的话,也必须要一个开关,见图5

5 SMM identifier

6.2 SMRAM 重定位到1 MByte以上的内存

CPUSMM的时候,所有的段基寄存器只能通过改变段寄存器值来更新。段寄存器是16位的,能够用的也就最多才20位,这20位就是平常理解的段基址(段寄存器左移4位确定段基址址)。如果SMRAM被重置到了1MByte以上的内存地址,当软件在实模式下运行的时候是不能初始化段寄存器(Segment register)指向SMRAM的基地址(SMBASE)的。

如果使用32位地址,覆盖前缀而产生的偏移就可计算出SMRAM的正确地址。(笔者:我的理解其实这里就是指修改了段选择子的隐藏部分啦。只是表述不同罢了。)例如,如果SMBASE已经被重置到了FFFFFFHDSESFS,和GS寄存器被初始化为0SMRAM里的数据可以通过使用32位偏移寄存器来访问,如下面的例子:

MOV esi,00FFxxxxH ; 16M一下的一个64K</spa

分享到:
评论

相关推荐

    dnSpy-net-win32-222.zip

    dnSpy-net-win32-222.zip

    和美乡村城乡融合发展数字化解决方案.docx

    和美乡村城乡融合发展数字化解决方案.docx

    如何看待“适度宽松”的货币政策.pdf

    如何看待“适度宽松”的货币政策.pdf

    C#连接sap NCO组件 X64版

    NCO 3.0.18 64位

    法码滋.exe法码滋2.exe法码滋3.exe

    法码滋.exe法码滋2.exe法码滋3.exe

    基于MATLAB的导航科学计算库

    * GPS IMU经典15维ESKF松组合 * VRU/AHRS姿态融合算法 * 捷联惯导速度位置姿态解算例子 * UWB IMU紧组合融合 * 每个例子自带数据集

    毕业设计Jupyter Notebook基于深度网络的垃圾识别与分类算法研究项目源代码,用PyTorch框架中的transforms方法对数据进行预处理操作,后经过多次调参实验,对比不同模型分类效果

    在现代社会生活与生产活动下,不可避免的会产生巨量且多样的垃圾。我国的人口和经济总量均位居世界前列,因此,必然面临着庞大数量的垃圾处理的难题。如何通过人工智能来对垃圾进行有效分类,成为当前备受关注的研究热点。本文为展开基于深度网络的垃圾识别与分类算法研究,先使用PyTorch框架中的transforms方法对数据进行预处理操作,后经过多次调参实验,对比朴素贝叶斯模型、Keras卷积神经网络模型、ResNeXt101模型的垃圾分类效果。确定最佳分类模型是ResNeXt101,该模型在GPU环境下的分类准确率达到了94.7%。最后利用postman软件来测试API接口,完成图片的在线预测。在微信开发者工具的基础上,利用一些天行数据的垃圾分类的API接口再结合最佳模型的API接口,开发出了一个垃圾分类微信小程序。本文的研究内容丰富和完善了垃圾图像分类的相关研究,也为后续的研究提供了一定的参考价值。

    C#上位机开发与工控通讯实战课程

    一、上位机简介   在单片机项目开发中,上位机也是一个很重要的部分,主要用于数据显示(波形、温度等)、用户控制(LED,继电器等),下位机(单片机)与 上位机之间要进行数据通信的两种方式都是基于串口的: USB转串口 —— 上位机和下位机通过USB转串口连接线直接相连进行数据交互 串口转WIFI(ESP8266)—— 上位机和下位机基于TCP/IP协议通过以太网或者WIFI传输数据 串口转蓝牙(HC-06)—— 不多用,暂不介绍   Windows上位机(EXE可执行程序),最早用VB语言开发,后来由于C++的发展,采用MFC开发,近几年,微软发布了基于.NET框架的面向对象语言C#,更加稳定安全,再配合微软强大的VS进行开发,效率奇高。   本文使用Visual Studio 2022作为开发环境,上位机开发主要有WPF框架与Winform框架,他们都是基于.NET框架 WPF需要C/S基础,使用XAML来构建应用UI,界面比较美观,但是内存开销大 Winform可以使用窗口控件来构建应用,比较简单易学 二、开发环境设置 1. 安装Visual Studio 首先,确保你已经

    course_s4_ALINX_ZYNQ_MPSoC开发平台Linux驱动教程V1.04.pdf

    course_s4_ALINX_ZYNQ_MPSoC开发平台Linux驱动教程V1.04.pdf

    基于JavaWeb的毕业季旅游一站式定制服务平台_88z1j4jp_208-wx-(1).zip

    基于JavaWeb的毕业季旅游一站式定制服务平台_88z1j4jp_208-wx-(1).zip

    数据恢复软件 Apeaksoft Data Recovery for Mac v1.6.16

    Apeaksoft Data Recovery for Mac v1.6.16

    cms测试练习项目(linux系统部署)

    cms测试练习项目(linux系统部署),可以用来进行python的测试练手项目

    大学录取结果数据集,大学录取结果分析数据,大学录取因素分析

    数据集简介:大学录取结果分析 概述 大学录取结果数据集包含了有关大学录取过程的信息,包括关键变量,可用于分析不同学术因素与申请者是否被录取之间的关系。该数据集非常适合进行探索性数据分析、训练预测模型以及研究影响录取决策的因素。 数据集列描述 admit:指示申请者是否被录取(1=被录取,0=未录取)。 paes:申请者在高等教育能力测试(PAES)中获得的分数。 nem:中学教育成绩平均分,评分范围从1.0到7.0。 rank:申请者在其班级中的排名,数值越低表示排名越好。 数据集目的 本数据集旨在让用户探索学术指标(如PAES分数、GPA和排名)与大学录取成功率之间的关系。这可以用于: 开发预测模型:基于学术表现预测录取可能性。 识别趋势:找出影响录取的关键学术因素。 生成可视化图表:理解分数分布及录取结果的关系。 数据集规模 记录数:1813条。 列数:5列。

    STM32F427+rtthread下的bootload 网口(webclient)+串口(ymodem)传输,代码无质量,谨慎使用

    STM32F427+rtthread下的bootload 网口(webclient)+串口(ymodem)传输,代码无质量,谨慎使用

    电影院购票-JAVA-基于springBoot的电影院购票系统设计与实现(毕业论文)

    1. 用户管理功能 用户注册与登录:用户可以通过手机号、邮箱等方式注册账户,并且可以通过账号登录系统进行购票、查看历史订单等操作。 个人信息管理:用户可以查看和修改个人信息(如姓名、手机号、邮箱等),并进行密码重置等操作。 实名认证:部分电影院购票系统要求用户进行实名认证,确保用户身份的真实性。 2. 电影信息展示功能 电影排片查询:用户可以查看当前和未来一段时间内的电影排片表,包括电影名称、上映时间、影片时长、类型、导演、演员等详细信息。 电影详情页:点击具体电影后,用户可以查看电影的详细信息,如剧情介绍、影评、评分、预告片等内容。 电影评分与评论:用户可以查看其他观众的评分和评论,也可以对已观看的电影进行评分和评论。 3. 座位选择与预定功能 影厅座位图:系统展示每场次的影厅座位图,用户可以通过座位图查看当前座位的状态(如可选、已选、已售出、VIP座位等)。 座位选择:用户可以选择自己喜欢的座位,系统会实时更新座位的可用状态,避免重复选择。 座位偏好设置:用户可以设置自己的座位偏好,如选择前排、中排或后排,靠窗或靠过道等。 4. 电影票购买与支付功能 票价展示:系统会展示每个座位的

    Bukkit-BETA1.8.1服务端核心

    Bukkit-BETA1.8.1服务端核心

    快速排序在Go中的高效实现与应用

    内容概要:本文详细介绍了快速排序算法的原理和在Go语言中的高效实现方法。首先解释了快速排序的基本思想和实现步骤,接着提供了Go语言中实现快速排序的核心代码,并讨论了性能优化策略。最后,通过具体的应用场景实例,展示了快速排序在实际项目中的高效应用。 适合人群:具备一定编程基础,特别是对Go语言感兴趣的开发人员。 使用场景及目标:①理解快速排序算法的基本原理和分治策略;②学习如何在Go语言中高效实现快速排序;③掌握快速排序在实际项目中的应用实例。 阅读建议:本文不仅详细讲解了快速排序的原理,还提供了具体的实现代码和优化策略,建议读者在阅读过程中尝试实现和调试代码,以便更好地理解和掌握相关知识点。

    java毕设项目之学生社团管理系统+vue(完整前后端+说明文档+mysql+lw).zip

    项目包含完整前后端源码和数据库文件,均测试可正常运行 环境说明: 开发语言:Java 框架:ssm,mybatis JDK版本:JDK1.8 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/idea Maven包:Maven3.3 部署容器:tomcat7

    NSMethodNotImplementedException如何解决.md

    NSMethodNotImplementedException如何解决

    计算机接口实验报告.zip

    计算机接口实验报告,环境:PC 机一台,TD-PITE 实验装置一套。报告内容有,实验目的、实验设备、实验内容、实验步骤、实验程序(汇编)、实验结果、实验总结,一步到位!!!!!! 一步到位!!!!!!

Global site tag (gtag.js) - Google Analytics