• 代码示例_数据传递



    //头文件
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/fs.h>
    #include <linux/device.h>
    #include <linux/slab.h>
    
    #include <asm/io.h>
    #include <asm/uaccess.h>
    
    
    //面向对象编程----设计设备的类型
    struct s5pv210_led{
        unsigned int major;
        struct class * cls;
        struct device * dev;
        int data;
    };
    struct s5pv210_led *led_dev;
    
    volatile unsigned long *gpco_conf;
    volatile unsigned long *gpco_data;
    
    
    //实现设备操作接口
    int led_open(struct inode *inode, struct file *filp)
    {
    
        printk("--------^_^ %s------------
    ",__FUNCTION__);
        //将对应的管脚设置为输出
        *gpco_conf &= ~(0xff<<12);   //19--12清0
        *gpco_conf |= 0x11<<12;        //19---12赋值:00010001
    
        return 0;
    }
    ssize_t led_write(struct file *filp, const char __user *buf, size_t size, loff_t *flags)
    {
        int ret;
        printk("--------^_^ %s------------
    ",__FUNCTION__);
    
        //应用空间数据转换为内核空间数据
        ret = copy_from_user(&led_dev->data,buf,size);
        if(ret != 0){
            printk("copy_from_user error!
    ");
            return -EFAULT;
        }
    
        if(led_dev->data){
            //点灯
            *gpco_data |= 0x3<<3;
        }else{
            //灭灯
            *gpco_data &= ~(0x3<<3);
        }
    
        return size;
    }
    
    int led_close(struct inode *inode, struct file *filp)
    {
        printk("--------^_^ %s------------
    ",__FUNCTION__);
        //灭灯
            *gpco_data &= ~(0x3<<3);
        return 0;
    }
    
    
    static struct file_operations fops = {
        .open = led_open,
        .write = led_write,
        .release = led_close,
    };
    
    
    //加载函数和卸载函数
    static int __init led_init(void)   //加载函数-----在驱动被加载时执行
    {
        int ret;
        printk("--------^_^ %s------------
    ",__FUNCTION__);
        //0,实例化设备对象
        //参数1 ---- 要申请的空间的大小
        //参数2 ---- 申请的空间的标识
        led_dev = kzalloc(sizeof(struct s5pv210_led),GFP_KERNEL);
        if(IS_ERR(led_dev)){
            printk("kzalloc error!
    ");
            ret = PTR_ERR(led_dev);
            return -ENOMEM;
        }
        
        //1,申请设备号
    #if 0
        //静态申请主设备号
        led_dev->major = 256;
        ret = register_chrdev(led_dev->major,"led_drv",&fops);
        if(ret < 0){
            printk("register_chrdev error!
    ");
            return -EINVAL;
        }
    #else
        //动态申请主设备号
        led_dev->major = register_chrdev(0,"led_drv",&fops);
        if(led_dev->major < 0){
            printk("register_chrdev error!
    ");
            ret =  -EINVAL;
            goto err_kfree;
        }
    #endif
    
        //2,创建设备文件-----/dev/led1
        led_dev->cls = class_create(THIS_MODULE,"led_cls");
        if(IS_ERR(led_dev->cls)){
            printk("class_create error!
    ");
            ret = PTR_ERR(led_dev->cls);
            goto err_unregister;
        }
        
        led_dev->dev = device_create(led_dev->cls,NULL,MKDEV(led_dev->major,0),NULL,"led");
        if(IS_ERR(led_dev->dev)){
            printk("device_create error!
    ");
            ret = PTR_ERR(led_dev->dev);
            goto err_class;
        }
    
    
        //3,硬件初始化----地址映射
    
            gpco_conf = ioremap(0xE0200060,8);
            gpco_data = gpco_conf+1;
        
        return 0;
    
    err_class:
        class_destroy(led_dev->cls);
    
    err_unregister:
        unregister_chrdev(led_dev->major,"led_drv");
        
    err_kfree:
        kfree(led_dev);
        return ret;
    
        
    }
    
    static void __exit led_exit(void)   //卸载函数-----在驱动被卸载时执行
    {
        printk("--------^_^ %s------------
    ",__FUNCTION__);
        device_destroy(led_dev->cls,MKDEV(led_dev->major,0));
        class_destroy(led_dev->cls);
        unregister_chrdev(led_dev->major,"led_drv");
        kfree(led_dev);
    }
    
    //声明和认证
    module_init(led_init);
    module_exit(led_exit);
    MODULE_LICENSE("GPL");

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    int main(void)
    {
    
        int fd;
        int on;
    
        fd = open("/dev/led",O_RDWR);
        if(fd < 0){
            perror("open");
            exit(1);
        }
    
        //闪灯
        while(1){
            //点灯
            on = 1;
            write(fd,&on,sizeof(on));
            sleep(1);
    
            //灭灯
            on = 0;
            write(fd,&on,sizeof(on));
            sleep(1);
        }
    
        close(fd);
        return 0;
    }

    #指定内核源码路径
    KERNEL_DIR = /home/farsight/s5pv210/kernel/linux-3.0.8
    CUR_DIR = $(shell pwd)
    MYAPP = test
    
    all:
        #让make进入内核源码编译,同时将当前目录中的c程序作为内核模块一起编译
        make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
        arm-none-linux-gnueabi-gcc -o $(MYAPP) $(MYAPP).c
    
    clean:
        #删除上面编译生成的文件
        make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
        rm -rf $(MYAPP)
    
    install:
        cp *.ko $(MYAPP) /opt/rootfs/drv_module
    
    #指定当前目录下哪个文件作为内核模块编
    obj-m = led_drv.o
    Stay hungry, stay foolish 待续。。。
  • 相关阅读:
    【纯水题】POJ 1852 Ants
    【树形DP】BZOJ 1131 Sta
    【不知道怎么分类】HDU
    【树形DP】CF 1293E Xenon's Attack on the Gangs
    【贪心算法】CF Emergency Evacuation
    【思维】UVA 11300 Spreading the Wealth
    【树形DP】NOI2003 逃学的小孩
    【树形DP】BZOJ 3829 Farmcraft
    【树形DP】JSOI BZOJ4472 salesman
    【迷宫问题】CodeForces 1292A A NEKO's Maze Game
  • 原文地址:https://www.cnblogs.com/panda-w/p/10991322.html
Copyright © 2020-2023  润新知