()shi linux字符设备,Linux字符设备驱动基础(三)
Linux字符設(shè)備驅(qū)動基礎(chǔ)(三)
6 創(chuàng)建設(shè)備節(jié)點(diǎn)
6.1 手動創(chuàng)建設(shè)備節(jié)點(diǎn)
查看申請的設(shè)備名及主設(shè)備號:
cat /proc/devices
# cat /proc/devices
Character devices:
1 mem
2 pty
3 ttyp
4 /dev/vc/0
4 tty
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
11 module_test
Block devices:
8 sd
93 spinor
259 blkext
Mknod用法:
# mknod
BusyBox v1.27.1 (2018-10-22 13:38:05 CST) multi-call binary.
Usage: mknod [-m MODE] NAME TYPE MAJOR MINOR
Create a special file (block, character, or pipe)
-m MODE Creation mode (default a=rw)
TYPE:
b Block device
c or u Character device
p Named pipe (MAJOR and MINOR are ignored)
如:mknod module_test b 11 0
6.2 自動創(chuàng)建設(shè)備節(jié)點(diǎn)
利用udev(mdev)來實(shí)現(xiàn)設(shè)備文件的自動創(chuàng)建,首先應(yīng)保證支持udev(mdev),由busybox配置。
在驅(qū)動用加入對udev 的支持主要做的就是:在驅(qū)動初始化的代碼里調(diào)用class_create(…)為該設(shè)備創(chuàng)建一個(gè)class,再為每個(gè)設(shè)備調(diào)用device_create(…)創(chuàng)建對應(yīng)的設(shè)備。
內(nèi)核中定義的struct class結(jié)構(gòu)體,顧名思義,一個(gè)struct class結(jié)構(gòu)體類型變量對應(yīng)一個(gè)類,內(nèi)核同時(shí)提供了class_create(…)函數(shù),可以用它來創(chuàng)建一個(gè)類,這個(gè)類存放于sysfs下面,一旦創(chuàng)建好了這個(gè)類,再調(diào)用 device_create(…)函數(shù)來在/dev目錄下創(chuàng)建相應(yīng)的設(shè)備節(jié)點(diǎn)。
這樣,加載模塊的時(shí)候,用戶空間中的udev會自動響應(yīng) device_create()函數(shù),去/sysfs下尋找對應(yīng)的類從而創(chuàng)建設(shè)備節(jié)點(diǎn)。
第一步:創(chuàng)建class類
Struct class chardev_test_class = class_create(THIS_MODULE, CHARDEV_DRV_NAME);
源碼如下:
/* This is a #define to keep the compiler from merging different
* instances of the __key variable */
#define class_create(owner, name)\
({\
static struct lock_class_key __key;\
__class_create(owner, name, &__key);\
})
參數(shù):
-Owner:THIS_MODULE;
-Name:class name。
/**
* class_create - create a struct class structure
* @owner: pointer to the module that is to "own" this struct class
* @name: pointer to a string for the name of this class.
* @key: the lock_class_key for this class; used by mutex lock debugging
*
* This is used to create a struct class pointer that can then be used
* in calls to device_create().
*
* Returns &struct class pointer on success, or ERR_PTR() on error.
*
* Note, the pointer created here is to be destroyed when finished by
* making a call to class_destroy().
*/
struct class *__class_create(struct module *owner, const char *name,
struct lock_class_key *key)
{
struct class *cls;
int retval;
cls = kzalloc(sizeof(*cls), GFP_KERNEL);
if (!cls) {
retval = -ENOMEM;
goto error;
}
cls->name = name;
cls->owner = owner;
cls->class_release = class_create_release;
retval = __class_register(cls, key);
if (retval)
goto error;
return cls;
error:
kfree(cls);
return ERR_PTR(retval);
}
class銷毀函數(shù):
/**
* class_destroy - destroys a struct class structure
* @cls: pointer to the struct class that is to be destroyed
*
* Note, the pointer to be destroyed must have been created with a call
* to class_create().
*/
void class_destroy(struct class *cls)
{
if ((cls == NULL) || (IS_ERR(cls)))
return;
class_unregister(cls);
}
第二步:創(chuàng)建device
Struct device *dev = device_create(chardev_test_class, &pdev->dev,
MKDEV(major, minor), NULL,
CHARDEV_DRV_NAME);
參數(shù):
-class:該設(shè)備需綁定的class類;
-parent:該設(shè)備的父設(shè)備;
-devt:該設(shè)備的設(shè)備號;
-drvdata:設(shè)備私有參數(shù);
-fmt:設(shè)備名
/**
* device_create - creates a device and registers it with sysfs
* @class: pointer to the struct class that this device should be registered to
* @parent: pointer to the parent struct device of this new device, if any
* @devt: the dev_t for the char device to be added
* @drvdata: the data to be added to the device for callbacks
* @fmt: string for the device's name
*
* This function can be used by char device classes. A struct device
* will be created in sysfs, registered to the specified class.
*
* A "dev" file will be created, showing the dev_t for the device, if
* the dev_t is not 0,0.
* If a pointer to a parent struct device is passed in, the newly created
* struct device will be a child of that device in sysfs.
* The pointer to the struct device will be returned from the call.
* Any further sysfs files that might be required can be created using this
* pointer.
*
* Returns &struct device pointer on success, or ERR_PTR() on error.
*
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
{
va_list vargs;
struct device *dev;
va_start(vargs, fmt);
dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
va_end(vargs);
return dev;
}
設(shè)備銷毀函數(shù):
/**
* device_destroy - removes a device that was created with device_create()
* @class: pointer to the struct class that this device was registered with
* @devt: the dev_t of the device that was previously registered
*
* This call unregisters and cleans up a device that was created with a
* call to device_create().
*/
void device_destroy(struct class *class, dev_t devt)
{
struct device *dev;
dev = class_find_device(class, NULL, &devt, __match_devt);
if (dev) {
put_device(dev);
device_unregister(dev);
}
}
總結(jié)
以上是生活随笔為你收集整理的()shi linux字符设备,Linux字符设备驱动基础(三)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux笔记软件,Linux Ubun
- 下一篇: linux shell创建进程数,[原创