Am335x 下GPIO控制实例-驱动程序(转)

Posted xihong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Am335x 下GPIO控制实例-驱动程序(转)相关的知识,希望对你有一定的参考价值。

看了这么多的资料,现在决定上手了,下面将用两种方式来实现对GPIO 117的控制
1,用直接添加到内核的方式,实现MISC的驱动(misc_register)
2,用手工安装的方式,实现简单字符设备驱动(register_chrdev)

实现前提:当前所用的GPIO没有被其它设备所使用,大家可以用我前面BLOG说的方式查看GPIO的使用情况,当前我所用的GPIO本来是bluetooth的开关,需要屏蔽一个函数。不然后面的驱动申请IO都会失败。
函数为Board-am335xevm.c 中的wl12xx_bluetooth_enable();

一,MISC驱动的实现
1,参考linux SDK for AM335x Ver 1.1.pdf P28,添加kernel 配置选项
  打开/driver/input/misc/Kconfig并添加:

[objc] view plain copy
 
  1. config INPUT_GPIOTEST  
  2. bool "Gpio 117 test"  
  3. help  
  4. Just test the Gpio 117 status  



  打开/driver/input/misc/Makefile并添加:
  

[plain] view plain copy
 
  1. obj-$(CONFIG_INPUT_GPIOTEST)+=GpioTestDriver.o  


2,实现GpioTestDriver.c

[objc] view plain copy
 
  1. #include <linux/gpio.h>  
  2. #include <linux/module.h>  
  3. #include <linux/kernel.h>  
  4. #include <linux/moduleparam.h>  
  5. #include <linux/delay.h>  
  6. #include <linux/types.h>  
  7. #include <linux/miscdevice.h>  
  8. #include <linux/device.h>  
  9. #include <linux/fs.h>  
  10. #include <linux/init.h>  
  11.   
  12. #define TEST_IO_NUM(117)  
  13. #define NAME_MISC"GpioTest"  
  14. #define NAME_MOUDULE"GpioTest1"  
  15. #define USE_MISC_MODE1  
  16. static int major = 251;  
  17.   
  18. void GpioTest(void);  
  19.   
  20. static long GpioIOctl(struct file *filp, unsigned cmd, unsigned long arg)  
  21. {  
  22. GpioTest();  
  23. return 1;  
  24. }  
  25.   
  26. void GpioTest(void)  
  27. {  
  28. int iCount = 0;  
  29.   
  30. for(iCount = 0; iCount <=20; iCount++ )  
  31. {  
  32. if(iCount%2 == 0)  
  33. {  
  34. gpio_direction_output(TEST_IO_NUM, 1);  
  35. printk(KERN_INFO"#######IO117 statu is high.\r\n");  
  36. }  
  37. else  
  38. {  
  39. gpio_direction_output(TEST_IO_NUM, 0);  
  40. printk(KERN_INFO"#######IO117 statu is low.\r\n");  
  41. }  
  42. mdelay(3000);  
  43. }  
  44. printk(KERN_INFO"#######App run over!");  
  45. }  
  46.   
  47.   
  48.   
  49. static int GpioOpen(struct inode *inode, struct file *file)  
  50. {  
  51. int iRen = -1;  
  52. iRen = gpio_request(TEST_IO_NUM, "IO117");  
  53. if(iRen < 0)  
  54. {   
  55. printk(KERN_INFO"#######Failed to request the IO117!");  
  56. }else  
  57. {  
  58. printk(KERN_INFO"#######Success to request the IO117");  
  59. }  
  60. return iRen;  
  61. }  
  62.   
  63. static int GpioClose(struct inode *inode, struct file *file)  
  64. {  
  65. printk(KERN_INFO"#######Free the IO117");  
  66. gpio_free(TEST_IO_NUM);  
  67. return 1;  
  68. }  
  69.   
  70. //****entry point for TEST GPIO module  
  71. static const struct file_operations gpio_test_driver = {  
  72. .owner = THIS_MODULE,  
  73. .unlocked_ioctl= GpioIOctl,  
  74. .llseek = no_llseek,  
  75. .open = GpioOpen,  
  76. .release = GpioClose,   
  77. };  
  78.   
  79. #if USE_MISC_MODE  
  80. static struct miscdevice gpiotest_misc_device = {  
  81. .minor    = MISC_DYNAMIC_MINOR,  
  82. .name     = NAME_MISC,  
  83. .fops     = &gpio_test_driver,  
  84. };  
  85. #endif  
  86.   
  87. static int __init GpioTestInit(void)  
  88. {  
  89. int iRet;  
  90. printk(KERN_INFO"#######GpioTest modules is install!\r\n");  
  91. #if USE_MISC_MODE  
  92. iRet = misc_register(&gpiotest_misc_device);  
  93. if (iRet) {  
  94. printk(KERN_INFO"#######unable to register a misc device\r\n");  
  95. return iRet;  
  96. }  
  97. #else  
  98. iRet = register_chrdev(major, NAME_MOUDULE, &gpio_test_driver);  
  99. if (iRet < 0) {  
  100. printk(KERN_INFO"#######unable to register a chr device\r\n");  
  101. return iRet;  
  102. }  
  103. #endif  
  104.   
  105. return iRet;  
  106. }  
  107.   
  108. static void __exit GpioTestExit(void)  
  109. {  
  110. #if USE_MISC_MODE  
  111. misc_deregister(&gpiotest_misc_device);  
  112. #else  
  113. unregister_chrdev(major, NAME_MOUDULE);  
  114. #endif  
  115. printk(KERN_INFO"#######GpioTest modules is exit!\r\n");  
  116. }  
  117.   
  118. module_init(GpioTestInit);  
  119. module_exit(GpioTestExit);  
  120. MODULE_AUTHOR("david.hu<[email protected]>");  
  121. MODULE_LICENSE("GPL");  
  122. MODULE_DESCRIPTION("Gpio117 Test driver");  



3,直接编译:
make uImage
拷到小板上升级运行
注意启动的过程有打印:
[    3.730712] #######GpioTest modules is install!
这里表示我们的驱动已经合入NK里去了,当然我们也可以命令:ls /dev,可以看到有GpioTest这个存在
4,写测试APP

[objc] view plain copy
 
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <sys/ioctl.h>  
  4. #include <unistd.h>  
  5. #include <sys/stat.h>  
  6. #include <linux/input.h>  
  7. #include <fcntl.h>  
  8.   
  9. int main(int argc, charchar *argv)  
  10. {  
  11. int fd;  
  12.   
  13. fd = open("/dev/GpioTest", O_RDWR);  
  14. if(fd < 0)  
  15. {  
  16. printf("***Can‘t open the gpiotest!\r\n");  
  17. return -1;  
  18. }   
  19. ioctl(fd, 0, 0);  
  20. close(fd);  
  21. printf("***App run over!\r\n");  
  22.   
  23. return 1;  
  24. }  



将编译的.out文件拷到小机上面运行,看是不是会打印正确的结果。

二,字符设备驱动的实现
1,代码的实现,请将上面MISC的代码里#define USE_MISC_MODE1改成0
2,makefile的实现

[plain] view plain copy
 
  1. KERNEL_DIR := /home/ding/workdir/david/EVMBoard/board-support/linux-3.2  
  2.   
  3. PLATFORM := "am335x-evm"  
  4. MACHINE_NAME := "am335x"  
  5.   
  6. # If CROSS_COMPILE is not set by Rules.make then set a sane default  
  7. CROSS_COMPILE ?= arm-arago-linux-gnueabi-  
  8. export CROSS_COMPILE  
  9.   
  10. obj-m := GpioTestDriver.o  
  11.   
  12. MAKE_ENV = ARCH=arm  
  13.   
  14. PWD := $(shell pwd)  
  15. all:  
  16. $(MAKE) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" -C $(KERNEL_DIR) $(MAKE_ENV) \  
  17.    M=$(PWD) modules  
  18.   
  19. clean:  
  20. rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers  


3,将编译的ko拷入小机,然后命令:

[plain] view plain copy
 
  1. insmod ./GpioTestDriver.ko  
  2. lsmod  
  3. mknod /dev/GpioTestDriver c 251 0  



4,实现APP的代码
将上面MISC的代码作如下修改:

[plain] view plain copy
 
  1. fd = open("/dev/GpioTestDriver", O_RDWR);  


5,运行APP查看结果



总结:两个驱动代码实现差不多,但是步骤不一样,主要体现在模块需要安装。MISC会自动创建设备文件,它的主设备号是10,字符设备需要我们来指定。
可安装的字符设备对驱动的编写测试是非常有帮助的。

http://blog.csdn.net/hudaweikevin/article/details/16826995

以上是关于Am335x 下GPIO控制实例-驱动程序(转)的主要内容,如果未能解决你的问题,请参考以下文章

AM335X开发板外扩GPIO资源如何使用?

AM335x移植linux内核_转

am335x Lan8710a 双网口配置

记录 am335x 因为 pinmux 配置不对导致 不断的原因

am335x内核初始化路径

am335x uboot2016.05 (MLO u-boot.img)执行流程(转)