ImageVerifierCode 换一换
格式:DOCX , 页数:11 ,大小:342.54KB ,
资源ID:29225070      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/29225070.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Linux下SPI驱动测试程序.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Linux下SPI驱动测试程序.docx

1、Linux下SPI驱动测试程序Linux下SPI驱动测试程序Linux下的SPI总线驱动(一)2013-04-12 15:08:46分类:LINUX版权所有,转载请说明转自一SPI理论介绍SPI总线全名,串行外围设备接口,是一种串行的主从接口,集成于很多微控制器内部。和I2C使用2根线相比,SPI总线使用4根线:MOSI (SPI 总线主机输出/ 从机输入)、MISO (SPI总线主机输入/从机输出)、SCLK(时钟信号,由主设备产生)、CS(从设备使能信号,由主设备控制)。由于SPI总线有专用的数据线用于数据的发送和接收,因此可以工作于全双工,当前市面上可以找到的SPI外围设备包括RF芯片、

2、智能卡接口、E2PROM、RTC、触摸屏传感器、ADC。SCLK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCLK 时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCLK时钟线的控制可以完成对通讯的控制。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和

3、采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C 系统要稍微复杂一些。二SPI驱动移植我们下面将的驱动的移植是针对Mini2440的SPI驱动的移植Step1:在Linux Source Code中修改arch/arm/mach-s3c2440/文件,加入头文件:#include #include 然后加入如下代码:static struct spi_board_info s3c2410_spi0_board = 0 =

4、.modalias = spidev, us_num = 0, hip_select = 0, rq = IRQ_EINT9, ax_speed_hz = 500 * 1000, in_cs = S3C2410_GPG(2), .num_cs = 1, us_num = 0, pio_setup = s3c24xx_spi_gpiocfg_bus0_gpe11_12_13, odalias = spidev, .bus_num = 1, .chip_select = 0, .irq = IRQ_EINT2, .max_speed_hz = 500 * 1000, ;static struct

5、s3c2410_spi_info s3c2410_spi1_platdata = .pin_cs = S3C2410_GPG(3), .num_cs = 1, .bus_num = 1, .gpio_setup = s3c24xx_spi_gpiocfg_bus1_gpg5_6_7,;Step2:在mini2440_devices平台数组中添加如下代码:&s3c_device_spi0,&s3c_device_spi1,Step3:最后在mini2440_machine_init函数中加入如下代码: &s3c2410_spi0_platdata;spi_register_board_info(

6、s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board); &s3c2410_spi1_platdata;spi_register_board_info(s3c2410_spi1_board, ARRAY_SIZE(s3c2410_spi1_board);Step4:最后需要修改arch/arm/plat-s3c24xx/KConfig文件找到config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 bool help SPI GPIO configuration code for BUS0 when connected t

7、o GPE11, GPE12 and GPE13.config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7 bool help SPI GPIO configuration code for BUS 1 when connected to GPG5, GPG6 and GPG7.修改为config S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 bool S3C24XX_SPI_BUS0_GPE11_GPE12_GPE13 help SPI GPIO configuration code for BUS0 when connected to GPE11

8、, GPE12 and GPE13.config S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7 bool S3C24XX_SPI_BUS1_GPG5_GPG6_GPG7 help SPI GPIO configuration code for BUS 1 when connected to GPG5, GPG6 and GPG7.Step5:最后make menuconfig配置,选中System Type和SPI support相应文件Step6:执行make生成zInage,将编译好的内核导入开发板,并且编译测试程序运行即可。好了,我们的SPI驱动移植就做好了,我们可以编

9、写SPI测试代码进行测试。三SPI设备和驱动的注册在SPI子系统中,包含两类设备驱动。一类称之为.SPI主控设备驱动,用于驱动SPI主控设备,以和SPI总线交互,读写通信数据。另一类称之为SPI接口设备驱动,用于解析SPI主控设备驱动读取的数据,形成有意义的协议数据。下面我们就看看SPI主控设备的注册、SPI主控设备驱动的注册、SPI接口设备的添加、SPI接口设备的注册、SPI接口设备驱动的注册五个过程。主控设备的注册我们在移植的Step3:最后在mini2440_machine_init函数中加入如下代码: &s3c2410_spi0_platdata;spi_register_board_

10、info(s3c2410_spi0_board, ARRAY_SIZE(s3c2410_spi0_board); &s3c2410_spi1_platdata;spi_register_board_info(s3c2410_spi1_board, ARRAY_SIZE(s3c2410_spi1_board);这里面的s3c_device_spi0其实定义在archarmplat-s3c24xx中,跟踪下static struct resource s3c_spi0_resource = 0 = .start = S3C24XX_PA_SPI, .end = S3C24XX_PA_SPI + 0

11、x1f, .flags = IORESOURCE_MEM, , 1 = .start = IRQ_SPI0, .end = IRQ_SPI0, .flags = IORESOURCE_IRQ, ;static u64 s3c_device_spi0_dmamask = 0xffffffffUL;struct platform_device s3c_device_spi0 = .name = s3c2410-spi, .id = 0, .num_resources = ARRAY_SIZE(s3c_spi0_resource), .resource = s3c_spi0_resource, .d

12、ev = .dma_mask = &s3c_device_spi0_dmamask, .coherent_dma_mask = 0xffffffffUL ;EXPORT_SYMBOL(s3c_device_spi0);这样就能理解移植时添加 &s3c2410_spi0_platdata代码,其实是把s3c2410_spi0_platdata作为平台设备的私有数据。在s3c_device_spi0中就包含了设备的寄存器地址,设备名称,设备所产生的总线号,总线挂载的数目,及各种配置函数。然后由函数platform_add_devices(smdk2440_devices, ARRAY_SIZE(s

13、mdk2440_devices);统一把2440所有设备进行注册。然后看下这个platform_add_devices注册函数主要干了什么事情。在linux/drivers/base /中105行定义了这个函数。函数调用platform_device_register()来进行注册。然后在platform_device_regisrer中调用device_initialize(pdev-dev)platform_device_add(pdev)这俩个函数,从函数名称上我们推断一个是初始化设备信息中的dev结构体,另一个是把这个设备增加到什么地方去。首先看初始化dev结构体。初看下初始化了kob

14、j相关东西,初始化链表,同步锁,还有相关标志。然后看platform_device_add里面内容。把其中一个pdev-=& platform_bus_type (全局变量)至此我们基本可以确定了,这个设备属于platform_bus_type。所以这个设备的总线信息就知道了,但是总线还不知道这个设备,不过放心,在接下来的初始化过程中有一个函数bus_add_device,会让总线知道这个函数。这样至此我们就把一个设备注册完毕,初始化了一些我们能初始化的东西。结果之一是设备在总线上可以找到。SPI接口设备的添加在移植的Step1中,曾经添加了如下代码static struct spi_boar

15、d_info s3c2410_spi0_board = 0 = .modalias = spidev, us_num = 0, hip_select = 0, rq = IRQ_EINT9, ax_speed_hz = 500 * 1000, /SPI的最大速率 ;上面结构体来填充SPI接口的设备信息,然后通过函数spi_register_board_info(s3c2410_spi0_board,ARRAY_SIZE(s3c2410_spi0_board);注册。下面来跟踪下这个函数干了些什么事情。int _init spi_register_board_info(struct spi_bo

16、ard_info const *info, unsigned n) struct boardinfo *bi; bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL); if (!bi) return -ENOMEM; bi-n_board_info = n;/把s3c2410_spi0_board 的信息都拷贝到结构体 memcpy(bi-board_info, info, n * sizeof *info); mutex_lock(&board_lock); list_add_tail(&bi-list, &board_list);

17、 mutex_unlock(&board_lock); return 0;在这个函数里面,是把s3c2410_spi0_board的信息都拷贝到结构体struct boardinfo struct list_head list; unsigned n_board_info; struct spi_board_info board_info0;这里使用编程技巧定义个元素为0的数组,目的是接收s3c2410_spi0_borad里面的不确定元素,因为事先不知道元素的多少。然后在系统编译的时候会把board_info的内存默认为0,所以赋值的时候还要自动申请内存。memcpy(bi-board_in

18、fo, info, n * sizeof *info);然后定义了同步锁,创建了链表。list_add_tail(&bi-list, &board_list);这部分好像就到这个地方了,系统把信息保存到一块内存中,我们可以通过全局变量board_list找到这块地方。 SPI主控设备驱动的注册在文件中static int _init s3c24xx_spi_init(void) return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe);在platform_driver_probe中会调用platform_drive

19、r_register(drv);继续跟踪int platform_driver_register(struct platform_driver *drv) drv- = &platform_bus_type; /总线类型 if (drv-probe) drv- = platform_drv_probe; if (drv-remove) drv- = platform_drv_remove; if (drv-shutdown) drv- = platform_drv_shutdown; return driver_register(&drv-driver);看到没这个和SPI主控设备的注册过程中

20、的最终挂接的总线类型是一致的。这样SPI主控设备和SPI主控驱动都要注册到同一个总线上,总线再根据名称一样来进行匹配。 SPI接口设备的注册我们继续看在文件在s3c24xx_spi_probe里面我们调用spi_bitbang_start(&hw-bitbang);这就是SPI接口驱动的注册。跟踪spi_bitbang_start函数,我们看到它调用了spi_register_master(bitbang-master);在函数spi_register_master()里面有一函数调用scan_boardinfo(master);用来扫描设备。static void scan_boardinf

21、o(struct spi_master *master)struct boardinfo *bi;mutex_lock(&board_lock);list_for_each_entry(bi, &board_list, list) /通过board_list遍历链表,取得设备信息struct spi_board_info *chip = bi-board_info;unsigned n;for (n = bi-n_board_info; n 0; n-, chip+) if (chip-bus_num != master-bus_num)continue;(void) spi_new_devi

22、ce(master, chip);mutex_unlock(&board_lock);我们跟踪scan_boardinfo中的spi_new_device函数发现,spi_new_device调用spi_alloc_device,而在spi_alloc_device函数中有一句spi- = &spi_bus_type;这说明该设备就挂在全局变量spi_bus_type总线上了。然后在spi_new_device中调用spi_add_device函数,目的我们已经看到,最终SPI接口的设备注册到了spi_bus_type上了,如果把SPI接口设备的驱动也注册到这个总线上,然后根据名称进行匹配则d

23、evice和driver就配对成功。 SPI接口设备驱动的注册我们以的驱动为例,来追踪该驱动的注册static int _init spidev_init(void)int status;BUILD_BUG_ON(N_SPI_MINORS 256);status = register_chrdev(SPIDEV_MAJOR, spi, &spidev_fops); /注册字符设备if (status 0)return status;spidev_class = class_create(THIS_MODULE, spidev);if (IS_ERR(spidev_class) unregist

24、er_chrdev(SPIDEV_MAJOR, return PTR_ERR(spidev_class);status = spi_register_driver(&spidev_spi); /注册SPI接口设备驱动if (status = &spi_bus_type;if (sdrv-probe)sdrv- = spi_drv_probe;if (sdrv-remove)sdrv- = spi_drv_remove;if (sdrv-shutdown)sdrv- = spi_drv_shutdown;return driver_register(&sdrv-driver);好了,我们在spi_register_driver里看到了sdrv- = &spi_bus_type;这说明我们的SPI设备驱动也接到了SPI总线上了,这个正好跟我们上面说的SPI接口设备的注册中提到的SPI设备也注册到SPI总线的,这样就可以通过驱动名匹配上了。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1