Android 从硬件到应用:一步一步向上爬 1 -- 从零编写底层硬件驱动程序
2014-12-12 20:26
423 查看
硬件平台:TI AM335X Starter Kit
开发源码:TI-Android-ICS-4.0.3-DevKit-EVM-SK-3.0.1.bin
主机系统:Ubuntu 10.04
这次写《Android 从硬件到应用》是想尝试从底层的最简单的GPIO硬件驱动开始,一步一步的向上走,经过硬件抽象层HAL、JNI方法等,最终编写出APP,达到硬件调用的目的,期间会增加一些Android下C程序测试底层驱动的细节。既然是从零编写驱动,那就要脱离源码包里已有的一些api函数,从硬件电路开始。找到EVM板GPIO处原理图:
我要控制LED D1的状态,如上图所示,D1接了Q4,也就是BSS138,N沟道的MOS器件,AM335X_GPIO_LED4为高电平时,Q4的栅极漏极导通,D1为亮,反之,灭。首先设置GPIO时钟:
一、CM_PER_GPIO1_CLKCTRL:地址0x44E000AC 要装载的值为 0x00040002
接着设置GPIO1输出使能:
二、GPIO_OE:地址0x4804C134 要装载的值为 0x0
然后设置输出GPIO1的输出:
三、GPIO_DATAOUT:地址0x4804C13C 要装载的值为 0x00000010或者是0x00000000,让AM335X_GPIO_LED4引脚为高或低,这样D1就可以亮灭
编写驱动程序 android_gpio.c:移到drivers/char目录下
make ARCH=arm CROSS_COMPILE=arm-eabi- uImage
生成uImage,重新启动新系统,ls /dev 查看设备:
发现AdrIO设备,第一步完成,注意在操作物理地址时一定要对位进行操作,不然
GPIO1会影响到AM335X Starter Kit的LCD显示,下一步就要执行C程序测试该驱动。
开发源码:TI-Android-ICS-4.0.3-DevKit-EVM-SK-3.0.1.bin
主机系统:Ubuntu 10.04
这次写《Android 从硬件到应用》是想尝试从底层的最简单的GPIO硬件驱动开始,一步一步的向上走,经过硬件抽象层HAL、JNI方法等,最终编写出APP,达到硬件调用的目的,期间会增加一些Android下C程序测试底层驱动的细节。既然是从零编写驱动,那就要脱离源码包里已有的一些api函数,从硬件电路开始。找到EVM板GPIO处原理图:
我要控制LED D1的状态,如上图所示,D1接了Q4,也就是BSS138,N沟道的MOS器件,AM335X_GPIO_LED4为高电平时,Q4的栅极漏极导通,D1为亮,反之,灭。首先设置GPIO时钟:
一、CM_PER_GPIO1_CLKCTRL:地址0x44E000AC 要装载的值为 0x00040002
接着设置GPIO1输出使能:
二、GPIO_OE:地址0x4804C134 要装载的值为 0x0
然后设置输出GPIO1的输出:
三、GPIO_DATAOUT:地址0x4804C13C 要装载的值为 0x00000010或者是0x00000000,让AM335X_GPIO_LED4引脚为高或低,这样D1就可以亮灭
编写驱动程序 android_gpio.c:移到drivers/char目录下
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/uaccess.h> /* copy_to_user,copy_from_user */ #include <linux/miscdevice.h> #include <linux/device.h> #include <asm/io.h> static struct class *gpio_class; volatile unsigned long *DIR; volatile unsigned long *DAT; volatile unsigned long *CLK; int gpio_open (struct inode *inode,struct file *filp) { *CLK = 0x00040002; //Enable *DIR = (*DIR)&0xffffffef; //output return 0; } ssize_t gpio_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos) { return 0; } ssize_t gpio_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos) { char val_buf[2]; int ret; ret = copy_from_user(val_buf,buf,count); switch(val_buf[0]) { case 0x31 : *DAT = (*DAT)|0x00000010; break; case 0x30 : *DAT = (*DAT)&0xffffffef; break; default : break; } return count; } struct file_operations gpio_fops = { .owner = THIS_MODULE, .open = gpio_open, .read = gpio_read, .write = gpio_write, } ; int major; int gpio_init (void) { major = register_chrdev(0,"Android_gpio",&gpio_fops); gpio_class = class_create(THIS_MODULE, "Android_gpio"); device_create(gpio_class,NULL,MKDEV(major,0),NULL,"AdrIO"); DIR = (volatile unsigned long *)ioremap(0x4804C134,4); DAT = (volatile unsigned long *)ioremap(0x4804C13C,4); CLK = (volatile unsigned long *)ioremap(0x44E000AC,4); printk ("gpio is ready\n"); return 0; } void gpio_exit (void) { unregister_chrdev(major,"Android_gpio"); device_destroy(gpio_class,MKDEV(major,0)); class_destroy(gpio_class); iounmap(DIR); iounmap(DAT); iounmap(CLK); printk ("module exit\n"); return ; } MODULE_LICENSE("GPL"); module_init(gpio_init); module_exit(gpio_exit);打开drivers/char目录下的Makefile,增加:
obj-$(CONFIG_ANDROID_GPIO) += android_gpio.o打开drivers/char目录下的Kconfig,增加:
config ANDROID_GPIO tristate "android gpio enable" default y源码目录下执行:
make ARCH=arm CROSS_COMPILE=arm-eabi- uImage
生成uImage,重新启动新系统,ls /dev 查看设备:
# ls /dev AdrIO alarm android_adb ashmem binder block bus
发现AdrIO设备,第一步完成,注意在操作物理地址时一定要对位进行操作,不然
GPIO1会影响到AM335X Starter Kit的LCD显示,下一步就要执行C程序测试该驱动。
相关文章推荐
- Android 从硬件到应用:一步一步向上爬 6 -- 编写APP测试框架层硬件服务(完)
- Android 从硬件到应用:一步一步向上爬 2 -- 运行 C 程序测试硬件驱动
- Android 从硬件到应用:一步一步向上爬 4 -- 使用 JNI 方法调硬件驱动
- Android 从硬件到应用:一步一步向上爬 3 -- 硬件抽象层访问硬件驱动
- Android 从硬件到应用:一步一步向上爬 5 -- 在Frameworks层添硬件服务
- Android 从硬件到应用:一步一步向上爬 4 -- 使用 JNI 方法调硬件驱动
- android udp通信(应用层与底层硬件的通信)
- 一步一步的学习android应用开发到系统底层开发之android数据解析JSON篇
- 一步一步的学习android应用开发到系统底层开发之android开发层次及所需技术
- Android 驱动之旅: 第一章 在Android 内核源代码工程中编写硬件驱动程序
- Android系统上层应用能访问底层硬件的简要原理
- 在Ubuntu上为Android系统编写Linux内核驱动程序
- Android Service 两种编写及应用
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 为Android系统编写Linux内核驱动程序
- Google应用在Android上的Push机制以及C2DM框架的底层实现
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu上为Android系统编写Linux内核驱动程序
- 在Ubuntu上为Android系统编写Linux内核驱动程序