硬體通過中斷與作業系統進行通訊,通過對硬體驅動程式處註冊中斷處理程式,快速響應硬體的中斷。
硬體中斷優先順序很高,打斷當前正在執行的程式。有兩種情況:
硬體中斷在中斷處理程式中處理
硬體中斷延後再進行處理
這個具體硬體相關,在中斷處理程式中處理,打斷了當前正在執行的程式;所有中斷都將被遮蔽;如果占用時間太長不合適,
造成系統互動性,反應能力都會受到影響。 需要在其中判斷平衡:
如果乙個任務對時間非常敏感,將其放在中斷處理程式中執行;
如果乙個人和和硬體相關,將其放在中斷處理程式中執行;
如果乙個任務要保證不被其他中斷打斷,將其放在中斷處理程式中執行;
其餘情況考慮延後機制中執行——下半部。
軟中斷是在編譯期間靜態分配的,在程式執行前將軟中斷假如到表中。
下面看一下這個過程:
加入軟中斷型別:
linux3.5.3**:
enum//軟中斷表:;
static structsoftirq_actionsoftirq_vec[nr_softirqs]
//軟中斷結構體
struct註冊軟中斷處理函式:softirq_action
;
void open_softirq(int nr, void (*action)(struct softirq_action *))觸發軟中斷:
void raise_softirq(unsigned int執行軟中斷:nr)
void irq_exit(void軟中斷的基本結構如下圖表示:)void __do_softirq(void
)
//下乙個軟中斷
h++;
//下乙個軟中斷狀態標誌位
pending >>= 1
; }
while
(pending);
local_irq_disable();
pending =local_softirq_pending();
if (pending && --max_restart)
goto
restart;
if(pending)
wakeup_softirqd();
lockdep_softirq_exit();
__local_bh_enable(softirq_offset);
}
軟中斷中表中有一種型別是:tasklet_softirq
tasklet就是利用軟中斷實現中斷推後處理機制。通常使用較多的是tasklet而不是軟中斷。
tasklet資料結構:
structstate:tasklet_struct
;
enumcount:為0允許啟用執行;
宣告tasklet:可以動態或者靜態方式
靜態:
#define declare_tasklet(name, func, data) \動態:struct tasklet_struct name =
#define declare_tasklet_disabled(name, func, data) \
struct tasklet_struct name =
void tasklet_init(struct tasklet_struct *t,同時需要編寫tasklet處理函式。void (*func)(unsigned long), unsigned long
data)
排程tasklet:
void tasklet_hi_schedule(struct tasklet_struct *t)執行tasklet處理程式:繼續看上面排程tasklet程式執行:
inline void raise_softirq_irqoff(unsigned intksoftirqd核心執行緒:軟中斷才被觸發頻率很高,在處理過程中還會重新觸發軟中斷;執行會導致使用者空間程序無法獲得處理時間處於飢餓狀態;nr)//
使用ksoftirqd核心執行緒來處理
static
void wakeup_softirqd(void
)
對重新觸發的軟中斷立即處理,會導致佔據處理時間過長;不進行立即處理不合適;
對此解決方法:
l 只要還有被觸發並等待處理和過程中重新觸發的軟中斷的軟中斷,本次執行就要負責處理;軟中斷立即處理,使用者空間得不到執行時間。
l 不處理過程中觸發的軟中斷,放到下乙個中斷執行時機時處理。軟中斷得不到立即處理,系統空閒時造成不合理;保證使用者空間得到執行時間。
兩種方式有存在問題,只能在這其中採取這種的方式:
核心使用執行緒處理軟中斷,執行緒優先順序較低,可以被搶占;能夠保證軟中斷被處理,也能保證使用者空間程式得到執行時間。
每個cpu上有存在這樣乙個執行緒:ksoftirqd/0或者ksoftirqd/1……
static __init int spawn_ksoftirqd(void工作佇列(work queue)通過核心執行緒將中斷下半部分程式推後執行到執行緒中執行,工作佇列可以建立執行緒來處理相應任務。)early_initcall(spawn_ksoftirqd);
static
int __cpuinit cpu_callback(struct notifier_block *nfb,
unsigned
long
action,
void *hcpu)
工作佇列建立的執行緒為工作者執行緒:worker thread;系統提供預設的執行緒來處理工作者佇列。
工作者執行緒資料結構:
structcpu工作佇列資料結構:workqueue_struct cpu_wq;
/*i: cwq's
*/struct list_head list; /*
w: list of all workqueues
*/……
}
struct工作資料結構:cpu_workqueue_struct ;
struct宣告工作佇列:靜態:work_struct ;
#define declare_work(n, f) \動態:struct work_struct n = __work_initializer(n, f)
#define init_work(_work, _func) \需要編寫工作佇列處理函式:dowhile (0)
typedef void (*work_func_t)(struct work_struct *work);排程工作佇列:
int schedule_work(struct work_struct *work)喚醒工作者佇列執行緒處理。int queue_work(struct workqueue_struct *wq, struct work_struct *work)
執行工作者佇列處理程式:
static可以建立新的工作者佇列和執行緒來處理。平衡是個很關鍵的問題!int worker_thread(void *__worker)
while
(keep_working(gcwq));
}
Linux 核心學習 6 中斷和異常處理
配置功能選項 中斷流程 連線ioapic引腳的裝置觸發中斷 檢測delivery status是否為0,不是0則等待,否則設其為1 sent pending 將中斷傳送至對應的cpu cpu響應中斷 對於level觸發的中斷,設定irr為1,並等待cpu觸發eoi,再將irr復位0 delivery...
Linux核心學習筆記(五) 系統呼叫
系統呼叫在使用者空間程序和硬體裝置之間新增了乙個中間層。作用 應用程式通過使用者空間實現的應用程式設計介面 api 而不是直接通過系統呼叫來程式設計。unix最流行的應用程式設計介面是基於posix標準的,posix定義的api函式和系統呼叫之間有著直接關係。c庫實現了unix系統的主要api,包括...
linux核心學習筆記
核心的配置 a.make s3c2410 deconfig b.make menuconfig 圖形化配置 c.使用廠家給出的配置 生成.config 編譯生成核心,使用如下命令 make vmlinux make uimage 帶頭部 真正核心 1 config 建立生成autoconf.h 供源...