DMA,远远超出了预计的难度。失败告终。代之以IO Port Introduction。



A Sample DMA transfer



24.3.1. A Sample DMA transfer

Here is an example of the steps that occur to cause and perform a DMA transfer. In this example, the floppy disk controller (FDC) has just read a byte from a diskette and wants the DMA to place it in memory at location 0x00123456. The process begins by the FDC asserting the DRQ2 signal (the DRQ line for DMA channel 2) to alert the DMA controller.

The DMA controller will note that the DRQ2 signal is asserted. The DMA controller will then make sure that DMA channel 2 has been programmed and is unmasked (enabled). The DMA controller also makes sure that none of the other DMA channels are active or want to be active and have a higher priority. Once these checks are complete, the DMA asks the CPU to release the bus so that the DMA may use the bus. The DMA requests the bus by asserting the HRQ signal which goes to the CPU.

The CPU detects the HRQ signal, and will complete executing the current instruction. Once the processor has reached a state where it can release the bus, it will. Now all of the signals normally generated by the CPU (-MEMR, -MEMW, -IOR, -IOW and a few others) are placed in a tri-stated condition (neither high or low) and then the CPU asserts the HLDA signal which tells the DMA controller that it is now in charge of the bus.

Depending on the processor, the CPU may be able to execute a few additional instructions now that it no longer has the bus, but the CPU will eventually have to wait when it reaches an instruction that must read something from memory that is not in the internal processor cache or pipeline.

Now that the DMA “is in charge”, the DMA activates its -MEMR, -MEMW, -IOR, -IOW output signals, and the address outputs from the DMA are set to 0x3456, which will be used to direct the byte that is about to transferred to a specific memory location.

The DMA will then let the device that requested the DMA transfer know that the transfer is commencing. This is done by asserting the -DACK signal, or in the case of the floppy disk controller, -DACK2 is asserted.

The floppy disk controller is now responsible for placing the byte to be transferred on the bus Data lines. Unless the floppy controller needs more time to get the data byte on the bus (and if the peripheral does need more time it alerts the DMA via the READY signal), the DMA will wait one DMA clock, and then de-assert the -MEMW and -IOR signals so that the memory will latch and store the byte that was on the bus, and the FDC will know that the byte has been transferred.

Since the DMA cycle only transfers a single byte at a time, the FDC now drops the DRQ2 signal, so the DMA knows that it is no longer needed. The DMA will de-assert the -DACK2 signal, so that the FDC knows it must stop placing data on the bus.

The DMA will now check to see if any of the other DMA channels have any work to do. If none of the channels have their DRQ lines asserted, the DMA controller has completed its work and will now tri-state the -MEMR, -MEMW, -IOR, -IOW and address signals.

Finally, the DMA will de-assert the HRQ signal. The CPU sees this, and de-asserts the HOLDA signal. Now the CPU activates its -MEMR, -MEMW, -IOR, -IOW and address lines, and it resumes executing instructions and accessing main memory and the peripherals.

For a typical floppy disk sector, the above process is repeated 512 times, once for each byte. Each time a byte is transferred, the address register in the DMA is incremented and the counter in the DMA that shows how many bytes are to be transferred is decremented.

When the counter reaches zero, the DMA asserts the EOP signal, which indicates that the counter has reached zero and no more data will be transferred until the DMA controller is reprogrammed by the CPU. This event is also called the Terminal Count (TC). There is only one EOP signal, and since only DMA channel can be active at any instant, the DMA channel that is currently active must be the DMA channel that just completed its task.

If a peripheral wants to generate an interrupt when the transfer of a buffer is complete, it can test for its -DACKn signal and the EOP signal both being asserted at the same time. When that happens, it means the DMA will not transfer any more information for that peripheral without intervention by the CPU. The peripheral can then assert one of the interrupt signals to get the processors’ attention. In the PC architecture, the DMA chip itself is not capable of generating an interrupt. The peripheral and its associated hardware is responsible for generating any interrupt that occurs. Subsequently, it is possible to have a peripheral that uses DMA but does not use interrupts.

It is important to understand that although the CPU always releases the bus to the DMA when the DMA makes the request, this action is invisible to both applications and the operating systems, except for slight changes in the amount of time the processor takes to execute instructions when the DMA is active. Subsequently, the processor must poll the peripheral, poll the registers in the DMA chip, or receive an interrupt from the peripheral to know for certain when a DMA transfer has completed.






/*<br /> File name: Dij.c<br /> Description: 寻找最短路径,采用Dijskra算法<br /> */</p> <p>#include <stdio.h></p> <p>#define N 5<br /> #define O 1</p> <p>//集合标志<br /> #define S 0<br /> #define R 1</p> <p>#define INF 0xFFFF</p> <p>int Near[N]; //V0到其他点的最短距离<br /> int path[N];</p> <p>void Dij(int A[][N],int path[])<br /> {<br /> int i,j;<br /> int n=N;<br /> int v;<br /> int shortest;<br /> int bitmap[N]; //集合标志</p> <p> for(i=0;i<n></n><n></n><n><=shortest){ v=j; //记录下最近点的下标 shortest=Near[j]; //记录下最短距离 } } } bitmap[v]=S; //将在V中找到的离S最近的v点取出加入到S集合中 //更新V0到S集合所有点的距离 for(j=0;j</n><n>< Near[j]){ Near[j]=shortest+A[v][j]; //更新V0到R集合中所有点的路径长度 //求取路径 path[j]=v;//记录下是谁指向j节点,这个记录是不断更新的,直到最后一次才能确定 } } } } } void print_path(int path[],int i) { printf("COST(%d to %d) = %dt",O+1,i+1,path[i]); //print path O->i</p> <p> if(path[i]==-1) { printf(&#8220;**n&#8221;);return; }<br /> while(1){<br /> printf(&#8220;%d&#8221;,i+1);<br /> i=path[i];<br /> if(i==path[i]){<br /> printf(&#8220;<-%d",O+1); break; } printf("<-"); }; printf("n"); } int main() { int s[N][N]={ {0,2,1,INF,INF}, {INF,0,INF,1,3}, {INF,2,0,INF,5}, {INF,INF,INF,0,1}, {INF,INF,INF,INF,0} }; int i,j; printf("Orignal Martixn"); for(j=0;j</n><n></n><n></n><n></n></stdio.h>


老虎 老鼠 傻傻分不清楚