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 真羡慕你现在的心情! 请你看看你让IO出个正脉冲的最小宽度多少?
页:
[1]