linx下如何驱动spi

linx下如何驱动spi,第1张

1、驱动分为平台驱动、控制器驱动、设备驱动、设备。

2、拿到一个开发板后,烧上系统,那我们基本上就有了平台驱动、控制器驱动。设备驱动基本都有的,官方实现了一个设备驱动,文件是spidev.c,它是一个设备驱动,它会在开机之后自动注册一个主设备号为153的字符设备。

3、当注册了SPI设备到系统中时,会根据名字进行匹配,如果名字是spidev则会调用 spidev.c中的probe函数,随后会在/dev/device/下面生成如spidevx.x的设备文件,通过该设备文件即可 *** 作SPI设备。

4、如何注册SPI设备到系统。在kernel/arch/arm/mach-xxxx,xxx是板子芯片型号,我用的事 mach-smdk6410.c。在里面找到spi_board_info结构体位置,例如:

static struct spi_board_info __initdata forlinx6410_mc251x_info[] = {

{

.modalias = "mcp2515",

.platform_data = &mcp251x_info,

.irq = IRQ_EINT(16),

.max_speed_hz = 10*1000*1000,

.bus_num = 1,

.chip_select = 0,

.mode = SPI_MODE_0,

.controller_data=&s3c64xx_spi1_csinfo,

},

}

本结构体就是SPI的板级信息,会在后面被spi_register_board_info()调用,随后在系统中注册这个设备。

我们需要做的是添加我们自己的信息

static struct spi_board_info __initdata forlinx6410_mc251x_info[] = {

{

.modalias = "mcp2515",

.platform_data = &mcp251x_info,

.irq = IRQ_EINT(16),

.max_speed_hz = 10*1000*1000,

.bus_num = 1,

.chip_select = 0,

.mode = SPI_MODE_0,

.controller_data=&s3c64xx_spi1_csinfo,

},

{

.modalias = "spidev", //用来匹配设备驱动,SPI的设备驱动叫spidev

.max_speed_hz = 10*1000*1000, //最大速率

.bus_num = 0, //在(0)号总线上

.chip_select = 0, //使用片选spi0_cs0

.mode = SPI_MODE_0, //SPI模式

.controller_data=&s3c64xx_spi0_csinfo,//控制器信息 },

}

其中的static struct s3c64xx_spi_csinfo s3c64xx_spi0_csinfo = {

.fb_delay=0x3,

.line=S3C64XX_GPC(3),//这个是片选控制引脚

.set_level=cs_set_level,

}

然后编译内核下载开发板上,重新启动过后就能后在/dev下面看到spidev0.0设备文件。

猜想:

写一个模块,收到填写该结构体,然后调用spi_register_board_info()来注册。我没有试过,应该是可以的。

5、使用的时候在用户应用空间中就使用open打开设备文件即可使用。

需要在封装一次。由于spidev.c仅提供数据接收与发送,但是对于具体的SPI怎么发的好像没有做。

因此我们具体的收发函数应该在此分装为如下

int fd

fd=open(device, O_RDWR)

读函数

输入:fd文件描述符,addr读的地址,read_data读出来数据存放的地址

输出:成功 *** 作的字节数,这个没有做好,需要改

unsigned char read_reg(int fd,unsigned char addr,unsigned char *read_data)

{

int ret=0

addr=addr<<1

addr=addr|0x80

ret=write(fd,&addr,sizeof(unsigned char))

ret|=read(fd,read_data,sizeof(unsigned char))

return ret

}

写函数

unsigned char write_reg(int fd,unsigned char addr,unsigned data)

{

int ret=0

unsigned char buff[2]={0}

buff[0]=addr<<1

buff[0]=buff[0]&0x7f

buff[1]=data

ret=write(fd,&buff,sizeof(buff))

return ret

}

然后其他具体 *** 作看我们的实际需要了,以上两个就可以正确读写了,你可以先用读函数读取设备各个寄存器的默认值,来观察读取是否正确。

如上DTS文件片段,SPI Device 节点必须定义在 SPI Master 节点下,其中 compatible 属性和 reg 属性,以上 compatible 属性用于匹配对应的 Driver 程序,reg 属性用于指定使用的 SPI Master 的编号,SPI 相关设备树文件识别见下文讲解。

匹配设备树文件在SPI子系统中有两个地方:在 spi_register_master() 中匹配和在 device register 时通过内核的通知链(notifier_block)来调用设备树匹配相关程序。

在 device register 时,需配置 CONFIG_OF_DYNAMIC 宏以开启动态匹配才能够使用设备树添加设备,该宏在 menuconfig/Device Drivers/Device Tree and Open Firmware support 中开启,如下图:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11856002.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存