关于Linux平台设备驱动模型,并不是创建新的设备分类,是在原有的字符设备基础上使用,将设备和驱动分开,生成两个.ko文件。
Linux内核维护一个全局设备链表,对应的总线会将驱动和设备链表里的设备名进行匹配,如果匹配成功就会将设备的信息传递给驱动的probe函数,probe函数得到设备的核心结构体platform_device的信息就可以进行对应的操作。
我们只需实现平台驱动和平台设备即可,平台总线是内核实现的,常见的总线如IIC、SPI、CAN等,LED、KEY这类型的普通字符设备,linux内核就使用虚拟的平台总线struct bus_type platform_bus_type来匹配这类设备。

首先来看platform_device平台设备层结构体。

我们只需要关注name、id、num_resources、resource、dev这几个成员。
struct platform_device{
const char *name; //自定义的设备名,用于和驱动匹。
int id; //当设备和驱动一对一匹配时,所设值为-1
struct device dev; //下面列举其成员介绍。该结构体下的release函数是必须实现的
u32 num_resources; //设备的个数,即设备资源数组的元素个数
struct resource *resource; //设备所用资源数组的首地址
};
接下来看platform_device下的resources结构体。

我们需关注前四个成员,最后一个成员是由内核实现。
struct resource{
resource_size_t start; //所用资源的起始物理地址
resource_size_t end; //所用资源的结束物理地址
const char *name; //自定义的资源名称,此名称不与驱动相匹配,可以随便写,但要有意义
unsigned long flags; //所用资源的类型,例如中断IORESOURCE_IRQ,外设或者用于和设备通讯的支持直接寻址的地址空间IORESOURCE_MEM
};
接下来看platform_device结构体下的struct device,由于结构体过大,只展示重要的部分。


struct device{
void *platform_data; //这个指针指向设属性信息,platform_driver可以获取该数据
void *driver_data ; //用来告诉驱动需要服务的设备的类型
void (*release)(struct device *dev); //释放平台设备时会调用此函数,必须要实现
}
因此,编写平台设备的步骤大概如下:
1、分析硬件原理图,写出所使用的设备的占用资源情况,例如GPIO0寄存器的起始物理地址,GPIO0寄存器所占用的空间大小
2、定义并初始化一个资源结构数组struct resource,存放所有使用到的设备的信息。
3、编写一个release函数,在释放平台设备device时会调用此函数。
4、定义并初始化一个平台设备核心结构struct platform_device,其下的name是用来与driver下的name匹配的。
5、在模块初始化函数中调用注册平台设备函数,将平台设备核心结构体注册到内核中。
6、在模块卸载函数中调用注销平台设备函数,将平台设备核心结构体从内核中注销。
接下来实现平台驱动platform_driver核心结构体。

我们只需关注要用到的成员。
struct platform_driver {
int (*probe)(struct platform_device *); //指向设备探测函数,当与设备相匹配时调用此函数,参数是将平台设备指针传入,通过操作平台设备指针可以初始化硬件。是很重要的函数
int (*remove)(struct platform_device *);//指向移除设备函数,当总线上的设备和驱动匹配关系解除时会调用此函数。如果probe函数中申请了资源,就需要在此函数中按顺序释放
struct device_driver driver; //此结构体下的name成员和设备相匹配,还有一个成员是用于和设备树相匹配,下面会列出
const struct platform_device_id *id_table; /如果需要匹配多个设备,也可以使用此成员
};
接下来看platform_driver下的device_driver结构体。

我们只需关注重要的成员。
struct device_driver{
const char *name; //此名字会和平台设备的名字相匹配
const struct of_device_id *of_match_table; //此成员下的compatible是和设备的名字相匹配,下面会列出。是用于设备树的方式实现一个驱动匹配多个设备
}

接下来关注platform_driver下的platform_device_id。

struct platform_device_id {
char name[PLATFORM_NAME_SIZE]; //此成员用于和设备名相匹配
kernel_ulong_t driver_data; //此成员用于来保存设备的配置
};
因此,平台驱动有三种方式和平台设备相匹配。
第一种:也就是优先级最低的一种。platform_driver下的name成员和平台设备platform_device下的name成员匹配。
第二种:优先级第二高。平台设备platform_device下的name成员和platform_driver下的platform_device_id所指向的数组的每个元素的name匹配。
第三种:优先级最高,使用的是设备树方式。platform_driver下的device_driver下的of_device_id所指向的每个元素的compatible值与设备树中设备节点的compatibl值相匹配。
这里的优先级是指,当设备树方式实现时,会先用设备树方式匹配,当设备树无法匹配时会使用platform_device_id匹配,最后再使用platform_driver下的name成员匹配。
因此,平台驱动层的编写大概如下:
1、定义一个probe探测函数和remove删除函数。
2、如果需要用到platform_device_id,则需要定义一个platform_device_id的数组来存储相应的设备信息。如果不需要用到则跳过。
3、如果需要用到设备树匹配,则定义一个of_device_id数组来存储设备的信息和数据。如果不需要用到则跳过。
4、定义一个平台设备驱动核心结构体platform_driver并初始化里面需要用到的成员。
5、在模块初始化函数中调用注册平台驱动函数。
6、在模块卸载函数中调用注销平台驱动函数。
一般probe探测函数框架如下:
1、获取平台设备的属性信息、数据,利用传进来的指针可以得到。
2、探测资源。
3、申请资源
4、使用资源,映射寄存器、申请中断资源等。
5、初始化硬件设备。
6、注册input子系统设备、字符设备、块设备、网络设备等。
remove函数就将probe函数中所申请占用的资源按顺序进行释放。
我在rspec中收到来自webkit驱动程序的以下消息:Capybara::Driver::Webkit::WebkitInvalidResponseError:UnabletoloadURL:http://127.0.0.1:44923/posts几天前它成功了。问题出在save_page方法上。有什么问题吗? 最佳答案 当我的页面出现错误时,我收到过类似的错误消息。您应该通过在测试模式下启动服务器(railss-etest)并自行访问页面来手动检查情况是否如此。 关于ruby-on-
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。问题1)我想知道rubyonrails是否有功能类似于primefaces的gem。我问的原因是如果您使用primefaces(http://www.primefaces.org/showcase-labs/ui/home.jsf),开发人员无需担心javascript或jquery的东西。据我所知,JSF是一个规范,基于规范的各种可用实现,prim
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit
在Ruby(1.8.X)中为什么Object既继承了内核又包含了内核?仅仅继承还不够吗?irb(main):006:0>Object.ancestors=>[Object,Kernel]irb(main):005:0>Object.included_modules=>[Kernel]irb(main):011:0>Object.superclass=>nil请注意,在Ruby1.9中情况类似(但更简洁):irb(main):001:0>Object.ancestors=>[Object,Kernel,BasicObject]irb(main):002:0>Object.included
Linux操作系统——网络配置与SSH远程安装完VMware与系统后,需要进行网络配置。第一个目标为进行SSH连接,可以从本机到VMware进行文件传送,首先需要进行网络配置。1.下载远程软件首先需要先下载安装一款远程软件:FinalShell或者xhell7FinalShellxhell7FinalShell下载:Windows下载http://www.hostbuf.com/downloads/finalshell_install.exemacOS下载http://www.hostbuf.com/downloads/finalshell_install.pkg2.配置CentOS网络安装好
文章目录一基础定义二创建逻辑卷2-1准备物理设备2-2创建物理卷2-3创建卷组2-4创建逻辑卷2-5创建文件系统并挂载文件三扩展卷组和缩减卷组3-1准备物理设备3-2创建物理卷3-3扩展卷组3-4查看卷组的详细信息以验证3-5缩减卷组四扩展逻辑卷4-1检查卷组是否有可用的空间4-2扩展逻辑卷4-3扩展文件系统五删除逻辑卷5-1备份数据5-2卸载文件系统5-3删除逻辑卷5-4删除卷组5-5删除物理卷六LVM逻辑卷缩容6-1缩容注意事项6-2标准缩容步骤一基础定义LVM,LogicalVolumeManger,逻辑卷管理,Linux磁盘分区管理的一种机制,建立在硬盘和分区上的一个逻辑层,提高磁盘分
RuntimeError:CUDAerror:device-sideasserttriggered问题描述解决思路发现问题:总结问题描述当我在调试模型的时候,出现了如下的问题/opt/conda/conda-bld/pytorch_1656352465323/work/aten/src/ATen/native/cuda/IndexKernel.cu:91:operator():block:[5,0,0],thread:[63,0,0]Assertion`index>=-sizes[i]&&index通过提示信息可以知道是个数组越界的问题。但是如图一中第二行话所说这个问题可能并不出在提示的代码段
如何在Ruby中获取linux系统(这必须适用于Fedora、Ubuntu等)的软件/硬件信息? 最佳答案 Chef背后的优秀人才,拥有一颗名为Ohai的优秀gemhttps://github.com/opscode/ohai以散列形式返回系统信息,例如操作系统、内核、规范、fqdn、磁盘、空间、内存、用户、接口(interface)、sshkey等。它非常完整,非常好。它还会安装命令行二进制文件(也称为ohai)。 关于ruby-如何在Ruby中获取linux系统信息,我们在Stack
我在LinuxMint17.2上。我最近使用apt-getpurgeruby删除了ruby。然后我安装了rbenv然后rbenvinstall2.3.0所以现在,~/.rbenv/versions/2.3.0/bin/ruby存在。但是现在,我无法执行geminstallrubocop。我明白了:$geminstallrubocoprbenv:gem:commandnotfoundThe`gem'commandexistsintheseRubyversions:2.3.0但是我可以~/.rbenv/versions/2.3.0/bin/geminstallrubocop。但是,
我是Ruby和RoR的新手。我有一个带有Ubuntu镜像的干净Linode实例,我想从源代码编译Ruby而不是使用apt-get。我已经在谷歌上搜索了执行此操作的说明,但经过一些尝试后,当我尝试运行一些教程示例时,我不断收到有关缺少zlib和其他一些包的错误。任何人都可以给我详细的说明(或链接),教我如何在从源代码编译Ruby之前安装必要的必备包吗?我的目的是编译Ruby的最新稳定版本,然后安装Rubygems和Rails。提前感谢您的帮助!!! 最佳答案 Thisblogpost涵盖从源代码编译ruby所需的包和安装过程;它引