linux 在某个core上的中断 affinity c语言函数,Linux中断处理体系结构
各種的異常的C處理函數(shù)可以分為5類,他們分布在不同的文件中。
1、在arch/arm/kernel/trapsc.c中
未定義指令異常,總?cè)肟诤瘮?shù)為do_undefinstr.
2、在arch/arm/mm/fault.c中
與內(nèi)存訪問相關(guān)的異常的C處理函數(shù),
3、在arch/arm/mm/irq.c中
中斷處理函數(shù)
4、在arch/arm/kernel/aclls.S中
swi異常的處理函數(shù)執(zhí)政被組織成一個(gè)表格:swi指令集起碼的位[23:0]被用來作為索引。這樣,通過不同的”swi index”指令就可以調(diào)用不同的swi異常處理函數(shù),它們被稱為系統(tǒng)調(diào)用,比如sys_open,sys_read,sys_write等。
5、沒有使用的異常。
中斷處理體系結(jié)構(gòu)
Linux內(nèi)核將所有的中斷統(tǒng)一編號(hào),使用一個(gè)irq_desc結(jié)構(gòu)數(shù)組來描述這些中斷:每個(gè)數(shù)組項(xiàng)對(duì)應(yīng)一個(gè)中斷(也有可能是一組中斷,他們共用相同的中斷號(hào)),里面記錄了中斷的名稱,中斷狀態(tài),中斷標(biāo)記(比如中斷類型,是否共享中斷等),并提供了中斷的底層硬件訪問函數(shù)(清除,屏蔽,使能中斷),提供了這個(gè)中斷的處理函數(shù)入口,通過它可以調(diào)用用戶注冊(cè)的中斷處理函數(shù)。
struct irq_desc {
irq_flow_handler_t handle_irq; /當(dāng)前中斷的處理函數(shù)入口/
struct irq_chip chip; /底層的硬件訪問*/
struct msi_desc *msi_desc;
void *handler_data;
void *chip_data;
struct irqaction action; / IRQ action list 用戶提供的中斷處理函數(shù)鏈表*/
unsigned int status; /* IRQ status IRQ狀態(tài)*/
unsigned int depth; /* nested irq disables */
unsigned int wake_depth; /* nested wake enables */
unsigned int irq_count; /* For detecting broken IRQs */
unsigned int irqs_unhandled;
spinlock_t lock;
#ifdef CONFIG_SMP
cpumask_t affinity;
unsigned int cpu;
#endif
#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
cpumask_t pending_mask;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
#endif
const char name; /中斷名稱*/
} ____cacheline_internodealigned_in_smp;
struct irq_chip {
const char *name;
unsigned int (startup)(unsigned int irq); /啟動(dòng)中斷,如果不設(shè)置,缺省為”enable”*/
void (shutdown)(unsigned int irq); /關(guān)閉中斷,如果不設(shè)置,缺省為”disable”*/
void (enable)(unsigned int irq); /使能中斷,如果不設(shè)置,缺省為”unmask”*/
void (disable)(unsigned int irq); /禁止中斷,如果不設(shè)置,缺省為”mask”*/
void (ack)(unsigned int irq); / 相應(yīng)中斷,通常是清除當(dāng)前中斷使得可以接收下一個(gè)中斷*/
void (mask)(unsigned int irq); /屏蔽中斷源*/
void (mask_ack)(unsigned int irq); /屏蔽和相應(yīng)中斷*/
void (unmask)(unsigned int irq); /開啟中斷源*/
void (*eoi)(unsigned int irq);
void (*end)(unsigned int irq);
void (*set_affinity)(unsigned int irq, cpumask_t dest);
int (*retrigger)(unsigned int irq);
int (*set_type)(unsigned int irq, unsigned int flow_type);
int (*set_wake)(unsigned int irq, unsigned int on);
/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
void (*release)(unsigned int irq, void *dev_id);
#endif
/*
* For compatibility, ->typename is copied into ->name.
* Will disappear.
*/
const char *typename;
};
struct irqaction {
irq_handler_t handler; /用戶注冊(cè)的中斷處理函數(shù)/
unsigned long flags; /中斷標(biāo)志,比如是否共享中斷,電平觸發(fā)還是邊沿觸發(fā)等/
cpumask_t mask; /用于SMP(對(duì)稱多處理器系統(tǒng))/
const char name; /用戶注冊(cè)的中斷名字,”cat /proc/interrupts”時(shí)可以看到*/
void dev_id; /用戶傳給上面的handler的參數(shù),還可以用來區(qū)分共享中斷*/
struct irqaction *next;
int irq; /中斷號(hào)/
struct proc_dir_entry *dir;
};
中斷處理流程如下:
1、發(fā)生中斷時(shí),CPU執(zhí)行異常向量vector_irq的代碼。
2、在vector_irq里面,最終會(huì)調(diào)用中斷處理的總?cè)肟诤瘮?shù)asm_do_IRQ.
3、asm_do_IRQ根據(jù)中斷號(hào)調(diào)用irq_desc數(shù)組項(xiàng)中的handle_irq.
4、handle_irq會(huì)使用chip成員中的函數(shù)來設(shè)置硬件,比如清除中斷,禁止中斷,重新使能中斷等。
5、handle_irq逐個(gè)調(diào)用用戶在action鏈表中注冊(cè)的處理函數(shù)。
可見,中斷體系結(jié)構(gòu)的初始化就是構(gòu)造這些數(shù)據(jù)結(jié)構(gòu),比如irq_desc數(shù)組項(xiàng)中的handle_irq,chip等成員;用戶注冊(cè)中斷時(shí)就是構(gòu)造action鏈表;用戶卸載中斷就是從action鏈表中去除不需要的項(xiàng)。
用戶(即驅(qū)動(dòng)程序)通過request_irq函數(shù)向內(nèi)核注冊(cè)中斷處理函數(shù),request_irq函數(shù)根據(jù)中斷號(hào)找到irq_desc數(shù)組項(xiàng),然后在它的action鏈表中添加一個(gè)表項(xiàng)。
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
{
…
action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
…
action->handler = handler;
action->flags = irqflags;
cpus_clear(action->mask);
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
…
retval = setup_irq(irq, action);
…
}
requset_irq函數(shù)首先使用這4個(gè)參數(shù)構(gòu)造一個(gè)irqaction結(jié)構(gòu),然后調(diào)用setup_irq函數(shù)將它鏈入鏈表中;
setup_irq函數(shù)完成了3個(gè)功能:
1、將新建的irqaction結(jié)構(gòu)鏈入irq_desc[irq]結(jié)構(gòu)的action鏈表中。如果action鏈表為空,則直接鏈入。如果先判斷新建的irqaction結(jié)構(gòu)和鏈表中的irqaction結(jié)構(gòu)所表示的中斷類型是否一致:即是否都聲明為“可共享的”,是否都是用相同的觸發(fā)方式(電平,邊沿,極性),如果一致,則將新建的irqaction結(jié)構(gòu)鏈入。
2、設(shè)置irq_desc[irq]結(jié)構(gòu)中chip成員的還沒設(shè)置的指針,讓它們只想一些默認(rèn)函數(shù)。
3、設(shè)置中斷的觸發(fā)方式。
4、啟動(dòng)中斷。
asm_do_IRQ是中斷的C語言總?cè)肟诤瘮?shù);
中斷是一種很稀缺的資源,當(dāng)不再使用一個(gè)設(shè)備時(shí),應(yīng)該釋放它占據(jù)的中斷。這通過free_irq函數(shù)來實(shí)現(xiàn);
void free_irq(unsigned int irq, void *dev_id)
總結(jié)
以上是生活随笔為你收集整理的linux 在某个core上的中断 affinity c语言函数,Linux中断处理体系结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 函数 缩小文件,linux
- 下一篇: linux服务器ftp上传文件为空,Li