RV1106 SPI 无法阻塞式接收问题

  • 您好,SPI协议中SCK的时钟信号都是主机发送的,引脚悬空时SPI控制器仍然会尝试接收数据所以在软件上不会表现出阻塞
  • 引脚悬空,sck引脚和MOSI引脚上均无信号,为什么会判断接收到了数据呢?
    请问有没有这方面的资料推荐呢?
  • 这种和内核相关的建议直接查看源码,SPI例程相关的部分在drivers/spi/spidev.c中,大概的流程为
    1 匹配到“rockchip,spidev”后默认调用unlocked_ioctl(对应函数spidev_ioctl),本身调用的就是不阻塞的ioctl函数
    2 先获取到SPI_IOC_WR_MODE 和 SPI_IOC_WR_BITS_PER_WORD 从用户空间传入的参数
    3 调用spidev_get_ioc_message检查传入的spi_ioc_transfer 结构体是否合法,合法就将数据拷贝到内核空间(memdup_user)
    4 调用spidev_message 处理传入的 spi_ioc_transfer 结构体
    5 在进行数据对齐处理后调用spi_message_add_tail 和 spidev_sync 后执行

    Code: Select all

    	/* copy any rx data out of bounce buffer */
    	for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
    			n;
    			n--, k_tmp++, u_tmp++) {
    		if (u_tmp->rx_buf) {
    			if (copy_to_user((u8 __user *)
    					(uintptr_t) u_tmp->rx_buf, k_tmp->rx_buf,
    					u_tmp->len)) {
    				status = -EFAULT;
    				goto done;
    			}
    		}
    	}
    
    把RX的信息拷贝到用户空间用于显示,其中的spi_message_add_tail 只是将信息添加到消息链表(非阻塞)。spidev_sync 用于传输SPI(阻塞),其中spidev_sync调用spi_sync
    6 在spi_sync 中 ctlr->transfer 为 spi_queued_transfer, 调用内核线程异步实现spi信息的处理,可以推断出在执行ioctl时没有进行阻塞交给内核进程处理