硬件_键盘是如何工作的(一)

前言

键盘工作的探寻,以及硬件是如何工作的探寻

键盘是常见的输入设备,讨论他和操作系统的交互,以及操作系统与程序之间的交互.

概述

键盘的接口(现在一般是USB接口,以前是圆口)和主板相连,在某个程序中,敲击键盘执行某些指令.从数据的角度来仔细分析这一过程:键盘输入的数据,由操作系统扫描后,得到某些数据Data,再发给当前程序执行操作.其中操作系统想得到数据Data需要调用硬件驱动程序.当前程序执行的操作依赖于Data

键盘和操作系统的交互

下面用一段拟人的对话来解释键盘和操作系统之间的互动

键盘:报告,我是一个硬件设备,代号xxxxxxxxxx(每个硬件设备都有mac码--机器识别码)

操作系统:有什么指教?

键盘:我已连接主板接口,申请向你传送数据.请将这些数据,在程序programA运行时传给他

操作系统:好的

操作系统扮演的角色

操作系统负责提取端口数据,并将数据发给需要的程序.

操作系统像多个邮箱的所有者(邮箱就是硬件端口).而硬件是邮箱租赁者.他们有约定:硬件不断往邮箱里投递信件(数据),操作系统负责把邮件送到指定的位置,但不允许租赁邮箱的人翻看除了自己租赁外邮箱的内容(数据泄露)

但在笔者的例子中,所有租赁者的邮件(数据)内容完全公开,由操作系统屏蔽掉非当前进程.

1.提取端口数据

CPU有硬件中断机制,可以访问内存中的所有地址.这里笔者认为在安装主板的时候,应申请一些内存空间作为端口地址---此后的程序中这些地址不能被用作其他用途,例如分配给程序使用.然后由CPU轮询端口地址,取得数据.因此操作系统内部有下面一张表:

|-----|------------|---------|
| 端口号 | 端口地址 | 对应设备mac |
| 1 | 0x12345678 | 无 |
| 2 | 0x1234567c | 无 |
| 3 | 0x12345680 | 无 |

假设每个端口占4个字节---为了表述方便,没安插设备则无mac号.卸载设备后,删除对应内容.

2.发送数据给程序

这部分内容和操作系统的运行有关,笔者不知道,以下是笔者想的一个方案,内容不可实现,只谈思路.

=============================内容分割线↓===================================

全局变量设置(一和二)

一.

1.在键盘插上端口后,驱动文件可以获得端口地址.

2.操作系统每获得一次数据,即调用一次驱动程序handle().驱动程序有个全局变量char * keyboard_p;

复制代码
//伪代码
void handle_kb(){
    if(非激活程序)
        keyboard_p=null;    //如果是非当前激活程序,指针指向空,屏蔽数据
    else
        keyboard_p=端口地址; //预设端口地址可以被用在驱动程序中
}

//如果不成功,改
void change(char** k){
    *k=端口地址;             //将端口地址传给指针k(传入的是双重指针)
}

void handle_kb(){
    if(非激活程序)
        keyboard_p=null;    
    else
        change(&keyboard_p); 
}

二.

全局变量keyboard_p和handle_kb()函数由操作系统给出,当键盘插上端口后,mac信息给出这是一个键盘,操作系统扫描端口数据后调用全局变量keyboard_p和全局函数handle_kb().

一和二几乎相同,二选一.

三.进程端

现在进程端可以通过全局变量*keyboard_p获得键盘输入的内容.

用获得的键盘内容(数字)执行不同的函数.有三个部分需要编写,主程序main函数调用键盘数据处理程序handle_kb();键盘处理程序kb_handle()调用具体处理函数.

main函数部分

复制代码
//伪代码
int main(void){
    ...
    ...                     //主程序其他内容
    while(1){               //无限循环,程序一直运行
        kb_handle();        //调用键盘处理函数    
    }
    return;
}

键盘处理函数

复制代码
//伪代码-键盘处理函数
void kb_handle(){
    if(*keyboard==1){       //键盘字符a对应数字1,以下类同     
        printf("字母a\n");
        push_a();           //输入字符a的程序
    }
    ....                    //其他输入字符处理程序   
    .... 
    if(*keyboard==QUIT){    //取一个数字,表达Alt+F4,退出程序
        push_Alt_F4();      //退出程序的代码
    }
}

具体处理函数部分,如push_a(),push_Alt_F4()略

小结

笔者用全局变量的思路来解决硬件,操作系统和进程之间的通信问题.现实不是这样做的,但除了通信部分,其他内容是可行的.需要解决的内容:

1>操作系统识别硬件,怎么识别呢?端口给键盘的USB供电,通电后给出一些信息,如mac.

2>操作系统接收mac信息后,用几张表来记录数据,以此类推

|-----|------------|------------|------|---|-----|------------|------------|------|
| 端口号 | 端口地址 | 对应设备mac | 设备数据 | | 端口号 | 端口地址 | 对应设备mac | 设备数据 |
| 1 | 0x12345678 | 0xabcdefgh | 实时刷新 | | 1 | 0x12345688 | 0xabcdefgi | 实时刷新 |
| 2 | 0x12345679 | 无 | 无 | | 2 | 0x1234568a | 无 | 无 |
| 3 | 0x1234567a | 无 | 无 | | 3 | 0x1234568c | 无 | 无 |
| | | | | | | | | |
| 一个字节的端口(8位)表 |||| | 二个字节的端口(16位)表 ||||

3>操作系统判断"当前程序",每台机算机运行时只有唯一的"活动窗口".

4>全局变量的设定,可以由操作系统给出,也可以由设备驱动给出.

但不得不说这是个很大的漏洞,如果计算机有其他程序可以绕开屏蔽,则数据将泄露.所以这个方案只有一半可用.

其他

程序的实现是软硬件协作的结果,当现有的代码无法完成需求时,考虑向底层寻求支持.

操作系统应有硬件的解决方案,制定一套规范,并给出软件接口(例如外部用接口函数获得数据)

这里也引出一个分工问题,键盘设计人员向操作系统设计者索要接口.他们分属两个体系.

=============================内容分割线↑===================================

举例:用键盘打出字符(英文)

英文字符的组织

假设表示字符的像素图放在symbol.dat里,有一张索引表

|-----|------|----------|
| 序号 | 代表字符 | 占据空间(假设) |
| 1 | a | 28 |
| 2 | b | 24 |
| 3 | c | 16 |
| ... | ... | ... |
| 26 | z | 18 |
| | | |
| 英文字符文件索引表 |||

略去大写字母

数据端

把索引表+数据文件+查找算法视作数据端,数据端可以用像素图表达出任意一个字符(可参照笔者其他帖子).数据端对外接口是索引表中的序号,序号可以表达出对应的字符.因此如果外面的函数返回值是字符对应的序号,则可以表示出字符.

进程端处理函数

这里的处理函数对应上一小节的内容,如下

复制代码
//对应函数代码
char push_a(){
    return 1;
};

char push_b(){
    return 2;
}

当进程端调用处理函数时,即可得到序号对应的数字,并查找到对应字符.

其他

索引表

索引表的形式不一定是数据库里的表,可用C/C++的数据类型表示,

因为不用计算偏移,所以可以直接这样表示:

复制代码
//伪代码
char index[26]={28,24,16,....18};

字符写入光标位置

查找到字符,写到光标所在位置,关联到对象的设计方法,这里不展开了.

汉字字符

汉字字符的表达基本思路是一样的,但数据端设计会麻烦一点,可以参照笔者其他帖子.

小结

键盘的一点思考.键盘的实现思路可以用在其他输入设备(传感器,手写笔等)上

相关推荐
雪碧透心凉_16 小时前
PythonWin32API窗口与鼠标操作
开发语言·python·计算机外设
遇见小修修17 小时前
电脑无法正常启动原因分析 零基础排查教程
计算机外设·电脑
硅基手札21 小时前
【I2C 技术系列 11】I2C Linux 驱动框架
linux·驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
开开心心就好2 天前
把手机变成电脑麦克风,WiFi连接就能用
智能手机·ffmpeg·计算机外设·电脑·word·音视频
硅基手札2 天前
【I2C 技术系列 08】I2C 控制器寄存器与 IP 架构
驱动开发·stm32·单片机·嵌入式硬件·mcu·架构·计算机外设
硅基手札2 天前
【I2C 技术系列 09】I2C 传输模式:轮询 / 中断 / DMA
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
打工仔折腾 AI2 天前
鸿蒙平板远控电脑实测:ToDesk蓝牙键鼠、双模式鼠标与跨端剪贴板落地记录
人工智能·后端·python·性能优化·计算机外设·电脑·harmonyos
打工仔折腾 AI2 天前
鸿蒙端ToDesk远控电脑实测:蓝牙键鼠、双模式鼠标与跨端剪贴板实践
后端·python·性能优化·计算机外设·电脑·harmonyos·ai agent 实战
硅基手札3 天前
【I2C 技术系列 05】I2C 多主仲裁与时钟同步
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
硅基手札3 天前
【I2C 技术系列 01】I2C 电气特性与物理层
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设