应用程序和驱动中使用SPI设备的流程
2017-03-02 11:26
295 查看
编写SPI设备驱动有两种方法。一种是利用系统给我们提供的spidev.c来实现一个spi适配器的设备文件。然后通过在应用层操作spi适配器来控制spi设备。另一种是为spi设备,独立编写一个设备驱动。注意:在后一种情况下,是不需要使用spidev.c的。
前一种方法也就是说只要系统实现了spi适配器的驱动并生成了设备文件, 那么挂在其上面的spi设备也可以在应用层直接通过操作这个设备文件来间接控制这个spi设备, 这样就省去了专门为这个设备编写驱动的麻烦。本文将详细描述在应用层和驱动层分别控制spi设备的流程。
关于在应用层如何使用spidev驱动的问题, 可以参考源码的documenation/spi目录下的文档, 其中spidev_test.c就是一个测试程序,可以参考。
下面将结合本人工作中实现的一个例子来介绍应用层使用spidev的流程。实际上流程比较简单:打开设备文件 -> 配置设备 -> 读写设备 -> 关闭设备文件。
1. 打开设备文件:
#defineICCARD_DEVICE_FILE ("/dev/spidev0.0") /*spi controller device file*/
/*1.open lcd device*/
fd_iccard= open(ICCARD_DEVICE_FILE, O_WRONLY);
if(fd_iccard< 0) {
LOGE("can'topen ICCARD device file");
return0;
}
跟打开普通的文件没有什么区别。
2. 配置设备:
static uint8_ticcard_spi_mode = SPI_MODE_3; /*spi operation mode*/
/*2.initialize SPI controller*/
/*
* spi mode
*/
ret= ioctl(fd_iccard, SPI_IOC_WR_MODE, &iccard_spi_mode);
if (ret< 0) {
LOGE("can'tset spi mode");
gotoinit_failed;
}
ret =ioctl(fd_iccard, SPI_IOC_RD_MODE, &iccard_spi_mode);
if (ret< 0) {
LOGE("can'tget spi mode");
gotoinit_failed;
}
/*
* bits per word
*/
ret =ioctl(fd_iccard, SPI_IOC_WR_BITS_PER_WORD, &iccard_spi_bits);
if (ret< 0) {
LOGE("can'tset bits per word");
gotoinit_failed;
}
ret =ioctl(fd_iccard, SPI_IOC_RD_BITS_PER_WORD, &iccard_spi_bits);
if (ret< 0) {
LOGE("can'tget bits per word");
gotoinit_failed;
}
/*
* max speed hz
*/
ret =ioctl(fd_iccard, SPI_IOC_WR_MAX_SPEED_HZ, &iccard_spi_speed);
if (ret< 0) {
LOGE("can'tset max speed hz");
gotoinit_failed;
}
ret =ioctl(fd_iccard, SPI_IOC_RD_MAX_SPEED_HZ, &iccard_spi_speed);
if (ret< 0) {
LOGE("can'tget max speed hz");
gotoinit_failed;
}
通过ioctl系统调用设置spi的工作模式(4种模式之一, 参考SPI协议),每个传输单元的位数,最大工作频率等。
3. 读写设备:
static structspi_ioc_transfer iccard_spi_msg = { /*spi message for transfer*/
.speed_hz = 2000000,
.bits_per_word = 8,
.delay_usecs = 0,
}; /*每个传输必须封装成这种格式*/
iccard_spi_msg.tx_buf= (unsigned long) NULL; /*我们的设备只需要读, 所以没有tx_buf*/
while(index< ICCARD_DATA_LEN)
{
iccard_spi_msg.rx_buf = (unsignedlong)&ic_data_ptr[index]; /*读到的数据缓存*/
iccard_spi_msg.len= 1; /*每次读1个字节*/
ret= ioctl(fd_iccard, SPI_IOC_MESSAGE(1), &iccard_spi_msg);
if(ret < 0)
{
LOGE("[AARON]read iccard failed");
return0;
}
index++;
}
同样的,通过ioctl系统调用,发送SPI_IOC_MESSAGE命令给设备,来读取或写入数据。
4. 关闭设备:
close(fd_iccard);
如上描述, spidev给开发人员提供了一种比较简单的操作SPI设备的方式, 开发人员可以不用会编写spi驱动就能使用spi设备。
·~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
关于spi驱动的链接
前一种方法也就是说只要系统实现了spi适配器的驱动并生成了设备文件, 那么挂在其上面的spi设备也可以在应用层直接通过操作这个设备文件来间接控制这个spi设备, 这样就省去了专门为这个设备编写驱动的麻烦。本文将详细描述在应用层和驱动层分别控制spi设备的流程。
关于在应用层如何使用spidev驱动的问题, 可以参考源码的documenation/spi目录下的文档, 其中spidev_test.c就是一个测试程序,可以参考。
下面将结合本人工作中实现的一个例子来介绍应用层使用spidev的流程。实际上流程比较简单:打开设备文件 -> 配置设备 -> 读写设备 -> 关闭设备文件。
1. 打开设备文件:
#defineICCARD_DEVICE_FILE ("/dev/spidev0.0") /*spi controller device file*/
/*1.open lcd device*/
fd_iccard= open(ICCARD_DEVICE_FILE, O_WRONLY);
if(fd_iccard< 0) {
LOGE("can'topen ICCARD device file");
return0;
}
跟打开普通的文件没有什么区别。
2. 配置设备:
static uint8_ticcard_spi_mode = SPI_MODE_3; /*spi operation mode*/
/*2.initialize SPI controller*/
/*
* spi mode
*/
ret= ioctl(fd_iccard, SPI_IOC_WR_MODE, &iccard_spi_mode);
if (ret< 0) {
LOGE("can'tset spi mode");
gotoinit_failed;
}
ret =ioctl(fd_iccard, SPI_IOC_RD_MODE, &iccard_spi_mode);
if (ret< 0) {
LOGE("can'tget spi mode");
gotoinit_failed;
}
/*
* bits per word
*/
ret =ioctl(fd_iccard, SPI_IOC_WR_BITS_PER_WORD, &iccard_spi_bits);
if (ret< 0) {
LOGE("can'tset bits per word");
gotoinit_failed;
}
ret =ioctl(fd_iccard, SPI_IOC_RD_BITS_PER_WORD, &iccard_spi_bits);
if (ret< 0) {
LOGE("can'tget bits per word");
gotoinit_failed;
}
/*
* max speed hz
*/
ret =ioctl(fd_iccard, SPI_IOC_WR_MAX_SPEED_HZ, &iccard_spi_speed);
if (ret< 0) {
LOGE("can'tset max speed hz");
gotoinit_failed;
}
ret =ioctl(fd_iccard, SPI_IOC_RD_MAX_SPEED_HZ, &iccard_spi_speed);
if (ret< 0) {
LOGE("can'tget max speed hz");
gotoinit_failed;
}
通过ioctl系统调用设置spi的工作模式(4种模式之一, 参考SPI协议),每个传输单元的位数,最大工作频率等。
3. 读写设备:
static structspi_ioc_transfer iccard_spi_msg = { /*spi message for transfer*/
.speed_hz = 2000000,
.bits_per_word = 8,
.delay_usecs = 0,
}; /*每个传输必须封装成这种格式*/
iccard_spi_msg.tx_buf= (unsigned long) NULL; /*我们的设备只需要读, 所以没有tx_buf*/
while(index< ICCARD_DATA_LEN)
{
iccard_spi_msg.rx_buf = (unsignedlong)&ic_data_ptr[index]; /*读到的数据缓存*/
iccard_spi_msg.len= 1; /*每次读1个字节*/
ret= ioctl(fd_iccard, SPI_IOC_MESSAGE(1), &iccard_spi_msg);
if(ret < 0)
{
LOGE("[AARON]read iccard failed");
return0;
}
index++;
}
同样的,通过ioctl系统调用,发送SPI_IOC_MESSAGE命令给设备,来读取或写入数据。
4. 关闭设备:
close(fd_iccard);
如上描述, spidev给开发人员提供了一种比较简单的操作SPI设备的方式, 开发人员可以不用会编写spi驱动就能使用spi设备。
·~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
关于spi驱动的链接
【推荐】 Linux spi驱动分析(三)----spiddev分析 | 7953 | 0 | 11 | 2013-12-30 | |
Linux spi驱动分析(二)----SPI核心(bus、device_driver和device) | 3670 | 0 | 5 | 2013-12-11 | |
Linux spi驱动分析(四)----SPI设备驱动(W25Q32BV) | 10805 | 10 | 11 | 2013-12-06 | |
Linux spi驱动分析(一)----总线驱动 | 8524 | 1 | 7 | 2013-11-13 | |
mini2440 SPI驱动移植 | 2754 | 0 | 1 | 2013-07-12 |
相关文章推荐
- 应用程序和驱动中使用SPI设备的流程
- SPI驱动及设备节点使用讲解
- 应用程序和驱动中使用I2C的流程
- 通过应用程序使用字符设备驱动
- 63 linux内核的SPI设备驱动模型及应用程序调用SPI控制器的方法
- USB自定义设备驱动开发——修改驱动后应用程序无法使用
- 在Zynq 7000平台上使用Linux spidev.c驱动,调试spi设备
- 关于2.6 的 spi驱动,spidev,使用从设备.
- 应用程序和驱动中使用I2C的流程
- 使用模型驱动开发来加速 Android 设备及应用程序的交付
- 关于2.6 的 spi驱动,spidev,使用从设备.
- 设备驱动编写流程之二
- 设备驱动编写流程之一
- 如何让插入的usb设备不自动装载驱动,进而使用libusb成功向设备传送数据
- 从USB设备插上到驱动probe调用流程分析
- Linux驱动程序开发(4) - 字符设备驱动(3)-LED设备驱动和应用程序
- SPI设备的驱动
- 未能创建视频预览。请检查设备连接,确定没有其他应用程序或用户使用该设备
- 块设备驱动向LINUX移植的常规步骤及INITRD的使用
- SPI设备的驱动