zoukankan      html  css  js  c++  java
  • linux 驱动入门4

    不吃苦中苦,难为人上人。努力,给老婆孩子提供个良好的生活居住环境。

    http://www.cnblogs.com/nan-jing/articles/5806399.html

    上文提到了如何创建proc节点。但是我经常看到有操作/sys节点的情况。 莫非应用可以操作sys节点? 问问了别人可以了。哎。别人只能给你说个大概。甚至只能和你说可以操作。为什么,如何操作。别人只能
    让你看代码。没别的招,想挣钱不? 想。想就看代码吧。

    老规矩,贴上全部代码。看看如何创建sys节点

    #include<linux/module.h>
    #include <linux/fs.h>
    #include <linux/errno.h>
    #include <linux/mm.h>
    #include <linux/sched.h>
    #include <linux/init.h>
    #include <linux/cdev.h>
    #include <asm/io.h>
    //臧春节 honeywell
    //#include <asm/system.h>
    #include <asm/uaccess.h>
    #include <linux/slab.h>
    #include <linux/device.h>
    #include <linux/proc_fs.h>
    #include <linux/sysfs.h>
    #include <linux/kobject.h>

    MODULE_AUTHOR("qcom.shanghai@gmail.com");
    MODULE_LICENSE("Dual BSD/GPL");

    #define GLOBALMEM_SIZE 0X1000
    #define MEM_CLEAR 0x1

    #define CJ_PROC_ENTRY "cjzang"
    #define CJ_PROC_NODE "cj_entry"

    static int globalmem_major = 0;

    struct globalmem_dev{
    struct cdev cdev;
    unsigned char mem[GLOBALMEM_SIZE];
    };

    struct globalmem_dev *globalmem_devp;

    struct class *globalmem_class;

    struct proc_dir_entry *proc_cj_entry;

    struct kobject *cj_sys;

    static int globalmem_open(struct inode *inode, struct file *filp){
    struct globalmem_dev *dev;
    dev = container_of(inode->i_cdev, struct globalmem_dev, cdev);
    filp->private_data = dev;
    printk(KERN_ALERT "globalmem_open!");
    return 0;
    }

    static int globalmem_release(struct inode *inode, struct file *filp){
    printk(KERN_ALERT "globalmem_release!");
    return 0;
    }

    static ssize_t globalmem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos){
    unsigned long p = *ppos;
    unsigned int count = size;
    int ret = 0;
    struct globalmem_dev *dev = filp->private_data;

    if (p >= GLOBALMEM_SIZE){
    return 0;
    }
    if (count > GLOBALMEM_SIZE - p){
    count = GLOBALMEM_SIZE - p;
    }

    if (copy_to_user(buf, (void *)(dev->mem + p), count)){
    ret = - EFAULT;
    }else {
    *ppos += count;
    ret = count;
    printk(KERN_ALERT "read %u bytes from %lu ", count, p);
    }
    return ret;
    }

    static ssize_t globalmem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos){
    unsigned long p = *ppos;
    unsigned int count = size;

    int ret = 0;
    struct globalmem_dev *dev = filp->private_data;

    if (p >= GLOBALMEM_SIZE){
    return 0;
    }

    if (count > GLOBALMEM_SIZE - p){
    //臧春节 honeywell
    count = GLOBALMEM_SIZE - p;
    }
    if (copy_from_user(dev->mem + p, buf, count)){
    ret = - EFAULT;
    }else {
    *ppos += count;
    ret = count;
    printk(KERN_ALERT "write %u bytes from %lu ", count, p);
    }

    return ret;
    }

    static loff_t globalmem_llseek(struct file *filp, loff_t offset, int orig){
    loff_t ret = 0;
    switch(orig){
    case 0:
    if (offset < 0){
    ret = - EFAULT;
    break;
    }
    if ((unsigned int)offset > GLOBALMEM_SIZE){
    ret = - EFAULT;
    break;
    }
    filp->f_pos = (unsigned int) offset;
    ret = filp->f_pos;
    break;

    case 1:
    if ((filp->f_pos + offset) > GLOBALMEM_SIZE){
    ret = - EFAULT;
    break;
    }

    if ((filp->f_pos + offset) < 0){
    ret = - EFAULT;
    break;
    }
    filp->f_pos += offset;
    ret = filp->f_pos;
    break;

    default:
    ret = - EFAULT;
    break;
    }

    return ret;

    }

    static long globalmem_ioctl(struct file *flip, unsigned int cmd, unsigned long arg){
    printk(KERN_ALERT "globalmem_ioctl");
    return 10L;
    }

    static const struct file_operations globalmem_fops = {
    .owner = THIS_MODULE,
    .llseek = globalmem_llseek,
    .read = globalmem_read,//臧春节 honeywell
    .write = globalmem_write,
    .unlocked_ioctl = globalmem_ioctl,
    .open = globalmem_open,
    .release = globalmem_release,
    };

    static int proc_show(struct seq_file *file, void *v){
    printk(KERN_ALERT "proc driver show!!!");
    seq_printf(file, "proc driver: %s ", "proc_proc_test");
    return 0;
    }

    static int proc_open(struct inode *inode, struct file *file){
    printk(KERN_ALERT "proc driver open!!!");
    single_open(file, proc_show, NULL);
    return 0;
    }

    static ssize_t proc_cj_write(struct file *file, const char __user *buffer, size_t count, loff_t *pos){
    printk(KERN_ALERT "proc driver wirte!!!");
    return 100;
    }

    static struct file_operations proc_file_ops = {
    .owner = THIS_MODULE,
    .open = proc_open,
    .read = seq_read,
    .write = proc_cj_write,
    .release = single_release,
    //臧春节 honeywell
    };

    static void globalmem_setup_cdev(struct globalmem_dev *dev, int index){
    int err, devno = MKDEV(globalmem_major, index);
    cdev_init(&(dev->cdev), &globalmem_fops);
    dev->cdev.owner = THIS_MODULE;
    err = cdev_add(&dev->cdev, devno, 1);
    if (err){
    printk(KERN_ALERT"cdev_add failed!");
    }
    }
    static int cj_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data){
    return 100;
    }

    static int cj_proc_write(struct file *file, const char *buffer, unsigned long count, void *data){
    return 100;
    }

    static int create_cjproc_entry(void){
    proc_cj_entry = proc_mkdir(CJ_PROC_ENTRY, NULL);
    if (proc_cj_entry == NULL){
    printk(KERN_ALERT"create /proc/%s failed ", CJ_PROC_ENTRY);
    return -1;
    }

    printk(KERN_ALERT"create /proc/%s success ", CJ_PROC_ENTRY);
    struct proc_dir_entry *pt_entry = proc_create(CJ_PROC_NODE, 0666, proc_cj_entry, &proc_file_ops);
    if (pt_entry == NULL){
    return -1;
    }
    // pt_entry->read_proc = cj_proc_read;
    // pt_entry->write_proc = cj_proc_write;

    return 0;
    }

    static ssize_t cj_sys_read(struct kobject *kobj, struct kobj_attribute *attr, char *buf){
    printk(KERN_ALERT "cj_sys_read");
    return 19;
    //臧春节 honeywell
    }

    static ssize_t cj_sys_write(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count){
    printk(KERN_ALERT "cj_sys_read");
    return 10;
    }

    static struct kobj_attribute cj_attribute = __ATTR(cj_attr, 0444, cj_sys_read, cj_sys_write);

    static int create_cjsys_entry(void){
    printk(KERN_ALERT "sys cj created!!!");
    cj_sys = kobject_create_and_add("cjsys", kernel_kobj);
    sysfs_create_file(cj_sys, &cj_attribute);
    //臧春节 honeywell
    return 0;
    }

    static void create_dev_node(int index){
    device_create(globalmem_class, NULL, MKDEV(globalmem_major, index), NULL, "globalmem_cj1");
    device_create(globalmem_class, NULL, MKDEV(globalmem_major, index + 1), NULL, "globalmem_cj2");
    }

    static int __init globalmem_init(void){
    int result;
    dev_t devno = MKDEV(globalmem_major, 0);
    if (globalmem_major){
    result = register_chrdev_region(devno, 2, "globalmem");
    }else {
    result = alloc_chrdev_region(&devno,0, 2, "globalmem");
    globalmem_major = MAJOR(devno);
    }
    printk(KERN_ALERT "major-------------->%d ", globalmem_major);
    if (result < 0){
    return result;
    }

    globalmem_class = class_create(THIS_MODULE, "globalmem_cls");
    create_dev_node(0);

    globalmem_devp = kmalloc(2 * sizeof(struct globalmem_dev), GFP_KERNEL);
    if (! globalmem_devp){
    result = -ENOMEM;
    goto fail_malloc;
    }
    memset(globalmem_devp, 0, 2 * sizeof(struct globalmem_dev));
    globalmem_setup_cdev(&globalmem_devp[0], 0);
    globalmem_setup_cdev(&globalmem_devp[1], 1);
    //臧春节 honeywell
    create_cjsys_entry();
    create_cjproc_entry();

    return 0;

    fail_malloc:
    unregister_chrdev_region(devno, 1);
    return result;
    }


    static void __exit globalmem_exit(void){
    cdev_del(&globalmem_devp[0].cdev);

    cdev_del(&globalmem_devp[1].cdev);
    kfree(globalmem_devp);
    unregister_chrdev_region(MKDEV(globalmem_major, 0), 2);
    class_destroy(globalmem_class);
    remove_proc_entry(CJ_PROC_ENTRY, NULL);
    remove_proc_entry(CJ_PROC_NODE, proc_cj_entry);
    }

    //臧春节 honeywell
    module_param(globalmem_major, int, 0555);
    module_init(globalmem_init);
    module_exit(globalmem_exit);

    解释:

    关键是这个函数
    static int create_cjsys_entry(void){
    printk(KERN_ALERT "sys cj created!!!");
    cj_sys = kobject_create_and_add("cjsys", kernel_kobj);
    sysfs_create_file(cj_sys, &cj_attribute);
    return 0;
    }

    sysfs_create_file 用这个参数kobject, attribute结构体包含了设备节点的读写方法。

    这里我遇到了问题。
    static struct kobj_attribute cj_attribute = __ATTR(cj_attr, 0444, cj_sys_read, cj_sys_write);

    这句话里的权限0444. 可以改成0555. 也就是说。//臧春节 honeywell只能读。不能写。改成0666就编译不过。这个诡异。为什么这个节点只能读不能写。

    一点点入门,一点点学习,关键在于坚持。要不断积累。

    写代码,玩女人。程序呀2大爱好。

  • 相关阅读:
    css将元素float和textalign方向一致时
    Asp.Net细节性问题技巧精萃
    ajax单个元素中实现多个回调函数
    javascript实现Observer模式来管理多个事件回调
    管闲事的小明
    字符串扩展
    (转的)计算组合数——整数拆分
    数学题杭电1002A+B。。。交了七遍,五遍竟然是没删除测试时候的输出= =。。。。
    快速排序。。。注意快速排序不适宜解决有重复数据的排序
    哈希查找统计元音
  • 原文地址:https://www.cnblogs.com/nan-jing/p/5820543.html
Copyright © 2011-2022 走看看