转自:http://bbs.eeworld.com.cn/thread-430437-1-1.html

这个问题很多人问,尤其是初入嵌入式的菜鸟。其实大家都认为android是java,已经不是linux,殊不知android就是靠着linux 才发展起来的,现在来说说有啥区别吧。

嵌入式android源码架构:uboot+linux kernel+android(包含文件系统,虚拟机,UI)

嵌入式linux:这是大部分人认识的linux uboot+linux kernel+文件系统+QT(UI),

当然两者的linux 内核因为上层UI的不同会稍有差别,不过还是非常接近的,做过linux的人可以无缝切换到android底层开发,所以大家说的学习android系统,其实最重要的就是学习linux驱动,再加一下android下的专门的HAL,JNI,java等等,不过大公司android相关部分也是专门的人做的了。



甚至连QT都不用了,因为linux很多设备都是没有UI的,所以要来干啥?直接无界面,照样是嵌入式linux。



现在大家说的什么嵌入式debian,ubuntu,其实也是站在linux巨人的肩膀上,其实都不算是linux的分支,只算是linux的延伸,小变化而已。看到这里大家知道嵌入式linux的强大了吧,反正是比wince 强大N倍啊。

O(∩_∩)O~,所以啊,学习嵌入式android,其实底下就是学习uboot,linux内核啊,不会搞这些就像搞应用一样,所以大家以为android就是java,是非常片面的。

以前老的,说了一下区别,可以参考一下

ARCH --  这是Android修改了arch/arm下面的一些文件:

arch/arm:

Chg: arch/arm/kernel/entry-armv.S

Chg: arch/arm/kernel/module.c

Chg: arch/arm/kernel/process.c

Chg: arch/arm/kernel/ptrace.c

Chg: arch/arm/kernel/setup.c

Chg: arch/arm/kernel/signal.c

Chg: arch/arm/kernel/traps.c

Chg: arch/arm/mm/cache-v6.S

Chg: arch/arm/vfp/entry.S

Chg: arch/arm/vfp/vfp.h

Chg: arch/arm/vfp/vfphw.S

Chg: arch/arm/vfp/vfpmodule.c

Goldfish --  这是Android为了模拟器所开发的一个虚拟硬件平台。Goldfish执行arm926T指令(在2.6.29中,goldfish也支持ATMv7指令),但是在实际的设备中,该虚拟平台的文件不会被编译。

arch/arm/mach-goldfish:

New: arch/arm/mach-goldfish/audio.c

New: arch/arm/mach-goldfish/board-goldfish.c

New: arch/arm/mach-goldfish/pdev_bus.c

New: arch/arm/mach-goldfish/pm.c

New: arch/arm/mach-goldfish/switch.c

New: arch/arm/mach-goldfish/timer.c

YAFFS2 --  和PC把文件存储在硬盘上不一样, 移动设备一般把Flash作为存储设备。尤其是NAND flash应用非常广泛(绝大多数手机用的都是NAND flash,三星的一些手机使用的是OneNAND)。NAND flash具有低成本和高密度的优点。

YAFFS2 是“Yet Another Flash File System, 2nd edition" 的简称。 它提供在Linux内核和NAND flash设备 之前高效率的接口。 YAFFS2并没有包含在标准的Linux内核中, Google把它添加到了Android的kernel

fs/yaffs2:

New: fs/yaffs2/devextras.h

New: fs/yaffs2/Kconfig

New: fs/yaffs2/Makefile

New: fs/yaffs2/moduleconfig.h

New: fs/yaffs2/yaffs_checkptrw.c

New: fs/yaffs2/yaffs_checkptrw.h

New: fs/yaffs2/yaffs_ecc.c

New: fs/yaffs2/yaffs_ecc.h

New: fs/yaffs2/yaffs_fs.c

New: fs/yaffs2/yaffs_getblockinfo.h

New: fs/yaffs2/yaffs_guts.c

New: fs/yaffs2/yaffs_guts.h

New: fs/yaffs2/yaffsinterface.h

New: fs/yaffs2/yaffs_mtdif1.c

New: fs/yaffs2/yaffs_mtdif1.h

New: fs/yaffs2/yaffs_mtdif2.c

New: fs/yaffs2/yaffs_mtdif2.h

New: fs/yaffs2/yaffs_mtdif.c

New: fs/yaffs2/yaffs_mtdif.h

New: fs/yaffs2/yaffs_nand.c

New: fs/yaffs2/yaffs_nandemul2k.h

New: fs/yaffs2/yaffs_nand.h

New: fs/yaffs2/yaffs_packedtags1.c

New: fs/yaffs2/yaffs_packedtags1.h

New: fs/yaffs2/yaffs_packedtags2.c

New: fs/yaffs2/yaffs_packedtags2.h

New: fs/yaffs2/yaffs_qsort.c

New: fs/yaffs2/yaffs_qsort.h

New: fs/yaffs2/yaffs_tagscompat.c

New: fs/yaffs2/yaffs_tagscompat.h

New: fs/yaffs2/yaffs_tagsvalidity.c

New: fs/yaffs2/yaffs_tagsvalidity.h

New: fs/yaffs2/yportenv.h

Bluetooth --  Google为Bluetooth打上了patch,fix了一些Bluetooth的bug

drivers/bluetooth:

Chg: drivers/bluetooth/bfusb.c

Chg: drivers/bluetooth/bt3c_cs.c

Chg: drivers/bluetooth/btusb.c

Chg: drivers/bluetooth/hci_h4.c

Chg: drivers/bluetooth/hci_ll.c

Scheduler --  对于Scheduler的改变非常小,我对它并没有去研究。

Chg: kernel/sched.c

New Android Functionality --  除了fix一些bug以及其他一些小的更改,Android增加了一些新的功能,介绍如下:

IPC Binder -- The IPC Binder is an Inter-Process Communication (IPC) mechanism. It allows processes to provide services to other processes via a set of higher-level APIs than are available in standard Linux. An Internet search indicated that the Binder concept
originated at Be, Inc., and then made its way into Palm's software, before Google wrote a new Binder for Android.

New: drivers/staging/android/binder.c

Low Memory Killer -- Android adds a low-memory killer that, each time it's called, scans the list of running Linux processes, and kills one. It was not clear in our cursory examination why Android adds a low-memory killer on top of the already existing one
in the standard Linux kernel.

New: drivers/staging/android/lowmemorykiller.c

Ashmem -- Ashmem is an Anonymous SHared MEMory system that adds interfaces so processes can share named blocks of memory. As an example, the system could use Ashmem to store icons, which multiple processes could then access when drawing their UI. The advantage
of Ashmem over traditional Linux shared memory is that it provides a means for the kernel to reclaim these shared memory blocks if they are not currently in use. If a process then tries to access a shared memory block the kernel has freed, it will receive
an error, and will then need to reallocate the block and reload the data.

New: mm/ashmem.c

RAM Console and Log Device -- To aid in debugging, Android adds the ability to store kernel log messages to a RAM buffer. Additionally, Android adds a separate logging module so that user processes can read and write user log messages.

New: drivers/staging/android/ram_console.c

Android Debug Bridge -- Debugging embedded devices can best be described as challenging. To make debugging easier, Google created the Android Debug Bridge (ADB), which is a protocol that runs over a USB link between a hardware device running Android and a developer
writing applications on a desktop PC. 

drivers/usb/gadget:

New: drivers/usb/gadget/android.c

Chg: drivers/usb/gadget/composite.c

Chg: drivers/usb/gadget/f_acm.c

New: drivers/usb/gadget/f_acm.h

New: drivers/usb/gadget/f_adb.c

New: drivers/usb/gadget/f_adb.h

New: drivers/usb/gadget/f_mass_storage.c

New: drivers/usb/gadget/f_mass_storage.h



Android also adds a new real-time clock, switch support, and timed GPIO support. We list the impacted files for these new modules at the end of this document.



Power Management --  Power management is one of the most difficult pieces to get right in mobile devices, so we split it out into a group separate from the other pieces. It's interesting to note that Google added a new power management system to Linux, rather
than reuse what already existed. We list the impacted files at the end of this document.

kernel/power:

New: kernel/power/consoleearlysuspend.c

New: kernel/power/earlysuspend.c

New: kernel/power/fbearlysuspend.c

Chg: kernel/power/main.c

Chg: kernel/power/power.h

Chg: kernel/power/process.c

New: kernel/power/userwakelock.c

New: kernel/power/wakelock.c

Miscellaneous Changes --  In addition to the above, we found a number of changes that could best be described as, 'Miscellaneous.' Among other things, these changes include additional debugging support, keypad light controls, and management of TCP networking

http://www.linuxfordevices.com/c ... id-to-a-new-device/

http://hi.baidu.com/smallbigwang/item/95c99ebcb0e9544cba0e1281

Android系统移植方法详解

http://www.anzhuoba.com/archiver/?tid-8419.html

[本文WORD文档下载:]



通过Android系统移植,让它在目标系统上运行起来。Android系统由于用的是linux内核,因此内核移植和嵌入式linux内核移植差异不大,过程如下:







(1)移植boot-loader和linux2.6内核到目标平台上,让linux内核可以启动起来,基本的驱动允许正常。

此过程完全是嵌入式linux的开发,这里直接跳过。需要注意的是,由于android已经被linux官方开除,因此从

网站上(如http://www.kernel.org/)下载的最新linux内核源代码已经不包含android的专有驱动,因此建议

从google网上下下载Linux内核,android源代码浏览网站如下:

http://android.git.kernel.org/

从该网站上发现内核相关的包如下:

kernel/common.git 通用android内核项目

kernel/experimental.git 实验性内核项目

kernel/linux-2.6.git 这个是标准的Linux内核,没有android的驱动

kernel/lk.git 微内核项目

kernel/msm.git 这个是高通msm7xxx系列芯片所用内核

kernel/omap.git

kernel/tegra.git NVIDIA Tegra系列芯片所用内核

下载内核代码的方法如下:

git clone git://android.git.kernel.org/kernel/common.git

下载完后用git branch -a查看所有git分支,结果如下:

  android-2.6.27

  origin/HEAD

  origin/android-2.6.25

  origin/android-2.6.27

  origin/android-2.6.29

  origin/android-2.6.32

  origin/android-2.6.35

  origin/android-2.6.36

  origin/android-goldfish-2.6.27

  origin/android-goldfish-2.6.29

然后切换到最新分支git checkout origin/android-2.6.36



(2)修改内核配置文件,打开Android必须的驱动(日志和BINDER)如下:

CONFIG_ANDROID=y

CONFIG_ANDROID_BINDER_IPC=y

CONFIG_ANDROID_LOGGER=y

此部分的代码在内核drivers/staging/android目录下。



(3)为了提高启动速度,采用ramdisk,将android文件系统的部分内容压缩到内核中。

首先打开内核驱动:

CONFIG_BLK_DEV_INITRD=y

CONFIG_INITRAMFS_SOURCE="root"

CONFIG_INITRAMFS_ROOT_UID=0

CONFIG_INITRAMFS_ROOT_GID=0

然后在android源代码编译出来的out/target/product/merlin/root目录复制到内核目录下。



(4)根据android文件系统的要求对nand flash进行重新分区,举例如下:

将nand flash分区以下8个分区

NTIM

OBM

U-boot

Kernel

System

UserData

Mass Storage

BBT



(5)根据分区表修改内核启动参数如下:

CONFIG_CMDLINE="ubi.mtd=4 ubi.mtd=5 ubi.mtd=6 root=ubi0_0 rootfstype=ubifs console=ttyS1,115200 uart_dma init=/init"

参数的意思是:载入的文件系统部分有3个分区,分别为nand flash的第4,5,6分区(从0编号),文件系统采用ubifs格式,控制台设备为ttyS1,波特率为115200

启动的第一个应用程序是/init



(6)确保控制台的设置和硬件保持一致,如:硬件上串口用的是UART1,则内核启动参数中设置有console=ttyS1,而且android的启动过程中设要设置正确,修改

部分位于android源代码system/core/init/init.c文件中,将

static char *console_name = "/dev/console";

修改成

static char *console_name = "/dev/ttyS1";



(7)修改android源代码system/core/rootdir目录下的init.rc文件,作如下修改(android默认yaffs2文件系统):

首先将android文件系统修改成可读写,将

    mount rootfs rootfs / ro remount

修改成

    mount rootfs rootfs / rw remount

然后修改挂载system和userdata部分的代码,将

    # Mount /system rw first to give the filesystem a chance to save a checkpoint

    mount yaffs2 mtd@system /system

    mount yaffs2 mtd@system /system ro remount



    # We chown/chmod /data again so because mount is run as root + defaults

    mount yaffs2 mtd@userdata /data nosuid nodev

    chown system system /data

    chmod 0771 /data

改成

    # Mount /system rw first to give the filesystem a chance to save a checkpoint

    mount ubifs ubi0_0 /system ro



    # We chown/chmod /data again so because mount is run as root + defaults

    mount ubifs ubi1_0 /data nosuid nodev

    chown system system /data

    chmod 0771 /data



(8)完成后编译内核,可以启动文件系统,控制台可用,但是没有显示启动log,而且不停的重启。



(9)系统不停的重启,因此控制台已经可用了,自然而然的想到看到logcat日志,一看,发现logcat设备居然没起来,配置文件里面都定义了

居然没起来,查看了下内核drivers/staging/android目录,没有.o文件,证明是没编译到,在看内核目录下的.config文件,发现居然没有了

logcat和binder的宏定义,配置文件里面有定义而.config文件中无定义,肯定是相关Kconfig文件的问题,通过分析drivers/staging目录下的

Kconfig文件发现是因为STAGING_EXCLUDE_BUILD宏默认是y,在配置文件中否定此宏即可,在配置文件中CONFIG_STAGING定义后加上即可,如下:

CONFIG_STAGING=y

# CONFIG_STAGING_EXCLUDE_BUILD is not set

修改后重新编译发现系统完成正常启动,启动过程中启动log也显示正常。

至此,android初步移植工作已经完成,当然,系统还有很多问题,需要下一步继续修改。

总结:android的移植按如下流程:

(1)android linux内核的普通驱动移植,让内核可以在目标平台上运行起来。

(2)正确挂载文件系统,确保内核启动参数和android源代码system/core/rootdir目录下的init.rc中的文件系统挂载正确。

(3)调试控制台,让内核启动参数中的console参数以及android源代码system/core/init/init.c中的console_name设置和硬件保持一致

(4)打开android相关的驱动(logger,binder等),串口输入logcat看logger驱动起来,没有的话调试logger驱动。

说明:ARM的内核配置文件定义在内核arch/arm/configs目录下。

haolele 发表于 2011-11-11 21:03:34

Android系统移植之按键移植本帖最后由 haolele 于 2011-11-11 21:04 编辑 



Android系统移植之按键移植这一部分主要是移植android的键盘和按键

(1)Android使用标准的linux输入事件设备(/dev/input目录下)和驱动,按键定义在内核include/linux/input.h文件中,

按键定义形式如下:

#define KEY_ESC            1

#define KEY_1            2

#define KEY_2            3



(2)内核中(我的平台是arch/arm/mach-mmp/merlin.c文件)中按键的定义如下形式:

static struct gpio_keys_button btn_button_table[] = {

    = {

        .code            =    KEY_F1,

        .gpio            =    MFP_PIN_GPIO2,

        .active_low        =    1,        /* 0 for down 0, up 1; 1 for down 1, up 0 */

        .desc            =    "H_BTN button",

        .type            =    EV_KEY,

        /* .wakeup            = */

        .debounce_interval    =    10,        /* 10 msec jitter elimination */

    },

    = {

        .code            =    KEY_F2,

        .gpio            =    MFP_PIN_GPIO3,

        .active_low        =    1,        /* 0 for down 0, up 1; 1 for down 1, up 0 */

        .desc            =    "O_BTN button",

        .type            =    EV_KEY,

        /* .wakeup            = */

        .debounce_interval    =    10,        /* 10 msec jitter elimination */

    },

    = {

        .code            =    KEY_F4,

        .gpio            =    MFP_PIN_GPIO1,

        .active_low        =    1,        /* 0 for down 0, up 1; 1 for down 1, up 0 */

        .desc            =    "S_BTN button",

        .type            =    EV_KEY,

        /* .wakeup            = */

        .debounce_interval    =    10,        /* 10 msec jitter elimination */

    },

};

static struct gpio_keys_platform_data gpio_keys_data = {

    .buttons  = btn_button_table,

    .nbuttons = ARRAY_SIZE(btn_button_table),

};



static struct platform_device gpio_keys = {

    .name = "gpio-keys",

    .dev  = {

        .platform_data = &gpio_keys_data,

    },

    .id   = -1,

};

上面定义是将MFP_PIN_GPIO2这个GPIO口的按键映射到Linux的KEY_F1按键,MPF_PIN_GPIO3映射到KEY_F2,MFP_PIN_GPIO1映射到KEY_F4



(3)上面(2)步实现了从硬件GPIO口到内核标准按键的映射,但是android并没有直接使用映射后的键值,而且对其再进行了一次映射,从内核标准键值

到android所用键值的映射表定义在android文件系统的/system/usr/keylayout目录下。标准的映射文件为qwerty.kl,定义如下:

key 399   GRAVE

key 2     1

key 3     2

key 4     3

key 5     4

key 6     5

key 7     6

key 8     7

key 9     8

key 10    9

key 11    0

key 158   BACK              WAKE_DROPPED

key 230   SOFT_RIGHT        WAKE

key 60    SOFT_RIGHT        WAKE

key 107   ENDCALL           WAKE_DROPPED

key 62    ENDCALL           WAKE_DROPPED

key 229   MENU              WAKE_DROPPED

key 139   MENU              WAKE_DROPPED

key 59    MENU              WAKE_DROPPED

key 127   SEARCH            WAKE_DROPPED

key 217   SEARCH            WAKE_DROPPED

key 228   POUND

key 227   STAR

key 231   CALL              WAKE_DROPPED

key 61    CALL              WAKE_DROPPED

key 232   DPAD_CENTER       WAKE_DROPPED

key 108   DPAD_DOWN         WAKE_DROPPED

key 103   DPAD_UP           WAKE_DROPPED

key 102   HOME              WAKE

key 105   DPAD_LEFT         WAKE_DROPPED

key 106   DPAD_RIGHT        WAKE_DROPPED

key 115   VOLUME_UP

key 114   VOLUME_DOWN

key 116   POWER             WAKE

key 212   CAMERA



key 16    Q

key 17    W

key 18    E

key 19    R

key 20    T

key 21    Y

key 22    U

key 23    I

key 24    O

key 25    P

key 26    LEFT_BRACKET

key 27    RIGHT_BRACKET

key 43    BACKSLASH



key 30    A

key 31    S

key 32    D

key 33    F

key 34    G

key 35    H

key 36    J

key 37    K

key 38    L

key 39    SEMICOLON

key 40    APOSTROPHE

key 14    DEL

        

key 44    Z

key 45    X

key 46    C

key 47    V

key 48    B

key 49    N

key 50    M

key 51    COMMA

key 52    PERIOD

key 53    SLASH

key 28    ENTER

        

key 56    ALT_LEFT

key 100   ALT_RIGHT

key 42    SHIFT_LEFT

key 54    SHIFT_RIGHT

key 15    TAB

key 57    SPACE

key 150   EXPLORER

key 155   ENVELOPE        



key 12    MINUS

key 13    EQUALS

key 215   AT



(4)android对底层按键的处理方法

android按键的处理是Window Manager负责,主要的映射转换实现在android源代码frameworks/base/libs/ui/EventHub.cpp

此文件处理来自底层的所有输入事件,并根据来源对事件进行分类处理,对于按键事件,处理过程如下:

(a)记录驱动名称为

(b)获取环境变量ANDROID_ROOT为系统路径(默认是/system,定义在android源代码/system/core/rootdir/init.rc文件中)

(c)查找路径为"系统路径/usr/keylayout/驱动名称.kl"的按键映射文件,如果不存在则默认用路径为"系统路径/usr/keylayout/qwerty.kl"

这个默认的按键映射文件,映射完成后再把经映射得到的android按键码值发给上层应用程序。

所以我们可以在内核中定义多个按键设备,然后为每个设备设定不同的按键映射文件,不定义则会默认用qwerty.kl



(5)举例

上面(2)步我们在内核中声明了一个名为"gpio-keys"的按键设备,此设备定义在内核drivers/input/keyboard/gpio_keys.c文件中

然后我们在内核启动过程中注册此设备:  platform_device_register(&gpio_keys);

然后我们可以自己定义一个名为gpio-keys.kl的android按键映射文件,此文件的定义可以参考querty.kl的内容,比如说我们想将MPF_PIN_GPIO3

对应的按键作android中的MENU键用,首先我们在内核中将MPF_PIN_GPIO3映射到KEY_F2,在内核include/linux/input.h中查找KEY_F2发现

#define KEY_F2            60

参照KEY_F2的值我们在gpio-keys.kl中加入如下映射即可

key 60    MENU              WAKE

其它按键也照此添加,完成后将按键表放置到/system/usr/keylayout目录下即可。

补充:

(1)android按键设备的映射关系可以在logcat开机日志中找的到(查找EventHub即可)

(2)android按键设备由Window Manager负责,Window Manager从按键驱动读取内核按键码,然后将内核按键码转换成android按键码,转换完成

后Window Manager会将内核按键码和android按键码一起发给应用程序来使用,这一点一定要注意。Android系统开发小知识-在android产品开 发中添加新的编译模块 Android开发中用户内容定义在vendor目录下,而用户产品的内容都定义在vendor/<company_name> /<board_name>目录下

如果需要添加新的内容,可以在该目录下新建子目录,同时修改AndroidBoard.mk文件即可。比如说要添加一个按键映射文件:

(1)在vendor/<company_name>/<board_name>目录下建立一个keymaps子目录

(2)将我们需要的按键映射文件gpio-keys.kl和power-button.kl复制到keymaps目录下

(3)在keymaps目录下新建一个Mdroid.mk文件,内容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)



file := $(TARGET_OUT_KEYLAYOUT)/gpio-keys.kl

ALL_PREBUILT += $(file)

$(file): $(LOCAL_PATH)/gpio-keys.kl | $(ACP)

    $(transform-prebuilt-to-target)



file := $(TARGET_OUT_KEYLAYOUT)/power-button.kl

ALL_PREBUILT += $(file)

$(file): $(LOCAL_PATH)/power-button.kl | $(ACP)

    $(transform-prebuilt-to-target)

(4)在vendor/<company_name>/<board_name>目录下的AndroidBoard.mk添加如下内容:

include $(LOCAL_PATH)/keymaps/Mdroid.mk

haolele 发表于 2011-11-11 21:04:44

Android系统移植之按键字符表本帖最后由 haolele 于 2011-11-11 21:05 编辑 



Android系统移植之按键字符表



上节讲android的Window Manager将内核按键码通过按键映射表转换成android按键码,

这节讲的是android按键码向android字符的转换,转换也是通过Window Manager来完成的

(1)原始按键字符表,我们知道一个按键是可以显示多个字符的,决定显示字符的是CAPS(大小写),FN,NUNMBER等按键

举例如下:

                                           

                                                        

# keycode       display number  base    caps    fn      caps_fn

                                                        

A               'A'     '2'     'a'     'A'     '#'     0x00

B               'B'     '2'     'b'     'B'     '<'     0x00

C               'C'     '2'     'c'     'C'     '9'     0x00E7

D               'D'     '3'     'd'     'D'     '5'     0x00

E               'E'     '3'     'e'     'E'     '2'     0x0301

F               'F'     '3'     'f'     'F'     '6'     0x00A5

G               'G'     '4'     'g'     'G'     '-'     '_'

H               'H'     '4'     'h'     'H'     '['     '{'

I               'I'     '4'     'i'     'I'     '$'     0x0302

J               'J'     '5'     'j'     'J'     ']'     '}'

K               'K'     '5'     'k'     'K'     '"'     '~'

L               'L'     '5'     'l'     'L'     '''     '`'

M               'M'     '6'     'm'     'M'     '!'     0x00

N               'N'     '6'     'n'     'N'     '>'     0x0303

O               'O'     '6'     'o'     'O'     '('     0x00

P               'P'     '7'     'p'     'P'     ')'     0x00

Q               'Q'     '7'     'q'     'Q'     '*'     0x0300

R               'R'     '7'     'r'     'R'     '3'     0x20AC

S               'S'     '7'     's'     'S'     '4'     0x00DF

T               'T'     '8'     't'     'T'     '+'     0x00A3

U               'U'     '8'     'u'     'U'     '&'     0x0308

V               'V'     '8'     'v'     'V'     '='     '^'

W               'W'     '9'     'w'     'W'     '1'     0x00

X               'X'     '9'     'x'     'X'     '8'     0xEF00

Y               'Y'     '9'     'y'     'Y'     '%'     0x00A1

Z               'Z'     '9'     'z'     'Z'     '7'     0x00

                                                        

# on pc keyboards

COMMA           ','     ','     ','     ';'     ';'     '|'

PERIOD          '.'     '.'     '.'     ':'     ':'     0x2026

AT              '@'     '0'     '@'     '0'     '0'     0x2022

SLASH           '/'     '/'     '/'     '?'     '?'     '\'

                                                        

SPACE           0x20    0x20    0x20    0x20    0xEF01  0xEF01

ENTER         0xa     0xa     0xa     0xa     0xa     0xa

                                                        

TAB             0x9     0x9     0x9     0x9     0x9     0x9

0               '0'     '0'     '0'     ')'     ')'     ')'

1               '1'     '1'     '1'     '!'     '!'     '!'

2               '2'     '2'     '2'     '@'     '@'     '@'

3               '3'     '3'     '3'     '#'     '#'     '#'

4               '4'     '4'     '4'     '$'     '$'     '$'

5               '5'     '5'     '5'     '%'     '%'     '%'

6               '6'     '6'     '6'     '^'     '^'     '^'

7               '7'     '7'     '7'     '&'     '&'     '&'

8               '8'     '8'     '8'     '*'     '*'     '*'

9               '9'     '9'     '9'     '('     '('     '('

                                                        

GRAVE           '`'     '`'     '`'     '~'     '`'     '~'

MINUS           '-'     '-'     '-'     '_'     '-'     '_'

EQUALS          '='     '='     '='     '+'     '='     '+'

LEFT_BRACKET    '['     '['     '['     '{'     '['     '{'

RIGHT_BRACKET   ']'     ']'     ']'     '}'     ']'     '}'

BACKSLASH       '\'     '\'     '\'     '|'     '\'     '|'

SEMICOLON       ';'     ';'     ';'     ':'     ';'     ':'

APOSTROPHE      '''     '''     '''     '"'     '''     '"'

STAR            '*'     '*'     '*'     '*'     '*'     '*'

POUND           '#'     '#'     '#'     '#'     '#'     '#'

PLUS            '+'     '+'     '+'     '+'     '+'     '+'



(2)android为了减少载入时间,并没有使用原始按键表文件,而是将其转换成二进制文件

转换的工具源代码在android源代码build/tools/kcm目录下,android在编译过程中会

首先编译转换工具,然后利用转换工具将android源代码sdk/emulator/keymaps目录下

的qwerty.kcm和qwerty2.kcm文件分别转换成qwerty.kcm.bin和qwerty2.kcm.bin

转换后的二进制文件复制到out/target/product/<board_name>/system/usr/keychars

目录下,也就是目标平台的/system/usr/keychars目录中。



(3)Window Manager对按键的处理在android源代码frameworks/base/libs/ui/EventHub.cpp文件中

Window Manager从内核接收到一个按键输入事件后会首先调用按键映射表将内核按键码映射成android按键码(这部分上节已讲),然后会

将android按键码转换成字符,具体过程如下:

(a)设置系统系统属性hw.keyboards.设备号.devname的值为设备名

以上节的gpio-keys设备为例,会设置系统属性hw.keyboards.65539.devname的值为gpio-keys

(b)载入按键字符表,首先载入/system/usr/keychars目录下的设备名.kcm.bin文件(此例即gpio-keys.kcm.bin文件),如果载入失败

则载入该目录下的querty.kcm.bin.

(c)利用载入的按键字符表将android按键转换成按键字符发给上层应用程序。



(4)一般情况下一个控制按键是不需要作按键字符表的,系统会调用默认的去处理,但是如果要开发一个全功能键盘(包含了字母和数字),那可能就需要

自己作一个专用的按键字符表了。android系统开发小问题-启动过程中android字符没有显示出来 android目标平台可以正常启动,但是启动过程中的android字符没有显示出来,这个是linux内核配置的问题

打开内核framebuffer控制台即可。

(1)make menuconifg后选择Device Drivers->Graphics support->Console display driver support->Framebuffer Console support

然后打开相关的几个配置选项即可。

(2)直接修改内核配置文件,如下:

CONFIG_FRAMEBUFFER_CONSOLE=y

CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y

# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set

CONFIG_FONTS=y

CONFIG_FONT_8x8=y

CONFIG_FONT_8x16=y

CONFIG_FONT_6x11=y

# CONFIG_FONT_7x14 is not set

# CONFIG_FONT_PEARL_8x8 is not set

# CONFIG_FONT_ACORN_8x8 is not set

# CONFIG_FONT_MINI_4x6 is not set

# CONFIG_FONT_SUN8x16 is not set

# CONFIG_FONT_SUN12x22 is not set

# CONFIG_FONT_10x18 is not set

(3)android启动过程中的android字符显示在源代码的system/core/init.c中,如下:

    if( load_565rle_image(INIT_IMAGE_FILE) ) {

    fd = open("/dev/tty0", O_WRONLY);

    if (fd >= 0) {

        const char *msg;

            msg = "\n"

        "\n"

        "\n"

        "\n"

        "\n"

        "\n"

        "\n"  // console is 40 cols x 30 lines

        "\n"

        "\n"

        "\n"

        "\n"

        "\n"

        "\n"

        "\n"

        "             A N D R O I D ";

        write(fd, msg, strlen(msg));

        close(fd);

    }

    }

haolele 发表于 2011-11-11 21:06:22

Android系统开发之触摸屏tslib移植(内核)和原理分析本帖最后由 haolele 于 2011-11-11 21:07 编辑



Android系统开发之触摸屏tslib移植(内核)和原理分析



首先了解一下tslib的运行原理,tslib的运行分成两部分

(1)校验

在LCD固定坐标位置依次显示出5个坐标让用户触摸,把LCD坐标和用户触摸时驱动屏驱动底层的坐标总共5组值保存起来

运行tslib库的算法对其进行运算,得出校准用7个值



(2)校准

每次触摸屏驱动读取到硬件坐标时应用校准用的7个值对该坐标进行一次运算,然后将运算后的坐标作为正常坐标即可。

按照上面的原理,

(1)我们先修改内核部分,我的平台用的触摸屏幕驱动是tsc2007,驱动文件为内核/drivers/input/touchscreen

目录下的tsc2007.c和ts_linear.c

其中,ts_linear.c中定义的是校准模块,该模块在proc文件系统中建立了7个文件,用来存放校准用的7个点,7的点的默认值

为1,0,0,0,1,0,1,对应的目标平台文件系统的位置为/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a6等7个文件

此模块中还定义了一个校准函数ts_linear_scale,此函数的主要内容是读取a0,a1,a2,a3,a4,a5,a6等7个文件中的值作为7个

校准值与传入的触摸平坐标值进行运算,返回运算结果。

ts_linear_scale函数定义如下:

int ts_linear_scale(int *x, int *y, int swap_xy)

{

    int xtemp, ytemp;



    xtemp = *x;

    ytemp = *y;



    if (cal.a == 0)

        return -EINVAL;



    *x = (cal.a + cal.a * xtemp + cal.a * ytemp) / cal.a;

    *y = (cal.a + cal.a * xtemp + cal.a * ytemp) / cal.a;



    if (swap_xy) {

        int tmp = *x;

        *x = *y;

        *y = tmp;

    }

    return 0;

}ts2007.c为触摸屏驱,与其他驱动不同的地方是在取得硬件坐标值发送之前先调用了ts_linear_scale函数对坐标值进行了校准

            if (x > 0 && y > 0)

            {

                ts_linear_scale(&x, &y, invert);

                input_report_abs(input, ABS_X, x);

                input_report_abs(input, ABS_Y, y);

                input_report_abs(input, ABS_PRESSURE, 255);

                input_report_abs(input, ABS_TOOL_WIDTH, 1);

                input_report_key(input, BTN_TOUCH, 1);

                input_sync(input);

            }



(2)在android源代码/system/core/rootdir/init.rc文件中添加tslib相关的宏定义如下:

# touchscreen parameters

    export TSLIB_FBDEVICE /dev/graphics/fb0

    export TSLIB_CALIBFILE /data/etc/pointercal

    export TSLIB_CONFFILE  /system/etc/ts.conf

    export TSLIB_TRIGGERDEV /dev/input/event0

    export TSLIB_TSDEVICE /dev/input/event1



(2)移植tslib库到android系统,比较麻烦,看下一节的内容。



(3)校验程序完成后会将生成的7个校准值写入到环境变量TSLIB_CALIBFILE对应的路径/data/etc/pointercal文件中



(4)校验完后将pointercal文件中的7个值分别写入到/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a6文件即可。



(5)开机启动的时候我们编写一个应用程序,首先判断环境变量TSLIB_CALIBFILE对应的路径/data/etc/pointercal文件是否存在,如果

文件存在而且非空,则将该文件中的7个值取出来分别写入到/proc/sys/dev/ts_device目录下a0,a1,a2,a3,a4,a5,a6文件



(6)为了确保未校验前触摸屏可用,我们将一次校验后得出的7个坐标值作为初始值,修改到内核ts_linear.c文件中。下面是源代码:

ts_linear.c文件

/*

*  Touchscreen Linear Scale Adaptor

*

*  Copyright (C) 2009 Marvell Corporation



*  Author: Mark F. Brown <markb@marvell.com>

*  Based on tslib 1.0 plugin linear.c by Russel King

*

* This library is licensed under GPL.

*

*/



#include <linux/module.h>

#include <linux/init.h>

#include <linux/kernel.h>

#include <linux/input.h>

#include <linux/interrupt.h>

#include <linux/wait.h>

#include <linux/delay.h>

#include <linux/platform_device.h>

#include <linux/proc_fs.h>

#include <linux/sysctl.h>

#include <asm/system.h>



/*

* sysctl-tuning infrastructure.

*/

static struct ts_calibration {

/* Linear scaling and offset parameters for x,y (can include rotation) */

    int a;

} cal;



static ctl_table ts_proc_calibration_table[] = {

    {

     .ctl_name = CTL_UNNUMBERED,

     .procname = "a0",

     .data = &cal.a,

     .maxlen = sizeof(int),

     .mode = 0666,

     .proc_handler = &proc_dointvec,

     },

    {

     .ctl_name = CTL_UNNUMBERED,

     .procname = "a1",

     .data = &cal.a,

     .maxlen = sizeof(int),

     .mode = 0666,

     .proc_handler = &proc_dointvec,

     },

    {

     .ctl_name = CTL_UNNUMBERED,

     .procname = "a2",

     .data = &cal.a,

     .maxlen = sizeof(int),

     .mode = 0666,

     .proc_handler = &proc_dointvec,

     },

    {

     .ctl_name = CTL_UNNUMBERED,

     .procname = "a3",

     .data = &cal.a,

     .maxlen = sizeof(int),

     .mode = 0666,

     .proc_handler = &proc_dointvec,

     },

    {

     .ctl_name = CTL_UNNUMBERED,

     .procname = "a4",

     .data = &cal.a,

     .maxlen = sizeof(int),

     .mode = 0666,

     .proc_handler = &proc_dointvec,

     },

    {

     .ctl_name = CTL_UNNUMBERED,

     .procname = "a5",

     .data = &cal.a,

     .maxlen = sizeof(int),

     .mode = 0666,

     .proc_handler = &proc_dointvec,

     },

    {

     .ctl_name = CTL_UNNUMBERED,

     .procname = "a6",

     .data = &cal.a,

     .maxlen = sizeof(int),

     .mode = 0666,

     .proc_handler = &proc_dointvec,

     },



    {.ctl_name = 0}

};



static ctl_table ts_proc_root[] = {

    {

     .ctl_name = CTL_UNNUMBERED,

     .procname = "ts_device",

     .mode = 0555,

     .child = ts_proc_calibration_table,

     },

    {.ctl_name = 0}

};



static ctl_table ts_dev_root[] = {

    {

     .ctl_name = CTL_DEV,

     .procname = "dev",

     .mode = 0555,

     .child = ts_proc_root,

     },

    {.ctl_name = 0}

};



static struct ctl_table_header *ts_sysctl_header;



int ts_linear_scale(int *x, int *y, int swap_xy)

{

    int xtemp, ytemp;



    xtemp = *x;

    ytemp = *y;



    if (cal.a == 0)

        return -EINVAL;



    *x = (cal.a + cal.a * xtemp + cal.a * ytemp) / cal.a;

    *y = (cal.a + cal.a * xtemp + cal.a * ytemp) / cal.a;



    if (swap_xy) {

        int tmp = *x;

        *x = *y;

        *y = tmp;

    }

    return 0;

}



EXPORT_SYMBOL(ts_linear_scale);



static int __init ts_linear_init(void)

{

    ts_sysctl_header = register_sysctl_table(ts_dev_root);

    /* Use default values that leave ts numbers unchanged after transform */

    cal.a = 1;

    cal.a = 0;

    cal.a = 0;

    cal.a = 0;

    cal.a = 1;

    cal.a = 0;

    cal.a = 1;

    return 0;

}



static void __exit ts_linear_cleanup(void)

{

    unregister_sysctl_table(ts_sysctl_header);

}



module_init(ts_linear_init);

module_exit(ts_linear_cleanup);



MODULE_DESCRIPTION("touch screen linear scaling driver");

MODULE_LICENSE("GPL");







ts2007.c文件

/*

*  linux/drivers/input/touchscreen/tsc2007.c

*

*  touch screen driver for tsc2007

*

*  Copyright (C) 2006, Marvell Corporation

*

*  This program is free software; you can redistribute it and/or modify

*  it under the terms of the GNU General Public License version 2 as

*  published by the Free Software Foundation.

*/



#include <linux/module.h>

#include <linux/init.h>

#include <linux/kernel.h>

#include <linux/input.h>

#include <linux/interrupt.h>

#include <linux/wait.h>

#include <linux/delay.h>

#include <linux/platform_device.h>

#include <linux/freezer.h>

#include <linux/proc_fs.h>

#include <linux/clk.h>

#include <linux/i2c.h>

#include <mach/gpio.h>



#include <linux/sysctl.h>

#include <asm/system.h>



extern int ts_linear_scale(int *x, int *y, int swap_xy);



/* Use MAV filter */

#define TSC_CMD_SETUP 0xb0



/* Use 12-bit */

#define TSC_CMD_X 0xc0

#define TSC_CMD_PLATEX 0x80

#define TSC_CMD_Y 0xd0

#define TSC_CMD_PLATEY 0x90



#define TSC_X_MAX 4096

#define TSC_Y_MAX 4096

#define TSC_X_MIN 0

#define TSC_Y_MIN 0



/* delay time for compute x, y, computed as us */



#define DEBUG

#ifdef DEBUG

#define TS_DEBUG(fmt,args...) printk(KERN_DEBUG fmt, ##args )

#else

#define TS_DEBUG(fmt,args...)

#endif

static int x_min=TSC_X_MIN;

static int y_min=TSC_Y_MIN;

static int x_max=TSC_X_MAX;

static int y_max=TSC_Y_MAX;

static int invert = 0;

static int debounce_time  = 150;

static int init_debounce = true;

static int delay_time = 1;



enum tsc2007_status {

    PEN_UP,

    PEN_DOWN,

};



struct _tsc2007 {

    struct input_dev *dev;

    int x;        /* X sample values */

    int y;        /* Y sample values */



    int status;

    struct work_struct irq_work;

    struct i2c_client *client;

    unsigned long last_touch;

};

struct _tsc2007 *g_tsc2007;



/* update abs params when min and max coordinate values are set */

int tsc2007_proc_minmax(struct ctl_table *table, int write, struct file *filp,

                     void __user *buffer, size_t *lenp, loff_t *ppos)

{

    struct _tsc2007 *tsc2007= g_tsc2007;

    struct input_dev *input = tsc2007->dev;



    /* update value */

    int ret = proc_dointvec(table, write, filp, buffer, lenp, ppos);



    /* updated abs params */

    if (input) {

        TS_DEBUG(KERN_DEBUG "update x_min %d x_max %d"

            " y_min %d y_max %d\n", x_min, x_max,

            y_min, y_max); 

        input_set_abs_params(input, ABS_X, x_min, x_max, 0, 0);

        input_set_abs_params(input, ABS_Y, y_min, y_max, 0, 0);

    }

    return ret;

}



static ctl_table tsc2007_proc_table[] = {

    {

        .ctl_name    = CTL_UNNUMBERED,

        .procname    = "x-max",

        .data        = &x_max,

        .maxlen        = sizeof(int),

        .mode        = 0666,

        .proc_handler    = &tsc2007_proc_minmax,

    },

    {

        .ctl_name    = CTL_UNNUMBERED,

        .procname    = "y-max",

        .data        = &y_max,

        .maxlen        = sizeof(int),

        .mode        = 0666,

        .proc_handler    = &tsc2007_proc_minmax,

    },

    {

        .ctl_name    = CTL_UNNUMBERED,

        .procname    = "x-min",

        .data        = &x_min,

        .maxlen        = sizeof(int),

        .mode        = 0666,

        .proc_handler    = &tsc2007_proc_minmax,

    },

    {

        .ctl_name    = CTL_UNNUMBERED,

        .procname    = "y-min",

        .data        = &y_min,

        .maxlen        = sizeof(int),

        .mode        = 0666,

        .proc_handler    = &tsc2007_proc_minmax,

    },

    {

        .ctl_name    = CTL_UNNUMBERED,

        .procname    = "invert_xy",

        .data        = &invert,

        .maxlen        = sizeof(int),

        .mode        = 0666,

        .proc_handler    = &proc_dointvec,

    },

    {

        .ctl_name    = CTL_UNNUMBERED,

        .procname    = "debounce_time",

        .data        = &debounce_time,

        .maxlen        = sizeof(int),

        .mode        = 0666,

        .proc_handler    = &proc_dointvec,

    },

    {

        .ctl_name    = CTL_UNNUMBERED,

        .procname    = "delay_time",

        .data        = &delay_time,

        .maxlen        = sizeof(int),

        .mode        = 0666,

        .proc_handler    = &proc_dointvec,

    },

    { .ctl_name = 0 }

};



static ctl_table tsc2007_proc_root[] = {

    {

        .ctl_name    = CTL_UNNUMBERED,

        .procname    = "ts_device",

        .mode        = 0555,

        .child        = tsc2007_proc_table,

    },

    { .ctl_name = 0 }

};



static ctl_table tsc2007_proc_dev_root[] = {

    {

        .ctl_name    = CTL_DEV,

        .procname    = "dev",

        .mode        = 0555,

        .child        = tsc2007_proc_root,

    },

    { .ctl_name = 0 }

};



static struct ctl_table_header *sysctl_header;



static int __init init_sysctl(void)

{

    sysctl_header = register_sysctl_table(tsc2007_proc_dev_root);

    return 0;

}



static void __exit cleanup_sysctl(void)

{

    unregister_sysctl_table(sysctl_header);

}



static int tsc2007_measure(struct i2c_client *client, int *x, int * y)

{

    u8 x_buf = {0, 0};

    u8 y_buf = {0, 0};



    i2c_smbus_write_byte(client, TSC_CMD_PLATEX);

    msleep_interruptible(delay_time);



    i2c_smbus_write_byte(client, TSC_CMD_X);

    i2c_master_recv(client, x_buf, 2);

    *x = (x_buf<<4) | (x_buf >>4);



    i2c_smbus_write_byte(client, TSC_CMD_PLATEY);

    msleep_interruptible(delay_time);



    i2c_smbus_write_byte(client, TSC_CMD_Y);

    i2c_master_recv(client, y_buf, 2);

    *y = (y_buf<<4) | (y_buf >>4);

    *y = 4096 - *y; //added by allen

    printk("\ntouchscreen x = 0x%x, y = 0x%x\n",*x,*y);

    return 0;

}



static void tsc2007_irq_work(struct work_struct *work)

{

    struct _tsc2007 *tsc2007= g_tsc2007;

    struct i2c_client *client = tsc2007-> client;

    struct input_dev *input = tsc2007->dev;



    int x = -1, y = -1, is_valid = 0;

    int tmp_x = 0, tmp_y = 0;



    int gpio = irq_to_gpio(client->irq);





    /* Ignore if PEN_DOWN */

    if(PEN_UP == tsc2007->status){



        if (gpio_request(gpio, "tsc2007 touch detect")) {

            printk(KERN_ERR "Request GPIO failed, gpio: %X\n", gpio);

            return;

        }

        gpio_direction_input(gpio);    

        

        while(0 == gpio_get_value(gpio)){



                        if ((jiffies_to_msecs(

                                ((long)jiffies - (long)tsc2007->last_touch)) <

                 debounce_time &&

                tsc2007->status == PEN_DOWN) ||

                init_debounce)

                        {

                init_debounce = false;

                                tsc2007_measure(client, &tmp_x, &tmp_y);

                                TS_DEBUG(KERN_DEBUG

                "dropping pen touch %lu %lu (%u)\n",

                                jiffies, tsc2007->last_touch,

                                jiffies_to_msecs(

                (long)jiffies - (long)tsc2007->last_touch));

                                schedule();

                continue;

                        }





            /* continue report x, y */

            if (x > 0 && y > 0)

            {

                ts_linear_scale(&x, &y, invert);

                input_report_abs(input, ABS_X, x);

                input_report_abs(input, ABS_Y, y);

                input_report_abs(input, ABS_PRESSURE, 255);

                input_report_abs(input, ABS_TOOL_WIDTH, 1);

                input_report_key(input, BTN_TOUCH, 1);

                input_sync(input);

            }



            tsc2007->status = PEN_DOWN;

            tsc2007_measure(client, &x, &y);

            TS_DEBUG(KERN_DEBUG "pen down x=%d y=%d!\n", x, y);

            is_valid = 1;

            schedule();

        }



        if (is_valid)

        {

            /*consider PEN_UP */

            tsc2007->status = PEN_UP;

            input_report_abs(input, ABS_PRESSURE, 0);

            input_report_abs(input, ABS_TOOL_WIDTH, 1);

            input_report_key(input, BTN_TOUCH, 0);

            input_sync(input);

            tsc2007->last_touch = jiffies;

            TS_DEBUG(KERN_DEBUG "pen up!\n"); 

        }



        gpio_free(gpio);    

    }

}



static irqreturn_t tsc2007_interrupt(int irq, void *dev_id)

{    

    schedule_work(&g_tsc2007->irq_work);

    

    return IRQ_HANDLED;

}



static int __devinit tsc2007_probe(struct i2c_client *client, 

                const struct i2c_device_id *id)

{

    struct _tsc2007 *tsc2007;

    struct input_dev *input_dev;

    int ret;



    tsc2007 = kzalloc(sizeof(struct _tsc2007), GFP_KERNEL);

    input_dev = input_allocate_device();



    g_tsc2007 = tsc2007;



    if (!tsc2007 || !input_dev) {

        ret = -ENOMEM;

        goto fail1;

    }



    i2c_set_clientdata(client, tsc2007);



    tsc2007->dev = input_dev;



    input_dev->name = "tsc2007";

    input_dev->phys = "tsc2007/input0";



    //input_dev->id.bustype = BUS_HOST;

    input_dev->dev.parent = &client->dev;



    __set_bit(EV_KEY, input_dev->evbit);

    __set_bit(BTN_TOUCH, input_dev->keybit);



    __set_bit(EV_ABS, input_dev->evbit);

    __set_bit(ABS_PRESSURE, input_dev->evbit);

    __set_bit(ABS_X, input_dev->evbit);

    __set_bit(ABS_Y, input_dev->evbit);



    input_set_abs_params(input_dev, ABS_X, x_min, x_max, 0, 0);

    input_set_abs_params(input_dev, ABS_Y, y_min, y_max, 0, 0);

    input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);



    ret = request_irq(client->irq, tsc2007_interrupt, 

        IRQF_DISABLED | IRQF_TRIGGER_FALLING,

         "tsc2007 irq", NULL);

    if (ret){

        printk(KERN_ERR "tsc2007 request irq failed\n");

        goto fail2;

    }



    ret = input_register_device(tsc2007->dev);

    if (ret){

        printk(KERN_ERR "tsc2007 register device fail\n");

        goto fail2;

    }



    /*init */

    tsc2007->status = PEN_UP;

    tsc2007->client = client;

    tsc2007->last_touch = jiffies;



    INIT_WORK(&tsc2007->irq_work, tsc2007_irq_work);



    /* init tsc2007 */

    i2c_smbus_write_byte(client, TSC_CMD_SETUP);



    return 0;



fail2:

    free_irq(client->irq, client);

fail1:

    i2c_set_clientdata(client, NULL);

    input_free_device(input_dev);

    kfree(tsc2007);

    return ret;

}



static int __devexit tsc2007_remove(struct i2c_client *client)

{

    struct _tsc2007 *tsc2007 = i2c_get_clientdata(client);



    if(client->irq)

        free_irq(client->irq, client);

    

    i2c_set_clientdata(client, NULL);

    input_unregister_device(tsc2007->dev);

    kfree(tsc2007);



    return 0;

}



static struct i2c_device_id tsc2007_idtable[] = { 

    { "tsc2007", 0 }, 

    { } 

}; 



MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);



static struct i2c_driver tsc2007_driver = {

    .driver = {

        .name     = "tsc2007",

    },

    .id_table       = tsc2007_idtable,

    .probe        = tsc2007_probe,

    .remove        = __devexit_p(tsc2007_remove),

};



static int __init tsc2007_ts_init(void)

{

    init_sysctl();

    return i2c_add_driver(&tsc2007_driver);     

}



static void __exit tsc2007_ts_exit(void)

{

    cleanup_sysctl();

    i2c_del_driver(&tsc2007_driver);

}



module_init(tsc2007_ts_init);

module_exit(tsc2007_ts_exit);



MODULE_DESCRIPTION("tsc2007 touch screen driver");

MODULE_LICENSE("GPL");

haolele 发表于 2011-11-11 21:07:48

Android系统开发之tslib移植本帖最后由 haolele 于 2011-11-11 21:08 编辑 



Android系统开发之tslib移植



(1)切换至tslib目录然后执行如下命令(以marvell平台为例)

./autogen.sh

echo "ac_cv_func_malloc_0_nonnull=yes" > arm-marvell-linux.cache

./configure --host=arm-marvell-linux-gnueabi --prefix=/work/svn/ts_build --cache-file=arm-marvell-linux.cache

上面三步仅仅是为了取得tslib目录下的config.h文件



(2)将tslib复制到android源代码vendor/<company_name>/<board_name>目录下



(3)修改vendor/<company_name>/<board_name>目录下的AndroidBoard.mk文件,加入如下内容

include $(LOCAL_PATH)/tslib/Mdroid.mk

一定要主义LOCAL_PATH这个宏的时效性



(4)在tslib目录下创建Mdroid.mk,内容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)



TS_PATH := $(LOCAL_PATH)



include $(TS_PATH)/src/Mdroid.mk

include $(TS_PATH)/plugins/Mdroid.mk

include $(TS_PATH)/tests/Mdroid.mk



include $(CLEAR_VARS)

file := $(TARGET_OUT_ETC)/ts.conf

$(file) : $(TS_PATH)/etc/ts.conf | $(ACP)

    $(transform-prebuilt-to-target)

ALL_PREBUILT += $(file)





(5)在tslib/src目录下创建Mdroid.mk,内容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)



LOCAL_SRC_FILES:= ts_attach.c ts_close.c ts_config.c \

    ts_error.c ts_fd.c ts_load_module.c ts_open.c ts_parse_vars.c \

    ts_read.c ts_read_raw.c ts_option.c



LOCAL_C_INCLUDES += \

        $(LOCAL_PATH)/../



LOCAL_SHARED_LIBRARIES += libutils libcutils



LOCAL_SHARED_LIBRARIES += libdl

LOCAL_PRELINK_MODULE := false

LOCAL_MODULE := libts



include $(BUILD_SHARED_LIBRARY)





(6)在tslib/plugins目录下创建Mdroid.mk,内容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)



LOCAL_SRC_FILES:= input-raw.c



LOCAL_C_INCLUDES += \

        $(LOCAL_PATH)/../ \

        $(LOCAL_PATH)/../src



LOCAL_SHARED_LIBRARIES := libts

LOCAL_MODULE := input

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)





include $(CLEAR_VARS)

LOCAL_SRC_FILES:= pthres.c



LOCAL_C_INCLUDES += \

        $(LOCAL_PATH)/../ \

        $(LOCAL_PATH)/../src



LOCAL_SHARED_LIBRARIES := libts

LOCAL_MODULE := pthres

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)





include $(CLEAR_VARS)

LOCAL_SRC_FILES:= variance.c



LOCAL_C_INCLUDES += \

        $(LOCAL_PATH)/../ \

        $(LOCAL_PATH)/../src



LOCAL_SHARED_LIBRARIES := libts

LOCAL_MODULE := variance

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)





include $(CLEAR_VARS)

LOCAL_SRC_FILES:= dejitter.c



LOCAL_C_INCLUDES += \

        $(LOCAL_PATH)/../ \

        $(LOCAL_PATH)/../src



LOCAL_SHARED_LIBRARIES := libts

LOCAL_MODULE := dejitter

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)



include $(CLEAR_VARS)

LOCAL_SRC_FILES:= linear.c



LOCAL_C_INCLUDES += \

        $(LOCAL_PATH)/../ \

        $(LOCAL_PATH)/../src



LOCAL_SHARED_LIBRARIES := libts

LOCAL_MODULE := linear

LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)





(7)在tslib/tests目录下创建Mdroid.mk,内容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)



LOCAL_SRC_FILES:= ts_calibrate.c fbutils.c testutils.c font_8x8.c font_8x16.c



LOCAL_C_INCLUDES += \

        $(LOCAL_PATH)/../ \

        $(LOCAL_PATH)/../src



LOCAL_SHARED_LIBRARIES := libts



LOCAL_SHARED_LIBRARIES += libutils libcutils



LOCAL_MODULE := tscalibrate



include $(BUILD_EXECUTABLE)





(8)在tslib/config.h文件中加入如下定义:

#define TS_CONF  "/system/etc/ts.conf"

#define PLUGIN_DIR "/system/lib"

#define TS_POINTERCAL "/data/etc/pointercal"





(9)将下面路径文件

tslib/src/ts_open.c

tslib/tests/ts_calibrate.c

tslib/tests/fbutils.c

中的

#include <sys/fcntl.h>

修改成

#include <fcntl.h>



(10)将tslib/tests/ts_calibrate.c文件中

static int clearbuf(struct tsdev *ts)

修改为

static void clearbuf(struct tsdev *ts)



(11)修改tslib/etc/ts.conf内容如下:

module_raw input

module pthres pmin=1

module variance delta=30

module dejitter delta=100

module linear



(12)在android源代码init.rc中声明tslib相关的宏如下:

# touchscreen parameters

    export TSLIB_FBDEVICE /dev/graphics/fb0

    export TSLIB_CALIBFILE /data/etc/pointercal

    export TSLIB_CONFFILE  /system/etc/ts.conf

    export TSLIB_TRIGGERDEV /dev/input/event0

    export TSLIB_TSDEVICE /dev/input/event1



(13)重新编译后即可调用tscalibrate命令来校验触摸屏,校验后产生一个/data/etc/pointercal文件。

嵌入式linux和嵌入式android系统有什么区别和联系?的更多相关文章

  1. 第二章 Android系统与嵌入式开发

    第二章 Android系统与嵌入式开发 第二章首先要先了解Android和嵌入式Lnux系统有什么区别和联系,嵌入式Linux系统是在嵌入式设备中运行Linux系统:Android系统是在嵌入式设备中 ...

  2. 嵌入式系统基础知识(一): 系统结构和嵌入式Linux

    目录 一. 嵌入式体系结构 二. 开发过程中的分工 三. 嵌入式软件体系结构 四. 嵌入式Linux 一. 嵌入式体系结构 <嵌入式系统设计师教程>这本书的前三章脉络很清晰, 按照嵌入式系 ...

  3. 嵌入式Linux学习笔记(三) 字符型设备驱动--LED的驱动开发

    在成功构建了一个能够运行在开发板平台的系统后,下一步就要正式开始应用的开发(这里前提是有一定的C语言基础,对ARM体系的软/硬件,这部分有疑问可能要参考其它教程),根据需求仔细分解任务,可以发现包含的 ...

  4. Android零基础入门第2节:Android 系统架构和应用组件那些事

    原文:Android零基础入门第2节:Android 系统架构和应用组件那些事 继上一期浅谈了Android的前世今生,这一期一起来大致回顾一下Android 系统架构和应用组件. 一.Android ...

  5. Android系统简介(中):系统架构

    Android的系统架构栈分为4层,从上往下分别是Applications.Application framework.Libraries  & Android Runtime.Linux  ...

  6. 关于Android系统的启动流程

    当按下Android设备电源键时究竟发生了什么?Android的启动过程是怎么样的?什么是Linux内核?桌面系统linux内核与Android系统linux内核有什么区别?什么是引导装载程序?什么是 ...

  7. 嵌入式linux驱动开发之给linux系统添加温度传感器模块

    忙了几天,终于可以让ds18b20在自己的开发板的linux系统上跑了!虽然ds18b20不是什么新鲜玩意,但是想想知己可以给linux系统添加模块了还是有点小鸡冻呢! 虽然说现在硬件的资源非常丰富而 ...

  8. 基于s5pv210嵌入式linux系统sqlite3数据库移植

    基于s5pv210嵌入式linux系统sqlite3数据库移植 1.下载源码 http://www.sqlite.org/download.html 最新源码为3080100 2.解压 tar xvf ...

  9. 嵌入式Linux系统运行流程图

    /************************************************************************ * 嵌入式Linux系统运行流程图 * 说明: * ...

随机推荐

  1. java replaceAll 忽略大小写

    public static void main(String[] args) { String temp=" CLASS_path : /aaabb/"; System.out.p ...

  2. php使用163邮箱发送邮件

    email.class.php文件 <? class smtp { /* Public Variables */ var $smtp_port; var $time_out; var $host ...

  3. [Swift通天遁地]七、数据与安全-(9)文件的压缩和解压

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. TypeScript `unknown` 类型

    unknown 字面理解和 any 其实没差,任何类型都可赋值给它,但有一点, Anything is assignable to unknown, but unknown isn't assigna ...

  5. IOC框架---什么是IOC

    1 IoC理论的背景    我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑.                    ...

  6. vue 中展示PDF内容

    vue 中展示PDF内容 不久前有个需要改的需求,以前是直接根据链接让用户下载对应pdf文件来查看,最主要是给用户查看,然而这种并不是很安全的,其他用户可以进行下载或者使用pdf链接分享给其他人,所以 ...

  7. SQL Server 2008R2 Set IDENTITY_INSERT 表名 ON/OFF不能与insert into select 的语句一起执行?

    大家都知数据库表中的列可以自增长,但是有时候我们需要插入数据的时候会指定这一列的数据. 这时候我们可以很简单的利用sql语句来执行新增一条的数据,如下: set IDENTITY_INSER 表名 o ...

  8. Java常用类库(二):Iterator迭代器和子范围视图

    今天介绍集合类的以下内容: l  Iterator迭代器 l  子范围视图简介 Iterator迭代器: 应该将java迭代器认为是位于两个元素之间, 当调用next 时,迭代器就越过下一个元素,并返 ...

  9. InputStream和Reader

    java.io下面有两个抽象类:InputStream和ReaderInputStream是表示字节输入流的所有类的超类Reader是用于读取字符流的抽象类InputStream提供的是字节流的读取, ...

  10. 【转】Java 集合系列10之 HashMap详细介绍(源码解析)和使用示例

    概要 这一章,我们对HashMap进行学习.我们先对HashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用HashMap.内容包括:第1部分 HashMap介绍第2部分 HashMa ...