十 linux核心時鐘

2021-10-24 22:52:45 字數 4905 閱讀 3716

1、核心時鐘

作業系統的核心都需要乙個系統時鐘才可以工作,這個系統時鐘是硬體提供的,作業系統用該時鐘進行計時,如sleep()、時間片輪轉。

作業系統核心使用的時鐘,叫核心時鐘,也叫滴答時鐘。

stm32f407 + uc/os-iii ---->作業系統核心時鐘頻率:os_ticks_per_sec = 200

s5p6818 + linux ---->作業系統核心時鐘頻率:hz = 1000

linux的核心時鐘,是由處理器的定時器提供的。

2、核心時鐘的頻率是與硬體平台相關

s5p6818 + linux —>如何初始化linux核心時鐘的???

1)首先找到linux原始碼針對s5p6818平台的主初始化原始檔

/arch/arm/mach-s5p6818/cpu.c

2)找到機器巨集

machine_start

(s5p6818, cfg_sys_cpu_name)

.atag_offset =

0x00000100

,.fixup = cpu_fixup,

.map_io = cpu_map_io,

.init_irq = nxp_cpu_irq_init,

.handle_irq = gic_handle_irq,

.timer =

&nxp_cpu_sys_timer,

.init_machine = cpu_init_machine,

#if defined config_cma && defined config_ion

.reserve = cpu_mem_reserve,

#endif

machine_end

機器巨集中,定義了一些資料和函式,這些資料和函式在linux核心初始化的時候,都是針對乙個具體的硬體平台的。

每個硬體平台都有乙個這樣的機器巨集。

3)找到系統時鐘的定義

.timer	=

&nxp_cpu_sys_timer,

struct sys_timer nxp_cpu_sys_timer =

;

4)找到定時器的初始化函式–>timer_initialize

static

void __init timer_initialize

(void

)

5)timer_source_init(cfg_timer_sys_tick_ch); //0

猜測使用的是timer0作為核心時鐘。

3、核心時鐘的頻率

stm32f407 + uc/os-iii ---->作業系統核心時鐘頻率:os_ticks_per_sec = 200

s5p6818 + linux ---->作業系統核心時鐘頻率:hz = 1000

核心時鐘的頻率與處理器的效能有關係。一般處理器的效能越高,hz的值可以設的大一些。

hz的值越大,有什麼優缺點??

系統計時的精度會越高,計時越準確,系統的實時性越好。系統處理時鐘中斷的頻率越高,系統的負擔就越重。

1、hz是乙個全域性的常數

hz就是linux核心時鐘的頻率,hz是linux系統中的乙個常數,當配置核心的時候,hz的就設好了,如果重新修改hz的值,重新配置、編譯linux核心。

printk

("hz=%d\n"

, hz)

;

2、如何設定hz的值

system type —>

timer frequency (1000 hz) —>

( ) 100 hz

( ) 250 hz

( ) 300 hz

(x) 1000 hz

條件編譯選項:config_hz_1000

去核心原始碼搜尋

$ grep hz_1000 ./ -r

3.hz的定義

define hz config_hz /* internal kernel timer frequency */

//.config --->autoconf.h

#define config_hz 1000

1、什麼是jiffies

jiffies是乙個全域性的變數,記錄了linux核心從啟動到現在經過了多少核心時鐘週期。1秒鐘內,jiffies增加hz次。

jiffies是核心時鐘的計數值。

jiffies/hz ---->linux系統啟動到現在用了多少秒。

printk

("jiffies=%lu\n"

,jiffies)

;

2、jiffies的定義

jiffies = jiffies_64;

u64 __jiffy_data jiffies_64;

unsigned

long

volatile __jiffy_data jiffies;

注意:

char — 8bits

short — 16bits

int ---- 32bits

long ---- 問題:cpu是64bits,但是編譯器是32bits —>long = 32bits

1、應用程式的延時函式 —>會產生阻塞

#include

unsigned

intsleep

(unsigned

int seconds)

;int

usleep

(useconds_t usec)

;

2、驅動程式的延時函式–>睡眠延時(會產生阻塞)—>長時間延時

#include

void

ssleep

(unsigned

int seconds)

void

msleep

(unsigned

int msecs)

3、驅動程式的延時函式–>忙等待延時(不會產生阻塞)---->短時間延時

void

mdelay

(unsigned

long x)

void

ndelay

(unsigned

long x)

void

udelay

(unsigned

long x)

|------------------|

_____

int data;

int timer_cnt =0;

dowhile

(data ==0)

;dowhile

(data ==1)

;得到timer_cnt,就是us的計時值

linu核心動態定時器是依賴於linux核心時鐘的,動態定時器的週期只能是核心時鐘週期的整數倍。

動態定時器不是硬體定時器的驅動,而是利用核心動態定時器產生的時鐘週期。

1、定義乙個動態定時器

#include

struct timer_list

;

例:

static

struct timer_list gec6818_timer;

2、初始化動態定時器

void

init_timer

(struct timer_list *timer)

設定動態定時器的超時時間和超時處理函式

void

gec6818_timer_fun

(unsigned

long data)

//data=10

gec6818_timer.function = gec6818_timer_fun;

gec6818_timer.expires = jiffies +

100;

//當前時間開始,100個jiffy後,會產生超時(100ms)

gec6818_timer.data =

10;

3、將動態定時器加入核心,並啟動動態定時器

void

add_timer

(struct timer_list *timer)

4、修改動態定時器的超時時間,並啟動timer

int

mod_timer

(struct timer_list *timer,

unsigned

long expires)

5、刪除動態定時器

int

del_timer

(struct timer_list *timer)

示例**:led_dev.c

Linux核心時鐘框架

逢山開路 遇水架橋,今天想自己寫個adc的驅動,發現不清楚系統各個模組的系統時鐘如何使用。總不能自己想怎麼弄,就怎麼弄吧,還是學學框架吧 使用時鐘的框架。adc clock clk get null,adc if adc clock clk use adc clock clk enable adc ...

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...