驱动代码
1 /* 2 led驱动 同时开关所有的LED 3 GPF4、5、6控制LED 4 5 寄存器 地址 R/W 描述 复位值 6 GPFCON 0x56000050 R/W 配置端口 F 的引脚 0x0 7 GPFDAT 0x56000054 R/W 端口 F 的数据寄存器 – 8 GPFUP 0x56000058 R/W 端口 F 的上拉使能寄存器 0x00 9 保留 0x5600005C – 保留 – 10 **/ 11 #include <linux/module.h> 12 #include <linux/kernel.h> 13 #include <linux/fs.h> 14 #include <linux/init.h> 15 #include <linux/delay.h> 16 #include <asm/uaccess.h> 17 #include <asm/irq.h> 18 #include <asm/io.h> 19 #include <asm/arch/regs-gpio.h> 20 #include <asm/hardware.h> 21 22 23 volatile unsigned long *gpfcon = NULL; 24 volatile unsigned long *gpfdat = NULL; 25 26 struct class * led_dev1_class; 27 struct class_device * led_dev1_class_device; 28 29 static int led_dev1_open(struct inode *inode, struct file *file) 30 { 31 /* 配置GPF4,5,6为输出 */ 32 *gpfcon &= ~((0x03<<(4*2)) | (0x03<<(5*2)) | (0x03<<(6*2))); 33 *gpfcon |= ((0x01<<(4*2)) | (0x01<<(5*2)) | (0x01<<(6*2))); 34 35 return 0; 36 } 37 38 static ssize_t led_dev1_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos) 39 { 40 int val; 41 42 //从用户空间拷贝数据到内核空间 43 copy_from_user(&val, buf, count); // copy_to_user(); 44 45 if(val == 1) 46 { 47 /* 点灯 低电平 */ 48 *gpfdat &= ~((0x01 << 4)|(0x01 << 5)|(0x01 << 6)); 49 } 50 else 51 { 52 /* 灭灯 高电平*/ 53 *gpfdat |= ((0x01 << 4)|(0x01 << 5)|(0x01 << 6)); 54 } 55 56 return 0; 57 } 58 59 /* 定义一个文件操作的结构体 */ 60 static struct file_operations led_dev1_fops = 61 { 62 .owner = THIS_MODULE, 63 .open = led_dev1_open, 64 .write = led_dev1_write, 65 }; 66 67 68 int major; //存储设备号 69 /* 70 驱动入口函数 71 **/ 72 static int __init led_dev1_init(void) 73 { 74 /* 注册设备 */ 75 major = register_chrdev(0,"led_dev1",&led_dev1_fops); 76 77 //创建一个 struct class 结构体 78 led_dev1_class = class_create(THIS_MODULE,"led_dev1"); 79 //在加载模块是自动创建一个设备节点 80 led_dev1_class_device = class_device_create(led_dev1_class,NULL,MKDEV(major,0),NULL,"led_dev1"); 81 82 //地址映射 83 gpfcon = ioremap(0x56000050,16); 84 gpfdat = gpfcon + 1; 85 86 /**/ 87 return 0; 88 } 89 90 /* 91 驱动出口函数 92 **/ 93 static void __exit led_dev1_exit(void) 94 { 95 /* 卸载设备 */ 96 unregister_chrdev(major,"led_dev1"); 97 //删除设备节点 98 class_device_unregister(led_dev1_class_device); 99 //销毁 struct class 结构体 100 class_destroy(led_dev1_class); 101 //取消地址映射 102 iounmap(gpfcon); 103 104 } 105 106 /* 将函数指定为驱动的入口和出口函数 */ 107 module_init(led_dev1_init); 108 module_exit(led_dev1_exit); 109 /* 模块的许可证声明 */ 110 MODULE_LICENSE("GPL");
测试代码
/* led_dev1 驱动测试函数 */ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> int main(int argc,char **argv) { int fd; int val; fd = open("/dev/led_dev1",O_RDWR); if(fd < 0) { printf("can't open "); } if(argc != 2) { printf("Usage: "); printf("%s <on/off> ",argv[0]); return 0; } if (strcmp(argv[1], "on") == 0) { val = 1; } else { val = 0; } write(fd,&val,4); return 0; }
Makefile
1 KERN_DIR = /work/system/linux-2.6.22.6 2 3 all: 4 make -C $(KERN_DIR) M=`pwd` modules 5 6 clean: 7 make -C $(KERN_DIR) M=`pwd` modules clean 8 rm -rf modules.order 9 obj-m += led_dev1.o