2013-07-28 2 views
3

우리는 많은 데이터를 빠르게 처리하기 위해 자일링스 Zynq FPGA 사용자 정의 DMA 디바이스를 개발 중이다. 베어 메탈에서 모든 작업을 할 수 있었지만 Linux에서는 문제가 있습니다. ARM Linux 커널 3.9에서 작업합니다. 우리 디바이스의 커널 드라이버를 인스턴스화하고 사용하는 방법을 모르겠습니다. https://github.com/Xilinx/linux-xlnx/blob/master/drivers/dma/xilinx/xilinx_axidma.c 공유 할 수있는 제안이나 예제 코드가 있습니까?dma 드라이버 리눅스 모듈을 인스턴스화하고 사용하는 방법

는 지금 우리가 여기 코드의 일부 사용할 계획 : http://www.mjmwired.net/kernel/Documentation/DMA-API-HOWTO.txt

을하지만 우리는 구조체 장치를 초기화하는 방법을 잘하지 않습니다.

답변

5

xilinx_axidma.c 코드에서 xdev-> dev 및 chan-> dev는 이미 & (op-> dev)으로 초기화되었습니다. DMA API의 첫 번째 매개 변수로 xdev-> dev 또는 chan-> dev를 전달할 수 있습니다. xilinx_axidma.c에 직접 DMA 버퍼 풀을 생성 할 필요가 없습니다. 한마디로, 초기화가 올바르게 수행되었습니다. DMA API를 사용할 수 있습니다. 어쩌면 하나의 버퍼 대신 Tx/Rx 버퍼 링을 만들 것입니다. FPGA 칩 DMA 컨트롤러는 물리적 주소를 사용하기 때문에 커널 모듈은 가상 주소를 사용합니다. 따라서 BD/버퍼 접근 방식과 같은 버퍼 링의 모든 버퍼에 대해 vaddrs와 paddrs를 모두 유지하는 구조를 만들어야합니다.

(1) 어떻게 DMA 버퍼를 할당 :

vaddr = (unsigned long) dma_alloc_coherent(xdev->dev, size, paddr, GFP_KERNEL); 

리턴 값 할당 된 DMA 버퍼의 가상 주소, 그리고 paddr 저장 그것의 물리 어드레스. FPGA 칩 DMA 컨트롤러는 paddr을 사용하고 커널 모듈은 vaddr을 사용합니다.

(2) 후 D 캐시 무효화 기능을 다음 FPGA, 호출의 수신 된 데이터 :

dma_unmap_single(xdev->dev, paddr, length, DMA_FROM_DEVICE); 

paddr는 DMA 버퍼의 물리 주소이다.

D 캐시 플러시 기능에 따라, FPGA에 호출을 하나의 버퍼를 전송하기 전에 (3)

:

paddr = dma_map_single(xdev->dev, vaddr, length, DMA_TO_DEVICE); 

paddr는 DMA 버퍼의 물리 주소를 상기 VADDR는 가상 어드레스이다 DMA 버퍼.

dma_free_coherent(xdev->dev, size, vaddr, paddr); 

VADDR이, 반면 DMA 버퍼의 가상 주소 :

paddr = dma_map_single(xdev->dev, vaddr, length, DMA_FROM_DEVICE); 

(5) 어떻게 DMA 버퍼를 해제하기 :

(4) 수신 버퍼의 실제 주소를 가져옵니다 paddr은 실제 주소입니다.

+0

마침내 얻었습니다. https://github.com/culurciello/zynq_linux_drivers_elab – Euge

관련 문제