linux环境下LED驱动编程一例
效果:流水灯
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 <linux/module.h> 2: #include <linux/kernel.h> 3: #include <linux/fs.h> 4: #include <linux/cdev.h> 5: #include <asm/io.h>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<<arg)), my_led_dev.map_data); 59: break;
60: case LED_S_OFF:
61: writel((readl(my_led_dev.map_data)) & (~(0x1<<arg)), my_led_dev.map_data); 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 <stdio.h> 2: #include <sys/types.h> 3: #include <sys/stat.h> 4: #include <fcntl.h> 5: #include <stdlib.h> 6: #include <sys/ioctl.h>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: }
本文来自博客园,作者:dolinux,未经同意,禁止转载

浙公网安备 33010602011771号