kernel-char设备的建立
kernel下的设备分成了一些类,char block char。。
这里就贴出来一个样例能够建立一个char设备 ,抛砖引玉吧
这是kernel中的 drivers/char/msm_smd_pkt.c
先要启动初始化module
module_init(smd_pkt_init);
smd_pkt_init会在启动之后调用
static int __init smd_pkt_init(void)
{
int i;
int r;
创造char设备的结构体
r = alloc_chrdev_region(&smd_pkt_number, 0,
NUM_SMD_PKT_PORTS, DEVICE_NAME);
if (r) {
pr_err("alloc_chrdev_region() failed %d\n", r);
return r;
}
创造class下的设备机构提
smd_pkt_classp = class_create(THIS_MODULE, DEVICE_NAME);
if (IS_ERR(smd_pkt_classp)) {
r = PTR_ERR(smd_pkt_classp);
pr_err("class_create() failed %d\n", r);
goto unreg_chardev;
}
for (i = 0; i < NUM_SMD_PKT_PORTS; ++i) {
smd_pkt_devp[i] = kzalloc(sizeof(struct smd_pkt_dev),
GFP_KERNEL);
if (IS_ERR(smd_pkt_devp[i])) {
r = PTR_ERR(smd_pkt_devp[i]);
pr_err("kmalloc() failed %d\n", r);
goto clean_cdevs;
}
smd_pkt_devp[i]->i = i;
以下几行都是私有数据的赋值 我们不用关心 不须要能够删掉
init_waitqueue_head(&smd_pkt_devp[i]->ch_read_wait_queue);
smd_pkt_devp[i]->remote_open = 0;
init_waitqueue_head(&smd_pkt_devp[i]->ch_opened_wait_queue);
mutex_init(&smd_pkt_devp[i]->ch_lock);
mutex_init(&smd_pkt_devp[i]->rx_lock);
mutex_init(&smd_pkt_devp[i]->tx_lock);
关键地方就是这里了:
char设备的结构初始化
cdev_init(&smd_pkt_devp[i]->cdev, &smd_pkt_fops);
smd_pkt_devp[i]->cdev.owner = THIS_MODULE;
char设备添加
r = cdev_add(&smd_pkt_devp[i]->cdev,
(smd_pkt_number + i), 1);
if (r) {
pr_err("cdev_add() failed %d\n", r);
kfree(smd_pkt_devp[i]);
goto clean_cdevs;
}
char设备在dev下创造一个节点设备 这个一定要有哦
smd_pkt_devp[i]->devicep =
device_create(smd_pkt_classp, NULL,
(smd_pkt_number + i), NULL,
smd_pkt_dev_name[i]);
if (IS_ERR(smd_pkt_devp[i]->devicep)) {
r = PTR_ERR(smd_pkt_devp[i]->devicep);
pr_err("device_create() failed %d\n", r);
cdev_del(&smd_pkt_devp[i]->cdev);
kfree(smd_pkt_devp[i]);
goto clean_cdevs;
}
}
pr_info("SMD Packet Port Driver Initialized.\n");
return 0;
后面就是错误处理了 无论了
clean_cdevs:
if (i > 0) {
while (--i >= 0) {
mutex_destroy(&smd_pkt_devp[i]->ch_lock);
mutex_destroy(&smd_pkt_devp[i]->rx_lock);
mutex_destroy(&smd_pkt_devp[i]->tx_lock);
cdev_del(&smd_pkt_devp[i]->cdev);
kfree(smd_pkt_devp[i]);
device_destroy(smd_pkt_classp,
MKDEV(MAJOR(smd_pkt_number), i));
}
}
class_destroy(smd_pkt_classp);
unreg_chardev:
unregister_chrdev_region(MAJOR(smd_pkt_number), NUM_SMD_PKT_PORTS);
return r;
}
最新文章
- HTTP中的POST、GET区别
- 【软件分析与挖掘】BOAT: An Experimental Platform for Researchers to Comparatively and Reproducibly Evaluate Bug Localization Techniques
- Android开发新手第一要素
- 删除docker私有库镜像
- action属性
- 关于移动div的具体实现(js)
- 什么是内存泄漏?(What is a memory leak?)
- IE的缓存
- Lastpass&mdash;&mdash;密码管理工具
- call(),apply()方法解析(一)
- Android远程桌面助手(B1413)
- es6学习笔记--模板字符串
- java中的数据类型,运算符,字符串,输入输出,控制流,大数值,数组; 《java核心技术卷i》 第三章:java基本程序结构;
- sql server 查询某个时间段共有多少周及每周的日期段
- 【MEVN架构】mongodb+ express + vue + nodejs 搭建后台
- Google Kickstart Round.B C. Diverse Subarray
- 【BZOJ2138】stone Hall定理+线段树
- lucene4 Filter
- web 后端规范与思想
- 【CS231N】6、神经网络动态部分:损失函数等