Android驱动例子(LED灯控制)(1…

来源:互联网 发布:dns域名污染 编辑:程序博客网 时间:2024/06/06 03:05

Android驱动例子(LED灯控制)

[日期:2011-04-13]来源:Linux社区  作者:ok138ok
本例子,讲述在Android2.1上完全自已开发一个驱动去控制硬件口并写应用测试该驱动,通过这样一个例子,解析android下的驱动开发流程的应用调用流程,可以说是很好的入门引导

要达到的效果:通过Android的应用,调用驱动程序,在开发板上控制4个LED的亮灭。

一、硬件原理

Android驱动例子(LED灯控制)(1)

如上图,通过4个IO口控制这LED,低电平LED亮,

这4个IO口分别是GPM1, GPM2, GPM3, GPM4,

二、驱动程序

1、在kernel文件夹下的driver目录,新键驱动文件夹

# cd kernel_Android_2.6.28.6/drivers

进到开发板的kernel目录,建驱动文件夹

#mkdir ledtest

2、在/driver/ledtest目录下,新建leddriver.c ,leddriver.h , Kconfig,Makefile 等4个文件

leddriver.c

leddriver.c
  1. #include <linux/kernel.h>
  2. #include <linux/sched.h>
  3. #include <linux/timer.h>
  4. #include <linux/init.h>            
  5. #include <linux/module.h>
  6. #include <mach/hardware.h>
  7. #include <asm/io.h>
  8. #include <asm/uaccess.h>
  9. #include <plat/gpio-cfg.h>
  10. #include <plat/regs-clock.h>
  11. #include <plat/regs-lcd.h>
  12. #include <plat/regs-gpio.h>
  13. #include <mach/map.h>
  14. #include <linux/gpio.h>
  15. #include <plat/gpio-bank-m.h>
  16. #include <linux/cdev.h>
  17. #include <linux/fs.h>//for register_chrdev()
  18. #include <linux/device.h>
  19. #include <mach/map.h>
  20. #include "leddriver.h"
  21. #include <linux/miscdevice.h>        
  22. #include <linux/watchdog.h>        
  23. #include <linux/fs.h>            
  24. #defineViberator_MAJOR        97  //?÷éè±?o?
  25. #defineSCULL_NR_DEVS           4
  26. #defineSCULL_QUANTUM         4000
  27. #define SCULL_QSET            1000
  28. //---do as the GIOdriver
  29. #defineDEVCOUNT                4
  30. #defineGIO_MINOR               
  31. static dev_tdev;        //éê?? μ?μ??÷ éè±? o?
  32. static struct cdev *cdev_p;
  33. static int openCnt;
  34. //--è???±?á?------------
  35. intVIB_major  = 97;//we asigment it for test
  36. int VIB_minor = 0;
  37. int VIB_nr_devs = SCULL_NR_DEVS;
  38. int VIB_quantum =SCULL_QUANTUM;
  39. int VIB_qset = SCULL_QSET;
  40.  
  41. static struct class *vib_dev_class;
  42. #defineGPNCON  S3C64XX_GPNCON
  43. #defineGPNDAT  S3C64XX_GPNDAT
  44. #defineGPNPUD  S3C64XX_GPNPUD
  45. #define GPMCON S3C64XX_GPMCON
  46. #defineGPMDAT  S3C64XX_GPMDAT
  47. #define GPMPUD S3C64XX_GPMPUD
  48.  
  49. #define VIB_ON 0x11
  50.   #defineVIB_OFF 0x22
  51. static const struct file_operationsGPIO_Viberator_ctl_ops={
  52.     .owner        =THIS_MODULE,
  53.     .open    =GPIO_VIB_open,
  54.     .read    =GPIO_VIB_read,
  55.     .write    =GPIO_VIB_write,
  56.     .ioctl    =GPIO_VIB_ioctl,
  57.     .release    =GPIO_VIB_release,
  58. };
  59. ssize_t GPIO_VIB_read(struct file * file,char * buf,size_t count,loff_t *f_ops)
  60. {
  61.     printk("GPIO_VIB_read \r\n");
  62.     gpio_direction_output(S3C64XX_GPM(3),0);//
  63.     returncount ;
  64. }
  65. ssize_t GPIO_VIB_write(struct file *file,const char * buf, size_t count,loff_t *f_ops)
  66. {
  67.       printk("GPIO_VIB_write \r\n");
  68.       gpio_direction_output(S3C64XX_GPM(3),1);//
  69.    return count;
  70. }
  71.  
  72. //ssize_t GPIO_VIB_ioctl(structinode *  inode,struct file *file,unsigned int cmd, long data)
  73. static int GPIO_VIB_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  74. {
  75.     printk(KERN_ERR"VIB:GPIO_VIB_ioctl--CMD=%x \n",cmd);
  76.     switch(cmd)
  77.         {
  78.            caseVIB_ON:
  79.             gpio_direction_output(S3C64XX_GPM(1),0);//
  80.             gpio_direction_output(S3C64XX_GPM(2),0);//
  81.             gpio_direction_output(S3C64XX_GPM(3),0);//
  82.             gpio_direction_output(S3C64XX_GPM(4),1);//
  83.             printk(KERN_ERR"VIB:GPIO_VIB_ioctl--VIB_ON\n");
  84.             break;
  85.          caseVIB_OFF:
  86.             {
  87.             printk(KERN_ERR"VIB:GPIO_VIB_ioctl--VIB_OFF\n");
  88.             gpio_direction_output(S3C64XX_GPM(1),1);//
  89.             gpio_direction_output(S3C64XX_GPM(2),1);//
  90.             gpio_direction_output(S3C64XX_GPM(3),1);//
  91.             gpio_direction_output(S3C64XX_GPM(4),0);//
  92.             break;
  93.          }
  94.          default:break;
  95.                 
  96.     }
  97.         //gpio_free(S3C64XX_GPN(7));
  98. }
  99. ssize_t GPIO_VIB_open(struct inode * inode,struct file * file)
  100. {
  101. //?£?éêy
  102.   //MOD_INC_USE_COUNT;
  103.   printk("GPIO_VIB_open()\n");   
  104.   return 0;
  105. }
  106. ssize_t GPIO_VIB_release(struct inode * inode, struct file * file)
  107. {
  108.    // MOD_DEC_USE_COUNT;//?£?éêy??
  109.      printk("GPIO_VIB_release()\n");   
  110.     return0;
  111. }
  112. static int GPIO_VIB_CTL_init(void)
  113. {
  114.     intret  = -ENODEV;
  115.    int error ;
  116.     printk("----------------------------------------------\r\n");
  117.     //3?ê??ˉ???ú
  118.         s3c_gpio_cfgpin(S3C64XX_GPM(1),S3C_GPIO_SFN(1));//GPM1output
  119.         s3c_gpio_cfgpin(S3C64XX_GPM(2),S3C_GPIO_SFN(1));//GPM2output
  120.         s3c_gpio_cfgpin(S3C64XX_GPM(3),S3C_GPIO_SFN(1));//GPM3output
  121.         s3c_gpio_cfgpin(S3C64XX_GPM(4),S3C_GPIO_SFN(1));//GPM4output
  122. #if 1
  123. ret =register_chrdev(Viberator_MAJOR, "viberator",&GPIO_Viberator_ctl_ops);
  124. if (ret < 0){
  125.     printk(KERN_ERR"VIB: unable to get major%d\n", ret);
  126.     returnret;
  127. }
  128. //′′?¨\uc1class
  129. vib_dev_class =class_create(THIS_MODULE, "viberator");
  130. if (IS_ERR(vib_dev_class)){
  131.     unregister_chrdev(Viberator_MAJOR,"capi20");
  132.     returnPTR_ERR(vib_dev_class);
  133. }
  134. //′′?¨?úμ?£?
  135. device_create(vib_dev_class, NULL,MKDEV(Viberator_MAJOR, 0), NULL, "vib");
  136. // create a point under/dev/class/vib  
  137. //í¨1yé????aá?2?£??y?ˉ?ó??oó£??í?á?ú/dev/class/????éú3é\uc1vib?úμ?£?ó|ó?3ìDò?éò???2ù×÷???t???ù2ù×÷?a???úμ?£?í¨1y\uc1open,write,read μèoˉêy2ù×÷£??ê?é?éò??′oó??μ?ó|ó?ê?ày3ìDò?£
  138.   return0;    
  139. #endif
  140. #if 0
  141.     if((error = alloc_chrdev_region(&dev, 0, DEVCOUNT,"vibrate")) <0)
  142.         {
  143.         printk(KERN_ERR
  144.                "VIB:Couldn't alloc_chrdev_region, error=%d\n",
  145.                error);
  146.         return1;
  147.     }
  148.          printk("dev= %d  \n",dev);
  149.     cdev_p= cdev_alloc();
  150.     cdev_p->ops= &GPIO_Viberator_ctl_ops;
  151.     error= cdev_add(cdev_p, dev, DEVCOUNT);
  152.     if(error) {
  153.         printk(KERN_ERR
  154.                "VIB:Couldn't cdev_add, error=%d\n", error);
  155.         return1;
  156.     }
  157.  
  158.     vib_dev_class= class_create(THIS_MODULE, "vib-dev");
  159.     if(IS_ERR(vib_dev_class)) {
  160.         res= PTR_ERR(vib_dev_class);
  161.         gotoout_unreg_class;
  162.     }
  163.     return0;
  164. #endif
  165. out_unreg_class:
  166.     class_destroy(vib_dev_class);
  167. return 1;
  168. }
  169.  
  170. static int __init S3C6410_VIB_init(void)
  171. {
  172.     intret = -ENODEV;
  173.     //μ÷ó?oˉêy   
  174.         printk(KERN_ERR"Auly:S3C6410_VIB_init---\n");
  175.     ret= GPIO_VIB_CTL_init();
  176.     if(ret)
  177.         {
  178.         printk(KERN_ERR"Auly: S3C6410_VIB_init--Fail!!!\n");
  179.         returnret;
  180.     }
  181.     return0;
  182. }
  183. static void __exit cleanup_GPIO_VIB(void)
  184. {
  185.     //×¢?úéè±?
  186.   //  devfs_unregister_chrdev(Viberator_MAJOR,"gpio_vib_ctl");
  187. #if 0
  188.       cdev_del(cdev_p);
  189.     unregister_chrdev_region(dev,DEVCOUNT);
  190.     class_destroy(vib_dev_class);
  191. #endif
  192. device_destroy(vib_dev_class, MKDEV(Viberator_MAJOR, 0));
  193. class_destroy(vib_dev_class);
  194. unregister_chrdev(Viberator_MAJOR, "viberator");
  195. }
  196. MODULE_LICENSE("GPL");
  197. MODULE_DESCRIPTION("Peter first driver");
  198. MODULE_ALIAS_CHARDEV(Viberator_MAJOR, 0);
  199.  
  200. module_init(S3C6410_VIB_init);
  201. module_exit(cleanup_GPIO_VIB);
0 0