ATA接口的三种数据传输方式

(1)PIO(Programmable Input-Output)传输,可以分为PIO寄存器传输和PIO数据传输。PIO寄存器传输主要用于对ATA设备中的寄存器进行读写。读写的数据位数为8位DD[7:0]。ATA主机控制器根据所要读写的寄存器地址设置CS0_、CS1_、DA[2:0]地址信号,同时将DIOW_或DIOR_设为有效,ATA主机控制器或ATA设备驱动数据总线释放数据。当DIOW_或DIOR_撤销时,ATA主机控制器或ATA设备从数据总线上读取数据。对于PIO数据传输,所读写的地址为数据端口,读写数据为16位。

(2)MDMA(Multiword DMA)传输,用于数据传输。ATA主机控制器向ATA设备下达MDMA传输命令后,等待设备向主机发送DMARQ数据传输请求信号。当主机收到DMARQ信号后,向设备发送DMACK_响应信号。MDMA数据传输过程与PIO方式大致相同,也是通过DIOW_或DIOR_的周期变化来控制数据的传输。在数据传输过程中,DMARQ和DMACK_握手信号一直保持有效。

(3)UDMA(Ultra DMA),也是用于数据传输。这种传输方式的传输速度比MDMA要快,ATA/ATAPI-5协议中所定义的UDMA传输方式最高数据传输速率是66MB/s。UDMA对数据传输的控制信号重新进行了定义。另外,UDMA还引入了CRC数据校验机制,保证了数据传输过程的正确性,但其传输过程较为复杂。

下述代码可以大概得出硬盘的读写速度!


void speed(int buflen, int mod)
{
    /* int mod = 0; */
    int len = 50;
    FILE *fp;
    unsigned int i = 0, j = 0, tmp, tmp2;
    float t = 0.0;
    char *str = "/ata00/ch2.dat";
    char *data = (char *)malloc(buflen);
    if (mod == 0) {
        str = "/bd0/ch2.dat";
        len = 50;
    } else if (mod == 1)
        str = "/ata00/ch2.dat";
    else
        str = "/ata00:2/mx.dat";

    for (i = 0; i < buflen; i++) {
        data[i] = i & 0xff;
    }

    fp = fopen(str, "w+");
    if (fp == NULL) {
        logMsg("fopen error\n", 1, 2, 3, 4, 5, 6);
        return;
    }

    if (buflen > 1024)
        logMsg("test '%s' speed %dM data writted(buflen:%dK)!\n", str, len, buflen / 1024, 0, 0, 0);
    else
        logMsg("test '%s' speed %dM data writted(buflen:%d)!\n", str, len, buflen, 0, 0, 0);

    tmp = tickGet();
    i = 1024 * len * 1024 / buflen;

    for (j = 0; j < i; j++) {
        fwrite(data, buflen, 1, fp);
    }
    fclose(fp);
    tmp = tickGet() - tmp;
    t = tmp * 1.0 / 60;

    logMsg("Write speed:%3.2f MB/s  (%dM/%2.2fs)\n", len * 1.0 / t, len, t, 0, 0, 0);

    taskDelay(60 * 1);

    fp = fopen(str, "r+");

    tmp = tickGet();
    i = 1024 * len * 1024 / buflen;

    for (j = 0; j < i; j++) {
        fread(data, buflen, 1, fp);
    }
    fclose(fp);
    tmp = tickGet() - tmp;
    t = tmp * 1.0 / 60;
    logMsg(" Read speed:%3.2f MB/s  (%dM/%2.2fs)\n\n", len * 1.0 / t, len, t, 0, 0, 0);
}

void speed3()
{
    //SATA
    int i = 0;

    for (i = 0; i < 10; i++)
        speed(2 << i, 4);

    for (i = 0; i < 10; i++)
        speed((2 << i) * 1024, 4);
}

void speed4()
{
    //usb
    int i = 0;

    for (i = 0; i < 10; i++)
        speed(2 << i, 0);

    for (i = 0; i < 10; i++)
        speed((2 << i) * 1024, 0);
}