• 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

  • 相关阅读:
    第三十一章 线程------GIL、线/近程池、异/同步、异步回调
    第三十章 网路编程------线程
    第二十八章 网络编程------Socket
    第二十七章 网络编程
    第二十六章 oop中元类、异常处理
    第二十五章 面向对象------封装、内置函数、反射、动态导入
    第二十四章 面向对象------属性
    Document 对象
    正值表达式
    BOM和DOM
  • 原文地址:https://www.cnblogs.com/xihong2014/p/7003694.html
Copyright © 2020-2023  润新知