当前位置:文档之家› Android驱动开发实例(控制LED灯)(精)

Android驱动开发实例(控制LED灯)(精)

Android驱动例子(LED灯控制)本例子,讲述在Android2.1上完全自已开发一个驱动去控制硬件口并写应用测试该驱动,通过这样一个例子,解析android下的驱动开发流程的应用调用流程,可以说是很好的入门引导要达到的效果:通过Android的应用,调用驱动程序,在开发板上控制4个LED的亮灭。

一、硬件原理如上图,通过4个IO口控制这LED,低电平LED亮,这4个IO口分别是GPM1, GPM2, GPM3, GPM4,二、驱动程序1、在kernel文件夹下的driver目录,新键驱动文件夹# cd kernel_Android_2.6.28.6/drivers进到开发板的kernel目录,建驱动文件夹#mkdir ledtest2、在/driver/ledtest目录下,新建leddriver.c ,leddriver.h , Kconfig, Makefile 等4个文件leddriver.c1. #include2. #include3. #include4. #include/* For __init/__exit/... */5. #include6. #include7. #include8. #include9. #include10. #include11. #include12. #include13. #include14. #include15. #include16. #include17. #include//for register_chrdev(18. #include19. #include20. #include"leddriver.h"21. #include/* For MODULE_ALIAS_MISCDEV22. (WATCHDOG_MINOR */23. #include/* For the watchdog specific items */24. #include/* For file operations */25. #define Viberator_MAJOR 97 //?÷éè±?o?26. #define SCULL_NR_DEVS 427. #define SCULL_QUANTUM 400028. #define SCULL_QSET 100029. //---do as the GIO driver30. #define DEVCOUNT 431. #define GIO_MINOR 2 /* GIO minor no. */32. static dev_t dev; //éê ?? μ?μ??÷ éè±? o?33. static struct cdev *cdev_p;34. static int openCnt;35. //--è±?á?------------36. int VIB_major = 97;//we asigment it for test37. int VIB_minor = 0;38. int VIB_nr_devs = SCULL_NR_DEVS;39. int VIB_quantum = SCULL_QUANTUM;40. int VIB_qset = SCULL_QSET;41.42. static struct class *vib_dev_class;43. #define GPNCON S3C64XX_GPNCON44. #define GPNDAT S3C64XX_GPNDAT45. #define GPNPUD S3C64XX_GPNPUD46. #define GPMCON S3C64XX_GPMCON47. #define GPMDAT S3C64XX_GPMDAT48. #define GPMPUD S3C64XX_GPMPUD49.50. #define VIB_ON 0x1151. #define VIB_OFF 0x2252. static const struct file_operations GPIO_Viberator_ctl_ops={53. .owner = THIS_MODULE,54. .open = GPIO_VIB_open,55. .read =GPIO_VIB_read,56. .write =GPIO_VIB_write,57. .ioctl = GPIO_VIB_ioctl,58. .release =GPIO_VIB_release,59. };60. ssize_t GPIO_VIB_read(struct file * file,char * buf,size_t count,loff_t * f_ops61. {62. printk(" GPIO_VIB_read \r\n";63. gpio_direction_output(S3C64XX_GPM(3, 0;//64. return count ;65. }66. ssize_t GPIO_VIB_write (struct file * file,const char * buf, size_tcount,loff_t * f_ops67. {68. printk(" GPIO_VIB_write \r\n";69. gpio_direction_output(S3C64XX_GPM(3, 1;//70. return count;71. }72.73. //ssize_t GPIO_VIB_ioctl(struct inode * inode,struct file * file,unsigned int cmd, long data74. static int GPIO_VIB_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg75. {76. printk(KERN_ERR"VIB:GPIO_VIB_ioctl --CMD=%x \n",cmd;77. switch(cmd78. {79. case VIB_ON:80. gpio_direction_output(S3C64XX_GPM(1, 0;//81. gpio_direction_output(S3C64XX_GPM(2, 0;//82. gpio_direction_output(S3C64XX_GPM(3, 0;//83. gpio_direction_output(S3C64XX_GPM(4, 1;//84. printk(KERN_ERR"VIB:GPIO_VIB_ioctl --VIB_ON\n";85. break;86. case VIB_OFF:87. {88. printk(KERN_ERR"VIB:GPIO_VIB_ioctl --VIB_OFF\n";89. gpio_direction_output(S3C64XX_GPM(1, 1;//90. gpio_direction_output(S3C64XX_GPM(2, 1;//91. gpio_direction_output(S3C64XX_GPM(3, 1;//92. gpio_direction_output(S3C64XX_GPM(4, 0;//93. break;94. }95. default:break;96.97. }98. //gpio_free(S3C64XX_GPN(7;99. }100. ssize_t GPIO_VIB_open(struct inode * inode,struct file * file 101. {102. //?£?éêy103. //MOD_INC_USE_COUNT;104. printk("GPIO_VIB_open( \n";105. return 0;106. }107. ssize_t GPIO_VIB_release(struct inode * inode, struct file * file 108. {109. // MOD_DEC_USE_COUNT;//?£?éêy??110. printk("GPIO_VIB_release( \n";111. return 0;112. }113. static int GPIO_VIB_CTL_init(void114. {115. int ret = -ENODEV;116. int error ;117. printk("---------------------------------------------- \r\n"; 118. //3?ê??ˉú119. s3c_gpio_cfgpin(S3C64XX_GPM(1, S3C_GPIO_SFN(1;//GPM1 output 120. s3c_gpio_cfgpin(S3C64XX_GPM(2, S3C_GPIO_SFN(1;//GPM2 output 121. s3c_gpio_cfgpin(S3C64XX_GPM(3, S3C_GPIO_SFN(1;//GPM3 output 122. s3c_gpio_cfgpin(S3C64XX_GPM(4, S3C_GPIO_SFN(1;//GPM4 output 123. #if 1 /*?2ì?·?ê?×¢2á?y?ˉ*/124. ret = register_chrdev(Viberator_MAJOR, "viberator",&GPIO_Viberator_ctl_ops;125. if (ret < 0 {126. printk(KERN_ERR "VIB: unable to get major %d\n", ret;127. return ret;128. }129. //′′?¨\uc1class130. vib_dev_class = class_create(THIS_MODULE, "viberator";131. if (IS_ERR(vib_dev_class {132. unregister_chrdev(Viberator_MAJOR, "capi20";133. return PTR_ERR(vib_dev_class;134. }135. //′′?¨?úμ?£?136. device_create(vib_dev_class, NULL, MKDEV(Viberator_MAJOR, 0, NULL, "vib"; 137. // create a point under /dev/class/vib138. //í¨1yéaá?2?£??y?ˉ?ó??oó£??í?á?ú/dev/class/éú3é\uc1vib?úμ?£?ó|ó?3ìDò?éò2ù×÷tù2ù×÷?aúμ?£?í¨1y\uc1open ,write,read μèoˉêy2ù×÷£??ê?é?éò??′oó??μ?ó|ó?ê?ày3ìDò?£139. return 0;140. #endif141. #if 0/* ×¢2á?ˉì?*/142. if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "vibrate" < 0143. {144. printk(KERN_ERR145. "VIB: Couldn't alloc_chrdev_region, error=%d\n",146. error;147. return 1;148. }149. printk("dev = %d \n",dev;150. cdev_p = cdev_alloc(;151. cdev_p->ops = &GPIO_Viberator_ctl_ops;152. error = cdev_add(cdev_p, dev, DEVCOUNT;153. if (error {154. printk(KERN_ERR155. "VIB: Couldn't cdev_add, error=%d\n", error;156. return 1;157. }158.159. vib_dev_class = class_create(THIS_MODULE, "vib-dev";160. if (IS_ERR(vib_dev_class {161. res = PTR_ERR(vib_dev_class;162. goto out_unreg_class;163. }164. return 0;165. #endif166. out_unreg_class:167. class_destroy(vib_dev_class;168. return 1;169. }170.171. static int __init S3C6410_VIB_init(void172. {173. int ret = -ENODEV;174. //μ÷ó?oˉêy175. printk(KERN_ERR "Auly: S3C6410_VIB_init---\n";176. ret = GPIO_VIB_CTL_init(;177. if(ret178. {179. printk(KERN_ERR "Auly: S3C6410_VIB_init--Fail \n"; 180. return ret;181. }182. return 0;183. }184. static void __exit cleanup_GPIO_VIB(void185. {186. //×¢?úéè±?187. // devfs_unregister_chrdev(Viberator_MAJOR,"gpio_vib_ctl";188. #if 0189. cdev_del(cdev_p;190. unregister_chrdev_region(dev, DEVCOUNT;191. class_destroy(vib_dev_class;192. #endif193. device_destroy(vib_dev_class, MKDEV(Viberator_MAJOR, 0;194. class_destroy(vib_dev_class;195. unregister_chrdev(Viberator_MAJOR, "viberator";196. }197. MODULE_LICENSE("GPL";198. MODULE_DESCRIPTION("Peter first driver";199. MODULE_ALIAS_CHARDEV(Viberator_MAJOR, 0;200.201. module_init(S3C6410_VIB_init;202. module_exit(cleanup_GPIO_VIB;leddriver.h文件1. ssize_t GPIO_VIB_read(struct file * file,char * buf,size_t count,loff_t * f_ops;2. ssize_t GPIO_VIB_write (struct file * file,const char * buf, size_t count,loff_t * f_ops;3. static int GPIO_VIB_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg;4. ssize_t GPIO_VIB_open(struct inode * inode,struct file * file;5. ssize_t GPIO_VIB_release(struct inode * inode, struct file * file;6. static int GPIO_VIB_CTL_init(void;Kconfig 文件1. config LEDTEST2. tristate "LED test for ARMeasy"3. default n4. help5. this is a LED driver for ARMEASY with S3C6410Makefile文件1. obj-$(CONFIG_LEDTEST+=leddriver.o3、在内核配置里菜单里加入本驱动的配置项达到的效果是,可以通过内核配置来选择是否把本驱动编译进内核里,也就是出现在make menuconfig 后出来的界面里,可以参考9.8章<Android添加新驱动方法>1)在arch/arm/Kconfig文件里 menu "Device Drivers"与 endmenu之间添加1. source "drivers/ledtest/Kconfig"2)在drivers/Kconfig menu "Device Drivers" 和 endmenu之间添加1. source "drivers/ledtest/Kconfig"3修改/drivers/Makefile文件1. Obj-$(CONFIG_LEDTEST +=ledtest/4、编译驱动在kernel目录下,终端输入1. #make menuconfig“Device Drivers” 下面会看到“LED test for ARMeasy”,选择它,保存并退出1. #make这样,就会在/drivers/ledtest目录下得到leddrivr.ko文件,它就是驱动目标文件,已级编译进了zImage 里了,只要用这个kernel烧录到开发板,开机就会自动加载本驱动,PS,如果发现如上编译,没有在ledtest目录下生成leddriver.ko文件,也就是本根没有去编译本驱动,那就把ledtest目录入到/drivers/misc目录下,相应的修改misc下面,然后,在makefile里,不用选直接写成obj-y += leddriver.o,这样强制的包含进去编译。

相关主题