linux 驱动 insmod和probe函数

今天写了一个在2.6.35下的spi设备的驱动程序(写成模块,没编译进内核),按我对这类驱动程序的理解,该做的都做了,板文件都改过了,添加了spi_board_info,重新编译过,重新烧进板里了。
然后驱动函数实现了,init、exit、probe、remove、还有作为字符设备实现了操作集中的open、release、read、write等。。
问题是,当我insmod的时候是很顺利的,rmmod的时候也是很顺利的。insmod之后,/dev/下能找到我的设备文件的,问题是,不能用mknod(暂时忘了提示什么。。),同时,写一个c程序做测试,运行到open这个设备的时候,open函数的返回值是-1,即打不开,而且没有调用我写的open函数。。
回想一下,其实我的probe函数是有输出信息的,而实际情况中,从来没有见到这句话输出,所以想问一下到底什么时候会调用probe函数,还有insmod具体做了什么(本来以为insmod之后,内核发现有新的驱动,就会去match是否有新的设备,与此同时调用probe函数。。现在觉得理解错了)?

 
1个答案

probe函数的确是在driver和device绑定后执行的,一般建立device可以是静态的,也可以是动态建立,如果你想在arch下面的devices.c去静态建立设备,则你要注意你的spi_board_info是否有真正的注册到内核中去,示例代码如下:

   
 
     
  1. static struct spi_board_info xxx_spi0_board_info[] = {
  2.         {
  3.             .modalias = "xxx_spidev",
  4.             .bus_num = 0,
  5.             .chip_select = 0,
  6.             .max_speed_hz = 2 * 1000 *1000,
  7.         },
  8. };

添加如上结构后,在devices.c最后面会有一个函数去注册spi_board_info:

   
 
     
  1. static void __init xxx_init_machine(void)
  2. {
  3.         ...
  4.         spi_register_board_info(xxx_spi0_board_info,
  5.                                 ARRAY_SIZE(xxx_spi0_board_info));
  6.         ...
  7. }

如果device成功创建,则需要检查驱动程序里面的spi_driver.id_table.name与spi_board_info.modalias是否一致,因为driver和device是否绑定就是比较这两个name是不是相同的。driver里面的示例代码如下:

   
 
     
  1. static const struct spi_device_id xxx_spidev_ids[] = {
  2.         { "xxx_spidev", 1 },
  3.         { },
  4. };
  5. MODULE_DEVICE_TABLE(spi, xxx_spidev_ids);
  6. static struct spi_driver xxx_spidev_spi_driver = {
  7.         .driver = {
  8.             .name   = "xxx_spidev",
  9.             .owner  = THIS_MODULE,
  10.         },
  11.         .id_table = xxx_spidev_ids,
  12.         .probe  = xxx_spidev_probe,
  13.         .remove = __devexit_p(xxx_spidev_remove),
  14. };

insmod对我们来说最主要就是执行*.ko里面__init修饰的函数,一般在这个函数里面去注册driver,注册dirver的函数会通过name匹配是否有device存在,如果存在则执行probe函数。

关于动态建立device,spi调用的函数如下:

   
 
     
  1. struct spi_device *spi_new_device(struct spi_master *master,
  2.                                       struct spi_board_info *chip)

对于它的具体用法可以在内核代码里面找到参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
移植Linux摄像头驱动需要以下步骤: 1.了解摄像头硬件的接口和协议,以及摄像头的型号和厂商信息。 2.下载并安装Linux内核源代码,确保内核版本与目标设备的内核版本相同。 3.编写摄像头驱动程序,包括初始化、打开、关闭、读取和写入等函数。 4.将驱动程序编译成内核模块或静态链接到内核中。 5.将编译好的驱动程序拷贝到目标设备上,并加载驱动程序。 6.测试驱动程序是否正常工作,包括摄像头是否能够被正确识别和使用。 以下是一个简单的示例,演示如何移植Linux摄像头驱动: 1.首先,需要了解摄像头硬件的接口和协议,以及摄像头的型号和厂商信息。 2.下载并安装Linux内核源代码,确保内核版本与目标设备的内核版本相同。 3.编写摄像头驱动程序,包括初始化、打开、关闭、读取和写入等函数。例如: ```c #include <linux/module.h> #include <linux/kernel.h> #include <linux/usb.h> static struct usb_device_id my_usb_table[] = { { USB_DEVICE(0x1234, 0x5678) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, my_usb_table); static int my_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { printk(KERN_INFO "USB device (%04X:%04X) plugged\n", id->idVendor, id->idProduct); return 0; } static void my_usb_disconnect(struct usb_interface *interface) { printk(KERN_INFO "USB device removed\n"); } static struct usb_driver my_usb_driver = { .name = "my_usb_driver", .id_table = my_usb_table, .probe = my_usb_probe, .disconnect = my_usb_disconnect, }; static int __init my_usb_init(void) { return usb_register(&my_usb_driver);} static void __exit my_usb_exit(void) { usb_deregister(&my_usb_driver); } module_init(my_usb_init); module_exit(my_usb_exit); MODULE_LICENSE("GPL"); ``` 4.将驱动程序编译成内核模块或静态链接到内核中。例如: ```bash make -C /usr/src/linux M=$PWD modules ``` 5.将编译好的驱动程序拷贝到目标设备上,并加载驱动程序。例如: ```bash insmod my_usb_driver.ko ``` 6.测试驱动程序是否正常工作,包括摄像头是否能够被正确识别和使用。例如: ```bash dmesg | tail ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值