字符设备驱动-利用次设备号实现多路LED控制
驱动源码: int minor = MINOR(inode->i_rdev); //MINOR(inode->i_cdev); switch(minor) { case 0: { // 配置3引脚为输出 //s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP); *gpfcon &= ~(0x3<<(4*2)); *gpfcon |= (1<<(4*2)); //s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP); *gpfcon &= ~(0x3<<(5*2)); *gpfcon |= (1<<(5*2)); //s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP); *gpfcon &= ~(0x3<<(6*2)); *gpfcon |= (1<<(6*2)); // 都输出0 //s3c2410_gpio_setpin(S3C2410_GPF4, 0); *gpfdat &= ~(1<<4); //s3c2410_gpio_setpin(S3C2410_GPF5, 0); *gpfdat &= ~(1<<5); //s3c2410_gpio_setpin(S3C2410_GPF6, 0); *gpfdat &= ~(1<<6); break; } case 1: { s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP); s3c2410_gpio_setpin(S3C2410_GPF4, 0); break; } case 2: { s3c2410_gpio_cfgpin(S3C2410_GPF5, S3C2410_GPF5_OUTP); s3c2410_gpio_setpin(S3C2410_GPF5, 0); break; } case 3: { s3c2410_gpio_cfgpin(S3C2410_GPF6, S3C2410_GPF6_OUTP); s3c2410_gpio_setpin(S3C2410_GPF6, 0); break; } } return 0; char val; int minor = MINOR(file->f_dentry->d_inode->i_rdev); copy_from_user(&val, buf, 1); switch (minor) { case 0: { s3c2410_gpio_setpin(S3C2410_GPF4, (val & 0x1)); s3c2410_gpio_setpin(S3C2410_GPF5, (val & 0x1)); s3c2410_gpio_setpin(S3C2410_GPF6, (val & 0x1)); break; } case 1: { s3c2410_gpio_setpin(S3C2410_GPF4, val); break; } case 2: { s3c2410_gpio_setpin(S3C2410_GPF5, val); break; } case 3: { s3c2410_gpio_setpin(S3C2410_GPF6, val); break; } } return 0; .owner = THIS_MODULE, .open = led_drv_open, .write = led_drv_write, major = register_chrdev(0, "led_drv", &led_drv_fops); // 注册字符驱动, 告诉内核 leddrv_class = class_create(THIS_MODULE, "leddrv"); //创建设备节点 leddrv_class_devs[0] = class_device_create(leddrv_class, NULL, MKDEV(major, 0), NULL, "leddrv"); for (minor = 1; minor < 4; minor++) { leddrv_class_devs[minor] = class_device_create(leddrv_class, NULL, MKDEV(major, minor), NULL, "leddrv%d", minor); if (unlikely(IS_ERR(leddrv_class_devs[minor]))) return PTR_ERR(leddrv_class_devs[minor]); } gpfcon = (volatile unsigned long *)ioremap(0x56000050, 16); gpfdat = gpfcon + 1; return 0; unregister_chrdev(major, "led_drv"); // 卸载 for (minor = 0; minor < 4; minor++) { class_device_unregister(leddrv_class_devs[minor]); } class_destroy(leddrv_class); iounmap(gpfcon); printf("Usage:n"); printf("%s n",file); printf("eg. n"); printf("%s /dev/leds onn", file); printf("%s /dev/leds offn", file); printf("%s /dev/led1 onn", file); printf("%s /dev/led1 offn", file); int fd; char* filename; char val; if (argc != 3) { print_usage(argv[0]); return 0; } filename = argv[1]; fd = open(filename, O_RDWR); if (fd < 0) { printf("error, cant open %sn", filename); return 0; } if (!strcmp("on", argv[2])) { // 亮灯 val = 0; write(fd, &val, 1); } else if (!strcmp("off", argv[2])) { // 灭灯 val = 1; write(fd, &val, 1); } else { print_usage(argv[0]); return 0; } ls -l /dev/leddrv ls -l /dev/leddrv1 ./leddrvTest /dev/leddrv on ./leddrvTest /dev/leddrv off ./leddrvTest /dev/leddrv1 on ./leddrvTest /dev/leddrv2 on ./leddrvTest /dev/leddrv2 off ./leddrvTest /dev/leddrv3 on ./leddrvTest /dev/leddrv3 off
#include
.
.
#include
int major;
int minor = 0;
static struct class *leddrv_class;
static struct class_device *leddrv_class_devs[4];
volatile unsigned long *gpfcon = NULL;
volatile unsigned long *gpfdat = NULL;
static int led_drv_open(struct inode *inode, struct file *file)
{
}
static ssize_t led_drv_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
}
static struct file_operations led_drv_fops = {
};
static int led_drv_init(void)
{
}
static void led_drv_exit(void)
{
}
module_init(led_drv_init);
module_exit(led_drv_exit);
MODULE_LICENSE("GPL");
==================================================================================================
测试程序:
#include
#include
#include
#include
void print_usage(char *file)
{
}
int main(int argc, char **argv)
{
}
=================================================================================================
实验:
运行程序时输入不同的/dev/leddrv、/dev/leddrv1、/dev/leddrv2、/dev/leddrv3得到的次设备号不同,驱动程序中根据不同的次设备号控制不同的灯,输入不同的on、off命令write时写入的值不同,根据不同的值执行开关动作。
关键词: 字符设次设备号LED控

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW
或用微信扫描左侧二维码