zoukankan      html  css  js  c++  java
  • 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. ");  
    36. }  
    37. else  
    38. {  
    39. gpio_direction_output(TEST_IO_NUM, 0);  
    40. printk(KERN_INFO"#######IO117 statu is low. ");  
    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! ");  
    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 ");  
    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 ");  
    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! ");  
    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! ");  
    17. return -1;  
    18. }   
    19. ioctl(fd, 0, 0);  
    20. close(fd);  
    21. printf("***App run over! ");  
    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

  • 相关阅读:
    Android Gradle Plugin指南(五)——Build Variants(构建变种版本号)
    文件内容操作篇clearerr fclose fdopen feof fflush fgetc fgets fileno fopen fputc fputs fread freopen fseek ftell fwrite getc getchar gets
    文件操作篇 close creat dup dup2 fcntl flock fsync lseek mkstemp open read sync write
    嵌入式linux应用程序调试方法
    version control system:git/hg/subversion/cvs/clearcase/vss。software configruation management。代码集成CI:Cruisecontrol/hudson/buildbot
    最值得你所关注的10个C语言开源项目
    如何记录linux终端下的操作日志
    CentOS 5.5 虚拟机安装 VirtualBox 客户端增强功能
    sizeof, strlen区别
    C/C++嵌入式开发面试题
  • 原文地址:https://www.cnblogs.com/xihong2014/p/7003694.html
Copyright © 2011-2022 走看看