首先app.overlay的配置使用dma回调方式dma1{statusokay;};dmamux1{statusokay;};spi2{/* 使用 PLL1_Q 作为 SPI2 时钟源 */pinctrl-0spi2_nss_pb12spi2_sck_pb13spi2_miso_pb14spi2_mosi_pb15;pinctrl-namesdefault;statusokay;dmasdmamux1040(STM32_DMA_PERIPH_TX|STM32_DMA_PRIORITY_HIGH),dmamux1139(STM32_DMA_PERIPH_RX|STM32_DMA_PRIORITY_HIGH);dma-namestx,rx;};在pro.conf中添加CONFIG_NOCACHE_MEMORYy CONFIG_SPI_ASYNCy CONFIG_SPIy CONFIG_SPI_STM32y CONFIG_SPI_STM32_DMAy CONFIG_SPI_STM32_INTERRUPTymain.c测试#definePACKET_SIZE64#defineTEST_COUNT10/* 测试数据 */staticconstuint8_ttx_pattern[PACKET_SIZE]{0xAA,0x55,0x12,0x34,0xDE,0xAD,0xBE,0xEF,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xA5,0x5A,0xA5,0x5A,0xA5,0x5A,0xA5,0x5A,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11,0x00};__nocachestaticuint8_ttx_buffer[PACKET_SIZE];__nocachestaticuint8_trx_buffer[PACKET_SIZE];/* 同步信号量用于等待异步回调 */staticK_SEM_DEFINE(spi_sync_sem,0,1);/* 传输结果回调中写入 */staticintspi_transfer_result;/* SPI 配置 */staticstructspi_configspi2_cfg{.frequency16000000,.operationSPI_OP_MODE_MASTER|SPI_WORD_SET(8)|SPI_TRANSFER_MSB,.slave0,};/* * 异步传输完成回调 * 在中断上下文中调用仅做标记释放信号量不能做耗时操作 * */staticvoidspi_transfer_done(conststructdevice*dev,intresult,void*user_data){spi_transfer_resultresult;k_sem_give(spi_sync_sem);}/* * 单次异步收发封装提交 等待回调 * 返回 0 成功负值为错误码 * */staticintspi_transceive_async_once(conststructdevice*dev,conststructspi_config*cfg,constuint8_t*tx_data,size_ttx_len,uint8_t*rx_data,size_trx_len,int32_ttimeout_ms){/* 构建 TX buf */structspi_buftx_buf{.buf(void*)tx_data,.lentx_len,};structspi_buf_settx_set{.bufferstx_buf,.count1,};/* 构建 RX buf */structspi_bufrx_buf{.bufrx_data,.lenrx_len,};structspi_buf_setrx_set{.buffersrx_buf,.count1,};/* 提交异步传输 */intretspi_transceive_cb(dev,cfg,tx_set,rx_set,spi_transfer_done,NULL);if(ret0){printk(spi_transceive_cb submit failed: %d\n,ret);returnret;}/* 等待回调唤醒 */retk_sem_take(spi_sync_sem,K_MSEC(timeout_ms));if(ret!0){printk(SPI transfer timeout! (%d)\n,ret);return-ETIMEDOUT;}/* 检查传输结果 */if(spi_transfer_result0){printk(SPI transfer error: %d\n,spi_transfer_result);returnspi_transfer_result;}return0;}voidmy_thread(void*arg1,void*arg2,void*arg3){intpass0,fail0;k_msleep(500);printk(\n);printk(\n);printk( SPI2 DMA Async Loopback Test\n);printk( Connect: PB14(MISO) - PB15(MOSI)\n);printk( Packet size: %d bytes\n,PACKET_SIZE);printk(\n\n);conststructdevice*spi2DEVICE_DT_GET(DT_NODELABEL(spi2));if(!device_is_ready(spi2)){printk(ERROR: SPI2 device not ready!\n);while(1){k_sleep(K_FOREVER);}}printk(SPI2 device ready\n);printk(tx_buffer addr: %p\n,tx_buffer);printk(rx_buffer addr: %p\n,rx_buffer);memcpy(tx_buffer,tx_pattern,PACKET_SIZE);/* 循环测试 */for(inti0;iTEST_COUNT;i){memset(rx_buffer,0,PACKET_SIZE);intretspi_transceive_async_once(spi2,spi2_cfg,tx_buffer,PACKET_SIZE,rx_buffer,PACKET_SIZE,11000);if(ret0){printk([%2d] FAIL: error %d\n,i,ret);fail;continue;}if(memcmp(tx_buffer,rx_buffer,PACKET_SIZE)0){printk([%2d] PASS\n,i);pass;}else{printk([%2d] FAIL: data mismatch\n,i);printk( byte[0]: tx0x%02X rx0x%02X\n,tx_buffer[0],rx_buffer[0]);fail;}k_msleep(100);}printk(\n\n);printk( Result: PASS%d FAIL%d (Total%d)\n,pass,fail,TEST_COUNT);printk(\n);while(1){k_msleep(1000);}}使用正常的收发方式即收发一体上面配置中取消dma相关即可。main.c#definePACKET_SIZE8staticconstuint8_ttx_pattern[PACKET_SIZE]{0xAA,0x55,0x12,0x34,0xDE,0xAD,0xBE,0xEF};staticuint8_trx_buffer[PACKET_SIZE];staticstructspi_configspi2_cfg_fast{.frequency16000000,.operationSPI_TRANSFER_LSB|SPI_WORD_SET(8)|SPI_TRANSFER_MSB|SPI_MODE_CPOL|SPI_MODE_CPHA,.slave0,};voidmy_thread(void*arg1,void*arg2,void*arg3){intpass0,fail0;printk( SPI2 Interrupt Loopback Test \n);printk(Connect PB14(MISO) - PB15(MOSI)\n\n);conststructdevice*spi2DEVICE_DT_GET(DT_NODELABEL(spi2));if(!device_is_ready(spi2)){printk(SPI2 not ready!\n);}printk(SPI2 ready\n\n);for(inti0;i10;i){memset(rx_buffer,0,PACKET_SIZE);structspi_buftx{.buf(void*)tx_pattern,.lenPACKET_SIZE};structspi_bufrx{.bufrx_buffer,.lenPACKET_SIZE};structspi_buf_settx_set{.bufferstx,.count1};structspi_buf_setrx_set{.buffersrx,.count1};intretspi_transceive(spi2,spi2_cfg_fast,tx_set,rx_set);if(ret0){printk(Iter %d: fail\n,i);fail;continue;}if(memcmp(tx_pattern,rx_buffer,PACKET_SIZE)0){printk(Iter %d: OK\n,i);pass;}else{printk(Iter %d: mismatch\n,i);fail;}}printk(\n Result: Pass%d Fail%d \n,pass,fail);while(1){k_msleep(1000);}}