基于S3C2410处理器的IDE硬盘接口设计Word文件下载.docx
《基于S3C2410处理器的IDE硬盘接口设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于S3C2410处理器的IDE硬盘接口设计Word文件下载.docx(28页珍藏版)》请在冰豆网上搜索。
3IDE接口
3.1IDE接口基本概况
IDE的英文全称为“IntegratedDriveElectronics”,即“电子集成驱动器”,它的本意是指把“硬盘控制器”与“盘体”集成在一起的硬盘驱动器。
是现在普遍使用的外部接口,主要接硬盘和光驱。
采用16位数据并行传送方式,体积小,数据传输快。
一个IDE接口只能接两个外部设备。
把盘体与控制器集成在一起的做法减少了硬盘接口的电缆数目与长度,数据传输的可靠性得到了增强,硬盘制造起来变得更容易,因为硬盘生产厂商不需要再担心自己的硬盘是否与其它厂商生产的控制器兼容。
对用户而言,硬盘安装起来也更为方便。
IDE这一接口技术从诞生至今就一直在不断发展,性能也不断的提高,其拥有的价格低廉、兼容性强的特点,为其造就了其它类型硬盘无法替代的地位。
但其传输最大只能是133MB/s,远远低于串口的600MB/s的速度。
IDE/ATA磁盘驱动器与早期的ATA驱动器相比,增加了任务文件寄存器,包括数据寄存器、状态寄存器以及反映地址的驱动器号、磁头号、道号和扇区号寄存器等。
ATA接口规范定义了信号电缆和电源线的电器特征、互联信号的电器和逻辑特征,还定义了存储设备中可操作的寄存器以及命令和协议。
3.2IDE接口的发展和作用
早期的IDE接口有两种传输模式,一个是PIO(ProgrammingI/O)模式,另一个是DMA(DirectMemoryAccess)。
虽然DMA模式系统资源占用少,但需要额外的驱动程序或设置,因此被接受的程度比较低。
后来在对速度要求愈来愈高的情况下,DMA模式由于执行效率较好,操作系统开始直接支持,而且厂商更推出了愈来愈快的DMA模式传输速度标准。
而从英特尔的430TX芯片组开始,就提供了对UltraDMA33的支持,提供了最大33MB/sec的的数据传输率,以后又很快发展到了ATA66,ATA100以及迈拓提出的ATA133标准,分别提供66MB/sec,100MB/sec以及133MB/sec的最大数据传输率。
值得注意的是,迈拓提出的ATA133标准并没能获得业界的广泛支持,硬盘厂商中只有迈拓自己才采用ATA133标准,而日立(IBM),希捷和西部数据则都采用ATA100标准,芯片组厂商中也只有VIA,SIS,ALi以及nViidia对次标准提供支持,芯片组厂商中英特尔则只支持ATA100标准。
3.3寄存器
规范定义了两组寄存器:
命令寄存器和控制寄存器。
命令寄存器用来接收命令和传送数据,控制寄存器用来控制磁盘操作。
常用的寄存器包括数据寄存器、命令寄存器、驱动器/磁头寄存器、柱面号寄存器、扇区号寄存器、扇区数寄存器和状态寄存器。
3.4数据传输方式
ATA接口规范定义了两种数据传输方式:
可编程I/O(PIO)方式和DMA方式。
PIO传送方式下,CPU对控制器的访问都是通过PIO进行的,包括从控制器读取状态信息和错误信息,以及向控制器发送命令和参数。
在一次PIO数据传输过程中,CPU先选址,然后使读/写信号有效,CPU或控制器放数据到数据总线,控制器或CPU读取数据,操作完成后,释放总线,这样一次数据传输完成。
DMA方式,即直接内存访问,CPU把缓冲区的地址与需要读写的长度告诉外设,外设在准备好后向CPU发出一个DMA请求,要求CPU暂停使用内存,获得同意后就直接在内存和外设之间传输数据,完成后再把对内存的访问权归还给CPU。
IDE实物图
4硬件设计
IDE设备(例如硬盘、光驱等)上都会使用一组跳线来确定安装后的主盘(Master,MA)、从盘(Slave,SL)状态。
如果在一根IDE数据线上接两个IDE设备的话,还必须分别将这两个IDE设备设置为一个为主盘,另一个为从盘状态。
这样,安装后才能正常使用。
如果一根IDE数据线上只接惟一的IDE设备,不管这个IDE设备原先是设置为主盘还是从盘状态,都不需要对这个惟一的IDE设备重新设置跳线。
确定好硬盘的连接方案后,就要设置硬盘跳线了。
一般可以在硬盘的IDE接口与电源接口之间找到由3~5列跳线。
不管是什么硬盘,在跳线设置上,大致可分成主盘、从盘与电缆选择(CableSelect)三种。
硬盘的出厂预设值都是设为主盘,所以如果将硬盘设为主盘,一般就不用设置跳线了。
如图1所示,S3C2410与硬盘之间接口电路分为3个部分:
片选信号、数据信号和控制信号。
硬盘上寄存器分为两组,分别由IDE_CS0和IDE_CS1选中,DA0~DA2则用于组内寄存器寻址;
数据线DD0~DD15因存在输入/输出方向问题,故用nOE(读信号)接buffer(74LVTH162245)的DIR引脚来控制缓冲器方向;
控制信号部分因该CPU与硬盘之间DMA时序不一致,故采用一块EPM7032AETC44-7芯片用于调整其时序。
PIO模式下,不需要DMARQ和nDMACK信号,DMA模式下,这两个信号才起作用。
5驱动软件设计
硬盘驱动程序实现分为初始化、打开设备、设备I/O操作和释放设备等几部分。
下表说明接口引脚的定义
5.1硬盘初始化
与X86不同,在ARM体系结构中,对内存和外设的访问使用统一的指令,所以要对外设地址进行内存映射。
也就是说,通过一张表将I/O地址映射到内存空间中来,这部分工作是在系统初始化期间完成的。
在IDE子系统初始化期间,Linux系统一旦发现一个IDE控制器,就设置它的ide_hwif_t结构来反映这个控制器和与之相连的磁盘;
向Linux的VFS登记每一个控制器,并分别把它加到blk_dev和blkdevs向量表中;
请求控制适当的IRQ中断(主IDE控制器是14,次IDE控制器是15)和I/O空间(主控制器0x1f0,次控制器0x170):
为每一个找到的IDE控制器在gendisk列表中增加一个条目。
IDE硬盘的初始化工作由idedisk_init完成:
(1)在数组ide_hwifs中找出已登记得各IDE控制器控制的所有IDE硬盘(一个控制器最多控制两个硬盘),每个IDE硬盘对应一个ide_drive_t结构。
(2)对找到的每个IDE硬盘,调用函数ide_register_subdriver填写各IDE硬盘结构中的相关信息域,主要是填写其驱动程序结构ide_driver_t。
硬盘驱动中的函数do_rw_disk通过向磁盘控制寄存器写参数启动磁盘操作,完成真正的数据读写。
(3)对找到的每个IDE硬盘,调用函数idedisk_setup进一步设置其ide_drive_t结构,包括设置该结构的settings域、doorlocking域、cyl、head、sect域、id域等。
5.2打开设备
打开块设备的操作与打开普通文件的操作基本相同。
(1)在当前进程的文件描述符表中为打开文件找一个空位,申请一块内存,用于建立新文件的打开文件对象,即结构file。
(2)解析设备特殊文件名,获得其VFSinode和dentry结构,根据dentry结构填写file结构,尤其是将file结构的f_op域设为其VFSinode中的缺省文件操作。
(3)执行该文件操作集中的open操作,即blkdev_open,它根据设备特殊文件的主次设备号从blkdevs向量表中取出已经注册的文件操作集(file_operations)fops,用该结构代替file结构中的f_op域。
(4)执行中新文件操作集中的open操作,即bl带头kdev_open,它根据VFSinode中的i_rdev域查找数组ide_hwifsp[],从中找出该IDE硬盘所对应的ide_drive_t结构;
如果ide_drive_t结构中注册有驱动程序,执行驱动程序集中的open操作。
(5)将打开文件对象插入到当前进程的文件描述符表中,返回文件描述符,即打开文件对象在进程文件描述符表中的索引。
5.3设备I/O操作
读写块设备时要用到块缓冲区(bufer),对bufer的管理采用BuferCache机制。
它管理bufer的创建、撤销、回收、查找、更新等,同时还要与系统中的其它部分(如文件系统、内存管理等)交互。
Linux将BufferCache从块设备驱动程序中独立出来,作为对块设备读写的通用机制,所以对块设备的读、写、同步等操作采用的都是由操作系统提供的公共函数,一般为block_read()和block_write()。
为了减少对块设备操作的次数,读写块设备时采用延迟操作,尽量将多个读写操作合并,所以操作请求不是马上递交给物理设备,而是提供了一种手段记录每次的请求(request),并为每类块设备提供一个请求队列用来排队、合并、重组对该块设备的请求。
当需要从硬盘读时,block_read()函数首先查找BufferCache如果在其中能找到需要的buffer,则立刻返回:
否则,生成一个读请求,并将其加入相应的请求队列排队。
当需要向硬盘写时,block_write()为此次写操作生成一个buffer,而后生成一个写请求,并将其加入相应的请求队列排队。
块设备驱动程序提供了一个请求处理函数,对硬盘而言是函数do_rw_disk。
在适当的时候,硬盘的请求处理函数启动,do_rw_disk处理在请求队列上排队的请求,通过向硬盘发出读、写命令完成对设备的真正操作。
其伪代码如下:
DO_RW_DISK(COMMAND)
{
Set_Registers();
if(COMMAND=READ){
Setread_intrasinterruptprocessfunction
SendWIN_READorWIN_MULTREADcommandtoCommandregister
}
if(COMMAND=WRITE){
SendWIN_WRITEorWIN_MULTWRITEcommandtoCommandregister
GetthestatusofStatusregisterandsetDRQbit
Setwriteintrasinterruptprocessfunction
Senddatatobuferinthedisk
5.4释放设备
由设备驱动程序中的release操作完成,一般完成与打开设备相反的动作:
释放打开设备特殊文件时在file结构上所创建的私有结构;
如果是最后一个设备的释放,则从硬件上关闭设备。
6应用示例(给出相应的应用示例,1个或者几个例子都可)
6.1示例介绍
由于手边没有合适的机器做实物的实验,所以根据书上的介绍,给出应用示例。
这个示例是利用IDE接口改装光驱。
由于现在很多人的机器上都装有光驱,但原来旧的光驱读盘能力下降,加上网络资源的丰富,光驱变很少人使用了。
但丢弃了又很可惜,所以可以利用光驱加上单片机的控制,改造成一个CD播放器。
由于光驱本身没有播放功能,所以利用IDE接口连接单片机去控制光驱,改装后的CD播放器具有播放、前进、后退、停止等功能。
6.2设计原理
在本次示例中使用51单片机作为控制芯片,用它的P1、P2口组成16为的数据输入输出口,连接IDE的数据线。
P0口用于连接IDE的读写控制、复位和寄存器控制,由于P0口的驱动力比较低,所以用10k的中的排阻对其上拉。
光驱需要的电流比较大,一般要一点几安培的电流,在制作时可以使用开关电源模块或使用旧电脑上的AT电源。
还有一点IDE连接电缆的红色线为1号线,其他则书序排列到40号,同时要把光驱后面板上的跳线设置为主盘。
下表中列出了需要用到的元件名和作用。
6.3编程思路及部分函数介绍
像其他电脑接口或单片机应用制作一样,难点在于单片机控制程序的编写,ATAPI协议时从ATA协议发展出来的,它的控制命令和返回的数据格式十分复杂,用于光驱时对于不同形式的光盘,控制命令的使用方式也不太一样。
ATAPI有许多寄存器,操作这些不同的寄存器便可以实现CD读取的相应功能,如读状态寄存器应先设置好CS和DA,选定要操作的是状态寄存器,把DIOW应缴电平拉低,这时就可以读ATAPI的数据线DD了,得到当前设备状态,再把DIOW拉高完成读取。
在源码中ReadStatus(void)函数用作此功能。
在发送控制命令,可以分为两类,分别为ATACommand和ATAPIPacketcommand,前者只要先选择要操作的是命令寄存器,在向数据口发一个命令直接就可以实现所要的功能。
在源码中InitCDROM(void)函数就是用于此,如先选择命令寄存器再发送A1H到数据口,就可以执行识别光驱的自检命令,命令完成后读数据口可以得到光驱的相关信息。
后者的使用则相对复杂一些,发送信息包时,先向传输直接计数寄存器中写入药发送的字节数,再送A0H信息命令字到命令寄存器,通知设备要发送信息包,最后向数据寄存器发送信息包。
光驱播放CD时有一系列的动作,先是上点复位,光盘托盘打开,托盘关闭,读取曲目播放。
使用单片机对光驱进行CD播放控制时也应该有这样的顺序,在本文源码的主程序中先是调用速食化函数,对光驱进行复位和识别,初始化沉厚后就会调用读取TOC函数,读取曲目和相关值,然后在对按钮进行判断,做出相应的控制。
下图是设计原理图:
6.4IDE(ATAPI)引脚定义
从表一可以看到ATAPI各引脚的定义,下面是几个在实例中要使用的引脚具体说明:
1.DD(15:
0)DeviceData
DD占用3-18引脚,是一个8位或16位的双向数据线,在用于读写CDROM的寄存器时只使用低8位,而在传送信息包或数据时使用全部16位。
2.CS(1:
0)ChipSelectCS0,CS1是用于选择指令寄存器芯片的,为低电平有效,它和DA组合就可以选择所要操作的寄存器。
3.DA(2:
0)DeviceAddress
DA为三位的地址线,和CS组合选取要操作的寄存器。
4.DIOR(DeviceI/Oread)
DIOR为控制寄存器或数据口读的引脚,低电平有效。
5.DIOW(DeviceI/Owrite)
DIOW为控制寄存器或数据口写的引脚,低电平有效。
6.RESET
当此引脚为低电平时CDROM会被复位。
7.INTRQ(Deviceinterrupt)
INTRQ为中断请求,当CDROM在读写数据等状态下会在此引脚输出信号以使控制器中断程序得以执行,本实例中没有使用到这个方法。
8.IORDY(I/Ochannelready)
这个引脚可判断CDROM的数据口是否就绪,等待数据的输入或输出。
同样实例中没有使用到些引脚。
前6种引脚都在实例电路中一一连接在51单片机的IO引脚上,我们可以根据CDROM引脚所要求的电平去实现该引脚的功能,如RESET引脚为低电平有效,连接于单片机的P0.7引脚上,用如下的51C语言就可以实现对CDROM实行复位操作:
P0_7=0;
//拉低P0_7,RESET为低,复位开始
dmsec(100);
//调用延时函数延时一段时间
P0_7=1;
//拉高RESET,复位完成
6.5寄存器
在IDE界面中寄存器的作用可以分二类,一种是用于传送指令和返回数据,一种是用于控制设备和返回控制状态。
表3中指明了各ATAPI常用寄存器的地址和功能。
地址是用CS和DA组成,CS为寄存器区段的选择,再加上三位地址的DA就可以组合出多个地址编码选择不同的寄存器。
在单片机控制程序中可以把P3口IO引脚和DA、CS相连,在程序中控制P3口各引脚的电平状态去选择要操作的寄存器,再通过控制DIOR/DIOW引脚电平实现读写寄存器。
部分的寄存器地址是相同的,如状态寄存器和命令寄存器使用同一个地址,读这个地址时为操作状态寄存器,写这个地址时为操作状态寄存器。
6.6ATA命令
ATAPI是在ATA发展而来的,所以仍支持绝大部分的ATA命令。
这些命令会直接送到Command寄存器后被ATAPI设备所执行。
在这里只说明一下实例程序中所用到的一些相关命令。
1.ATAPI设备软复位命令(08H)
当向命令寄存器写入08H时,驱动器会执行软件复位命令,执行效果和硬件复位差不多。
2.设备诊断(90H)
执行这个命令时,驱动器会运行自身诊断程序,诊断结束后会返回一个值到错误寄存器,读取错误寄存器值并和标准值比较,当返回值不等于01H或81H时则说明CDROM自身诊断未通过(Device0)。
3.识别信息包功能IDENTIFYPACKETDEVICE(A1H)
这个命令执行后可以返回当前所选择的驱动器的信息包参数和其它相关的参数,如信息包的长度、驱动器的型号、驱动器序列号等等。
先向命令寄存器发1H,然后就可以在DATA寄存器中读取驱动器相关信息,每次可以读取两个字节。
5.信息包功能PACKET(AOH)
执行这个命令后驱动器将准备发送信息包命令,在执行这个命令之前应先向CylinderLow/High寄存器写入将发送一个值为命令信息包的长度除于2的数值,以让驱动器知道要接收多少次数据。
6.6信息包命令
ATAPI是在ATA发展过来的,最大的不同点就是有了针对CDROM等设备的信息包命令,实现两者的兼容。
从上文可以得知发送PACKET命令后就可以发送信息包命令了,简单说来就是ATAPI设备在收到PACKET命令后就会进入信息包的接收状态,如信息包正常发送完成后,设备就会执行这个信息包命令。
信息包的格式一般由12字节组成,有些设备是16字节,对于这个值的确定可以用"
识别信息包功能"
读取信息值。
首字节是指令字,以后的字节就是参数。
这些字节的
发送是这样实现的,选定DATA寄存器,把两个字节加在DD的十六位数据线上,控制DIOW为低,完成写入,再拉高DIOW,后两个字节加上数据线上……如此循环直到所有字节发送完。
文中的实例是针对CDROM中的CD播放功能的,那下面举几个CD播放要用到的信息包命令。
1.READSUBCHANNEL读次信道命令
这个命令执行后驱动器会返回CD中的次信道信息和播放状态等。
这些信息如:
当前的MSF地址,当前的音频播放状态和当前的轨道数等。
具体的实现可以参考实例程序中的voidReadSub(void)函数。
2.READTOCCommand读轨道TOC命令
TOC是指光盘中轨道的开始地址及其它相关信息,这些信息存在于Qsub-channel(Q子信道)中。
当指定要播放一条曲目,就要先知道曲目所在轨道的开始地址和结束地址。
这就需要用这个命令去读取光盘中轨道信息,它还将返回CD光盘的曲目数等。
MSF位是要求返地址格式为MSF地址格式,这个位一般要置1。
MSF地址格式是指光盘中的数据实际被写入的位置,最小单位是F,75个F字段则为一个S字段,而60个字段则为一个M字段。
F字段的有效值范围为0-74,S字段的有效值范围为0-59,M字段的有效值范围为0-99。
MSF地址的数据格式由4个字节组成,第一字节为保留字节,第二字节为M字段,第三字节为S字段,第四字节为F字段。
返回数据格式在第二字节和第九字节中,设它为的数值返回的数据形式也不同,在CD光盘播放中一般置零就可以了。
曲目号是指定要返回TOC数据的曲目号,它的有效值为00H-63H,也就是0-99号,当曲目号为AAH时则返回整张光盘的结束MSF地址。
具体编程方法可以参看voidReadTOC(unsignedcharTrack)函数的写法。
3.PLAYAUDIOMSFCommand播放命令当用读TOC命令得知曲目的MSF开始和结束地址数据后,就可以用播放命令去插放该曲目的音乐了。
要播放单个曲子可以先读它的开始MSF地址做为开始地址,再读下一曲子的MSF地址做为结束地址。
而播放整个光盘则可以先读首曲目的MSF地址做为开始地址,再用AAH去读最后的结束地址做为结束地址。
6.7源代码
#include<
at89x51.h>
#defineA0P0_0
#defineA1P0_1
#defineA2P0_2
#defineCS0P0_3
#defineCS1P0_4
#defineWRP0_5
#defineRDP0_6
#defineRSTP0_7
#defineCDCOMP0//CDROM控制线
#defineINTRQP3_7//INTRQ
#defineDBMP2//CDROM数据线高8位
#defineDBLP1//CDROM数据线低8位
//用变量设置P0的值,以方便对应于各寄存器的地址值
#defineREG_Data0xE0
#defineREG_Err0xE1//Features
#defineREG_Features0xE1
#defineREG_Sector0xE2
#defineREG_CyLow0xE4
#defineREG_CyHig0xE5
#defineREG_DriveHead0xE6
#defineREG_Status0xE7//Command
#defineREG_Command0xE7
#definePLAYKeyP3_2
#defineEJECTKeyP3_3
#defineSTOPKeyP3_5
#defineNEXTKeyP3_4
#definePREVIOUSKeyP3_6
#defineERRLEDP3_