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 中开启,如下图:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)