[블로그 통합으로 이전해 온 자료] - 2008. 4. 29. 20:58
* DMA
DMA 할당/해제
int request_dma( unsigned int dma, const char *device_id );
void free_dma( unsigned int dma );
DMA를 위한 메모리 할당/해제
void *dma_alloc_coherent( struct device *dev, size_t size, dma_addr_t *dma_handle, int flags );
void *dma_free_coherent( struct device *dev, size_t size, void *cpu_addr, dma_addr_t dma_handle );
unsigned long clain_dma_lock( void );
void disable_dma( unsigned int dma );
void clear_dma_ff( unsigned int dma );
void set_dma_mode( unsigned int dma, char mode );
void set_dma_addr( unsigned int dma, unsigned int a );
void set_dma_count( unsigned int dma, unsigned int count );
void enable_dma( unsigned int dma );
void release_dma_lock( unsigned long flags );
int get_dma_residue( unsigned int dma );
- DMA 전송 준비 함수 / DMA 완료 점검 함수 필요
unsigned template_dma_prepare( int channel, int mode, unsigned int buf, unsigned int count )
{
unsigned long flags = claim_dma_lock();
disable_dma( channel );
clear_dma_ff( channel );
set_dma_mode( channel, mode );
set_dma_addr( channel, virt_to_bus( buf ) );
set_dma_count( channel, count );
enable_dma( channel );
release_dma_lock( flags );
return 0;
}
int template_dma_isdone( int channel )
{
int residue;
unsigned long flags = claim_dma_lock( );
residue = get_dma_residue( channel );
release_dma_lock( flags );
return ( residue == 0 );
}
SetPageReserved( ) 할당된 페이지를 예약
ClearPageReserved( ) 예약된 페이지의 해제
file_operations 구조체의 mmap 필드
int dma_mmap_mmap( struct file *filp, struct vm_area_struct *vma )
{
unsigned long phys_addr;
phys_addr = virt_to_phys( dmabuff )
if ( remap_page_range( vma, vma->vm_start, phys_addr, DMA_BUFF_SIZE, vma->vm_page_prot ) )
return -EAGAIN;
return 0;
}
'실습 > 리눅스 커널' 카테고리의 다른 글
디바이스 드라이버의 동작 (0) | 2021.02.08 |
---|---|
Major, Minor # (0) | 2021.02.08 |
Memory Mapping (0) | 2021.02.08 |
인터럽트 (Interrupt) 처리 (0) | 2021.02.08 |
커널 타이머, 태스크릿, 작업큐 (0) | 2021.02.08 |