linux dma cache
void dma_sync_single_for_device(struct device *dev,dma_handle_t bus_addr, size_t size, enum dma_data_direction direction);如果設(shè)備要求較大的DMA緩沖區(qū),在其支持SG模式的情況下,申請(qǐng)多個(gè)不連續(xù)的,相對(duì)較小的DMA緩沖區(qū)通常是防止申請(qǐng)?zhí)蟮倪B續(xù)物理空間的方法,在Linux內(nèi)核中,使用如下函數(shù)映射SG:
int dma_map_sg(struct device *dev,struct scatterlist *sg, int nents,enum dma_data_direction direction); 其中nents是散列表入口的數(shù)量,該函數(shù)的返回值是DMA緩沖區(qū)的數(shù)量,可能小于nents。對(duì)于scatterlist中的每個(gè)項(xiàng)目,dma_map_sg()為設(shè)備產(chǎn)生恰當(dāng)?shù)目偩€地址,它會(huì)合并物理上臨近的內(nèi)存區(qū)域。下面在給出scatterlist結(jié)構(gòu):
struct scatterlist
{
struct page *page;
unsigned int offset; //偏移量
dma_addr_t dma_address; //總線地址
unsigned int length; //緩沖區(qū)長(zhǎng)度
}
執(zhí)行dma_map_sg()后,通過(guò)sg_dma_address()后可返回scatterlist對(duì)應(yīng)緩沖區(qū)的總線結(jié)構(gòu),sg_dma_len()可返回scatterlist對(duì)應(yīng)的緩沖區(qū)的長(zhǎng)度,這兩個(gè)函數(shù)的原型是:
dma_addr_t sg_dma_address(struct scatterlist *sg); unsigned int sg_dma_len(struct scatterlist *sg);
在DMA傳輸結(jié)束后,可通過(guò)dma_map_sg()的反函數(shù)dma_unmap_sg()去除DMA映射:
void dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction); SG映射屬于流式DMA映射,與單一緩沖區(qū)情況下流式DMA映射類(lèi)似,如果設(shè)備驅(qū)動(dòng)一定要訪問(wèn)映射情況下的SG緩沖區(qū),應(yīng)該先調(diào)用如下函數(shù):
int dma_sync_sg_for_cpu(struct device *dev,struct scatterlist *sg, int nents,enum dma_data_direction direction);
訪問(wèn)完后,通過(guò)下列函數(shù)將所有權(quán)返回給設(shè)備:
int dma_map_device(struct device *dev,struct scatterlist *sg, int nents,enum dma_data_direction direction);
Linux 系統(tǒng)中可以有一個(gè)相對(duì)簡(jiǎn)單的方法預(yù)先分配緩沖區(qū),那就是同步mem=參數(shù)預(yù)留內(nèi)存。例如,對(duì)于內(nèi)存為64MB的系統(tǒng),通過(guò)給其傳遞mem=62MB命令行參數(shù)可以使得頂部的2MB內(nèi)存被預(yù)留出來(lái)作為IO內(nèi)存使用,這2MB內(nèi)存可以被靜態(tài)映射,也可以執(zhí)行ioremap()。
相應(yīng)的函數(shù)都介紹完了:說(shuō)真的,好費(fèi)勁啊,我都想放棄了,可為了小王,我繼續(xù)哈在linux設(shè)備驅(qū)動(dòng)中如何操作呢:
像使用中斷一樣,在使用DMA之前,設(shè)備驅(qū)動(dòng)程序需要首先向系統(tǒng)申請(qǐng)DMA通道,申請(qǐng)DMA通道的函數(shù)如下:
int request_dma(unsigned int dmanr, const char * device_id); 同樣的,設(shè)備結(jié)構(gòu)體指針可作為傳入device_id的最佳參數(shù)。
使用完DMA通道后,應(yīng)該使用如下函數(shù)釋放該通道:void free_dma(unsinged int dmanr);
linux操作系統(tǒng)文章專(zhuān)題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論