Un: attribuer et libérer des numéros de périphérique
1. Allocation dynamique:
dev: les 12 bits supérieurs sont le numéro de périphérique principal, les 20 bits inférieurs sont le numéro de périphérique mineur; baseminor: l'adresse de début du numéro de périphérique mineur; count: le nombre de numéros de périphérique à allouer; name: le nom de périphérique
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
2. Allocation statique:
formulaire: numéro d'équipement à attribuer; nombre: quantité d'application; nom: nom de l'équipement
int register_chrdev_region(dev_t from, unsigned count, const char *name)
3. Libérez le numéro de l'appareil:
void unregister_chrdev_region(dev_t from, unsigned count)
Deux: enregistrer un nouveau périphérique de personnage
1. Structure de périphérique de caractères: struct cdev
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
2. Enregistrez et initialisez l'appareil
static struct cdev demo_dev;
static struct file_opetarions demo_fops = {
.owner = THIS_MOUDULE,
... ...
};
demo_dev.owner = THIS_MOUDULE;
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
3. Ajouter de l'équipement
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
4. Supprimez l'appareil
void cdev_del(struct cdev *p)
Trois: créer automatiquement des nœuds de périphérique
1. Créer et supprimer des classes d'appareils
struct class *class_create (struct module *owner, const char *name)
void class_destroy(struct class *cls);
2. Créer et supprimer des appareils
struct device *device_create(struct class *cls, struct device *parent,
dev_t devt, void *drvdata,
const char *fmt, ...);
extern void device_destroy(struct class *cls, dev_t devt);
Quatre: nouveau modèle de cadre d'équipement de personnage
#define DEV_COUNT 1
#define DEV_NAME "newchardev"
struct newchar_dev {
dev_t devid;
int major;
int minor;
struct cdev cdev;
struct class *class_newchar;
struct device *device_newchar;
};
struct newchar_dev newchardev;
static int newchar_init(void)
{
/* 创建设备号 */
alloc_chrdev_region(&newchardev.devid, 0, DEV_COUNT, DEV_NAME);
newchardev.major = MAJOR(newchardev.devid);
newchardev.minor = MINOR(newchardev.devid);
/* 创建初始化设备 */
newchardev.cdev.owner = THIS_MOUDLE;
cdev_init(&newchardev.cdev, &newchar_fops);
/* 添加设备 */
cdev_add(&newchardev.cdev, newchardev.devid, DEV_COUNT);
/* 创建设备类和设备 */
newchardev.class_newchar = class_create (THIS_MOUDLE, DEV_NAME);
newchardev.device_newchar = device_create(newchardev.class_newchar, NULL,
newchardev.devid, NULL, DEV_NAME);
}
static void newchar_exit(void)
{
device_destroy(newchardev.class_newchar, newchardev.devid);
class_destroy(newchardev.class_newchar);
cdev_del(&newchardev.cdev);
unregister_chrdev_region(newchardev.devid, DEV_COUNT);
}