通常情况下,DMA的行为跟CPU的行为是相互独立,分开的。但是对于某些存储或者外设,CPU跟DMA公用同一接口与其相连,当CPU跟DMA同时试图访问这些存储区或者外设的时候,会产生访问冲突,这时候就需要一个仲裁来决定谁具有优先权。当然也有一个例外,那就是映射在存储区(PF0)的ADC寄存器。当CPU和DMA试图同时访问该寄存器时,也不会产生任何冲突,即使对其他不同的地址的访问已经开始。当CPU和DMA通过不同的接口对同一存储区或者外设进行任何访问以及当CPU试图访问而DMA已经开始并正在对某存储区或外设进行访问时,都不会产生访问冲突。
会产生访问冲突的接口有以下几个:
• XINTF Memory Zones 0, 6 and 7
• L4 RAM
• L5 RAM
• L6 RAM
• L7 RAM
• Peripheral Frame 3 (McBSP-A, McBSP-B, and ePWM1-6/HRPWM1-6)
根据访问目标的不同,CPU仲裁规则有以下两点:
1.对于外部接口(XINTF)空间
• 当CPU和DMA试图在同一个时钟周期内访问XINTF的Zone空间时,DMA访问会被优先响应,随后响应所有被挂起的CPU访问请求(按照合适的CPU访问优先级:写入->读取->Fetch)。
• 如DMA试图在CPU对XINTF的访问正在等待被响应或者正在进行时对ZoneX进行访问,那么DMA访问会被挂起直到所有CPU对XINTF的访问结束。例如分别有一个CPU对Zone0的读写操作在等待响应,而此时有一个Fetch操作正在经行,那么当Fetch操作完成时,会继续响应CPU的写操作,继而是CPU读操作,当一切完成之后才能响应被挂起的DMA操作。
• 当CPU和DMA同时试图对XINTF进行写入操作时,会有一个时钟周期的停顿。
当使用CPU和DMA被用来对外部接口空间进行写操作的时候,外部空间接口的写缓冲可以用来避免两者之间的冲突。如果两者被用来对XINTF空间进行读取的话,那冲突便是家常便饭了。
该处最致命的问题就是如果DMA被挂起,那么就有可能导致DMA不去响应具有更高优先级的触发时间,比如不响应高速AD转换的数据读取事件导致数据丢失。在这种情况下,DMA就不应该用来向XINTF传送数据。因为如果DMA被挂起的时间太长的话,就会丢失很多其他的DMA触发事件。
DMA对XINTF进行的读取操作并不支持退出机制。如果DMA正在对某个XINTF空间进行访问但是DMA却被挂起(XREADY无响应),此时就可以通过CPU产生一个HARDRESET来结束其访问。HARDRESET操作类似与DMA的系统复位操作。而且HARDRESET需要XINTF释放处于就绪状态的外设,因此任何在写缓冲或者存在于XINTF或DMA上的数据将会丢失。
2.对于其他的外设或存储区
• 当CPU和DMA试图在同一个时钟周期通过相同的接口访问同一存储区或外设,那么DMA具有优先权,CPU被挂起。
• 如果一个CPU访问正在进行,另一个CPU访问处于等待状态,此时DMA的访问请求的优先级会高于后者CPU的访问请求。例如,CPU正在执行写操作,而一个CPU读操作正在等待被响应,这是如果出现DMA访问请求的话,当CPU写操作完成时会优先响应DMA访问请求,而不是CPU的读操作。
对于RAM的访问,可以通过一种PING-PONG机制来避免CPU和DMA的同时访问,从而避免了两者冲突而导致的挂起问题。
通常情况下,并不建议同时使用CPU和DMA同时对同一区域经行操作,这样会造成一些意想不到的错误。