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<343556608@qq.com>");  
  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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM