《电子技术应用》
您所在的位置:首页 > 可编程逻辑 > 其他 > Linux教学——探讨内核代码

Linux教学——探讨内核代码

2022-08-18
来源:电子技术应用专栏作家 嵌入式Linux
关键词: 内核代码

  最近因为要解决一个bug,需要在内核的f_hid.c里面做一些适配,需要把这部分代码研究透彻。

  在这几天之前我是根本不知道什么是In端点,Out端点,以及什么是endpoint 0的,而且最近的一段时间,我一直是在写应用方面的代码,也是趁着这个机会,好好拜读这部分。

  ——

  在HID 1.0之前,是没有什么OUT 端点的,都是用端点0来进行数据传输,不过端点0有一个问题,他的最大传输包的大小有限制。

  微信图片_20220818152226.jpg

  谢谢我飞哥给的截图

  之后,就有一个大佬在原来的内核代码上面做了一部分修改,在原来的enpoint 0 上加了一个OUT端点,意思就是说,本来从深圳到广州有绿皮火车,但是绿皮火车一次只能装下20个人,有一个人就发明了高铁,高铁一次可以装200个人。

  这个提交的链接

  https://github.com/torvalds/linux/commit/99c515005857ff7d6cd5c2ba272ccab5dc0ea648

  微信图片_20220818152245.png

  这个修改的commit里面说明了修改的原因,比如说使用端点0不能同步到字符设备,而且端点0的使用可能会导致数据丢失,所以加了一个OUT interrupt endpoint接口。

  重点来了

  并且这个补丁还会继续处理SET_REPORT  接口请求事件。

  ——

  好了,上面是这个文件的第一次修改,我们的代码里面也是用的原厂的SDK代码修改,但是这个修改有一个问题,实际上端点0的SET REPORT并没有正确请求,这是一个问题,但是这个问题不是Linux 代码的问题,应该是芯片原厂移植过来后出现的问题。

  之后,又有一个大佬重新对这个内核代码进行了改造

  提交的commit链接如下

  https://github.com/torvalds/linux/commit/d7428bc26fc767942c38d74b80299bcd4f01e7cb

  他的修改的主要是增加了配置选项,就是可以软件配置使用OUT endpoint还是端点0,这主要是不同的产品定义可能需求会不同。

  这个改造的原因是什么呢?

  微信图片_20220818152314.png

  有些主机设备,我们说的主机指的是USB的HOST设备,它不支持OUT endpoint 。

  还有一些苹果产品,他们天然就不能使用OUT端点来传输。

  其他巴拉巴拉的一些大家就自己看吧。

  ——

  截图给大家看看什么是端点0和OUT endpoint

  微信图片_20220818152333.jpg

  ——

  写了很多,还没有说到我要改造什么,其实就是对这部分机制熟悉了,要修改掉因为SET REPORT导致的一个bug。

  这也是一些看代码的思路吧,内核是分成很多很多模块的,大家想看哪些模块,去看看commit,去看看代码,其实挺有意思的。

  不过里面的一些命名并不是很清晰明了,比如IN这个东西,太简洁了,不是做USB的人估计很难明白,这些还有,要是去调试HID描述符,就知道那是太要绕脑子了。

  ——问题是什么?

  还是从HID来说,上面留言说的没问题,USB嘛,不就是一个发送,一个接口,设备到主机通过in端口,这个没问题。

  在HID低版本的时候用的是endpoint 0端口,也不能说是低版本,即使在高版本,也是可以用endpoint 0端口的「不同之处在于低版本只有endpoint 0」,我也拿了一些竞品的产品来看,他们也是可以通过endpoint 0来发送信息给设备端的。

  问题是,我们用的RK方案打开了out端点后不可以。

  其他产品在打开out端口的时候,也是可以用endpoint 0 发送数据到设备的。

  为什么我揪着这个endpoint 0发送呢?

  是因为测试发现通过这个端口可以使用set report 函数,用这个函数来发送消息不会出现偶发的超时问题。

  RK是怎么回复的呢?

  他们说他们提供的方案是用endpoint 0的,都不会有问题。

  而且看了内核代码,确实是配置想用哪个就用哪个,用户自己选择,用了out ,endpoint 0 就用不了了。

  微信图片_20220819154823.png

  人家代码也是写得很清楚了,就是更子的。

  ——那我们为什么不直接用RK的方案,直接用endpoint 0 就好了

  直接用endpoint 0我在之前的文章也说了,这样就可以兼容MAC的电脑,也不会出现一些乱七八糟可能性的问题。

  但是问题是,我们的应用程序开发的很多功能,都已经实现,都是用的out端点,包的长度也是1024, 这方案一搞下去,那所有人都要重写代码,重新测试了。

  微信图片_20220819154851.png

  —— 后面怎么修改了?

  因为如果加上

  微信图片_20220819154911.png

  设备是可以调用HOST的setreport接口的,我要做的,无非就是在这里判断下数据指令,然后传给应用程序就好了。

  问题就出在这里,usb的一些结构体,如果没有好好写,就可能影响到系统的东西。

  OUT端点写入数据的时候,是直接用到req结构体的

  微信图片_20220819154931.png

  这段代码在out端点接收没有问题,但是放到setreport部分来处理就出现了问题。

  setreport的处理不一样

  他给HOST来的数据在内核重新分配了空间。

  微信图片_20220819154949.png

  然后就针对这些不同的逻辑修改修改。

  细节就不说了

  内核代码不像应用代码,应用的调试是比较方便的,内核的调试涉及硬件设备就不同了,而且接口的处理也会不同,稍不注意引起的空指针问题,整个系统就挂了,应用还可以用守护进程拉起来,内核就不行,只能重启。

  不过内核都是C,看起来还是比较舒服的。


    更多信息可以来这里获取==>>电子技术应用-AET<<

微信图片_20210517164139.jpg

微信图片_20220706154608.jpg

电子技术应用专栏作家  嵌入式Linux

原文链接:https://mp.weixin.qq.com/s/humym3KbZsEzT2XSi-texw

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。