spi驱动子系统中probe函数的入口参数是怎么传的?

lr2131 2010-09-14 04:41:57
最近一直在做这个关于SPI驱动的项目,之前也没接触过Linux内核下的驱动,虽然以前用过单片机和ARM,能够使用GPIO模拟SPI来驱动外设,但现在换到Linux内核下需要用到Linux内核提供的方法来与底层SPI打交道,而反倒很不习惯,只能硬着头皮做了。看了一些程序,先简要的列一下流程:
1 static int aic26_probe(struct spi_device *this_dev)
{
if (this_dev)
{
aic26_spi_obj.spi = this_dev;
.............................
}
else
{
..........
}
..........
}
2 static struct spi_driver aic26_driver = {

.driver = {
.name = AIC26_DRIVER,
},
.probe = aic26_probe,
.remove = aic26_remove,

};
3 err = spi_register_driver(&aic26_driver);

问题:aic26_probe中的入口参数*this_dev是怎么传进来的,我知道这个函数是系统来调用的,这里的这个参数也是系统传进的,但我在程序运行时,发现这个this_dev是NULL,接下来对SPI的读写都是无效的,虽然platform_device_register()、
driver_register()、spi_register_driver()都成功返回。
而查看了/sys/bus/spi/driver,/sys/bus/platform/driver,/sys/bus/platform/device,都加载成功,而唯独在/sys/bus/spi/device中没有看到相关信息,我想应该是我的spi设备没有加载成功吧。现在我也不知道问题在哪,是不是platform_device_register()、driver_register()、spi_register_driver()过程中还是有问题。请高手指导,如果可以的话能不能提供一个简单的SPI子系统实例参考一下,实在是弄不明白,谢谢了。
...全文
1031 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
lr2131 2010-12-08
  • 打赏
  • 举报
回复
谢谢大家的回复,好久没上了。看了回复,基本上是说到点子上了有些,虽然最后还是没有完全搞明白问题出在哪,但问题也基本上解决了。
tgvlcw 2010-10-19
  • 打赏
  • 举报
回复
  楼上几位回答得都不错,但考虑到楼主可能是新手,理论的东西,太深了楼主也可能不太懂。我就举个例子吧,比如我用的是S3C6410的芯片。在arch/arm/plat-s3c64xx/目录下有一个文件叫devs.c,这个文件定义了板子上的各种各样的硬件资源,热插拔的除外。定义了硬件资源后,需要注册进内核,在arch/arm/mach-s3c6410目录下有一个文件叫mach-smdk6410.c这个文件最主要的功能就是将前面已经定义的硬件资源注册进内核,查看源代码就可以发现,最终调用的是一个platform_add_devices函数,在住里看这个函数调用了platform_device_register函数。那么在系统启动的时候,会将已经定义的硬件资源注册进内核,如果驱动是以模块编译的,在模块加载之前,platform_device_register调用的时候,会去匹配相应的驱动。因为是以模块编译的,驱动没有加载,所以匹配不了,硬件就不能工作。当手工加载模块进内核后,调用一个platform_driver_register的函数,这个函数会在一次进行设备与驱动的匹配,而硬件资源已经加载进内核了,这时就会匹配成功。这样在驱动中经过一系列的初始化后,硬件就可以工作了。
  当然,也可以将硬件资源与驱动的注册全部放在加载驱动的时候完成,也即是在你的驱动程序中调用platform_device_register和platform_driver_register这两个函数,不过这样不好。不利于理解。
  楼主你可以到你的arch/arm/plat-xx和arch/arm/mach-xx两个目录找找,上面所讲的硬件资源的定义与注册都是在这两个目录下。
  楼主在弄SPI驱动的话,建议把SPI子系统好好研究研究,这应该是linux驱动的各种子系统中最简单的了。我用的内核版本的是2.6.27,这个版本的SPI子系统比较简单,之后版本的SPI都要与DMA打交道,不容易理解。
井朝天 2010-10-14
  • 打赏
  • 举报
回复
http://blog.csdn.net/laojing123/archive/2010/10/14/5941615.aspx
somehc240 2010-10-14
  • 打赏
  • 举报
回复
在board.c 文件中有 spi_board-info 结构 在里面要加上你的设备的配置信息,设备名字,名字要和driver的一样 就能调用probe了也能看到设备了 spi/devices 下面能看到spi0.0 spi0.1之类的 里面有个modias的属性 你cat一下 就是你设备的名字,
qianjin0703 2010-09-27
  • 打赏
  • 举报
回复
系统初始化的时候要把你所需要的spi设备注册一下,加到一个双向循环链表中,系统加载spi主设备的时候会根据此链表逐一地注册spi设备
手机写程序 2010-09-25
  • 打赏
  • 举报
回复
记得好像是修改arch.c里SPI部分的内容,可能被注释了吧。
lr2131 2010-09-15
  • 打赏
  • 举报
回复
谢谢回帖,看来是时候看内核源码了。
soon 2010-09-15
  • 打赏
  • 举报
回复
首先说明,由于硬件关系,我没有做过SPI相关的实验,不过从做过的几个相关的子系统来看,还是先搞懂SPI子系统的构架,实现过程比较好,如果C还够用的话,可以直接到内核去看源代码,这样写起来才好。

本人第一次进行内核查看源码的是I2C子系统,用过I2C的都知道,裸机AT24C08的从机地址是0xA0,而在I2C子系切要求为0x50,还有为什么像AT24C08这类读需要两次启动I2C总线的器件为什么应用read不能完成等,看别人写的测试程序,一点都不懂,可以说是肓目搬照。后来,因为需要应用I2C算法与SMBus算法,所以不得不去查看源码,从这一次后,每学习一个子系统,都会去查看源码,分析。结果还真不一样。


lr2131 2010-09-15
  • 打赏
  • 举报
回复
我只用到了platform_device_register()、driver_register()、spi_register_driver()
这三个函数,是不是还得用device_register()之类的函数呀,确实应该是设备没有注册。我做了个验证,无视this_dev == NULL,继续读写寄存器,发现内核报错,大义似乎是操作了不该操作的空间。我加个注册设备的函数试试。
deep_pro 2010-09-14
  • 打赏
  • 举报
回复
我想需要你手动加一些代码,注册spi平台设备
deep_pro 2010-09-14
  • 打赏
  • 举报
回复
我熟悉pci ,pci也有这样的probe函数,我提供的仅供参考

Linux中总线、设备、驱动 这3者是非常重要的数据结构,它们互相之间都有联系
一旦一个设备和一个驱动能够匹配上,就会执行驱动里的probe

而probe的参数,pci里是struct pci_dev *pdev ,这个是由linux内核启动时遍历pci总线后得到的pci设备的描述符

所以我猜测,spi总线初始化时也会扫描总线上的设备

这里/sys/bus/spi/device 没有信息,不是你驱动的错
而是内核不知道有什么spi设备

4,437

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 内核源代码研究区
社区管理员
  • 内核源代码研究区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧