hid-ft260驱动学习笔记 1 - 驱动模块注册与注销

目录

1. ft260_driver_init初始化

1.1 tty设备

1.1.1 申请tty驱动设备

1.1.2 初始化tty驱动程序

1.1.3 注册tty设备

1.2 hid设备

2. ft260_driver_exit注销模块

3. 调试


hid-ft260.c的最底部可以看到该驱动的注册与注销接口的申明。

module_init(ft260_driver_init);
module_exit(ft260_driver_exit);

MODULE_DESCRIPTION("FTDI FT260 USB HID to I2C host bridge and TTY driver");
MODULE_AUTHOR("Michael Zaidman <michael.zaidman@gmail.com>");
MODULE_LICENSE("GPL v2");

module_init即模块注册接口,当Linux中运行lsmod或modprobe安装驱动时系统会调用这个函数。

module_exit是模块的注销接口,当Linux中运行rmmod卸载驱动时系统会调用这个函数。

MODULE_LICENSE用来指定模块许可协议,一般是GPL,这里的GPL v2表示GNU通用公共许可证第2版(GNU General Public License version 2)。这意味着该模块的源代码必须对所有用户开放,并且任何基于此模块修改或衍生的作品也必须在相同的许可证下发布,保证了软件的自由度和可获得性。这个申明一般是必须的,否则编译时会提示警告。

MODULE_AUTHOR申明作者,不是必须。

MODULE_DESCRIPTION是模块的说明,不是必须。

1. ft260_driver_init初始化

FT260可以作为UART、I2C和GPIO的设备存在,所以在初始化时注册了2个设备。

static int __init ft260_driver_init(void)
{

}

__init是注册模块时固定的写法。

1.1 tty设备

1.1.1 申请tty驱动设备

通过调用tty_alloc_driver函数,为串口通信(UART)分配一个终端(TTY)驱动。

	ft260_tty_driver = tty_alloc_driver(UART_COUNT_MAX,
		TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV);
	if (IS_ERR(ft260_tty_driver)) {
		pr_err("tty_alloc_driver failed: %d\n",
			(int)PTR_ERR(ft260_tty_driver));
		return PTR_ERR(ft260_tty_driver);
	}
  • UART_COUNT_MAX:指定最多可支持的UART设备数量。
  • TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV:这两个标志合起来表示驱动将以真实原始模式工作(不进行任何字符处理,直接传递数据)且允许动态创建设备文件。

返回的是分配好的tty驱动设备。全局变量ft260_tty_driver:

static struct tty_driver *ft260_tty_driver;

1.1.2 初始化tty驱动程序

	ft260_tty_driver->driver_name = "ft260_ser";
	ft260_tty_driver->name = "ttyFT";
	ft260_tty_driver->major = 0;
	ft260_tty_driver->minor_start = 0;
	ft260_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
	ft260_tty_driver->subtype = SERIAL_TYPE_NORMAL;
	ft260_tty_driver->init_termios = tty_std_termios;
	ft260_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
	ft260_tty_driver->init_termios.c_ispeed = 9600;
	ft260_tty_driver->init_termios.c_ospeed = 9600;
	tty_set_operations(ft260_tty_driver, &ft260_uart_ops);

这里设置了驱动程序的名称、设备名称、主设备号、从设备号类型和子类型。然后,它初始化了串口的终端属性,包括波特率、数据位、停止位、校验位等。最后,它将操作函数指针设置为ft260_uart_ops,以便在设备文件操作时调用相应的函数。

driver_name是该设备的name,无特殊设定。

name是该设备在Linux中显示的设备名称,这里配置为ttyFT,在/dev目录内就会有一个类似‘ttyFT0’的终端设备。

major是设备的主设备号,这里设置为0一般是表示该主设备号有系统分配空闲设备号。一般设置为0。

minor_start是设备的从设备号,一般为0起始。

type和subtype分别表示设备的类型和子类型。TTY_DRIVER_TYPE_SERIAL表示这是一个串口驱动程序,而SERIAL_TYPE_NORMAL表示这个串口是标准类型的串口。

init_termios设置为tty_std_termios意味着当该串口设备被打开时,它会使用默认的标准终端设置,包括输入输出速度、控制字符等配置,以确保终端能按照常见规则正确工作。

c_cflag初始化一个串口终端的控制模式。具体来说,它设置了以下参数:

  • 波特率(baud rate)为9600;
  • 数据位(data bits)为8位;
  • 奇偶校验(parity)为无;
  • 停止位(stop bits)为1位;
  • 启用读取(read)和挂断(hang up)操作;
  • 忽略modem控制线(local mode)。

c_ispeed和c_ospeed设置输入速度(c_ispeed)和输出速度(c_ospeed)为9600波特率。

最后配置操作函数指针ft260_uart_ops是串口驱动的核心部分,串口数据的读写等操作就是这个函数指针结构体实现的。

static const struct tty_operations ft260_uart_ops = {
	.open			= ft260_uart_open,
	.close			= ft260_uart_close,
	.write			= ft260_uart_write,
	.write_room		= ft260_uart_write_room,
	.chars_in_buffer	= ft260_uart_chars_in_buffer,
	.set_termios		= ft260_uart_set_termios,
	.hangup			= ft260_uart_hangup,
	.install		= ft260_uart_install,
	.cleanup		= ft260_uart_cleanup,
	.proc_show		= ft260_uart_proc_show,
	.get_icount		= ft260_uart_get_icount,
};

1.1.3 注册tty设备

	ret = tty_register_driver(ft260_tty_driver);
	if (ret) {
		pr_err("tty_register_driver failed: %d\n", ret);
		goto err_reg_driver;
	}

tty_register_driver函数用于将ft260_tty_driver注册到TTY系统中。如果注册失败,会输出错误信息并跳转到err_reg_driver标签处。

1.2 hid设备

对于GPIO和I2C,这部分属于一个非标准的hid设备,所以这里只注册为hid设备。

	ret = hid_register_driver(&ft260_driver);
	if (ret) {
		pr_err("hid_register_driver failed: %d\n", ret);
		goto err_reg_hid;
	}

hid_register_driver用于注册一个hid驱动程序,它接受一个指向ft260_driver结构体的指针作为参数,并返回一个整数值。ft260_driver是一个hid驱动结构体:

static struct hid_driver ft260_driver = {
	.name		= "ft260",
	.id_table	= ft260_devices,
	.probe		= ft260_probe,
	.remove		= ft260_remove,
	.raw_event	= ft260_raw_event,
};

这个结构体用于描述一个USB HID设备的驱动程序,具体包含了以下成员:

  • name:驱动程序的名称,此处为"ft260"。
  • id_table:指向一个设备ID列表的指针,用于匹配设备。
  • probe:指向一个函数ft260_probe的指针,该函数在设备插入时被调用,用于初始化设备。
  • remove:指向一个函数ft260_remove的指针,该函数在设备移除时被调用,用于反初始化设备。
  • raw_event:指向一个函数ft260_raw_event的指针,该函数用于处理设备的原始事件。

2. ft260_driver_exit注销模块

static void __exit ft260_driver_exit(void)
{
	hid_unregister_driver(&ft260_driver);
	tty_unregister_driver(ft260_tty_driver);
	tty_driver_kref_put(ft260_tty_driver);
}

__exit 是注销模块的标准写法。

函数中调用了hid_unregister_driver来注销hid设备驱动程序ft260_driver,调用tty_unregister_driver来注销串口驱动程序ft260_tty_driver,最后通过tty_driver_kref_put释放ft260_tty_driver的引用计数,它是和初始模块中的tty_alloc_driver成对出现的。

3. 调试

在Linux驱动模块中,不能使用printf打印信息,需要使用printk打印。在init和exit返回的位置添加打印看一下驱动安装与卸载

  • lsmod查看有没有hid-ft260
  • 命令"sudo insmod hid-ft260.ko" 安装驱动
  • 命令“cat /proc/device”查看驱动主设备号分配情况

  • 命令“sudo dmesg”查看log信息

  • 命令“sudo rmmod hid-ft260”卸载驱动
  • 命令“sudo dmesg”查看log信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/779882.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【基于R语言群体遗传学】-8-代际及时间推移对于变异的影响

上一篇博客&#xff0c;我们学习了在非选择下&#xff0c;以二项分布模拟遗传漂变的过程&#xff1a;【基于R语言群体遗传学】-7-遗传变异&#xff08;genetic variation&#xff09;-CSDN博客 那么我们之前有在代际之间去模拟&#xff0c;那么我们就想知道&#xff0c;遗传变…

LabVIEW透视变换

透视变换概述源程序在www.bjcyck.com下载 透视变换是一种几何变换&#xff0c;用于对图像进行扭曲&#xff0c;使其看起来从不同角度拍摄。这在计算机视觉和图像处理领域非常重要&#xff0c;例如在投影校正和图像配准中。LabVIEW提供了强大的图像处理工具&#xff0c;利用其V…

java生成json格式文件(包含缩进等格式)

生成json文件的同时保留原json格式&#xff0c;拥有良好的格式&#xff08;如缩进等&#xff09;&#xff0c;提供友善阅读支持。 pom.xml依赖增加&#xff1a; <dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactI…

LabVIEW在图像处理中的应用

abVIEW作为一种图形化编程环境&#xff0c;不仅在数据采集和仪器控制领域表现出色&#xff0c;还在图像处理方面具有强大的功能。借助其Vision Development Module&#xff0c;LabVIEW提供了丰富的图像处理工具&#xff0c;广泛应用于工业检测、医学影像、自动化控制等多个领域…

Linux防火墙使用(firewalld与iptables)

防火墙概述 防火墙是一种由硬件和软件组合而成&#xff0c;在内部网和外部网之间、专有网和公共网之间构造的保护屏障&#xff0c;用以保护用户资料和信息安全的一种技术 防火墙作用在于及时发现并处理计算机网络运行时可能存在的安全风险、数据传输等问题&#xff0c;从而实现…

Java | Leetcode Java题解之第212题单词搜索II

题目&#xff1a; 题解&#xff1a; class Solution {int[][] dirs {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};public List<String> findWords(char[][] board, String[] words) {Trie trie new Trie();for (String word : words) {trie.insert(word);}Set<String> a…

Apache Seata Mac下的Seata Demo环境搭建

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Mac下的Seata Demo环境搭建&#xff08;AT模式&#xff09; 前言 最近因为工作需要&#xf…

探讨3D沉浸式在线会议系统的研发 - Meta演示的元宇宙虚拟化身多人对话场景,Web端现在也可以实现了 !

要实现一个元宇宙多人会议系统&#xff0c;关键技术有&#xff1a; 1. 3D虚拟空间的构建&#xff08;含光影特效、虚拟现实和增强现实&#xff09; 2. 3D虚拟化身的构建&#xff08;含动画、表情、语音&#xff09; 3. 多人角色管理 4. 会话控制和信息同步 5. 语音合成 6…

免费的鼠标连点器电脑版教程!官方正版!专业鼠标连点器用户分享教程!2024最新

电脑技术的不断发展&#xff0c;许多用户在日常工作和娱乐中&#xff0c;需要用到各种辅助工具来提升效率或简化操作&#xff0c;而电脑办公中&#xff0c;鼠标连点器作为一种能够模拟鼠标点击的软件&#xff0c;受到了广大用户的青睐。本文将为大家介绍一款官方正版的免费鼠标…

对接海康sdk-linux下复制jar包中resource目录的文件夹

背景 在集成海康sdk时,需要将一些组件放到项目中作为静态资源,并且海康的sdk初始化也需要加载这些静态资源,在windows下,使用一些File路径的方式是可以正确加载的,但是在linux上就会加载失败。 首先我是将海康的sdk组件放到resource下的,并且按照windows和linux设置了两…

考虑数据库粒度的设计-提升效率

目录 概要 场景 设计思路 小结 概要 公开的资料显示&#xff0c;数据库粒度是&#xff1a;“在数据库领域&#xff0c;特别是数据仓库的设计中&#xff0c;粒度是一个核心概念&#xff0c;它直接影响到数据分析的准确性和存储效率。粒度的设定涉及到数据的详细程度和精度&…

CH11_JS的多重循环

第11章&#xff1a;Javascript的多重循环 本章目标 掌握二重循环的使用 掌握二重循环的控制语句的使用 课程回顾 循环控制有那几种方式 讲解内容 1. 回顾练习 需求说明 某次程序大赛&#xff0c;AI2101班有4名学员参加&#xff0c;学员的成绩由用户输入&#xff0c;计算…

文件系统技术架构分析

一文读懂&#xff1a;什么是文件系统 &#xff0c;有哪几类&#xff1f; ▉ 什么是文件系统&#xff1f; 技术大拿眉头皱了皱&#xff0c;忍住快要爆发的情绪。解释到&#xff1a; 数据以二进制形式存储于介质&#xff0c;但高低电平含义难解。文件系统揭秘这些二进制背后的意…

【踩坑】修复pyinstaller报错 No module named pkg_resources.extern

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 报错如下&#xff1a; 修复方法&#xff1a; pip install --upgrade setuptools pippyinstaller -F -w main.py --hidden-importpkg_resources.py2_wa…

前端位置布局汇总

HTML中脱离文档流的元素有&#xff1a; position: absolute - 元素相对于最近的已定位&#xff08;非 static&#xff09;祖先元素定位。 position: fixed - 元素相对于浏览器窗口定位。 float: left 或 float: right - 元素向左或向右浮动&#xff0c;周围的内容会环绕它。 …

认识流式处理框架Apache Flink

目录 一、Apache Flink 的基础概念 1.1 Apache Flink是什么&#xff1f; 1.2 Flink的定义 二、Apache Flink 的发展史 2.1 Flink前身Stratosphere 2.2 Flink发展时间线及重大变更 三、Flink核心特性 3.1 批流一体化 3.2 同时支持高吞吐、低延迟、高性能 3.3 支持事件时…

探索Linux:开源世界的无限可能

Linux是一款开源操作系统&#xff0c;它的起源可以追溯到上世纪90年代初。这个故事始于一个名叫Linus Torvalds的芬兰大学生&#xff0c;他在1983年开始编写一个用于个人电脑的操作系统内核。在他的努力下&#xff0c;Linux逐渐发展成为一个稳定而强大的操作系统。 然而&#…

分数的表示和运算方法fractions.Fraction()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 分数的表示和运算方法 fractions.Fraction() 选择题 以下代码三次输出的结果分别是&#xff1f; from fractions import Fraction a Fraction(1, 4) print(【显示】a ,a) b Fraction(1, 2…

网络基础:BGP协议

BGP&#xff08;边界网关协议&#xff0c;Border Gateway Protocol&#xff09;是一种用于在不同自治系统&#xff08;Autonomous Systems&#xff0c;AS&#xff09;之间交换路由信息的路径向量协议。BGP是互联网的核心路由协议之一&#xff0c;负责管理和维护互联网范围内的路…

为企业知识库选模型?全球AI大模型知识库RAG场景基准测试排名

大语言模型常见基准测试 大家对于AI模型理解和推理能力的的基准测试一定非常熟悉了&#xff0c;比如MMLU&#xff08;大规模多任务语言理解&#xff09;、GPQA&#xff08;研究生级别知识问答&#xff09;、GSMSK&#xff08;研究生数学知识考察&#xff09;、MATH&#xff08…