搜索
bottom↓
回复: 2

linux底下ok6410流水灯驱动成功

[复制链接]

出0入0汤圆

发表于 2013-4-11 19:56:24 | 显示全部楼层 |阅读模式
环境及工具:

 linux-2.6.36内核  硬件平台ok6410   

测试基本流程:

  PC与OK6410通过NFS文件系统成功连接后,编译驱动和gpio_test程序即可测试

  1://建立NFS件系统,让板子能和PC机建立通信。
  2:#make     //编译驱动程序
  3:#arm-linux-gcc  gpio_test.c  -o  gpio_test   //生成可执行代码
  4:将测试程序的工程文件拷贝到的是nfs下的文件系统中的/home/yufeng/nfs
  5:板子连接好NFS文件系统,并打开PC机下的串口终端, 启动后加载驱动模块   

              #insmod gpio_drv.ko  /*加载gpio驱动*/

  6:创建设备文件   #mknod  /dev/gpio  c   252  0 /*假设主设备号为252,创建设备文件节点*/
  7:测试  ./gpio_test

相关代码:

  1
  2 /* gpio_drv.h */
  3
  4 #ifndef         FS6410_GPIO_SET_H
  5 #define         FS6410_GPIO_SET_H
  6
  7 #include        <linux/ioctl.h>
  8 #define         GPIO_DEVICE_NAME                "gpio"
  9 #define         GPIO_DEVICE_FILENAME            "/dev/gpio"
10 #define         LED_NUM                                 4
11 #define         GPIO_IOCTL_MAGIC                'G'
12 #define         LED_D09_SWT                     _IOW(GPIO_IOCTL_MAGIC, 0, un    signed int)
13 #define         LED_D10_SWT                     _IOW(GPIO_IOCTL_MAGIC, 1, un    signed int)
14 #define         LED_D11_SWT                     _IOW(GPIO_IOCTL_MAGIC, 2, un    signed int)
15 #define         LED_D12_SWT                     _IOW(GPIO_IOCTL_MAGIC, 3, un    signed int)
16 #define         BEEP_SWT                        _IOW(GPIO_IOCTL_MAGIC, 4, un    signed int)
17 #define         LED_SWT_ON                      0
18 #define         LED_SWT_OFF                     1
19 #define         BEEP_SWT_ON                     1
20 #define         BEEP_SWT_OFF                    0
21
22 #endif /* FS6410_GPIO_SET_H */



1 /**********************************************************************
  2      * 文件名称 :   led_drive.c
  3      * 简介       :   OK6410 LED驱动
  4      * 说明       :   OK6410 开发板(S3C6410)LED(GPIO)驱动
  5 *******************************************************************/
  6      
  7     //系统头文件
  8     #include <linux/miscdevice.h>
  9     #include <linux/delay.h>
10     #include <asm/irq.h>
11     #include <mach/hardware.h>
12     #include <linux/kernel.h>
13     #include <linux/module.h>
14     #include <linux/init.h>  
15     #include <linux/mm.h>   
16     #include <linux/fs.h>   
17     #include <linux/types.h>
18     #include <linux/delay.h>
19     #include <linux/moduleparam.h>
20     #include <linux/slab.h>
21     #include <linux/errno.h>
22     #include <linux/ioctl.h>
23     #include <linux/cdev.h>
24     #include <linux/string.h>
25     #include <linux/list.h>
26     #include <linux/pci.h>
27     #include <asm/uaccess.h>
28     #include <asm/atomic.h>
29     #include <asm/unistd.h>
30     //--------------------------//
31     #include <mach/map.h>
32     #include <mach/regs-clock.h>
33     #include <mach/regs-gpio.h>
34     //--------------------------//
35     #include <plat/gpio-cfg.h>
36     #include <mach/gpio-bank-e.h>
37     #include <mach/gpio-bank-m.h>
38
39
40     ///////////////////////////////////////////////
41     //驱动模块名称
42     #define DEVICE_NAME "OK6410_LED"
43
44     //函数声明
45     ///////////////////////////////////////////////
46     static long OK6410_LED_ioctl(
47             struct file *file,
48             unsigned int cmd,
49             unsigned long arg);
50     static ssize_t OK6410_LED_write(
51             struct file *file,
52             const char __user *buff,
53             size_t size,
54             loff_t *loff);
55     static ssize_t OK6410_LED_read(
56             struct file *file,
57             char __user *buff,
58             size_t size,
59             loff_t *loff);
60     ///////////////////////////////////////////////////
61
62
63     /*  这个结构是字符设备驱动的核心
64     *   当应用程序操作设备文件所提供的open,read,write等函数,
65     *   最终会调用到这个结构中的对应函数
66     */
67     static struct file_operations dev_fops = {
68             .owner              = THIS_MODULE,      //这是一个宏,指向编译模
    块时自动创建的__this_module变量
69             .unlocked_ioctl     = OK6410_LED_ioctl,
70             .read               = OK6410_LED_read,
71             .write              = OK6410_LED_write
72     };
73
74     //注册驱动所使用的相关信息
75     static struct miscdevice misc = {
76             .minor = MISC_DYNAMIC_MINOR,
77             .name = DEVICE_NAME,                        //驱动模块名称
78             .fops = &dev_fops,
79     };
80
81     //LED设备访问信号量
82     struct semaphore led_sem;
83
84
85     /***********************************************************************    *****************************************
86     *函数名        :   static int  __init OK6410_LED_init(void)
87     *功能       : LED模块初始化函数
88     *参数       : 无
89     *返回       : 0:成功;<0:失败
90     *依赖       :     linux底层宏定义
91     *作者       : 异灵元(cp1300@139.com
92     *创建时间   :   2012/08/27 17:28
93     *最后修改时间:    2012/08/27 17:28
94     *说明     :   初始化LED硬件,注册LED驱动
95     ************************************************************************    ****************************************/
96     static int  __init OK6410_LED_init(void)
97     {
98         int ret;
99         unsigned int reg;
100
101         //GPIOM0-3 推挽输出
102         reg = readl(S3C64XX_GPMCON);    //获取GPIOM寄存器数据
103         reg &= (~0xffff);                   //清除之前设置
104         reg |= 0x1111;                  //推挽输出
105         writel(reg,S3C64XX_GPMCON);     //配置IO模式
106         reg = readl(S3C64XX_GPMDAT);    //读取输出寄存器之前数据
107         reg |= 0xf;
108         writel(reg,S3C64XX_GPMDAT);     //写入1,让所有的灯都熄灭
109
110         ret = misc_register(&misc);     //注册驱动
111         if(ret < 0)
112         {
113             printk(DEVICE_NAME " can't initialized LED!\n");
114             return ret;
115         }
116         init_MUTEX(&led_sem);           //注册信号量
117         printk(DEVICE_NAME " initialized\n");
118         return 0;   

119     }
120
121
122     /***********************************************************************    *****************************************
123     *函数名        :   static long OK6410_LED_ioctl(
124                             struct file *file,
125                             unsigned int cmd,
126                             unsigned long arg)
127     *功能       : 发送命令给LED驱动模块,无实际作用,直接返回0
128     *参数       : 无作用
129     *返回       : 0
130     *依赖       :     无
131     *作者       : 异灵元(cp1300@139.com
132     *创建时间   :   2012/08/27 17:28
133     *最后修改时间:    2012/08/27 17:28
134     *说明     :   无
135     ************************************************************************    ****************************************/
136     static long OK6410_LED_ioctl(
137             struct file *file,
138             unsigned int cmd,
139             unsigned long arg)
140     {
141         return 0;
142     }
143
144
145     /***********************************************************************    *****************************************
146     *函数名        :   static ssize_t OK6410_LED_write(
147                             struct file *file,
148                             const char __user *buff,
149                             size_t size,
150                             loff_t *loff)
151     *功能       : 写数据到LED驱动模块,低电平灯亮
152     *参数       : file:文件指针(无作用);buff:数据缓冲区指针;buff:数据
    数量;loff:无作用
153     *返回       : 0:成功;<0:失败
154     *依赖       :     linux底层宏
155     *作者       : 异灵元(cp1300@139.com
156     *创建时间   :   2012/08/27 17:43
157     *最后修改时间:    2012/08/27 17:43
158     *说明     :   点灯函数,低电平亮,0-3BIT有效;对应4个LED
159     ************************************************************************    ****************************************/
160     static ssize_t OK6410_LED_write(
161             struct file *file,
162             const char __user *buff,
163             size_t size,
164             loff_t *loff)
165     {
166         unsigned int reg;
167
168         if(down_interruptible(&led_sem))    //获取信号量
169             return -ERESTARTSYS;
170         reg = readl(S3C64XX_GPMDAT);
171         reg &= (~0xf);
172         reg |= buff[0] & 0xf;
173         writel(reg,S3C64XX_GPMDAT);
174         up(&led_sem);                           //释放信号量
175
176         return 0;
177     }
178
179
180     /***********************************************************************    *****************************************
181     *函数名        :   static ssize_t OK6410_LED_read(
182                             struct file *file,
183                             char __user *buff,
184                             size_t size,
185                             loff_t *loff)
186     *功能       : 读LED状态,低电平灯亮
187     *参数       : file:文件指针(无作用);buff:数据缓冲区指针;buff:数据
    数量;loff:无作用
188     *返回       : 0:成功;<0:失败
189     *依赖       :     linux底层宏
190     *作者       : 异灵元(cp1300@139.com
191     *创建时间   :   2012/08/27 17:48
192     *最后修改时间:    2012/08/27 17:48
193     *说明     :   读取灯的状态,低电平灯亮,0-3bit有效;对应4个LED
194     ************************************************************************    ****************************************/
195     static ssize_t OK6410_LED_read(
196             struct file *file,
197             char __user *buff,
198             size_t size,
199             loff_t *loff)
200     {
201         unsigned int reg;
202
203         if(down_interruptible(&led_sem))    //获取信号量
204             return -ERESTARTSYS;
205         reg = readl(S3C64XX_GPMDAT);
206         buff[0] = reg | 0xfffffff0;
207         up(&led_sem);                           //释放信号量
208
209         return 0;
210     }
211
212
213
214     /***********************************************************************    *****************************************
215     *函数名        :   static void __exit OK6410_LED_exit(void)
216     *功能       : 卸载LED驱动
217     *参数       : 无
218     *返回       : 无
219     *依赖       :     linux底层宏
220     *作者       : 异灵元(cp1300@139.com
221     *创建时间   :   2012/08/27 17:50
222     *最后修改时间:    2012/08/27 17:50
223     *说明     :   卸载驱动
224     ************************************************************************    ****************************************/
225     static void __exit OK6410_LED_exit(void)
226     {
227         unsigned int reg;
228
229         //GPIOM0-3 输入
230         reg = readl(S3C64XX_GPMCON);    //获取GPIOM寄存器数据
231         reg &= (~0xffff);                   //清除之前设置
232         writel(reg,S3C64XX_GPMCON);     //配置IO模式
233         misc_deregister(&misc);         //卸载驱动
234     }
235
236
237
238     //动态加载驱动接口(必须)
239     module_init(OK6410_LED_init);
240     module_exit(OK6410_LED_exit);
241     //其它信息(非必需)
242     MODULE_AUTHOR("cp1300@139.com");                        //驱动程序作者
243     MODULE_DESCRIPTION("OK6410(S3C6410) LED Driver");   //一些描述信息
244     MODULE_LICENSE("GPL");  //遵循的协议
245
246
247




  1 /****************************************************
  2      * 文件名称 :   led_teset.c
  3      * 简介       :   OK6410 LED驱动测试程序
  4      * 说明       :   OK6410 开发板(S3C6410)LED(GPIO)驱动测试程序
  5 *****************************************************/
  6
  7
  8 #include <stdio.h>
  9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <sys/ioctl.h>
13 #include <unistd.h>
14
15
16
17 int main(void)
18 {
19         int fd;
20         int retval;
21         unsigned char led;
22
23         //LED测试
24         printf("LED test...\n");
25         fd = open("/dev/OK6410_LED",O_RDWR);        //open led
26         if(fd == -1)
27         {
28             printf("open led error!\n");
29             exit(-1);
30         }
31         else
32         {
33             printf("open led ok!\n");
34         }
35         while(1)
36         {
37             for(retval = 0;retval < 4;retval ++)
38             {
39                 led = 1 << retval;
40                 led = ~led;
41                 write(fd,&led,sizeof((unsigned char)1));
42                 //read(fd,&led,sizeof((unsigned char)1));
43                 //printf("LED = 0x%X\n",led);
44                 usleep(1000 * 100); //100MS
45             }
46
47             for(retval = 2;retval > 0;retval --)
48             {
49                 led = 1 << retval;
50                 led = ~led;
51                 write(fd,&led,sizeof((unsigned char)1));
52                 //read(fd,&led,sizeof((unsigned char)1));
53                 //printf("LED = 0x%X\n",led);
54                 usleep(1000 * 100); //100MS
55             }
56
57         }
58         close(fd);
59         exit(0);
60 }


/*********Makefile*******/
1 ifeq ($(KERNELRELEASE),)
  2
  3 KERNELDIR ?= /home/yufeng/nfs/ok6410/linux-2.6.36.2-v1.05
  4
  5 PWD := $(shell pwd)
  6
  7 modules:
  8         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  9
10 modules_install:
11         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
12
13 clean:
14         rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
15
16 .PHONY: modules modules_install clean
17
18 else
19     obj-m := gpio_drv.o
20 endif
21

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。

出0入0汤圆

发表于 2013-4-11 20:41:44 | 显示全部楼层
真羡慕你现在的心情!

出0入0汤圆

发表于 2013-4-11 20:50:41 | 显示全部楼层
请你看看你让IO出个正脉冲的最小宽度多少?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-9-27 07:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表