在用户空间程序/ SPI应用程序中包含驱动程序

时间:2017-11-06 16:18:59

标签: c linux linux-device-driver userspace

目前我正在寻求使用Cadence SPI驱动程序在Linux上执行一些基本的读写操作。我刚刚使用了I2C驱动程序,但是我仍然对所有这些驱动程序如何组合以及是否存在它们都符合的通用接口感到困惑。

以下是我编写的使用I2C驱动程序的代码

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>

#include <errno.h>
#include <string.h>

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>

#define I2C_ADAPTER                 "/dev/i2c-0"
#define I2C_SWITHC_MUX_ADDRESS      0x74
#define DEVICE_ADDRESS              0x54


int main (int argc, char *argv[])
{
    int file;

    uint8_t reg, value;

    char *end;

    /* Take a value to write */

    printf("The device address on the bus: %d", DEVICE_ADDRESS);

    if(argc == 2) {
        value = strtol(argv[1], &end, 16);
        printf("value to write is: %d\n", value);
    }
    else {
        printf("arg failed\n\n.");
    }


    if((file = open(I2C_ADAPTER, O_RDWR)) < 0) {
        printf("Failed to open the bus\n");
        return -1;
    }

    if(ioctl(file, I2C_SLAVE_FORCE, I2C_SWITHC_MUX_ADDRESS) < 0) {
        printf("Unable to open device as slave \n%s\n", strerror(errno));
        return -1;
    }

    char buf[10];

    reg = DEVICE_ADDRESS;

    buf[0] = reg;
    buf[1] = value;

    if(write(file, buf, 2) != 2) {
        printf("Failed to write to bus %s.\n\n", strerror(errno));
    }
    else {
        printf("Successful write\n");
        printf(buf);
        printf("\n\n");
    }

    if(read(file, buf, 1) != 1) {
        printf("Failed to read from the i2c bus.\n %s\n\n", strerror(errno));
    }
    else {
        printf("Successful read\n");
        printf("Buf = [%02u]\n", buf[0]);
        printf("\n\n");
    }

    return 0;
}

我对实际调用驱动程序的位置感到困惑。现在我在这里阅读SPI驱动程序文档:

https://www.kernel.org/doc/html/v4.11/driver-api/spi.html

I2C驱动程序的相应文档位于:

https://www.kernel.org/doc/html/v4.11/driver-api/i2c.html

I2C文档中定义的第一个结构是i2c_driver。我不认为在编写I2C程序时,我使用了I2C驱动程序文档中定义的任何结构。我是否真的使用过I2C Cadence驱动程序?如果没有,我的程序如何被重写以使用I2C Cadence驱动程序,这样我就可以了解如何在用户空间中使用驱动程序,以便我可以使用SPI驱动程序。

2 个答案:

答案 0 :(得分:0)

把我的两分钱放进去,你可以选择使用i2c-tools实用程序。这很容易用linux处理i2c设备。参考如何使用它。 https://elinux.org/Interfacing_with_I2C_Devices

答案 1 :(得分:0)

这是从内核空间I2C框架到Cadence I2C驱动程序(与read()/write()类似)的调用堆栈的样子:

  1. 用户空间驱动程序ioctl()调用compat_i2cdev_ioctl()中的i2c-dev.c
  2. i2cdev_ioctl_rdwr()i2c_transfer()中呼叫i2c-core-case.c
  3. __i2c_transfer()呼叫adap->algo->master_xfer()

当您在.master_xfer函数中注册I2C驱动程序时,该函数指针i2c-cadence.c会用probe()中定义的回调进行初始化:

id->adap.algo = &cdns_i2c_algo;

struct i2c_algorithm cdns_i2c_algo = {
.master_xfer    = cdns_i2c_master_xfer,

希望有帮助。