效果:流水灯
led_drv.h
1: #ifndef __LED_DRV_H__
2: #define __LED_DRV_H__
3:
4: struct led_cmd
5: {
6: int status;
7: int num;
8: };
9:
10: #define LED_ALL_ON _IOW('L',0,int)
11: #define LED_ALL_OFF _IOW('L',1,int)
12: #define LED_S_ON _IOW('L',2,int)
13: #define LED_S_OFF _IOW('L',3,int)
14:
15:
16: #endif
led_drv.c
1: #include
2: #include
3: #include
4: #include
5: #include
6: #include "led_drv.h"
7:
8: MODULE_LICENSE("GPL");
9: static struct led_dev
10: {
11: struct cdev cdev;
12: void *map_con;
13: void *map_data;
14: dev_t devno;
15:
16: }my_led_dev;
17:
18:
19: static int led_open(struct inode *inode, struct file *file)
20: {
21: printk(KERN_INFO "led opened\n");
22: return 0;
23: }
24:
25: static ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
26: {
27: // LED_CMDP cmd = (LED_CMDP)buf;
28: struct led_cmd *cmd = (struct led_cmd *)buf;
29: if(cmd->status == 0)
30: {
31: writel(readl(my_led_dev.map_data) & (~(0x1<<(cmd->num))), my_led_dev.map_data);
32: }
33: else
34: {
35:
36: writel(readl(my_led_dev.map_data) | (0x1<<(cmd->num)), my_led_dev.map_data);
37: }
38: return 0;
39: }
40: static int led_close (struct inode *inode , struct file *file)
41: {
42: printk(KERN_INFO "led closed\n");
43: return 0;
44: }
45:
46: static int led_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg)
47: {
48: switch (cmd)
49: {
50:
51: case LED_ALL_ON:
52: writel((readl(my_led_dev.map_data) | 0xf), my_led_dev.map_data);
53: break;
54: case LED_ALL_OFF:
55: writel((readl(my_led_dev.map_data) & (~0xf)), my_led_dev.map_data);
56: break;
57: case LED_S_ON:
58: writel((readl(my_led_dev.map_data) | (0x1< 59: break;60: case LED_S_OFF:61: writel((readl(my_led_dev.map_data)) & (~(0x1< 62: break;63: default:64: return -EINVAL;65: }
66:
67: return 0;68: }
69: static struct file_operations led_fops =70: {
71: .owner = THIS_MODULE,
72: .open = led_open,
73: .release = led_close,
74: .write = led_write,
75: .ioctl = led_ioctl
76: };
77:
78:
79: int led_init(void)80: {
81:
82: int ret;83: my_led_dev.devno = MKDEV(250, 0);
84:
85: ret = register_chrdev_region(my_led_dev.devno,1, "pengdonglin");86:
87: if(ret < 0)88: {
89: return ret;90: }
91:
92: cdev_init(&my_led_dev.cdev, &led_fops);
93: my_led_dev.cdev.owner = THIS_MODULE;
94: ret = cdev_add(&my_led_dev.cdev, my_led_dev.devno, 1);
95: if(ret)96: {
97: return ret;98: }
99: /*100: my_led_dev.map_con = ioremap(0xe03001c0, 4);101: my_led_dev.map_data = ioremap(0xe03001c4, 4);102: */103: my_led_dev.map_con = ioremap(0xe03001c0, 8);
104: my_led_dev.map_data = my_led_dev.map_con + 4 ;
105:
106: writel((readl(my_led_dev.map_con) & (~0xffff)) | 0x1111, my_led_dev.map_con);
107: writel((readl(my_led_dev.map_data) & (~0xf))|0xf, my_led_dev.map_data);
108:
109: printk(KERN_INFO "init led\n");110:
111: return 0;112: }
113:
114: void led_exit(void)115: {
116: iounmap(my_led_dev.map_data);
117: iounmap(my_led_dev.map_con);
118: cdev_del(&my_led_dev.cdev);
119: unregister_chrdev_region(my_led_dev.devno,1);
120: printk(KERN_INFO "led exit\n");121: }
122:
123: module_init(led_init);
124: module_exit(led_exit);
Makefile
1: $(warning KERNELRELEASE=$(KERNELRELEASE))
2: ifeq ($(KERNELRELEASE),)
3:
4: KERNELDIR ?= /home/linux/arm/linux-2.6.35/
5:
6: #KERNELDIR ?= /lib/modules/$(shell uname -r)/build
7: PWD := $(shell pwd)
8:
9: modules:
10: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
11:
12: modules_install:
13: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
14:
15: clean:
16: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules*
17:
18: .PHONY: modules modules_install clean
19:
20: else
21: obj-m := led_drv.o
22: endif
23:
led_test.c
1: #include
2: #include
3: #include
4: #include
5: #include
6: #include
7: #include "led_drv.h"
8:
9: int main(void)
10: {
11: int fd;
12: int num = 0;
13: struct led_cmd led = {
14: 1,0
15: };
16:
17: printf("start!\n");
18:
19: if((fd = open("/dev/led", O_RDWR)) < 0)
20: {
21: perror("open error\n");
22: exit(-1);
23: }
24: write(fd, &led, 1);
25: sleep(1);
26:
27: ioctl(fd, LED_ALL_ON,0);
28:
29: sleep(1);
30: ioctl(fd, LED_ALL_OFF,0);
31:
32: while(1)
33: {
34: usleep(50000);
35: ioctl(fd, LED_S_ON,num);
36: usleep(50000);
37: ioctl(fd, LED_S_OFF,num);
38: num = (++num) % 4;
39: }
40:
41: close(fd);
42: return 0;
43: }