博文

目前显示的是 十月, 2017的博文

Android触摸屏虚拟按键实现方法

    在前几年流行的手机上,一般都会在底部有触摸按键功能(HOME、BACK等键),而这些触摸按键有些是直接用触摸屏的指定区域来模拟,有些是使用屏下的传感器来检测,而我们本次主要是讨论触摸屏的方式,一般情况下,我们直接在驱动里获取我们要模拟的多个指定区域,判断当前触摸的范围是否在指定区域,是则报以相应的KEYCODE,而最近在阅读https://source.android.com/devices/input/touch-devices这篇文档时, 知道在Android系统里也可能在驱动里面将预定好的区域坐标及键码配置好,由Android Frameworks来获取并进行处理,而我们只需要按要求设计好相应的区域和配置好文件即可,根据该文档,我们需要做如下一些配置步骤(下面以Android7.1源码来说明):     1.在实现虚拟按键时,内核必须有映射名为virtualkeys.<devicename>的虚拟按键映射文件,如触摸屏设备驱动程序里的设备名为touchyfeely,则虚拟按键映文件的路径必须为:       /sys/board_properties/virtualkeys.touchyfeely       虚拟按键映射文件描述了触摸屏上虚拟按键的坐标和Linux按键代码,该文件是一个纯文本文件,由一系列换行符或冒号分隔的虚拟按键布局描述组成。相应的语法要求如下:       注释行以“#”开头,只对本行有效。       每个虚拟按键由6个冒号分隔的数据进行描述: 0x01: 版本代码 。必须始终为 0x01。 <Linux key code>:虚拟按键的 Linux 按键代码。 <centerX>:虚拟按键中心的 X 轴坐标(以像素为单位)。 <centerY>:虚拟按键中心的 Y 轴坐标(以像素为单位)。 <width>:虚拟按键的宽度(以像素为单位)。 <height>:虚拟按键的高度(以像素为单位)。       所有的坐标和尺寸都是根据显示坐标系指定的。       下面是虚拟按键映射文件的两种格式:       a.一行           # All on one line           0x01:158:55

书写首个内核模块

在《为Ubuntu换颗“心”》一文中,我们已经了解到了如何去编译安装新的Kernel,编译过程也生成了相应的内核树,为什么要生成内核树呢?其实就跟我们写应用程序时一样,写程序会调用到其他的库文件或其他文件生成的目标文件,最后再由链接器把这些目标文件处理生成可执行文件,就是这道理,这为我们后期调试内核模块时打下了应有的基础,有了这编译调试内核模块的基础,接下来就可以开始尝试写我们的首个模块了。  于是接下来我们按照学习编程语言时写一个我们自己的Hello world——Hello xinu,向自己问声好,表扬下自己迈出这一步,踏入了内核驱动模块的圈。 下面是我们的hello_xinu.c文件内容: #include <linux/init.h> #include <linux/module.h> static int hello_xinu_init(void) { printk("Hello xinu!\n"); return 0; } static void hello_xinu_exit(void) { printk("Bye xinu!\n"); } module_init(hello_xinu_init); module_exit(hello_xinu_exit); 源码写好后,在此只需确认整个模块的入口,即module_init对应的hello_xinu_init,而出口是hello_xinu_exit,这个在后面的操作中可以确认。 接下来需要编译时用到的Makefile文件,内容如下: obj-m += hello_xinu.o CUR_PATH:=$(shell pwd) LINUX_KERNEL_PATH:=/home/xinu/linux-3.13.6 all: make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) modules clean: make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) clean 此处只需要确认下LINUX_KERNEL_PATH这个变量的值,请根据实际来确认。 我这边最终

搭建Eclipse+QEMU+GDB调试Linux Kernel环境

图片
0.前言 本文讲述搭建环境的关键环节,相应的工具及版本如下: JDK:1.6.0_45 Eclipse:eclipse-cpp-kepler-SR2-linux-gtk-x86_64.tar.gz Qemu:QEMU emulator version 1.5.0 (Debian 1.5.0+dfsg-3ubuntu5.3) OS:Ubuntu13.10,64bit 其中,JDK和Eclipse工具下载和配置可查阅“参考资料a”,而在我的OS环境里Eclipse会有菜单显示问题,可查阅“参考资料c”。 1.安装Eclipse插件CDT 运行Eclipse,点击菜单“Help”->“Install New Software...”,在弹出的对话框里点击“Work with:”后面的下拉按钮,选择“Kepler – http://download.eclipse.org/releases/kepler”(不同的Eclipse版本选择不一样,与自己下载的版本一致一即可),然后在下面的选择框中将“Programming Languages”的“C/C++ Autotools support”和“C/C++ Visual C++ Support”这两项(对应http://download.eclipse.org/releases/juno包里的CDT)以及“C/C++ Development Tools”和“C/C++ Development Tools SDK”选中,接下来点击“Next >”按钮两次和“Finish”一次(共显示3个页面),注意其间要选中接收条款,剩下就是自动连网下载安装选中的软件包,安装好后自动重启Eclipse即可。其中配置CDT 的界面如下: 除了上面与C/C++相关的工具,还需要安装与Linux相关的GDB,将“Linux Tools”里的“GDB Tracepoint Analysis”和“Mobile and Device Development”里的“C/C++ GDB Hardware Debugging”选中安装上,如下截图: 注:上面装的工具有些过多,可自行删减,这里是满足更多需求,将相关的全安装上了。 2.安装QEMU 执行如下命令即可安装下QEMU各平台的模拟工具: sudo apt-get insta

为Ubuntu换颗“心”

    对于现在的Linux发行版操作系统,都默认配置好相应的Kernel,但其版本远比最新的要旧,而最新的Kernel除了会修复已发现的BUG,有时还会更新部分框架以及新增功能模块代码,为了确保系统的稳定,还有体验下新功能,我们只好对操作系统的进行换“心”手术,这手术可不简单,首先要获得制作“心”的原材料和工具(即GNU/Linux Kernel源码和编译工具),然后将这些原材料加工成可用的“心”(即可执行的Kernel文件),最后再将这颗“心”更换到操作系统上。经过这么看似简单的3步,就完成了操作系统的核心更换大动作。下面让我们一一体验这些惊心动魄的大动作吧。 0.现有环境     Ubuntu13.10(3.11.0-12-generic),64位。 1.获取原材料和工具     刚装好的Ubuntu13.10系统默认使用的GNU/Linux Kernel版本是3.11.0-12-generic,而现在(2014-3-10)从https://www.kernel.org/网站查看到最新的版本为3.13.6,那么就下载它了:     cd ~     wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.13.6.tar.xz     上面步骤从Kernel官网下载了最新的稳定源码包,由于安装好的Ubuntu发行版系统里默认安装好了编译Kernel所需要的编译链接等加工工具(GCC、LD等),我们仅需确认安装进行menuconfig时需要的包(后面的步骤暂不需要,但会讲述到,使用sudo apt-get install libncurses5-dev安装)。 2.加工制作可用的“心”     获得源码后,我们先将源码包解压:     tar xvf linux-3.13.6.tar.xz     解压后需要配置下Kernel,首先进入解压后的源码目录:     cd linux-3.13.6     然后执行make help命令来了解我们有哪些配置模式可使用,执行该命令后有如下内容:     Configuration targets:          config - Update current config utilising a line-oriented

学习Linux Kernel DT(Device Tree)总结

图片
  之前在使用的 3.0.8 版本内核还没有使用上 DT ,而最近在研发使用的 3.10.37 版本内核已使用上了 DT ,瞬间感觉自己的知识体系更新慢了,查了资料发现 3.x 版本的内核已经支持 DT 了,为何 ARM 也要使用上 DT 呢?      在旧版本的 ARM Linux 内核里,我们习惯上会去 arch/arm/mach-XXX/ 目录下进行一些板载级设备配置,尤其在 board-YYY.c 文件里使用 platform_add_devices() 等函数去注册一堆硬件设备以及板级初始化操作,还有如下宏: MACHINE_START(project name, "board name")         .boot_params    = PLAT_PHYS_OFFSET + 0x800,         .fixup          = XXX_fixup,         .reserve        = & XXX_reserve,         .map_io         = XXX_map_io,         .init_irq       = XXX_init_irq,         .timer          = &XXX_timer,         .init_machine   = XXX_init, MACHINE_END      其中的 XXX_init 函数里就会调用 platform_add_devices() 。      以及 arch/arm/plat-XXX 目录下也有一堆平台级的操作,一般在进行移植工作的时候,就是修改了上面的 board-YYY.c 文件,调试好了各种 Clock 之后,剩下的就是设备驱动程序了。这些处理往往在所有 ARM 平台里有很多的相同操作和共同定义,而这些往往存在了大量的重复编码工作,故而 Linux 内核的开发人员和 ARM 的相关人员引入了 DT 来改善该问题,相关的历史有如下引用内容: Linus Torvalds 在 2011 年 3 月 17 日的 ARM Linux 邮件列表宣称“ this whole ARM thing is a f*cking pain in the ass ”,引发 AR