imx6ull spi-imx.c 驱动接收导致内存问题
spi-imx.c驱动接收导致重启:
原来是如果上一次SPI发送还有要接收的数据,接下一次spi发送中如果上次的接收缓存用的是临时变量,这次保存数据时原来的空间已经被释放,而spi_imx->rx_buf只有在本次接收中spi_imx_pio_transfer,被重置
while (spi_imx->devtype_data->rx_available(spi_imx))
spi_imx->rx(spi_imx);
所以有两种修改方式:
1、用局的buff接收;
2、spi_imx_transfer中spi_imx->rx改为:eadl(spi_imx->base + MXC_CSPIRXDATA)
[ 1722.007813] yytek,board spi2.2: I/O Error in PIO
[ 1722.014474] yytek,board spi2.2: SPI transfer failed: -110
[ 1722.056835] spi_master spi2: failed to transfer one message from queue
[ 1739.448762] yytek,board spi2.2: I/O Error in PIO
[ 1739.460088] yytek,board spi2.2: SPI transfer failed: -110
[ 1739.485536] spi_master spi2: failed to transfer one message from queue
[ 1744.006441] yytek,board spi2.2: I/O Error in PIO
[ 1744.015674] yytek,board spi2.2: SPI transfer failed: -110
[ 1744.048348] spi_master spi2: failed to transfer one message from queue
[ 2142.018245] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: syscpld_run+0x94/0x94 [sysdrv]
``` code
static int spi_imx_transfer(struct spi_device *spi,
struct spi_transfer *transfer)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
/* flush rxfifo before transfer */
while (spi_imx->devtype_data->rx_available(spi_imx))
spi_imx->rx(spi_imx);
if (spi_imx->slave_mode)
return spi_imx_pio_transfer_slave(spi, transfer);
if (spi_imx->usedma)
return spi_imx_dma_transfer(spi_imx, transfer);
else
return spi_imx_pio_transfer(spi, transfer);
}
#define MXC_SPI_BUF_RX(type) \
static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx) \
{ \
unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA); \
\
if (spi_imx->rx_buf) { \
*(type *)spi_imx->rx_buf = val; \
spi_imx->rx_buf += sizeof(type); \
} \
\
spi_imx->remainder -= sizeof(type); \
}
static int spi_imx_pio_transfer(struct spi_device *spi,
struct spi_transfer *transfer)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
unsigned long transfer_timeout;
unsigned long timeout;
spi_imx->tx_buf = transfer->tx_buf;
spi_imx->rx_buf = transfer->rx_buf;
spi_imx->count = transfer->len;
spi_imx->txfifo = 0;
spi_imx->remainder = 0;
```