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);
}