如果与用户进程交互的数据是1,2,4,8字节的话, 可用put_user(x,p) //x为值, p为地址
如果从用户进程获取1,2,4字节的话, 可用get_user(x,p)
| /////////// ///动态申请内存, 并清零. size为申请多大(不要超过128K), //flags为标志(常为GFP_KERNEL). 成功返回地址, 失败返回NULL // GFP_ATOMIC, 使用系统的内存紧急池 void *kmalloc(size_t size, gfp_t flags);//申请后要内存要清零 void *kzalloc(size_t size, gfp_t flags); //申请出来的内存已清零 void kfree(const void *objp); //回收kmalloc/kzalloc的内存 void *vmalloc(unsigned long size); //申请大内存空间 void vfree(const void *addr); //回收vmalloc的内存 // kmalloc申请出来的内存是物理地址连续的, vmalloc不一定是连续的 ///// container_of(ptr, type, member) type包括member成员的结构体, //ptr是type类型 结构体的member成员的地址. //此宏根据结构体成员的地址获取结构体变量的首地址 #define container_of(ptr, type, member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );}) #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 15 typedef struct led_dev_t { 16 dev_t mydevid; 17 unsigned int *rLEDCON; 18 unsigned int *rLEDDAT; 19 struct cdev mycdev; 20 }LED_DEV; LED_DEV myled; //ind->i_cdev是指向myled.mycdev成员的地址 //结构体变量myled首地址可由container_of(ind->i_cdev, LED_DEV, mycdev)获取; |
/////// 自动创建设备文件 ////
| #include <linux/device.h> |
1.
| struct class *cl; cl = class_create(owner, name) ; //owner指属于哪个模块, name类名 //创建出来后可以查看 /sys/class/类名 void class_destroy(struct class *cls); //用于销毁创建出来的类 |
2. 创建设备文件
| struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) __attribute__((format(printf, 5, 6))); device_create(所属的类, NULL, 设备号, NULL, "mydev%d", 88); //在/dev/目录下产生名字为mydev88的设备文件 void device_destroy(struct class *cls, dev_t devt); //用于销毁创建出来的设备文件 //////// int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops) ; //注册设备号并创建驱动对象 void unregister_chrdev(unsigned int major, const char *name); //反注册设备号并删除驱动对象 static inline int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops) { return __register_chrdev(major, 0, 256, name, fops); } int __register_chrdev(unsigned int major, unsigned int baseminor, unsigned int count, const char *name, const struct file_operations *fops) { struct char_device_struct *cd; struct cdev *cdev; int err = -ENOMEM; cd = __register_chrdev_region(major, baseminor, count, name); if (IS_ERR(cd)) return PTR_ERR(cd); cdev = cdev_alloc(); if (!cdev) goto out2; cdev->owner = fops->owner; cdev->ops = fops; kobject_set_name(&cdev->kobj, "%s", name); err = cdev_add(cdev, MKDEV(cd->major, baseminor), count); if (err) goto out; cd->cdev = cdev; return major ? 0 : cd->major; out: kobject_put(&cdev->kobj); out2: kfree(__unregister_chrdev_region(cd->major, baseminor, count)); return err; } |








