全志 T113 与 SDNAND 的典型连接方式如下:
T113 引脚 | SDNAND 引脚 | 描述 |
---|---|---|
GPIO0_A0 | CLK | 时钟线 |
GPIO0_A1 | CMD | 命令线 |
GPIO0_A2 | DAT0 | 数据线 0 |
GPIO0_A3 | DAT1 | 数据线 1 |
GPIO0_A4 | DAT2 | 数据线 2 |
GPIO0_A5 | DAT3 | 数据线 3 |
VDD_3V3 | VCC | 电源(3.3V) |
GND | GND | 地 |
注意事项:
git clone https://github.com/allwinner-zh/linux-5.4.git -b t113-v1.0cd linux-5.4
配置内核
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- t113_evb_defconfigmake ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
在菜单配置中选择:
Device Drivers ---> <*> MMC/SD/SDIO card support ---> <*> MMC block device driver <*> Secure Digital Host Controller Interface support <*> Allwinner SD/MMC Host Controller support
编译内核与驱动
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage dtbs modules -j4
修改arch/arm/boot/dts/sunxi-t113.dtsi
文件,添加 SDNAND 控制器配置:
sdmmc1: mmc@1c13000 { compatible = "allwinner,sun8i-h3-mmc"; reg = <0x01c13000 0x1000>; interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ccu CLK_BUS_MMC1>, <&ccu CLK_MMC1>; clock-names = "ahb", "mmc"; resets = <&ccu RST_BUS_MMC1>; reset-names = "mmc"; bus-width = <4>; vmmc-supply = <®_vcc3v3>; non-removable; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; }; &pio { mmc1_pins: mmc1-pins { allwinner,pins = "PA0", "PA1", "PA2", "PA3", "PA4", "PA5"; allwinner,function = "mmc1"; allwinner,pull = <1 1 1 1 1 1>; // 上拉 }; };
下面是一个简单的 SDNAND 读写测试程序:
#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#define BLOCK_SIZE 512#define TEST_BLOCKS 10int main(int argc, char *argv[]) { int fd; char *device = "/dev/mmcblk0"; unsigned char buffer[BLOCK_SIZE * TEST_BLOCKS]; unsigned char read_buffer[BLOCK_SIZE * TEST_BLOCKS]; int i, ret; // 检查参数 if (argc > 1) { device = argv[1]; } // 打开设备 fd = open(device, O_RDWR); if (fd < 0) { perror("无法打开设备"); return -1; } // 填充测试数据 for (i = 0; i < BLOCK_SIZE * TEST_BLOCKS; i++) { buffer[i] = i % 256; } // 写入测试数据 printf("写入测试数据到块设备... "); ret = write(fd, buffer, BLOCK_SIZE * TEST_BLOCKS); if (ret != BLOCK_SIZE * TEST_BLOCKS) { perror("写入失败"); close(fd); return -1; } // 重新定位到开始位置 lseek(fd, 0, SEEK_SET); // 读取测试数据 printf("从块设备读取数据... "); ret = read(fd, read_buffer, BLOCK_SIZE * TEST_BLOCKS); if (ret != BLOCK_SIZE * TEST_BLOCKS) { perror("读取失败"); close(fd); return -1; } // 验证数据 printf("验证数据... "); for (i = 0; i < BLOCK_SIZE * TEST_BLOCKS; i++) { if (buffer[i] != read_buffer[i]) { printf("数据验证失败!偏移量:%d,期望值:0x%02X,实际值:0x%02X ", i, buffer[i], read_buffer[i]); close(fd); return -1; } } printf("SDNAND读写测试成功! "); close(fd); return 0;}
arm-linux-gnueabihf-gcc -o sdnand_test sdnand_test.c
将程序复制到开发板
使用 scp 或 U 盘将生成的sdnand_test
可执行文件复制到开发板上
运行测试
# 确保有执行权限chmod +x sdnand_test# 运行测试(需要root权限)sudo ./sdnand_test /dev/mmcblk0
通过以上步骤,你应该能够成功驱动全志 T113 上的 SDNAND 设备。