1、引言
(2)可以使用兩種方式傳送資料
第二種:應用程式不斷地發資料,驅動程式不斷地取資料,不斷地發給硬體。解決了聲音斷續的問題,但是要建立乙個非常大的緩衝區(在驅動程式裡面申請的 ,稱其為buffer)
乙個取樣點的資料報括左聲道資料和右聲道資料
這裡hw_ptr是指標( 更新是指指標向後移)
2、怎麼寫驅動(s3c2440_dma.c(platform))
(1)負責資料傳輸的是平台部分裡面的dma檔案,修改s3c2440_dma.c
3、分配/釋放buffer
建立音效卡時,s3c2440_dma_new函式被呼叫,函式裡分配dma buffer.銷毀音效卡時,釋放dma buffer
(1)分配dma buffer
static int s3c2440_dma_new(struct snd_soc_pcm_runtime *rtd)
//return ret;}
(2)釋放dma buffer}
4、request_irq
(1)open函式
static int s3c2440_dma_open(struct snd_pcm_substream *substream)
return 0;
}(2)中斷請求函式(資料傳輸成功後,更新hw_ptr等資訊)
static irqreturn_t s3c2440_dma2_irq(int irq, void *devid)//左邊引數是中斷號,右邊是裝置id
return irq_handled;}
5、 s3c2440_dma_hw_params(準備dma傳輸的參設設定)
static int s3c2440_dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
6、prepare函式(準備dma傳輸的資料)
7、載入需要傳輸的資料
/* 資料傳輸: 源,目的,長度 */
8、dma_trigger函式(觸發dma傳輸,
傳輸完成後,產生中斷,進入中斷處理函式s3c2440_dma2_irq)
9、dma_pointer函式(表示下一次dma傳輸的位置(每一次dma傳輸乙個period),hw_ptr指標是根據dma位置來確定的)
/* 返回結果是frame(單位是frame) */
static snd_pcm_uframes_t s3c2440_dma_pointer(struct snd_pcm_substream *substream)
10、總結
(1)建立音效卡時導致 s3c2440_dma_new函式被呼叫
(2)s3c2440_dma_new函式裡面分配dma buffer(分配最大的,128k,但並不表示一定要用完(根據應用程式引數決定))
(4)設定引數(在s3c2440_dma_hw_params函式中),驅動程式分配了很大一塊空間,確定buffer_size(應用程式傳進來的params引數決定的),period_size(buffer裡是逐個peroid傳輸的)
一次dma傳輸是以period傳輸的
(5)準備dma傳輸(s3c2440_dma_prepare),載入第乙個period(load_dma_period)
(6)啟動dma 傳輸(s3c2440_dma_trigger),乙個period傳輸完後會產生中斷)呼叫中斷處理函式(s3c2440_dma2_irp更新偏移位址。更新alsa驅動的其他狀態資訊。如果還有資料,再次載入period,再次啟動
從零基礎學習資料庫之DML語言(二)
select 語句的乙個基本結構了解了,繼續學習一些語法知識吧。我們現在做一件稍微麻煩的事情,希望查詢結果集中顯示出作者的姓名,即au fname和au lname的結合。這就需要對列進行運算。使用字串連線符就可以做到了。程式清單如圖所示,在乙個 裡進行。字串連線運算子 例如 abc def abc...
從零基礎學習資料庫之DML語言(一)
等等,au lname 是什麼?怎麼這個列的名稱這麼亂?這是一種命名規則,是人們長期以來總結的比較合適的命名規則,叫做匈牙利命名法。第一次看到這種命名時,相比把變數名命名成 a b 或者 a1 雖然比較亂,但是這樣命名的結果是有意義,更容易理解。當然,不可否認的是也許針對某個特別的程式設計例項會有更...
從零基礎學習資料庫之DML語言(二)
select 語句的乙個基本結構了解了,繼續學習一些語法知識吧。我們現在做一件稍微麻煩的事情,希望查詢結果集中顯示出作者的姓名,即au fname和au lname的結合。這就需要對列進行運算。使用字串連線符就可以做到了。程式清單如圖所示,在乙個 裡進行。字串連線運算子 例如 abc def abc...