C 使用spi bitbang驱动程序

C 使用spi bitbang驱动程序,c,linux,kernel,spi,C,Linux,Kernel,Spi,我正在编写一个内核模块来读写SPI设备(CC1200)。 我的linux设备没有本机SPI,所以我正试图让总线有点问题 我发现linux有内置的bitbang代码(linux/spi/spi_bitbang.h),但我不知道如何设置它。它需要结构作为spi_设备和spi_主机,每一个都需要结构设备,这需要结构作为kobject和更多,其中大多数我不知道如何使用它们,以及如何使用它们来实现简单的位碰撞 我在网上找过一些例子,但实际上没有找到。所包含的bitbang代码没有一次使用,只有一些参考文件

我正在编写一个内核模块来读写SPI设备(CC1200)。 我的linux设备没有本机SPI,所以我正试图让总线有点问题

我发现linux有内置的bitbang代码(linux/spi/spi_bitbang.h),但我不知道如何设置它。它需要结构作为spi_设备和spi_主机,每一个都需要结构设备,这需要结构作为kobject和更多,其中大多数我不知道如何使用它们,以及如何使用它们来实现简单的位碰撞

我在网上找过一些例子,但实际上没有找到。所包含的bitbang代码没有一次使用,只有一些参考文件表明它“简单”

我将非常感谢任何帮助,也许bitbang库甚至不是一条好路。也许我可以自己写(如何高效地完成?我有4个内核,但它在后台运行很多东西)

感谢

由于SPI的性质,即数据由主设备计时和读取,因此主设备的位碰撞驱动程序没有问题,因为从设备不应依赖于稳定的时钟。但当然,这取决于从属设备是否在实践中起作用

如果您使用的是linux内核,则无需实现您自己的位碰撞驱动程序,因为已经有一个
spi gpio.c

我猜如何启动和运行它将是通过定义要在
devicetree
中使用的
GPIO
引脚,然后驱动程序将能够充当任何其他物理层驱动程序

我快速浏览了
drivers/spi/spi gpio.c
源代码,甚至还提供了一个简短的用户指南,说明如何在不使用通用gpio层开销的情况下直接内联访问gpio引脚

/*
 * Because the overhead of going through four GPIO procedure calls
 * per transferred bit can make performance a problem, this code
 * is set up so that you can use it in either of two ways:
 *
 *   - The slow generic way:  set up platform_data to hold the GPIO
 *     numbers used for MISO/MOSI/SCK, and issue procedure calls for
 *     each of them.  This driver can handle several such busses.
 *
 *   - The quicker inlined way:  only helps with platform GPIO code
 *     that inlines operations for constant GPIOs.  This can give
 *     you tight (fast!) inner loops, but each such bus needs a
 *     new driver.  You'll define a new C file, with Makefile and
 *     Kconfig support; the C code can be a total of six lines:
 *
 *    #define DRIVER_NAME  "myboard_spi2"
 *    #define  SPI_MISO_GPIO  119
 *    #define  SPI_MOSI_GPIO  120
 *    #define  SPI_SCK_GPIO   121
 *    #define  SPI_N_CHIPSEL  4
 *    #include "spi-gpio.c"
 */

PS:你确定你的平台没有spi吗?我在HiSilicon工作过的所有SoC都有spi。首先,我要再次检查这一点,编辑:似乎他们已经改变了界面,在4.19及更高版本的现代内核中,你不能再这样做了,原因与i2c不能这样做相同。 我现在就把这个放在这里,也许它会有用。我自己也在为家庭自动化使用较旧的内核,但它是在一个专用网络上

我原来的答覆是:

虽然您可以通过一起破解自己的内核模块来实现这一点,但您可以调查spi gpio自定义,只需加载模块并传递要用作参数的管脚,您可以在运行时执行所有操作,而无需“编译”要使用的管脚。您可以在OpenWrt项目中找到此模块:

我希望在初始化时,它能为您提供某种SPI设备,您可以从用户空间进行写入。请注意,我自己并没有使用过这个模块,但不久前我使用了i2c对应模块,它的工作方式类似

P>可选的,你可以考虑引入一个ARDUIO来与你的SPI总线对话,然后将SPI数据翻译成Linux设备所能理解的东西。 如果你不想制作自己的电路板,纳米电路板可能会满足你的需要,而且成本很低


然后对于接口,您将有几个选择:USB、UART、i2c或1wire,如果您有引脚,甚至还有一个并行接口。例如,github上有一个单线从库:。

你怎么能从PC上访问到bang SPI?这不是一个实时系统。SPI对计时非常挑剔。正确的解决方案可能是让PC机使用MCU,而不是PC机,更像是SoC。我正在重写软件,硬件是定制的,但已经“完成”——设备在总线上。旧的驱动程序是专有的,不再起作用(为了满足需要),所以我知道有人不知怎么做了。此外,SoC将是SPI主控芯片,因此我控制时钟,这对于计时来说应该不会有问题。据我所知,SPI在计时方面非常灵活。这个设备也并没有通信所需的最低频率。所以它是RTLinux还是类似的?而“挑剔的SPI”的程度则取决于你与什么人交流。ADC、定制IC、存储器、显示器、无线电芯片、MEMS等都倾向于对时间进行挑剔。你不能发送时钟的4位,然后一段时间后再回来发送其余的。除非从机是哑移位寄存器,否则它不敏感。它是HiSilicon SoC上的armv7l Linux 4.4.35。我正在与一个通用的868MHz射频芯片CC1200通信,我想将其设置为只捕获wmbus(单向)数据包,然后从用户空间程序读取它们。我已经为这个芯片编译了内核模块,但是它在868频段上使用了不同的无线协议,而且它是封闭源代码的,所以我必须重新编写它,而且我不容易在网上找到任何示例。所以它仍然是某种PC。我怀疑你的无线电芯片会不会高兴,如果你中断SPI传输去咀嚼上下文开关一两年。这完全取决于您的实时性要求和芯片的时序要求。无论如何,即使你有一个合适的MCU,比特爆炸总是一个坏主意。我看过通用比特爆炸的linux内核实现,但是有太多的结构我不知道如何初始化,所以我最终制作了自己的子例程。结果相当可靠,只有调试内核打印看起来非常慢,但尽管从设备似乎可以处理字节之间的抖动和延迟。此外,我认为我的HiSilicon芯片有一些SPI,但我正在开发一个产品的现有实现,我的目标是重新使用它,所以我必须使用我现有的,不幸的是。它连接到通用GPIO pin。使用其中一种标准实现的主要好处是,它由希望解决安全问题的人维护,并且已经连接到系统的其他部分,例如
/dev/spidev0.0
。如果不需要,您了解的自定义实现可能比配置错误的通用驱动程序更快、更安全。