• 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
    ", led_config_value);
        
        writel(led_config_value, led_config);
        led_config_value = readl(led_config);
        
        printk("led_config_value = 0x%x
    ", 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
    ", led_data_value);
                
                writel(led_data_value, led_data);
                led_data_value = readl(led_data);
                
                printk("led_data_value = 0x%x
    ", led_data_value);
                
                return 0;
            
            case 0:
                led_data_value = led_data_value | (0x0f << 5);
                
                printk("led_data_value = 0x%x
    ", led_data_value);
                
                writel(0xff, led_data);
                led_data_value = readl(led_data);
                
                printk("led_data_value = 0x%x
    ", 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!
    ");
             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)运行测试代码进行测试

  • 相关阅读:
    Start Python 学习笔记(琐碎知识,持续更新。。。)
    电子商务网站数据分析常用指标(转)
    设计模式学习笔记——适配器(Adapter)模式
    Json概述以及python对json的相关操作
    数据层参考资料
    Oracle内存组件与进程的相关知识总结
    面试题_二分查找及其变形
    两路归并的数组和链表实现
    Mysq性能分析 —— Genral log(普通日志)与 Slow log(慢速日式)
    设计模式学习笔记——工厂方法模式
  • 原文地址:https://www.cnblogs.com/wulei0630/p/9499712.html
Copyright © 2020-2023  润新知