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信息

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

eclipse ide中文件编码的修改,解决中文乱码的问题。

1、先上一张图&#xff1a; 记得之前设置过&#xff0c;但是稍微一变&#xff0c;环境编码又到了ISO-8859-1了&#xff0c;然后就出现了乱码。 2、设置eclipse的编码&#xff1a; Preferences--General -- Content Types -- Text -- Java Properties File -- Default encoding…

使用myCobot280和OAK-D OpenCV DepthAI摄像头制作一个实时脸部跟踪的手机支架!

引言 由于YouTube和Netflix的出现&#xff0c;我们开始躺着看手机。然而&#xff0c;长时间用手拿着手机会让人感到疲劳。这次我们制作了一个可以在你眼前保持适当距离并调整位置的自动移动手机支架&#xff0c;让你无需用手拿着手机。请务必试试&#xff01; 准备工作 这次我们…

Vue3从入门到精通(三)

vue3插槽Slots 在 Vue3 中&#xff0c;插槽&#xff08;Slots&#xff09;的使用方式与 Vue2 中基本相同&#xff0c;但有一些细微的差异。以下是在 Vue3 中使用插槽的示例&#xff1a; // ChildComponent.vue <template><div><h2>Child Component</h2&…

昇思25天学习打卡营第08天|模型训练

模型训练 模型训练一般分为四个步骤&#xff1a; 构建数据集。定义神经网络模型。定义超参、损失函数及优化器。输入数据集进行训练与评估。 现在我们有了数据集和模型后&#xff0c;可以进行模型的训练与评估。 ps&#xff1a;这里的训练和Stable Diffusion中的训练是一样…

进程的概念

一.进程和程序的理解 首先抛出结论&#xff1a;进程是动态的&#xff0c;暂时存在于内存中&#xff0c;进程是程序的一次执行&#xff0c;而进程总是对应至少一个特定的程序。 程序是静态的&#xff0c;永久的存在于磁盘中。 程序是什么呢&#xff1f;程序其实就是存放在我们…

图像分类-数据驱动方法

K近邻算法&#xff08;K-Nearest Neighbors&#xff0c;简称KNN&#xff09; KNN算法通过比较新样本与训练集中的样本的距离&#xff0c;然后根据最近的K个邻居的投票结果来决定新样本的分类。 如图所示&#xff0c;K越大的边界会更加平滑&#xff0c;本质上是根据某一样本最近…

红薯小眼睛接口分析与Python脚本实现

文章目录 1. 写在前面2. 接口分析3. 算法脚本实现 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Py…

递归(三)—— 初识暴力递归之“字符串的全部子序列”

题目1 &#xff1a; 打印一个字符串的全部子序列 题目分析&#xff1a; 解法1&#xff1a;非递归方法 我们通过一个实例来理解题意&#xff0c;假设字符串str “abc”&#xff0c;那么它的子序列都有那些呢&#xff1f;" ", “a”&#xff0c; “b”&#xff0c;…

Vue的民族民俗文化分享平台-计算机毕业设计源码22552

基于Vue的民族民俗文化分享平台设计与实现 摘 要 本文介绍了一种基于Vue.js前端框架和Express后端框架的民族民俗文化分享平台的设计和实现。该平台旨在通过线上方式&#xff0c;促进民族民俗文化的传播与分享&#xff0c;增强公众对多元文化的了解和认同。 平台为普通用户提供…

前后端的导入、导出、模板下载等写法

导入&#xff0c;导出、模板下载等的前后端写法 文章目录 导入&#xff0c;导出、模板下载等的前后端写法一、导入实现1.1 后端的导入1.2 前端的导入 二、基础的模板下载2.1 后端的模板下载-若依基础版本2.2 前端的模板下载2.3 后端的模板下载 - 基于资源文件读取2.4 excel制作…

24西安电子科技大学马克思主义学院—考研录取情况

01、马克思主义学院各个方向 02、24马克思主义学院近三年复试分数线对比 PS&#xff1a;马院24年院线相对于23年院线增加15分&#xff0c;反映了大家对于马克思主义理论学习与研究的热情高涨&#xff0c;也彰显了学院在人才培养、学科建设及学术研究等方面的不断进步与成就。 6…

直接更新flowable数据库的流程定义信息的一种方法

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

文章解读与仿真程序复现思路——太阳能学报EI\CSCD\北大核心《绿电交易场景下计及温控负荷的高铁站两阶段调度策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

【第21章】MyBatis-Plus多数据源支持

文章目录 前言一、dynamic-datasource1. 特性2. 约定3. 使用方法3.1 引入依赖3.2 配置数据源3.3 使用 DS 切换数据源 二、mybatis-mate1.特性2.使用方法2.1 配置数据源2.2 使用 Sharding 切换数据源2.3 切换指定数据库节点 三、实战1. 引入库2. 配置3. 使用 DS 切换数据源4. 测…

vue项目打包部署后 浏览器自动清除缓存问题(解决方法)

vue打包部署后 浏览器缓存问题&#xff0c;导致控制台报错ChunkLoadError: Loading chunk failed的解决方案 一、报错如下&#xff1a; 每次build打包部署到服务器上时&#xff0c;偶尔会出现前端资源文件不能及时更新到最新&#xff0c;浏览器存在缓存问题&#xff0c;这时在…

Pandas数据可视化详解:大案例解析(第27天)

系列文章目录 Pandas数据可视化解决不显示中文和负号问题matplotlib数据可视化seaborn数据可视化pyecharts数据可视化优衣库数据分析案例 文章目录 系列文章目录前言1. Pandas数据可视化1.1 案例解析&#xff1a;代码实现 2. 解决不显示中文和负号问题3. matplotlib数据可视化…

ListBox自动滚动并限制显示条数

1、实现功能 限制ListBox显示的最大条数&#xff1b; ListBox自动滚动&#xff0c;显示最新行&#xff1b; 2、C#代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using Syst…

JUC并发编程基础(包含线程概念,状态等具体实现)

一.JUC并发编程基础 1. 并行与并发 1.1 并发: 是在同一实体上的多个事件是在一台处理器上"同时处理多个任务"同一时刻,其实是只有一个事件在发生. 即多个线程抢占同一个资源. 1.2 并行 是在不同实体上的多个事件是在多台处理器上同时处理多个任务同一时刻,大家…

【C++】main函数及返回值深度解析

一.main函数介绍 1.main函数怎么写 #include <iostream>int main() {// 程序的代码放在这里std::cout << "Hello, World!" << std::endl;return 0; }在这个例子中&#xff1a; #include <iostream> 是预处理指令&#xff0c;它告诉编译器…

在昇腾服务器上使用llama-factory对baichuan2-13b模型进行lora微调

什么是lora微调 LoRA 提出在预训练模型的参数矩阵上添加低秩分解矩阵来近似每层的参数更新&#xff0c;从而减少适配下游任务所需要训练的参数。 环境准备 这次使用到的微调框架是llama-factory。这个框架集成了对多种模型进行各种训练的代码&#xff0c;少量修改就可使用。 …