Linux字符设备驱动--Led设备驱动
①驱动源码
#include <linux/module.h> #include <linux/init.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/io.h> #define LEDCON 0x56000010 #define LEDDAT 0x56000014 unsigned int *led_config; unsigned int *led_data; struct cdev cdev; dev_t devno; int led_open(struct inode *node, struct file *filp) { unsigned int led_config_value = 0; led_config = ioremap(LEDCON, 4); led_data = ioremap(LEDDAT, 4); led_config_value = readl(led_config); led_config_value = led_config_value & (~(0xffff << 10)); led_config_value = led_config_value | (0x5555 << 10); printk("led_config_value = 0x%x\n", led_config_value); writel(led_config_value, led_config); led_config_value = readl(led_config); printk("led_config_value = 0x%x\n", led_config_value); return 0; } long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned int led_data_value = readl(led_data); switch (cmd) { case 1: led_data_value = led_data_value & (~(0x0f << 5)); printk("led_data_value = 0x%x\n", led_data_value); writel(led_data_value, led_data); led_data_value = readl(led_data); printk("led_data_value = 0x%x\n", led_data_value); return 0; case 0: led_data_value = led_data_value | (0x0f << 5); printk("led_data_value = 0x%x\n", led_data_value); writel(0xff, led_data); led_data_value = readl(led_data); printk("led_data_value = 0x%x\n", led_data_value); return 0; default: return -EINVAL; } } static struct file_operations led_fops = { .open = led_open, .unlocked_ioctl = led_ioctl, }; static int led_init(void) { cdev_init(&cdev, &led_fops); alloc_chrdev_region(&devno, 0 , 1 , "myled"); cdev_add(&cdev, devno, 1); return 0; } static void led_exit(void) { cdev_del(&cdev); unregister_chrdev_region(devno,1); } MODULE_LICENSE("GPL"); module_init(led_init); module_exit(led_exit);
② Makefile
obj-m := Led.o KDIR := /home/Linux/Kernal/linux-2.6.29 all: make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order
③ 应用层测试代码
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> int main(int argc, char *argv[]) { int fd; int cmd; if (argc < 2) { printf("please enter the second para!\n"); return 0; } cmd = atoi(argv[1]); fd = open("/dev/led", O_RDWR); if (cmd == 1) ioctl(fd, 1); else ioctl(fd, 0); return 0; }
④ 测试步骤
(1)安装驱动模块:Led.ko
(2)查看主设备号:cat /proc/devices(查找led对应的主设备号)
(3)创建设备文件:mknod /dev/led c 主设备号 0
(4)运行测试代码进行测试