Linux核心時鐘框架

2021-05-24 22:59:48 字數 3475 閱讀 8788

逢山開路 遇水架橋,今天想自己寫個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()註冊了系統的所有時鐘,仔細看看它。 在這個函式被呼叫之前,**已經根據3c2410_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成員,不能被關閉。

*/return0;

}//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核心時鐘

1 核心時鐘 作業系統的核心都需要乙個系統時鐘才可以工作,這個系統時鐘是硬體提供的,作業系統用該時鐘進行計時,如sleep 時間片輪轉。作業系統核心使用的時鐘,叫核心時鐘,也叫滴答時鐘。stm32f407 uc os iii 作業系統核心時鐘頻率 os ticks per sec 200 s5p68...

linux核心的rtc時鐘配置

linux核心的rtc時鐘配置,見device drivers real time clock 我們的rtc主要是有三種介面配置,一種是i2c介面,一種是spi介面,還有就是cpu自帶rtc時鐘晶元。推薦配置如下 i2c介面rtc時鐘支援晶元 dallas maxim ds1307 37 38 39...

深入Linux核心架構筆記 動態時鐘

為節省系統功耗,只在有些任務需要實際執行時,才啟用週期時鐘,否則會臨時禁用週期時鐘,對該技術的支援可以在編譯時選擇,啟用此選項的系統也稱無時鐘系統。判斷原則 當系統排程選擇idle程序來執行時,動態時鐘系統會禁用週期時鐘,直到下乙個定時器即將到期為止 struct tich sched idle t...