硬件平台: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处原理图:

Android 从硬件到应用:一步一步向上爬 1 -- 从零编写底层硬件驱动程序_第1张图片

       我要控制LED D1的状态,如上图所示,D1接了Q4,也就是BSS138,N沟道的MOS器件,AM335X_GPIO_LED4为高电平时,Q4的栅极漏极导通,D1为亮,反之,灭。首先设置GPIO时钟:

Android 从硬件到应用:一步一步向上爬 1 -- 从零编写底层硬件驱动程序_第2张图片

一、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   #include   #include   #include  /* copy_to_user,copy_from_user */  #include   #include   #include     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程序测试该驱动。

更多相关文章

  1. Android硬件抽象层(HAL)概要介绍和学习计划
  2. [置顶] Android 从硬件到应用:一步一步向上爬 6 -- 编写APP测试框
  3. Android PinyinIME 源码笔记 -- 1. 底层服务接口简介
  4. Android 从硬件到应用:一步一步向上爬 4 -- 使用 JNI 方法调硬件
  5. Android硬件设备检测
  6. android底层HAL层深入了解
  7. Android硬件入门-照相机

随机推荐

  1. SQL查询服务器硬盘剩余空间
  2. 高并发系统数据幂等的解决方案
  3. Activiti-Explorer使用sql server数据库
  4. SQL Server数据表字段自定义自增数据格式
  5. SQLServer批量更新两个关联表数据的方法
  6. 使用SQL批量替换语句修改、增加、删除字
  7. SQL Server 存储过程遇到“表 ''
  8. 浅谈数据库优化方案
  9. Win10 64位安装个人版SQL2000图文教程
  10. SQL Server触发器和事务用法示例