Chinaunix首页 | 论坛 | 博客
  • 博客访问: 87066
  • 博文数量: 22
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 13
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-25 12:38
文章分类
文章存档

2016年(5)

2013年(17)

我的朋友

分类: LINUX

2016-03-18 16:09:19

Camera V4L2 DQBUF 中涉及dma一致性的操作函数:
    dma_cache_maint(buf_node->vaddr, buf_node->size, DMA_FROM_DEVICE);
    转载下文:

CPU Cache原理

CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多。缓存的出现主要是为了解决CPU运算速度与内存 读写速度不匹配的矛盾,因为CPU运算速度要比内存读写速度快很多,这样会使CPU花费很长时间等待数据到来或把数据写入内存。在缓存中的数据是内存中的 一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可避开内存直接从缓存中调用,从而加快读取速度。

 

cache 一致性问题

由 于缓存存在于cpu与内存中间,所以任何外设对内存的修改并不能保证cache中也得到同样的更新,同样处理器对缓存中内容的修改也不能保证内存中的数据 得到更新。这种缓存中数据与内存中数据的不同步和不一致现象将可能导致 使用DMA 传输数据时 或 处理器运行自修改代码时产生错误。

 

DMA 与 Cache

在进行DMA 操作时,如果没有对Cache 进行适当的操作,将可能产生以下两种错误:

1. DMA 从外设读取数据到供处理器使用。DMA 将外部数据直接传到内存中,但cache 中仍然保留的是旧数据,这样处理器在访问数据时直接访问缓存将得到错误的数据。 

2. DMA 向外设写入由处理器提供的数据。处理器在处理数据时数据会先存放到cache 中,此时cache 中的数据有可能还没来得及写回到内存中的数据。如果这时DMA 直接从内存中取出数据传送到外设,外设将可能得到错误的数据。

 

为了正确进行DMA 传输,必须进行必要的cache 操作。 cache 操作主要分为 invalidate (作废) 和 writeback (写回) ,有时也将两着放在一起使用。

以linux 下对DMA 操作的函数为例:

参考:kernel/arch/arm/mm/dma-mapping.c

 

/*
 * Make an area consistent for devices.
 * Note: Drivers should NOT use this function directly, as it will break
 * platforms with CONFIG_DMABOUNCE.
 * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
 */
void dma_cache_maint(const void *start, size_t size, int direction)
{
 void (*inner_op)(const void *, const void *);
 void (*outer_op)(unsigned long, unsigned long);

 BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(start + size - 1));

 switch (direction) {
 case DMA_FROM_DEVICE:  /* invalidate only */
  inner_op = dmac_inv_range;
  outer_op = outer_inv_range;
  break;
 case DMA_TO_DEVICE:  /* writeback only */
  inner_op = dmac_clean_range;
  outer_op = outer_clean_range;
  break;
 case DMA_BIDIRECTIONAL:  /* writeback and invalidate */
  inner_op = dmac_flush_range;
  outer_op = outer_flush_range;
  break;
 default:
  BUG();
 }

 inner_op(start, start + size);
 outer_op(__pa(start), __pa(start) + size);
}
EXPORT_SYMBOL(dma_cache_maint);

 

1. DMA 从外设读取数据到供处理器使用时,可先进性invalidate 操作。这样将迫使处理器在读取cache中的数据时,先从内存中读取数据到缓存,保证缓存和内存中数据的一致性。

2. DMA 向外设写入由处理器提供的数据时,可先进性writeback 操作。这样可以DMA传输数据之前先将缓存中的数据写回到内存中。

如果不清楚DMA 操作的方向,也可先同时进行invalidate 和writeback 操作。操作的结果等同于invalidate 和 writeback 操作效果的和。

 

wince 操作系统也有一套cache 操作接口:

()

void OEMCacheRangeFlush( LPVOID pAddr, DWORD dwLength, DWORD dwFlags );

 dwFlags 的定义如下表

ValueDescription
CACHE_SYNC_WRITEBACKWrite back cached data.
CACHE_SYNC_DISCARDWrite back and discard cached data.
CACHE_SYNC_INSTRUCTIONSDiscard all cached instructions.

 

 自修改代码 与 Cache

当 处理器要执行自修改代码时,处理器首先生成新的代码存放到cache中,最后从cache 中装入再将指令送入处理器。如果处理器的cache 分为 D-Cache (数据缓存)和 I-Cache (指令缓存),则生成代码时会存入D-Cache ,而取代码时从 I-Cache 中读出,这样当D-Cache 和 I-Cache 中的数据(也就是新要生成的指令码)不相同时,会导致无法执行正确的指令。

为了使指令正确执行,需要对两个Cache中的数据及时进行同步:对D-Cache 进行writeback 操作,对I-Cashe 进行invalidate 操作。

阅读(1634) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~