尝试 select 一个 i2c 地址抛出 ioctl 失败:参数无效

Trying to select an i2c address throws ioctl failed: invalid argument

我正在 Common Lisp 中构建一个程序,该程序使用 raspberry pi 3B+ 上的 sysfs 通过 i2c 与 pca9685 通信。

初始化设备时,我需要使用 (ioctl fd +i2c-slave+ addr) select pca,其中 +i2c-slave+ = xf0703(selecting slave 的命令)和 addr = 0x40 (对于 pca9685)

但是从调用中我得到一个错误:

IOCTL 1795 failed: Invalid argument
[Condition of type SIMPLE-ERROR]
0: ((SETF I2C::IOCTL) 64 10 1795)
1: (I2C:I2C-START #S(I2C:I2C-DEV :FILENAME "/dev/i2c-1" :DEV 1 :ADDR 64))

我正在使用 cl-spidev 的 ioctl 实现。

由于我是sbcl,所以相关函数是

(defun (setf ioctl) (arg fd cmd)
  (sb-alien:with-alien ((value sb-alien:int))
    (setf value arg)
    (multiple-value-bind (wonp error)
        (sb-unix:unix-ioctl (stream-fd fd)
                            (if (< cmd (expt 2 31)) cmd (- cmd (expt 2 32)))
                            (sb-alien:alien-sap (sb-alien:addr value)))
      (unless wonp
        (error "IOCTL ~a failed: ~a" cmd (sb-impl::strerror error))))
    arg))

它是这样叫的

(setf (ioctl fd cl-i2c-lli:+i2c-slave+) addr)

我目前的猜测是 ioctl 函数正在传递一个指针,虽然它应该是一个普通的 long(根据 the docs),但我仍然无法完全理解它。我是否漏掉了一些明显的东西?

Adafruit python 库和 some 示例 C 实现的工作方式相同。

注释

您的假设是正确的,您正在使用的这个包装函数调用 ioctl 并带有指向您的值而不是值的指针。

你有没有简单地尝试过(sb-unix:unix-ioctl fd cl-i2c-lli:+i2c-slave+ addr)