键盘实现输入的思路

前言

探讨键盘的实现,从底层到上层每个层次做了什么

引入

键盘输入是如何被感知的.键盘输入的几个阶段:一是键盘和操作系统交互,二是操作系统传给CPU处理,三是CPU将处理的结果反馈给用户.

键盘到端口

键盘和端口现在通常是USB或者Type-C接口连接,以前是那种U型凹口.网上查了一下,数据位宽是8bit,即8位数据.USB接口采用4线制,2根电源线2根数据线,具体怎样传8bit数据可以不管.只需要明白两点:1.键盘的键位通常是86~104键,有7位(128)就够了.2.想象成有8根线连接到键盘上.

==========================以下↓内容属于发散思维=============================

键盘的识别

USB口和主板南桥的++USB控制器++相连,南桥通过PCI总线和CPU相连.当USB的接口插上去之后,电压发生变化,产生一系列动作.AI搜索"cpu如何识别usb设备"得到的流程简化为:

1.硬件握手:接口电压变化,++主机控制器++得到信息,由PCI总线送给CPU并触发CPU中断程序

以下的动作都和CPU中断有关,中断程序默认写在操作系统中,由CPU引脚触发.

2.读取信息.

包含设备基本信息,设备描述符等信息

3.匹配驱动

调用已写好的驱动程序

这部分内容很底层,和硬件联系紧密.笔者感觉应该由硬件工程师完成.同时给写软件的人一个思路:硬件是如何与CPU产生联系的,操作系统在其中扮演了什么角色.

1.硬件设备通电可以传输信息.这些信息事先已存入设备中

2.读取信息和匹配驱动都是由CPU中断产生的.这些代码和硬件直接相关.例如假设usb控制器连接CPU的中断引脚为100,操作系统中给引脚编地址为0x64,那么识别信息就从下面开始---用上了绝对地址.

复制代码
/*检测到引脚信号*/
if(*(0x64)=1)或者对应机器指令

键盘驱动

把键盘输入转换成数据.USB控制器通过PCI总线和内存相连(内存有200多个引脚).他的代码类似这样,这里的数据引脚地址是8bit的抽象,得到一个1~255之间的数值.

复制代码
/*伪代码*/

value=*(数据引脚地址)
int main(void){
    if(value==1)
        检测到"a";
    else if(value==2)
        检测到"b";
    .....
}

实际上键盘的输入可以是多样的,8bit不止255个键位输入,例如在单片机中有除抖动,或者长按 .类似shift这种键,单按下去不给定义动作,但可以添加组合动作

复制代码
/*伪代码*/

value=*(数据引脚地址)
int main(void){
    if(value==65)
    {
        delay(100);    //延时100象征1ms,除去抖动确认是按下了这个键
        if(value==65)
            检测到"a";
    }
    else if(value==32)    
    {
        delay(2000);   //延时10000象征延时2秒,表示长按
        if(value==0)
            无动作;    
        else if(value==97)
            检测到"A";  //组合键,像shift+a
    }
    .....
}

value是由引脚地址采集到的数值 ---这里给个推理:ASCII码中:a用65表示,A用97表示,中间一个shift差距32,shift在8bit中相当于0B00100000,即第5位的按键(单个无组合)

==========================以上↑内容属于发散思维=============================

操作系统对键盘驱动的支持

1.键盘驱动编译后在操作系统中占一部分空间,CPU匹配驱动要给出驱动程序的地址

有的书本明确提到,操作系统越来越庞大的原因是各种驱动程序占的空间越来越大.

2.操作系统要用一个字节(8bit)来表示采集到的键盘数值.

内核应有专门的数据区,存储硬件数据.

3.操作系统把键盘驱动程序放到CPU缓存区(如果是没有缓存的CPU也没办法).

这点很容易想到,键盘输入不管在哪个程序运行时都有很高优先级,需要CPU及时响应.

4.操作系统给出和键盘相关的接口函数供其他程序调用,如:

复制代码
//接口函数
/*伪代码*/
value=*(0x00000001);    //假设0x00000001是操作系统采集键盘数据的地址

char keyboard_scan()
{
    if(value==65)
        按下了"a";
        return a;
    else if(value==66)
        按下了"b";
        return b;
    ...    
}

当然如果操作系统提供全局变量更好,直接采用绝对地址不符合代码习惯.

其他程序如何用键盘输入

假设有一个游戏程序

复制代码
/*伪代码*/

int main(void)
{
    while(1)
    {
        keyboard_handle();    //按键处理
        if(press alt+f4)      //按下alt+f4退出
            break;
    }
    return 0;
}

用上述的接口函数,或者直接用操作系统给的全局变量(如果有的话),

复制代码
/*伪代码*/
void keyboard_handle()
{
    if((keyborad_scan==65)||value==97)    //检测到a或者A,按下a或者A表示开火键
        开火;
    else if ...
}

小结

从键盘的实现推导出硬件到软件的一些过程.笔者对硬件部分也不是很熟,只谈一点思路.看起来硬件部分没有那么灵活,但也不简单,和CPU,总线,内存,操作系统联系紧密.硬件程序的输入条件电平(0或者1),还有对绝对地址的访问.在软件编程中,一般会采用虚拟地址或者底层给出的全局参数,几乎不会访问绝对地址.硬件程序在这点上的好处是绝对地址表示一种很实在的东西,

分开来看,硬件给信号,操作系统给驱动程序,给接口函数.应用程序(或者框架)用接口函数.

相关推荐
不脱发的程序猿2 天前
STM32制作单手鼠标键盘
stm32·嵌入式硬件·计算机外设·usb·qmk
AntsData4 天前
用 12K+ 条亚马逊评论信号,定位机械键盘下一版该改什么
java·大数据·计算机外设
时间的情敌4 天前
Vue3 + Cesium 鼠标交互绘制多边形 / 线(贴地绘制,动态预览,Entity 实现)
计算机外设
小幂同学5 天前
鼠标左右键自动点击怎么设置?单击、双击与宏录制说明
计算机外设·鼠标连点器·连点器·点击器·自动点击器
摩尔芯创5 天前
一期一会 | 什么是抬头显示器(HUD)?
计算机外设
苏州福兰克5 天前
运行裸眼3D显示器对电脑显卡配置有什么要求?
3d·计算机外设·电脑
巧手打字通-一起来打字5 天前
怎么才能科学快速的学会电脑26键盘打字?
计算机外设·电脑·键盘
苏州福兰克8 天前
没有3D内容,裸眼3D显示器还能用吗?
3d·计算机外设
豪气的程序猿8 天前
Windows 11 外接键盘偶尔漏键?用键盘小鹿练习前先做双设备对照
计算机外设·电脑