嵌入式linux和嵌入式android系统有什么区别和联系?
轉自:http://bbs.eeworld.com.cn/thread-430437-1-1.html
?
這個問題很多人問,尤其是初入嵌入式的菜鳥。其實大家都認為android是java,已經(jīng)不是linux,殊不知android就是靠著linux 才發(fā)展起來的,現(xiàn)在來說說有啥區(qū)別吧。
嵌入式android源碼架構:uboot+linux kernel+android(包含文件系統(tǒng),虛擬機,UI)
嵌入式linux:這是大部分人認識的linux uboot+linux kernel+文件系統(tǒng)+QT(UI),
當然兩者的linux 內核因為上層UI的不同會稍有差別,不過還是非常接近的,做過linux的人可以無縫切換到android底層開發(fā),所以大家說的學習android系統(tǒng),其實最重要的就是學習linux驅動,再加一下android下的專門的HAL,JNI,java等等,不過大公司android相關部分也是專門的人做的了。
甚至連QT都不用了,因為linux很多設備都是沒有UI的,所以要來干啥?直接無界面,照樣是嵌入式linux。
現(xiàn)在大家說的什么嵌入式debian,ubuntu,其實也是站在linux巨人的肩膀上,其實都不算是linux的分支,只算是linux的延伸,小變化而已。看到這里大家知道嵌入式linux的強大了吧,反正是比wince 強大N倍啊。
?
O(∩_∩)O~,所以啊,學習嵌入式android,其實底下就是學習uboot,linux內核啊,不會搞這些就像搞應用一樣,所以大家以為android就是java,是非常片面的。
?
以前老的,說了一下區(qū)別,可以參考一下
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為了模擬器所開發(fā)的一個虛擬硬件平臺。Goldfish執(zhí)行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應用非常廣泛(絕大多數(shù)手機用的都是NAND flash,三星的一些手機使用的是OneNAND)。NAND flash具有低成本和高密度的優(yōu)點。
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系統(tǒng)移植方法詳解
http://www.anzhuoba.com/archiver/?tid-8419.html
[本文WORD文檔下載:]
通過Android系統(tǒng)移植,讓它在目標系統(tǒng)上運行起來。Android系統(tǒng)由于用的是linux內核,因此內核移植和嵌入式linux內核移植差異不大,過程如下:
(1)移植boot-loader和linux2.6內核到目標平臺上,讓linux內核可以啟動起來,基本的驅動允許正常。
此過程完全是嵌入式linux的開發(fā),這里直接跳過。需要注意的是,由于android已經(jīng)被linux官方開除,因此從
網(wǎng)站上(如http://www.kernel.org/)下載的最新linux內核源代碼已經(jīng)不包含android的專有驅動,因此建議
從google網(wǎng)上下下載Linux內核,android源代碼瀏覽網(wǎng)站如下:
http://android.git.kernel.org/
從該網(wǎng)站上發(fā)現(xiàn)內核相關的包如下:
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文件系統(tǒng)的部分內容壓縮到內核中。
首先打開內核驅動:
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)根據(jù)android文件系統(tǒng)的要求對nand flash進行重新分區(qū),舉例如下:
將nand flash分區(qū)以下8個分區(qū)
NTIM
OBM
U-boot
Kernel
System
UserData
Mass Storage
BBT
(5)根據(jù)分區(qū)表修改內核啟動參數(shù)如下:
CONFIG_CMDLINE="ubi.mtd=4 ubi.mtd=5 ubi.mtd=6 root=ubi0_0 rootfstype=ubifs console=ttyS1,115200 uart_dma init=/init"
參數(shù)的意思是:載入的文件系統(tǒng)部分有3個分區(qū),分別為nand flash的第4,5,6分區(qū)(從0編號),文件系統(tǒng)采用ubifs格式,控制臺設備為ttyS1,波特率為115200
啟動的第一個應用程序是/init
(6)確保控制臺的設置和硬件保持一致,如:硬件上串口用的是UART1,則內核啟動參數(shù)中設置有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文件系統(tǒng)):
首先將android文件系統(tǒng)修改成可讀寫,將
? ? 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)完成后編譯內核,可以啟動文件系統(tǒng),控制臺可用,但是沒有顯示啟動log,而且不停的重啟。
(9)系統(tǒng)不停的重啟,因此控制臺已經(jīng)可用了,自然而然的想到看到logcat日志,一看,發(fā)現(xiàn)logcat設備居然沒起來,配置文件里面都定義了
居然沒起來,查看了下內核drivers/staging/android目錄,沒有.o文件,證明是沒編譯到,在看內核目錄下的.config文件,發(fā)現(xiàn)居然沒有了
logcat和binder的宏定義,配置文件里面有定義而.config文件中無定義,肯定是相關Kconfig文件的問題,通過分析drivers/staging目錄下的
Kconfig文件發(fā)現(xiàn)是因為STAGING_EXCLUDE_BUILD宏默認是y,在配置文件中否定此宏即可,在配置文件中CONFIG_STAGING定義后加上即可,如下:
CONFIG_STAGING=y
# CONFIG_STAGING_EXCLUDE_BUILD is not set
修改后重新編譯發(fā)現(xiàn)系統(tǒng)完成正常啟動,啟動過程中啟動log也顯示正常。
至此,android初步移植工作已經(jīng)完成,當然,系統(tǒng)還有很多問題,需要下一步繼續(xù)修改。
總結:android的移植按如下流程:
(1)android linux內核的普通驅動移植,讓內核可以在目標平臺上運行起來。
(2)正確掛載文件系統(tǒng),確保內核啟動參數(shù)和android源代碼system/core/rootdir目錄下的init.rc中的文件系統(tǒng)掛載正確。
(3)調試控制臺,讓內核啟動參數(shù)中的console參數(shù)以及android源代碼system/core/init/init.c中的console_name設置和硬件保持一致
(4)打開android相關的驅動(logger,binder等),串口輸入logcat看logger驅動起來,沒有的話調試logger驅動。
說明:ARM的內核配置文件定義在內核arch/arm/configs目錄下。
Android系統(tǒng)移植之按鍵移植本帖最后由 haolele 于 2011-11-11 21:04 編輯?
Android系統(tǒng)移植之按鍵移植這一部分主要是移植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)步實現(xiàn)了從硬件GPIO口到內核標準按鍵的映射,但是android并沒有直接使用映射后的鍵值,而且對其再進行了一次映射,從內核標準鍵值
到android所用鍵值的映射表定義在android文件系統(tǒng)的/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負責,主要的映射轉換實現(xiàn)在android源代碼frameworks/base/libs/ui/EventHub.cpp
此文件處理來自底層的所有輸入事件,并根據(jù)來源對事件進行分類處理,對于按鍵事件,處理過程如下:
(a)記錄驅動名稱為
(b)獲取環(huán)境變量ANDROID_ROOT為系統(tǒng)路徑(默認是/system,定義在android源代碼/system/core/rootdir/init.rc文件中)
(c)查找路徑為"系統(tǒng)路徑/usr/keylayout/驅動名稱.kl"的按鍵映射文件,如果不存在則默認用路徑為"系統(tǒng)路徑/usr/keylayout/qwerty.kl"
這個默認的按鍵映射文件,映射完成后再把經(jīng)映射得到的android按鍵碼值發(fā)給上層應用程序。
所以我們可以在內核中定義多個按鍵設備,然后為每個設備設定不同的按鍵映射文件,不定義則會默認用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發(fā)現(xiàn)
#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按鍵碼一起發(fā)給應用程序來使用,這一點一定要注意。Android系統(tǒng)開發(fā)小知識-在android產(chǎn)品開 發(fā)中添加新的編譯模塊 Android開發(fā)中用戶內容定義在vendor目錄下,而用戶產(chǎn)品的內容都定義在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
Android系統(tǒng)移植之按鍵字符表本帖最后由 haolele 于 2011-11-11 21:05 編輯?
Android系統(tǒng)移植之按鍵字符表
上節(jié)講android的Window Manager將內核按鍵碼通過按鍵映射表轉換成android按鍵碼,
這節(jié)講的是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按鍵碼(這部分上節(jié)已講),然后會
將android按鍵碼轉換成字符,具體過程如下:
(a)設置系統(tǒng)系統(tǒng)屬性hw.keyboards.設備號.devname的值為設備名
以上節(jié)的gpio-keys設備為例,會設置系統(tǒng)屬性hw.keyboards.65539.devname的值為gpio-keys
(b)載入按鍵字符表,首先載入/system/usr/keychars目錄下的設備名.kcm.bin文件(此例即gpio-keys.kcm.bin文件),如果載入失敗
則載入該目錄下的querty.kcm.bin.
(c)利用載入的按鍵字符表將android按鍵轉換成按鍵字符發(fā)給上層應用程序。
(4)一般情況下一個控制按鍵是不需要作按鍵字符表的,系統(tǒng)會調用默認的去處理,但是如果要開發(fā)一個全功能鍵盤(包含了字母和數(shù)字),那可能就需要
自己作一個專用的按鍵字符表了。android系統(tǒng)開發(fā)小問題-啟動過程中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);
? ? }
? ? }?
Android系統(tǒng)開發(fā)之觸摸屏tslib移植(內核)和原理分析本帖最后由 haolele 于 2011-11-11 21:07 編輯
Android系統(tǒng)開發(fā)之觸摸屏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文件系統(tǒng)中建立了7個文件,用來存放校準用的7個點,7的點的默認值
為1,0,0,0,1,0,1,對應的目標平臺文件系統(tǒng)的位置為/proc/sys/dev/ts_device目錄下a0,a1,a2,a3,a4,a5,a6等7個文件
此模塊中還定義了一個校準函數(shù)ts_linear_scale,此函數(shù)的主要內容是讀取a0,a1,a2,a3,a4,a5,a6等7個文件中的值作為7個
校準值與傳入的觸摸平坐標值進行運算,返回運算結果。
ts_linear_scale函數(shù)定義如下:
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為觸摸屏驅,與其他驅動不同的地方是在取得硬件坐標值發(fā)送之前先調用了ts_linear_scale函數(shù)對坐標值進行了校準
? ?? ?? ?? ?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系統(tǒng),比較麻煩,看下一節(jié)的內容。
(3)校驗程序完成后會將生成的7個校準值寫入到環(huán)境變量TSLIB_CALIBFILE對應的路徑/data/etc/pointercal文件中
(4)校驗完后將pointercal文件中的7個值分別寫入到/proc/sys/dev/ts_device目錄下a0,a1,a2,a3,a4,a5,a6文件即可。
(5)開機啟動的時候我們編寫一個應用程序,首先判斷環(huán)境變量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");
Android系統(tǒng)開發(fā)之tslib移植本帖最后由 haolele 于 2011-11-11 21:08 編輯?
Android系統(tǒng)開發(fā)之tslib移植
(1)切換至tslib目錄然后執(zhí)行如下命令(以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目錄下創(chuàng)建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目錄下創(chuàng)建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目錄下創(chuàng)建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目錄下創(chuàng)建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命令來校驗觸摸屏,校驗后產(chǎn)生一個/data/etc/pointercal文件。
轉載于:https://www.cnblogs.com/roger0212/p/4436673.html
總結
以上是生活随笔為你收集整理的嵌入式linux和嵌入式android系统有什么区别和联系?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GCC的内存边界对齐
- 下一篇: SpringMVC的国际化