#include
#include
#include
#include
#include
#include
#include
#include
#define SPI_DEVICE “/dev/spidev1.0”
#define SPI_MODE SPI_MODE_0
#define SPI_BITS 8
#define SPI_SPEED 100000000 // 100 MHz
#define CHUNK_SIZE (4 * 1024) // 4 KB per transfer
#define DMA_THRESHOLD_MBPS 5.0 // 判断 DMA 是否启用的速度阈值
int main() {
int fd = open(SPI_DEVICE, O_RDWR);
if (fd < 0) { perror("open"); return -1; }
uint8_t mode = SPI_MODE;
uint8_t bits = SPI_BITS;
uint32_t speed = SPI_SPEED;
if (ioctl(fd, SPI_IOC_WR_MODE, &mode) < 0) { perror("SPI_IOC_WR_MODE"); return -1; }
if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0) { perror("SPI_IOC_WR_BITS"); return -1; }
if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) < 0) { perror("SPI_IOC_WR_MAX_SPEED_HZ"); return -1; }
size_t total_len = 1024 * 1024; // 总数据量 1 MB
uint8_t *tx_buf = malloc(total_len);
uint8_t *rx_buf = malloc(total_len);
if (!tx_buf || !rx_buf) { perror("malloc"); return -1; }
memset(tx_buf, 0xAA, total_len);
memset(rx_buf, 0, total_len);
struct spi_ioc_transfer tr;
memset(&tr, 0, sizeof(tr));
tr.speed_hz = speed;
tr.bits_per_word = bits;
tr.delay_usecs = 0;
printf("Starting SPI DMA test (%zu bytes in chunks of %zu KB)...\n",
total_len, (size_t)CHUNK_SIZE / 1024);
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
size_t offset = 0;
while (offset < total_len) {
size_t chunk = (total_len - offset > CHUNK_SIZE) ? CHUNK_SIZE : (total_len – offset);
tr.tx_buf = (unsigned long)(tx_buf + offset);
tr.rx_buf = (unsigned long)(rx_buf + offset);
tr.len = chunk;
int ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1) {
perror("SPI_IOC_MESSAGE");
free(tx_buf);
free(rx_buf);
close(fd);
return -1;
}
offset += chunk;
}
clock_gettime(CLOCK_MONOTONIC, &end);
double elapsed = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec)/1e9;
double speed_mbps = total_len / (1024.0*1024.0) / elapsed;
printf("Transfer completed in %.6f seconds\n", elapsed);
printf("Approximate speed: %.2f MB/s\n", speed_mbps);
if (speed_mbps >= DMA_THRESHOLD_MBPS) {
printf(“DMA likely ENABLED (speed above %.1f MB/s)\n”, DMA_THRESHOLD_MBPS);
} else {
printf(“DMA likely DISABLED (speed below %.1f MB/s)\n”, DMA_THRESHOLD_MBPS);
}
free(tx_buf);
free(rx_buf);
close(fd);
return 0;
}
