天下无伤 发表于 2013-4-11 19:56:24

linux底下ok6410流水灯驱动成功

环境及工具:

 linux-2.6.36内核  硬件平台ok6410   

测试基本流程:

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

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

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

6:创建设备文件   #mknod/dev/gpioc   2520 /*假设主设备号为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 & 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 = 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

censtar 发表于 2013-4-11 20:41:44

真羡慕你现在的心情!

NJ8888 发表于 2013-4-11 20:50:41

请你看看你让IO出个正脉冲的最小宽度多少?
页: [1]
查看完整版本: linux底下ok6410流水灯驱动成功