LDD3笔记(3)

2006617星期六

当被调用的驱动程序无法满足调用者的请求,它应该阻塞该进程,进程置于休眠状态直到其请求可继续。

把进程置于休眠时,注意两条规则:1.不要在原子上下文中进入休眠。原子上下文是指:在执行多个步骤的时候,不能有并发的访问。 2. 被唤醒之后,必须检查,以确保我们等待的条件真正为真。

linux中,等待队列通过“等待队列头”来管理,它是一个wait_queue_head_t的结构体,定义在 linux/wait.h中。可以用静态或者动态的方法来初始化一个等待队列头。

可以用四种wait_event宏来把进程置于休眠。它需要的参数是queue(等待队列头)和condition(布尔表达式,条件为真时,将被唤醒)。

唤醒用的宏是两种wake_up宏。

有时调用者进程会通知我们它不想被阻塞。显式的非阻塞的I/Ofilp->f_flags中的O_NONBLOCK标志决定。 Linux/fcntl.h  linux/fs.h

在驱动程序中使用输出缓冲区可以提高性能。

注意 scull例子中如何使用while循环来实现 休眠和唤醒。

LDDLinux Device Drivers)是Linux内核开发的重要组成部分,主要涉及设备驱动程序的编写与调试。对于希望获取LDD相关中文资源或进行汉化工作的用户,以下是一些可行的方法和资源建议: ### 获取LDD中文资源的途径 1. **《Linux设备驱动程序(第三版)》中文版** 这本书是LDD领域的经典教材,由Jonathan Corbet、Alessandro Rubini 和 Greg Kroah-Hartman合著,已经被翻译成中文。它详细讲解了Linux驱动程序开发的基础知识、内核机制以及具体设备类型的驱动实现方式。可以通过各大图书网站或电子书平台获取正版中文译本[^1]。 2. **开源社区与技术博客** 国内许多技术社区和博客提供了LDD相关的中文教程和实践案例,例如优快云、知乎专栏、掘金等平台上有开发者分享的Linux驱动开发经验,涵盖字符设备、块设备、网络设备等不同类型驱动的编写方法[^1]。 3. **GitHub开源项目** 可以在GitHub上搜索“LDD 中文”或“Linux驱动开发 中文”等关键词,找到一些开源翻译项目或教学资料。这些项目通常包含翻译的书籍章节、教学笔记、示例代码等资源,适合初学者和进阶者学习使用[^1]。 ### LDD汉化方法 1. **文档翻译工具** 对于英文PDF或电子文档,可以使用自动化翻译工具(如Google Translate、DeepL)进行初步翻译,再结合人工校对提高准确性。特别注意技术术语的准确翻译,以确保技术内容的正确性。 2. **协作翻译平台** 利用协作翻译平台(如Crowdin、Transifex)组织多人协作翻译,适用于书籍、手册等较大规模的翻译项目。这类平台支持版本控制、术语库管理等功能,有助于提升翻译效率和一致性。 3. **本地化开发文档** 如果是面向中文用户的开发文档,建议在翻译过程中结合本地化需求,调整示例代码、注释以及术语使用,确保文档在技术准确性和语言表达上都符合中文读者的阅读习惯。 4. **参与开源翻译项目** Linux社区中有许多开源项目支持多语言翻译,参与这些项目不仅可以获得翻译经验,还能为中文技术社区做出贡献。例如,Linux Kernel文档的中文翻译项目可以在Git仓库中找到并参与协作。 ### 示例代码:字符设备驱动模板 以下是一个简单的字符设备驱动模板,适合用于LDD学习和实践: ```c #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/cdev.h> #define DEVICE_NAME "mychardev" #define BUF_LEN 100 static dev_t dev_num; static struct cdev my_cdev; static char msg[BUF_LEN] = {0}; static int device_open(struct inode *inode, struct file *file) { printk(KERN_INFO "Device opened\n"); return 0; } static ssize_t device_read(struct file *file, char __user *buffer, size_t length, loff_t *offset) { int bytes_read = 0; if (*offset >= BUF_LEN) return 0; while (length && (msg + *offset) < (msg + BUF_LEN)) { put_user(*(msg + *offset), buffer++); length--; bytes_read++; (*offset)++; } return bytes_read; } static ssize_t device_write(struct file *file, const char __user *buffer, size_t length, loff_t *offset) { int i; for (i = 0; i < length && i < BUF_LEN; i++) { get_user(msg[i], buffer + i); } return i; } static int device_release(struct inode *inode, struct file *file) { printk(KERN_INFO "Device closed\n"); return 0; } static struct file_operations fops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release, }; static int __init ldd_init(void) { alloc_chrdev_region(&dev_num, 0, 1, DEVICE_NAME); cdev_init(&my_cdev, &fops); cdev_add(&my_cdev, dev_num, 1); printk(KERN_INFO "Char device registered\n"); return 0; } static void __exit ldd_exit(void) { cdev_del(&my_cdev); unregister_chrdev_region(dev_num, 1); printk(KERN_INFO "Char device unregistered\n"); } module_init(ldd_init); module_exit(ldd_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple character device driver"); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值