嵌入式Linux输入子系统面经

目录

Q1. 应用程序如何访问到内核资源呢?

Q2. 讲一下Framebuffer原理

Q3. 如何在LCD的(x,y)坐标显示一个字符?

Q4. 讲一下输入系统的框架。分为哪几层?每一层的功能分别是什么?应用层如何通过输入系统框架访问到底层?

Q5. 内核中怎么表示一个输入设备?

 Q5. APP可以得到驱动程序上报的哪些数据?这些数据在哪里得到?

Q6. 驱动程序上报的数据长度可能不固定(与事件有关),APP如何知道读到了一个完整事件?

Q7. APP访问硬件有哪几种方式?

Q8. APP使用基本异步通知方式访问硬件需要使用那些函数?

Q9. 电阻屏和电容屏的区别

持续更新中

...

Q1. 应用程序如何访问到内核资源呢?

        Answer:通过系统调用(Syscall)使进程从用户态“陷入”到内核态。

        Q1.1 内核调用使用什么汇编指令了解吗?

                Answer:SWI(32-bit)、SVC(64-bit)

Q2. 讲一下Framebuffer原理

        Answer:Framebuffer是控制LCD的一套驱动程序。同时,Framebuffer也是保存一帧图像信息的内存,内存的大小是驱动程序根据LCD的分辨率、BPP等参数分配的。在Linux中,APP通过ioctl获得LCD分辨率、BPP,通过mmap映射Framebuffer,在Framebuffer中写入数据。

Q3. 如何在LCD的(x,y)坐标显示一个字符?

        要显示一个字符,从原理分为点阵字符和矢量字符。点阵字符放大后会模糊会有毛刺,而矢量字符无论放大多少倍都是清晰的。

        如果要显示一个点阵字符,需要找到该字符对应的点阵信息,如16*8,16*16, 32*32等格式,找到点阵信息之后就需要把这些信息放到Framebuffer中了。要放入的内存位置为:

tar_memory = start_memory + (x*width+y)*BPP/8

        式中,start_memory表示显存起始地址,APP打开LCD的设备文件后,通过ioctl得到。width表示LCD的宽度方向像素点个数,BPP(Bits Per Pixel)表示每像素比特数

        如果要显示一个矢量字符,可以使用Freetype库(一个开源的字体库),先描关键点,然后调用Freetype的库函数连线绘图。

        Q3.1 如何旋转显示

                如果要显示一个旋转字符,需要根据坐标旋转公式处理字符的关键点坐标。

Q4. 讲一下输入系统的框架。分为哪几层?每一层的功能分别是什么?应用层如何通过输入系统框架访问到底层?

        输入系统是Linux内核方便统一管理输入设备的软件架构。其从底层到上层主要可分为驱动层、核心层和事件层;驱动层负责从硬件获得数据,转换为标准的输入时间并向上汇报;核心层负责接收来自底层的输入事件,转发给上层的handler;事件层负责处理上报的输入事件,并需要给用户空间提供访问接口。

        APP可以直接访问驱动节点(/dev/input/event0,1,2...),也可以通过tslib、libinput等库来使用输入设备。访问信息链路为:

        1. APP发起读操作,若无数据则休眠;

        2. 用户操作设备,产生硬件中断;

        3. 驱动层对应的驱动程序处理中断,转换为标准输入事件(struct input_event)向核心层汇报;

        4. 核心层可以决定把输入事件转发给上面的哪个handler(event_handler, kbd_handler, joydev_handler)来处理。对应的handler会把休眠的APP唤醒,得到数据。

Q5. 内核中怎么表示一个输入设备?

        使用input_dev结构体来表示输入设备,内容如下:

 Q5. APP可以得到驱动程序上报的哪些数据?这些数据在哪里得到?

        可以得到一系列的输入时间,即一个个struct input_event,定义如下:

        驱动程序上报的数据包含三项重要内容:

        type哪类?比如按键类(EV_KEY)

        code哪个?比如KEY_A

        value:值,比如0-松开,1-按下,2-长按

        以及time:表示自开机以来经过的时间。

        这些数据会放到/dev/input/evenx(x=0,1,2...)中,你可以在shell中使用hexdump命令直接查看,也可以在程序中通过打开文件读数据得到。如:

         当我移动鼠标时,/dev/input/mice中就会产生驱动程序上报的数据。

Q6. 驱动程序上报的数据长度可能不固定(与事件有关),APP如何知道读到了一个完整事件?

        驱动程序上报完一系列数据后,会上报一个“同步事件”,表示数据上报完毕。APP读到:同步时间后,就知道读到了一个完整事件。

Q7. APP访问硬件有哪几种方式?

        1. 查询方式。不停地询问是否有数据到达;

        2. 休眠-唤醒。APP等待驱动程序数据到达后唤醒它;

        3. POLL。阻塞直到timeout或有数据到达。(可检测多个fd)

        4. 异步通知。也叫软中断方式,APP提前设定signal_handler,然后做自己的事,驱动程序上报数据后,由事件层给APP发送signal,APP收到signal后停下正做的事执行signal_handler。

Q8. APP使用基本异步通知方式访问硬件需要使用那些函数?

        1. fd = open(path, O_RDWR); //得到设备文件描述符,方便操作设备

        2. flag = fcntl(fd, F_GETFL); //得到当前文件flag

        3. fcntl(fd, F_SETFL, flag | FASYNC); //设置此设备采用异步通知方式

        4. fcntl(fd, F_SETOWN, getpid()); //告诉驱动程序我的pid,以接收SIGIO

Q9. 电阻屏和电容屏的区别

        电阻屏:主要原理是欧姆定律。它采用上下两块导电薄膜来检测触摸,手指触摸后两块导电薄膜的电流发生变化,以此来判断触摸位置。

                缺点:通常无法检测多点触摸

        电容屏: 利用玻璃表面的电场变化来检测触摸,手指触摸屏幕后,人体电荷改变了触摸区域的电场

                缺点:对于非导电物体触摸不敏感


持续更新中

...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值