linux kernel 模組時鐘的用法

2022-07-28 13:27:37 字數 3109 閱讀 2833

2012-01-31 14:27

7人閱讀

收藏 舉報

kernel-2.6.13各個模組時鐘的用法 (2009-10-15 17:06)

分類: 驅動入門

逢山開路 遇水架橋,今天想自己寫個adc的驅動,發現不清楚系統各個模組的系統時鐘如何使用。

總不能自己想怎麼弄,就怎麼弄吧,還是學學框架吧——使用時鐘的框架。

adc_clock = clk_get(null, "adc");

if (!adc_clock)

clk_use(adc_clock);

clk_enable(adc_clock);

上面的這段**是touchscreen的驅動中的一段,我不清楚,所以去學學系統各個模組時鐘的使用方式。

在系統的初始化的時候,看見過,但是忘了,在回顧一下。

那是在paging_init()中呼叫了 mdesc->map_io(),

void __init sbc2440_map_io(void)

跟 cpu_table 有關,拷貝過來

/* table of supported cpus */

static const char name_s3c2410  = "s3c2410";

static const char name_s3c2440  = "s3c2440";

static const char name_s3c2410a = "s3c2410a";

static const char name_s3c2440a = "s3c2440a";

static struct cpu_table cpu_ids __initdata = ,,,

};和時鐘相關的呼叫路徑: 在 s3c24xx_init_clocks() -> (cpu->init_clocks)(xtal)-> s3c24xx_setup_clocks()

這個s3c24xx_setup_clocks()註冊了系統的所有時鐘,仔細看看它。

在這個函式被呼叫之前,**已經根據 s3c2410_mpllcon,s3c2410_clkdivn暫存器 和 晶振 的頻率計算出了

fclk,hclk,pclk,他們應該分別是400m,100m,50m。

struct clk ;

clk資料結構是系統中時鐘的抽象,它用list串成乙個雙向鍊錶,在這個clocks煉表裡的clk結構,說明是系統中已經註冊的,

parent表示他的**,f,h,p之一,name是尋找到某個clk的唯一標識。enable是物件導向的思想的體現,不過,這裡

沒有用到,只是全部被填充為 s3c24xx_clkcon_enable()。

/* clock information */

static list_head(clocks);

static declare_mutex(clocks_sem);

/* clock definitions */

static struct clk init_clocks = ,,,

,,,,

,,,,

,,,,

};仔細看,usb-device 的parent有些特別,watchdog沒有enable,只有uart才有id,其他的id都是-1。

下面可以看 s3c24xx_setup_clocks()了,像所注視的那樣,它初始化了所有的時鐘,其實是註冊到clocks鍊錶裡面,以後可以從clocks

鍊錶中找到。

/* initalise all the clocks */

int __init s3c24xx_setup_clocks(unsigned long xtal,

unsigned long fclk,

unsigned long hclk,

unsigned long pclk)

}上面完成了系統其他部分時鐘初始化,當然這部分才是我們關心的內容,這些模組的時鐘源都來自base clock。

其中watchdog沒有enable成員,不能被關閉。

return 0;

}//s3c24xx_setup_clocks()end

下面是四個系統的基本時鐘,clk_xtal代表晶震。

他們的rate都被上面的函式確定了,而其他部分的時鐘還沒有rate呢。

/* base clocks */

static struct clk clk_xtal = ;

static struct clk clk_f = ;

static struct clk clk_h = ;

static struct clk clk_p = ;

巨集this_module,它的定義如下是#define this_module (&__this_module),__this_module是乙個struct module變數,

代表當前模組,跟current有幾分相似。可以通過this_module巨集來引用模組的struct module結構

好了,回頭看看讓我暈的函式。

adc_clock = clk_get(null, "adc");

if (!adc_clock)

clk_use(adc_clock);

clk_enable(adc_clock);

上面涉及到3個函式,分別是clk_get,clk_use,clk_enable()。

其中clk_get()的主要**如下:

list_for_each_entry(p, &clocks, list)

}看到了吧,不再clocks這個時鐘煉表裡的時鐘配置是不會被看到的,這都是s3c24xx_register_clock()函式的功勞,

然後他根據名字,找到對應的時鐘結構,比如根據"adc"找到adc的clk結構,然後增加對這個模組的使用計數,最後返回

這個找到的clk指標。

clk_use()很簡單,只是單純的增加本時鐘的使用

int clk_use(struct clk *clk)

在看時鐘開啟函式,

clk_enable(adc_clock)

int clk_enable(struct clk *clk)

這裡就體現出了物件導向的思想了,其中watchdog,四個基本的時鐘是沒有開啟關閉的。

當然這個函式也是最主要的操作,他包含了對暫存器clkcon的操作。

Linux kernel模組管理相關詳解

linux核心模組化設計 1.linux核心設計 單核心 模組化 動態裝載和解除安裝 1 linux 單核心設計,但充分借鑑了微核心體系的設計的優點 為核心引入了模組化機制 2 核心的組成部分 kernel 核心核心,一般為bzimage格式,通常位於 boot目錄,名稱為vmlinuz versi...

Linux kernel 關於keyboard部分

linux kernel 關於keyboard部分 keyboard.c 用於處理和鍵盤相關的input handler。其中包括後續的鍵碼轉換和輸出 atkbd.c 常用的鍵盤布局,用於獲得掃瞄碼,並將其傳送到input handler 鍊錶中 struct input handler kbd h...

Linux kernel併發處理

理解好併發處理,有幾個小概念是相關的。1.由於圖靈機本身是依賴side effect來工作,故同步互斥機制便有了必要性。角度來看,如果依賴了共享的變數,便意味著可能需要同步保護。如果是lamada演算的函式式程式設計,是不需要同步保護滴。2.死鎖dead lock的必要4條件。1.資源的獨占性 不可...