本程序採用动态映射的方法控制led。硬件平台为飞凌的ok6410
led.h:定义控制命令
#ifndef _LED_H #define _LED_H #define LED_MAGIC 'M' #define LED_ON _IO(LED_MAGIC, 0) #define LED_OFF _IO(LED_MAGIC, 1) #endif
驱动程序led.c
#include <linux/module.h> #include <linux/init.h> #include <linux/cdev.h> #include <linux/fs.h> #include <asm/uaccess.h> #include <asm/io.h> #include "led.h" #define LEDCON 0x7f008820//与详细平台相关 #define LEDDAT 0x7f008824 unsigned int *led_config; unsigned int *led_data; struct cdev leddev; dev_t devno; static int led_open(struct inode *inode, struct file *filp) { return 0; } static int led_close(struct inode *inode, struct file *filp) { return 0; } static long led_ioctl(struct file* filp, unsigned int cmd, unsigned long arg) { switch (cmd) { case LED_ON: writel(0x00, led_data); break; case LED_OFF: writel(0xff, led_data); break; default: return -EINVAL; } return 0; } struct file_operations ledfops = { .open = led_open, .unlocked_ioctl = led_ioctl, .release = led_close, }; static int led_init(void) { /*注冊字符设备*/ cdev_init(&leddev, &ledfops); alloc_chrdev_region(&devno, 0, 1, "leddev"); cdev_add(&leddev, devno, 1); /*映射配置寄存器*/ led_config = ioremap(LEDCON, 4); /*低四位设置为输出模式,这里暴力简单的解决没做处理*/ writel(0x00001111, led_config); /*映射数据寄存器*/ led_data = ioremap(LEDDAT, 4); printk("led_init "); return 0; } static void led_exit(void) { iounmap(led_config); iounmap(led_data); cdev_del(&leddev); unregister_chrdev_region(devno, 1); printk("led_exit "); } module_init(led_init); module_exit(led_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("liuwei"); MODULE_DESCRIPTION("char driver");
应用程序led_app.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include "led.h" int main(int argc, char *argv[]) { int cmd; if (argc < 2) { printf("Usage:%s <cmd> ", argv[0]); return 0; } cmd = atoi(argv[1]); int fd = open("/dev/leddev", O_RDWR); if (fd == -1) { perror("open"); return -1; } if (cmd == 1) ioctl(fd, LED_ON); else ioctl(fd, LED_OFF); close(fd); return 0; }
编译程序,使用命令mknod /dev/leddev c 252 0创建设备节点,主设备号可通过cat /proc/devices
执行应用程序
./led_app 0 熄灭led
./led_app 1 点亮led