Page 1 of 1
RV1106 SPI 无法阻塞式接收问题
Posted: 2024-09-12 14:16
by Muhe
板子型号:LuckFox Pico Pro/Max;
按照https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-RV1106/Luckfox-Pico-Pro-Max/Luckfox-Pico-SPI中的方法设置SPI,理论上SPI子设备应该阻塞式发送一次数据、接收一次数据,而我将MOSI与MISO悬空,用示波器测量其波形,发现确实是发送了一次数据,但并无接收数据的SCK信号,而且程序没有阻塞,请问这是什么原因造成的呢?
莫非需要将SPI设置为主机吗?
Re: RV1106 SPI 无法阻塞式接收问题
Posted: 2024-09-13 1:43
by Crocodile
您好,SPI协议中SCK的时钟信号都是主机发送的,引脚悬空时SPI控制器仍然会尝试接收数据所以在软件上不会表现出阻塞
Re: RV1106 SPI 无法阻塞式接收问题
Posted: 2024-09-13 11:56
by Muhe
引脚悬空,sck引脚和MOSI引脚上均无信号,为什么会判断接收到了数据呢?
请问有没有这方面的资料推荐呢?
Re: RV1106 SPI 无法阻塞式接收问题
Posted: 2024-09-19 10:01
by Crocodile
这种和内核相关的建议直接查看源码,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时没有进行阻塞交给内核进程处理