www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]一,要使用DMA先要初始化一個結(jié)構(gòu)體這個結(jié)構(gòu)體就只有一個字段name,在DMA中斷請求時這個name將傳遞個dev_name。intrequest_irq( , , ,const char *dev_name,);。struct s3c2410_dma_client {char *name;};還得知道要

一,

要使用DMA先要初始化一個結(jié)構(gòu)體這個結(jié)構(gòu)體就只有一個字段name,在DMA中斷請求時這個name

將傳遞個dev_name。intrequest_irq( , , ,const char *dev_name,);。

struct s3c2410_dma_client {
char *name;
};

還得知道要使用的DMA源。然后就可以調(diào)用下面函數(shù)來請求該DMA源對應(yīng)的DMA通道了。

int s3c2410_dma_request(unsigned int channel,struct s3c2410_dma_client *client,void *dev)

在上面請求函數(shù)中做了兩項(xiàng)重要工作:

(1)

調(diào)用函數(shù)chan = s3c2410_dma_map_channel(channel); 根據(jù)DMA源在 源-----通道 管理結(jié)構(gòu)體

dma_sel.map(該結(jié)構(gòu)體在《DMA原理》中講過)中找出一個該DMA源所能請求并且空閑的通道,再根據(jù)

該通道號在數(shù)組s3c2410_chans[ch]中獲取一個被部分初始化過的DMA通道管理結(jié)構(gòu)體s3c2410_dma_chan。

然后將這個結(jié)構(gòu)體指針放到數(shù)組dma_chan_map[channel] 中,該數(shù)組中存放的都是在使用的DMA通道的管理結(jié)構(gòu)體

指針,獲取DMA通道管理結(jié)構(gòu)體用下面函數(shù)來實(shí)現(xiàn):

static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
{

。。。。。。
return dma_chan_map[channel];
}

下面是函數(shù)s3c2410_dma_map_channel()中的主要工作。

ch_map = dma_sel.map + channel;

。。。。。。

dmach = &s3c2410_chans[ch];
dmach->map = ch_map;
dma_chan_map[channel] = dmach;

(2)

獲取DMA通道之后注冊該通道的中斷,并關(guān)聯(lián)中斷函數(shù)s3c2410_dma_irq(),該函數(shù)在后面講解。

request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,client->name, (void *)chan);

二,

int s3c2410_dma_devconfig(int channel,enum s3c2410_dmasrc source,int hwcfg,unsigned long devaddr)
{
struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);

。。。。。

chan->source = source;
chan->dev_addr = devaddr;
chan->hw_cfg = hwcfg;

switch (source) {
case S3C2410_DMASRC_HW://源在外設(shè),既是從外設(shè)讀數(shù)據(jù)到內(nèi)存,源的地址是確定的。
dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);//初始化源控制寄存器
dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr);//將源地址寫入初始源寄存器
dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));//目的地址在系統(tǒng)總線AHB上

chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);//將目的初始寄存器地址存于chan->addr_reg。

//外設(shè)的地址是確定的,內(nèi)存地址不確定,chan->addr_reg上存的地址或是初始源寄存器,初始目的寄存器

//根據(jù)從外設(shè)讀寫數(shù)據(jù)的不同而不同,但內(nèi)存的地址始終是寫到chan->addr_reg所指向的寄存器中。
break;

case S3C2410_DMASRC_MEM:////源在內(nèi)存,既是將內(nèi)存數(shù)據(jù)寫到外設(shè),目的地址是確定的。
dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr);
dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);

chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
break;

default:

return -EINVAL;
}

return 0;
}

三,

int s3c2410_dma_config(unsigned int channel, int xferunit,int dcon)
{
struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);//找出源channel對應(yīng)的DMA通道管理結(jié)構(gòu)體。

dcon |= chan->dcon & dma_sel.dcon_mask;//設(shè)定DMA源選擇位

switch (xferunit) {//數(shù)據(jù)傳輸?shù)膯挝淮笮?br/>case 1:
dcon |= S3C2410_DCON_BYTE;
break;

case 2:
dcon |= S3C2410_DCON_HALFWORD;
break;

case 4:
dcon |= S3C2410_DCON_WORD;
break;

default:
return -EINVAL;
}

dcon |= S3C2410_DCON_HWTRIG;//源觸發(fā),不是軟件觸發(fā)
dcon |= S3C2410_DCON_INTREQ;//中斷使能

//將DMA通道控制寄存器的配置存于chan->dcon,到現(xiàn)在DMA通道控制寄存器中還有傳輸計(jì)數(shù)的值沒有配置了,

//當(dāng)內(nèi)存加載到初始源寄存器或是初始目的寄存器時再配置該值,并將chan->dcon中的值一并寫入DMA控制寄存器。

chan->dcon = dcon;
chan->xfer_unit = xferunit;

return 0;
}

四,

int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
{
struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);

。。。。。。

//設(shè)置回調(diào)函數(shù)。待傳輸數(shù)據(jù)的內(nèi)存空間可能是不連續(xù)的,有很多段,當(dāng)一段內(nèi)存用完后

//調(diào)用該回調(diào)函數(shù)進(jìn)行處理。

chan->callback_fn = rtn;

return 0;
}

五,

int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
{
struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);

chan->flags = flags;//設(shè)定flags的值比如S3C2410_DMAF_AUTOSTART,這個值在后面會用到。

return 0;
}

六,

s3c2410_dma_ctrl(host->dma, S3C2410_DMAOP_FLUSH);//下面講解

//函數(shù)s3c2410_dma_ctrl()的原型如下:

int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
{
struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);

switch (op) {
case S3C2410_DMAOP_START:
return s3c2410_dma_start(chan);

case S3C2410_DMAOP_STOP:
return s3c2410_dma_dostop(chan);

case S3C2410_DMAOP_PAUSE:
case S3C2410_DMAOP_RESUME:
return -ENOENT;

case S3C2410_DMAOP_FLUSH:
return s3c2410_dma_flush(chan);

case S3C2410_DMAOP_STARTED:
return s3c2410_dma_started(chan);

case S3C2410_DMAOP_TIMEOUT:
return 0;

}

return -ENOENT; /* unknown, don't bother */
}

此處我們傳輸?shù)闹凳荢3C2410_DMAOP_FLUSH,應(yīng)該執(zhí)行函數(shù)s3c2410_dma_flush(chan);。

static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
{
。。。。。。

chan->curr = chan->next = chan->end = NULL; ////

。。。。。。

s3c2410_dma_waitforstop(chan);//循環(huán)等待屏蔽觸發(fā)寄存器中的DMA通道開關(guān)位的關(guān)閉。

return 0;
}

七,

//先將各內(nèi)存段掛到sg連上,調(diào)用函數(shù)dma_map_sg()映射一個發(fā)散/匯聚 DMA 操作,返回合并后的內(nèi)存段數(shù)。

dma_len =dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, enum dma_data_direction direction)

for (i = 0; i < dma_len; i++) {

//分配一個數(shù)據(jù)段管理結(jié)構(gòu)體,并將各數(shù)據(jù)段穿成單向鏈表,以及加載一個數(shù)據(jù)段到DMA通道

//并開啟DMA數(shù)據(jù)傳輸s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,S3C2410_DMAOP_START);

res = s3c2410_dma_enqueue(unsigned int channel, void *id,dma_addr_t data, int size)
}

int s3c2410_dma_enqueue(unsigned int channel, void *id,
dma_addr_t data, int size)
{
struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
struct s3c2410_dma_buf *buf;
unsigned long flags;

//從內(nèi)存池dma_kmem為內(nèi)存管理結(jié)構(gòu)體s3c2410_dma_buf分配內(nèi)存。

buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);

buf->next = NULL;
buf->data = buf->ptr = data;//該段內(nèi)存的物理地址
buf->size = size;//該段內(nèi)存的大小
buf->id = id;
buf->magic = BUF_MAGIC;

local_irq_save(flags);

if (chan->curr == NULL) {//該函數(shù)第一次被調(diào)用也就是加載該通道的第一段內(nèi)存會進(jìn)入下面分支。

//在多段內(nèi)存工作過程中chan->curr指向當(dāng)前 目的/源 寄存器中加載的內(nèi)存段,也表示內(nèi)存段鏈表

//中的第一個內(nèi)存段。chan->next指向初始 目的/源 寄存器中加載的內(nèi)存段。也表示內(nèi)存段鏈表

//中的第二個內(nèi)存段。chan->end表示內(nèi)存段鏈表中最后一個內(nèi)存段。

chan->curr = buf;
chan->end = buf;//此時只有一段內(nèi)存。
chan->next = NULL;
} else {

chan->end->next = buf;//以后內(nèi)存段都是從鏈表尾插入鏈表的。
chan->end = buf;
}

//第一個內(nèi)存段加入chan->next指向第一個內(nèi)存段,第二個內(nèi)存段加入chan->next指向第二個內(nèi)存段,

////第三個內(nèi)存段加入chan->next還是指向第二個內(nèi)存段,
if (chan->next == NULL)
chan->next = buf;

//只有函數(shù)s3c2410_dma_ctrl()中調(diào)用的各函數(shù)可以改變chan->state的值,該值代表DMA通道的工作狀態(tài)。

//chan->load_state表示內(nèi)存段的在DMA寄存器中的加載情況,一般在存儲段加載函數(shù)中改變

//該值。在第一次調(diào)用該函數(shù)時是不會進(jìn)入下面分支的,第一次調(diào)用本函數(shù)會在下面調(diào)用函數(shù)

//s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,S3C2410_DMAOP_START);開啟DMA數(shù)據(jù)傳輸,

//第二次調(diào)用該函數(shù)可能就會進(jìn)入下面分支了。
if (chan->state == S3C2410_DMA_RUNNING) {
if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {

//如果開啟了DMA數(shù)據(jù)傳輸有一段內(nèi)存加載到了初始 目的/源 地址寄存器,但DMA當(dāng)前 目的/源 地址寄存器中還沒有

//加載內(nèi)存地址,則等待初始 目的/源 地址寄存器中的內(nèi)存地址加載到當(dāng)前 目的/源 地址寄存器中。
if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
。。。。。。
}
}

while (s3c2410_dma_canload(chan) && chan->next != NULL) {

//如果DMA當(dāng)前 目的/源 地址寄存器 或 DMA初始 目的/源 地址寄存器中沒有加載內(nèi)存地址則,加載一段內(nèi)存

/*

函數(shù)s3c2410_dma_loadbuf

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉