关于使用Windows 10和键盘第2部分示例的PC的操作

在这一部分中,我们将考虑关于从键盘到CPU的已按下键信息的处理方式,其中将包含很多图片,而这并不是最后一部分。我将从以用户模式编写的程序员(用户程序,Web,移动应用程序)的角度来谈论这一点,因此可能存在不准确之处。从事电子产品的人不太可能找到对自己有用的东西。第一部分在这里


接受高级程序员教育的问题是,学生在不了解上下文的情况下详细研究了脱离上下文的各个方面。高学期的几个学期可以理解物理学,可以理解电气工程,电气设备,汇编程序,操作系统,算法,系统编程以及许多其他科目,它们都已纳入了五年制标准课程。大量的细节,没有人解释这是如何适应全局的,假设五年后,学生会将其束缚在脑海中,然后他将使用.Net,永远不会碰到电子学和内核模式。我相信,不必如此详细地了解计算机的操作,就足以对技术体系中正在发生的事情有一个大致的了解。如果组成大学培训计划的人开设了驾驶学校,您将学习俄语,书法和流体力学,因为您需要与检查员进行交流,更换流体并编写说明性注释。文章中会有一些错误,因此它不适合通过专业学科的考试,但是这样做之后,您将更容易理解PC设备。

在猫流量之下。

键盘键是一个按钮,用于关闭触点,电流通过触点。闭合/打开机制的制作方式不必完全按下按钮,因为否则手指会很快疲劳并且键盘将不符合人体工程学。在本节中,键如下所示。右侧是施加电压的触点。


可以确定键击的键盘“大脑”是微控制器,它本质上是一台微型计算机,具有程序,该程序通过向每个键施加电压来检查每个键,如果键通过,则按下该键。微控制器的腿有自己的名称,可以用代码访问,它们用于与外界通信。支腿可以控制微控制器的操作,报告芯片状态或用于读取/传输数据。
程序(固件)可以用C或汇编语言编写,并通过编程器上传到微控制器。它是带有用于安装微控制器的连接器的设备,可以通过运行特殊软件的USB连接到计算机。这是程序员在现实生活中的样子:
通过该程序,可以设置或测量每条腿的电压。查找被按下的键的算法是将电压施加到一条腿上,然后在另一条腿上对其进行测量,如果按下了该键,则第二条腿的电压将与输入电压大致相同。因此,在无限循环中将检查所有键。通常,键盘具有80-110个按钮,并且接触控制器(引脚)小得多。因此,他们使用诸如“键盘矩阵”之类的方法-所有键都分布在列和行中,并且算法被简化为找到与程序施加电压的行相交的列。与联系人的列/行对应关系在此处突出显示。


实际上,矩阵可能看起来像这样。左边是工业,右边是自制。


在伪代码上,固件程序中确定按下键的部分看起来像这样。

for (int i = 0; i < COLSC; i++) {
 	SetPower(columns[i], 3.0 f);
  	for (int j = 0; j < ROWSC; j++) {
    		float power = GetPower(rows[j]);
    		if (power >= 3.0f - THRESHOLD) {
      			BYTE key = keys[i, j];
      			SendKey(key);
    		}
  	}
}

每个密钥对应一个扫描代码,它是标准化的,并且是一个8位数字,即一个字节。因此,当按下Y键时,键盘控制器将必须发送数字21(0x15),而释放时将发送数字149(0x95)。发货如何完成?当然,您使用JSON,Web服务或在进程之间发送数据,并且知道要发送数据需要序列化,即变成接收者可以反序列化的字节或格式化文本的数组,即在其地址空间中重新创建一个对象。在如此低的水平下,什么可以序列化数据?我们只需要传输1个字节(8位)。展望未来,我会说我们将一点一点地传输数据。

在数学中,有一个公式可以将我们熟悉的任何十进制数转换为零和一的序列,反之亦然。该公式已在计算机技术中得到应用。在第一部分中,我偶然提到了模拟技术是利用物理定律,而数字则是在零和一的水平上工作。这意味着模拟电话将人类语音的整个频谱编码为一系列电磁波,而数字电话则使用一种芯片将芯片将人类语音转换为数字数据(例如WAV文件),然后以电磁波的形式按零和一的序列进行传输。仅在这种情况下,而不是语音的整个频谱,仅必须表示两个值-0和1.它们可以由不同长度,不同电压的波来表示,光脉冲通过光纤,纸上的黑白条纹,打孔卡上的孔。

按下的Y键的二进制扫描代码看起来像00010101。我们将沿着负责数据(DATA的微控制器支路传输它们逻辑单元为3.3V或更高,逻辑零-电压约为0V。这是要抓住的地方-如何连续传递三个零?为此,我们需要第二条腿,我们将其称为CLOCK,当这条腿上的一个腿意味着一个比特的传输会话已经开始,而零已经结束。值(电压)的这种变化将在一定的时间间隔(例如50纳秒)内发生,因为在另一端有第二个微控制器以其自己的速度工作,并以无限循环的方式监听CLOCK和DATA连接到的支路。在此示例中,我假设键盘通过PS2连接器连接,如下所示。通过USB端口,传输算法将有所不同。如您所见,PS2端口具有称为数据,时钟的引脚。除了它们之外,还有一个触点,PS2端口控制器通过该触点将操作所需的5V电压分配给键盘和一个接地触点,该触点简单地显示在键盘主体上。不使用其他联系人。
PS / 2 端口之所以称为串行总线,是因为它逐一传输位(一个位序列)。并行端口一次将数据传输到多个触点,并且可以为一个数据传输会话一次传输例如一个字节(8位)。

端口,总线和协议之间有什么区别?总线就像端口一样,是一组触点(接线)以及关于如何使用它们的协议,只有端口具有用于连接外部设备的连接,并且总线用于通信主板上的组件。端口本质上是中间带有连接器的总线。协议是通过联系人进行的交互。在PS / 2的示例中,这是通过时钟和数据触点进行数据传输的顺序。

以前,Intel 8042微控制器非常普遍,既用于键盘又用作PS2端口控制器,即两个相同的芯片交换数据。 Windows中的PS2端口驱动程序称为8042prt.sys。

实际上,我们传输的不是8位,而是11位,因为数据是作为数据包消息传输的。另外的3位指示数据的开始和结束-在开始处为0,在结束处为0 1,这种协议用于在PS2中将数据从设备传输到主机。如果您更喜欢理解代码,则它可能看起来像伪代码中SendKey函数。它通过PS2总线发送有关按键的数据。


void SendBit(BYTE bit) {
	float power = (bit != 0) ? 3.3f : 0.0f;
	SetPower(DATA, power);
	SetPower(CLOCK, 3.3f);
	Sleep(50);
	SetPower(CLOCK, 0.0f);
	Sleep(50);
}

void SendData(BYTE data) {
	SendBit(0);
	
	for (BYTE i = 0; i < sizeof(BYTE); i++) {
		BYTE bit = (data >> i) & 1;
		SendBit(bit);
	}

	SendBit(0);
	SendBit(1);
}

不一定总是需要手动设置每个分支上的电压以进行数据传输。在某些情况下,寄存器中存储的值会自动显示在触点上。

在图形上,这种数据传输将如下显示。时间沿X轴,电压沿Y轴。


在模拟技术中,信号可能会失真,即 电线没有连接任何东西,但由于附近有电磁场,电压表上显示的电压为0.5V。因此,使用阈值电压的概念。如果电压小于阈值,则我们假定逻辑为零,否则为1。考虑到可能的失真,按下的Y键的扫描代码可能如下所示:


在仔细研究键盘上的数据如何到达CPU之前,让我们先谈谈微芯片总线主板

微控制器和微电路


微控制器可以执行缝入其中的程序,具有一定数量的RAM内存,并可以存储数据和程序代码。在芯片中,可以在设计阶段设置程序。手动创建实现算法的电路非常耗时,因此,可以使用一种称为VHDL(硬件描述语言)的特殊编程语言来设计微电路。这是一种高级编程语言,可以翻译成电路图,通过一个程序运行,该程序在板上找到无线电元件的最佳位置,并最终以物理形式制成。图片仅供参考。



微芯片和微控制器中的数据和命令如何表示?计算机技术的基础是晶体管,人类已学会在微观尺寸上制造晶体管。晶体管就是这样一种无线电元件,它具有三个分支:一个输入,一个输出,以及在它们之间的控制,用于打开或关闭两个分支之间的电流。下图说明了晶体管的操作,水说明了电流。


电压施加到输入端,如果控件有电压,则电流流到输出,否则将为0V。我们有8个晶体管,每个晶体管都有一个连接到输出端的LED,该LED要么亮着,要么不亮,我们可以想象到256种独特的组合(2的8的幂)。Lapochki会从右到左以及十进制数字进行解释。低位数字在右边。
那些。一个灯泡代表一位信息(0或1),八个灯泡代表一个字节。可以在晶体管上构建逻辑运算符AND,OR,NOT,XOR。


例如,在AND运算器电路中(在上图的左侧),仅当两个输入电压都不为零时,输出才会具有电压。已经有人发明了基于按位逻辑运算和位移的加,乘,除和减法算法。芯片制造商只需要实现它们。按位加法算法的操作如下所示;我们将不对其进行分析:


纳米晶体管是微观的,可以放置在数以百万计的板上。英特尔处理器如下图所示,其中一个内核大概是什么样子。图片是说明性的。


在相同的情况下,微电路可能包含一个微控制器。

轮胎


通常,在教科书中,轮胎显示为粗体箭头,如下图所示。这样做是为了避免绘制触点的所有连接(可能很多)。PS2总线的操作非常简单,您只需要三个引脚即可。但是有些总线具有例如124个用于数据传输的触点。



有以下类型的轮胎:
  • 数据-这些触点上的位被解释为数据:数字,符号,图片的一部分或其他二进制数据。总线宽度影响吞吐量,每秒传输的位数
  • 地址-这些引脚上的位被解释为内存中的物理地址。该总线的宽度决定了支持的最大RAM容量。
  • — . CPU RAM I/O.
  • . , . ATX 24 Pin 12V PSU Connector, .


轮胎可以由基材组成,即 一些触点用于数据,其他触点用于地址,其他触点用于控制以及向其传输功率的触点。交替使用相同的联系人同时传输数据和地址的方法称为多路复用例如,英特尔8086处理器具有20位的数据和地址总线,在其引脚图上,其触点由AD0-AD19(支线16-2和39-35)指示。


在更复杂的情况下,我们可能有几个连接到相同触点的微电路。对于正常的通信,他们需要一个附加的芯片来确定谁在什么时间点可以使用它们,这被称为总线控制器。。在下图中,真空中的球形总线:四个相同的微控制器通过总线控制器将数据传输到用户微控制器。红线是总线控制器分配给与其连接的所有芯片的电压。数据通过绿线传输并与总线控制器进行“协商”,蓝线为Clock,总线控制器通过时钟同步控制器的通信,因为它们可以以不同的速度运行。如果逻辑单元位于蓝线上,则有权使用总线的芯片可以执行与外界的一种交互作用-例如,读取一点。


总线控制器可以被视为不可或缺的组件,因为与外界的通信将通过总线控制器进行,而总线上实际有多少芯片或实际的外部设备并不重要。为了进行数据传输,主板具有广泛的总线网络。尽管有很多芯片组,但大多数情况下它们遵循典型的布局,因为连接到主板的所有设备均分为:
  • 慢-键盘,硬盘驱动器,网卡,音频等
  • 快速-CPU,RAM,GPU。
在此基础上划分,主板上有两个主要的芯片-的南桥,负责协调所有慢速设备的工作,以及北桥,快速设备的协调。在现代计算机中,北桥位于CPU本身,南桥可以称为平台控制器中枢,但这并没有改变本质。这两个网桥都通过总线互连,通过它们相互通知重大事件。特别令人感兴趣的是时钟发生器,处理器,RAM和图形卡通过该时钟发生器同步它们的工作,即同一条蓝线。超频这实际上是在更改BIOS设置,以便更频繁地进行同步,而硬件(主要是CPU)将更难加热,消耗更多功率并更快地开发其资源。相反的是,当速度降低以节省电池电量或降低噪音时。

芯片组是一组旨在相互配合使用的芯片。它们提供母板上组件之间的通信,并提供计时器等功能。该芯片组仅与一个处理器品牌配合使用,AMD不能与Intel芯片组一起插入主板,它们甚至具有不同的触点。主板图如下所示:
是否需要硬件封装的示例?英特尔芯片组具有称为Super IO的芯片,如下图所示,并通过LPC总线连接到南桥。LPC是用于连接CLOCK,DATA,VCC(POWER)的智能名称。该芯片包含所有用于外围设备的旧芯片的仿真,包括用于PS2端口的8042芯片。还有一个用于软盘和其他干扰进度的端口控制器仿真器。在主板的总图中,Super IO和LPC总线均在上面指出


现代的PS2端口直接连接到Super I / O芯片。绿色是键盘,紫色是鼠标。以前,它连接到Intel 8042微控制器。


主板由电介质制成,即 不导电的材料。电流只能流过板上印刷的线条。母板有很多层,每个层上都有自己的触点印刷,因此,如果您在看不见线路的地方钻孔母板,则可以通过损坏板内部的不可见触点来破坏母板。现在,您可以仔细研究一下将数据从PS2分发到CPU的过程。

从PS2到处理器的道路


通常,在8086处理器上考虑计算机体系结构,这是正确的,因为它与现代CPU相比非常简单,另一方面,这是错误的,因为它很旧并且不能反映现代计算机的体系结构。英特尔8086不需要任何桥接器,因为它是如此之慢以至于可以与一条总线上的外围设备配合使用,即以一种频率。我不了解现代的CPU和芯片组,因此我将在类似于真实的虚拟机和芯片组上进行解释。在我的示例中,将有一个虚构的CPU与Intel 8086非常相似。 Super IO芯片有一百多个触点,并且Internet上有文档,但是我看不出要弄清键盘和LPC总线实际用于与South Bridge通信的哪些引脚。最主要的是原理,可以用不同的方式来实现。

让我们快速浏览一下图片,以记住我们已经通过了。绿色箭头表示我们将采取的道路。


因此,来自键盘的数据已经到达PS2端口控制器,该控制器曾经是Intel 8042芯片,现在由Super IO芯片进行仿真。现在,让我们分析一下带有虚拟CPU的虚拟主板上的进一步操作过程。 PS2控制器接收到按下的Y键的扫描代码,现在将电压提供给接触信号(紫色线,请参见下图),可编程中断控制器应在该信号上通知键盘数据。该信号从一个芯片传输到另一个芯片,直到北桥将其传递给中断管理器。


可编程中断控制器英特尔8259芯片,其中8条腿(其名称IRQ0-IRQ7)被保留用于从特定端口接收通知( nterrupt ř ë Q uest)。键盘与IRQ1引脚相连,打印机与IRQ7引脚相连,软盘,声卡,并行端口以及其他与该引脚相连的引脚。当然,可以有八个以上的设备,因此,当另一个类似的PIC连接到名称为IRQ2的腿上时,就使用了级联之类的技术,在该腿上,计数不是从0开始,而是从7开始。鼠标与IRQ12绑定,即脚IRQ5在第二张PIC上。

现在,中断控制器应将键盘上的事件通知CPU。发生这种情况如下:
  1. INT (Interrupt) , INTR (Interrupt Request) . CPU , , .. . , . exception .
  2. INTR, .
  3. ( D0-D7) , . PIC ( IRQ).

    , ? . . — (x, y, z, w). .
  4. CPU AD0-AD7 , . IDT (Interrupt Descriptior Table) , , . CPU .

    . . , IDT C# .

    struct IDT_entry{
    	unsigned short int offset_lowerbits;
    	unsigned short int selector;
    	unsigned char zero;
    	unsigned char type_attr;
    	unsigned short int offset_higherbits;
    };
     
    struct IDT_entry IDT[256];
    
  5. , INTA (Interrupt Acknowledged).

最简单的代码中的键盘中断处理程序将如下所示。它调用一个指示中断处理完成的命令,即向INTA脚发送信号。

void irq1_handler(void) {
	  outb(0x20, 0x20); //EOI
}

您可以了解有关如何在osdev上配置中断向量表的更多信息

现在我们知道了中断是如何发生的,但是我们不知道中断处理程序如何读取有关按键的信息。从软件的角度来看,PS2端口是两个寄存器,只有I / O端口号不能通过内存中名称或地址访问它们。这两个单字节寄存器分配给端口0x60和0x64,第一个(0x60)将包含密钥的扫描代码。第二个端口用于将状态和命令传输到PS2端口(不是键盘!)。 x86体系结构指令集具有命令IN storeTofromPortNum它将值从指定的I / O端口读入指定的寄存器。例如IN AL,0x60会将来自键盘的数据保存到AL寄存器。它可能像这样工作:

  1. 在我们考虑的处理器中,存在AD0-AD20支路,它们可用于指示地址和数据。这既是数据总线又是地址总线。除了它们之外,还有许多控制分支,例如,引脚号28(S2),其值将指示从存储器或输入/输出设备进行读取的北桥。IN命令在此处讨论I / O设备时设置值。
  2. CPU (- AD0-AD20) 0110 0000, 0x60. CPU , . , - , - . 0x60 SuperIO , - .
  3. Super IO . 0x60 PS2, .
  4. . Intel 8042, SuperIO, LPC , . .. , .
  5. CPU (- 8 AD0-AD20).
  6. CPU AL. .

整个算法的工作时间为纳秒级,因此即使处理器花了一些时间等待I / O操作,它也几乎可以立即运行。

如您现在所了解的那样,从外部设备读取数据,例如RAM存储器等等。 CPU相当慢。通过编写一个程序在文件中逐行打印10,000行,而不是将它们复制到缓冲区并立即保存,可以注意到这种缓慢。硬盘驱动器连接到南桥,内部还有一个控制器,用于控制数据的直接放置。

RAM通过总线连接到CPU,从中读取数据需要一些时间。为了加速CPU,它具有一个缓存,即晶体管所在的区域表示即将需要或经常使用的数据,其读取速度比RAM板快得多,RAM板通过北桥与CPU通信。 RAM被称为动态随机存取存储器,因为电容器用于表示其中的数据。电容器是一种无线电元件,就像电池一样,可以保持一段时间直到完全放电。仅在此放电会很快发生。因此,电容器必须充电,这会立即发生,足以施加电压。带电电容器-逻辑1,否则为0。用于高速缓存静态RAM它不需要充电,因此工作更快,但成本更高。高速缓存分为3个级别,在处理器访问RAM之前,在搜索请求的数据期间会对其进行顺序检查。在较旧的处理器上,当L2和L3高速缓存都是外部芯片时,第一级高速缓存(L1)是CPU的一部分,并且以相同的频率使用它。现在它们都与处理器位于同一芯片上。L1缓存是最快和最小的内存大小,L2具有更多的内存,但速度较慢。L3是最大的缓存,也是最慢的缓存(通常称为共享缓存),因为它存储所有CPU内核的数据,而L1和L2是为每个单独的内核创建的。

在下一部分中,我们将讨论Windows如何接收和处理接收到的数据。

All Articles