www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 嵌入式 > 嵌入式軟件
[導讀]作者:劉洪濤,華清遠見嵌入式學院金牌講師,ARM公司ATC授權培訓講師。作者:劉洪濤,華清遠見嵌入式學院金牌講師,ARM公司ATC授權培訓講師。三、中斷處理過程這一節(jié)將以S3

作者:劉洪濤,華清遠見嵌入式學院金牌講師,ARM公司ATC授權培訓講師。

作者:劉洪濤,華清遠見嵌入式學院金牌講師,ARM公司ATC授權培訓講師。

三、中斷處理過程

這一節(jié)將以S3C2410為例,描述linux-2.6.26內(nèi)核中,從中斷開始,中斷是如何一步一步執(zhí)行到我們注冊函數(shù)的。

3.1 中斷向量表 arch\arm\kernel\entry-armv.S

__vectors_start:

swi SYS_ERROR0

b vector_und + stubs_offset

ldr pc, .LCvswi + stubs_offset

b vector_pa^ + stubs_offset

b vector_da^ + stubs_offset

b vector_addrexcptn + stubs_offset

b vector_IRq + stubs_offset

b vector_fiq + stubs_offset

.globl __vectors_end

__vectors_end:

中斷發(fā)生后,跳轉(zhuǎn)到b vector_irq + stubs_offset的位置執(zhí)行。注意現(xiàn)在的向量表的初始位置是0xffff0000。

3.2 中斷跳轉(zhuǎn)的入口位置 arch\arm\kernel\entry-armv.S

.globl __stubs_start

__stubs_start:

/*

* Interrupt dispatcher

*/

vector_stub irq, IRQ_MODE, 4 @IRQ_MODE在include\asm\ptrace.h中定義:0x12

.long __irq_usr @ 0 (USR_26 / USR_32)

.long __irq_invalid @ 1 (FIQ_26 / FIQ_32)

.long __irq_invalid @ 2 (IRQ_26 / IRQ_32)

.long __irq_svc @ 3 (SVC_26 / SVC_32)

.long __irq_invalid @ 4

.long __irq_invalid @ 5

.long __irq_invalid @ 6

.long __irq_invalid @ 7

.long __irq_invalid @ 8

.long __irq_invalid @ 9

.long __irq_invalid @ a

.long __irq_invalid @ b

.long __irq_invalid @ c

.long __irq_invalid @ d

.long __irq_invalid @ e

.long __irq_invalid @ f

上面代碼中vector_stub宏的定義為:

.macro vector_stub, nAME, mode, correction=0

.align 5

vector_\name:

.if \correction

sub lr, lr, #\correction

.endif

@

@ Save r0, lr_<exception> (parent PC) and spsr_<exception>

@ (parent CPSR)

@

stmia sp, {r0, lr} @ save r0, lr

mrs lr, spsr

str lr, [sp, #8] @ save spsr

@

@ Prepare for SVC32 mode. IRQs remain disabled.

@

mrs r0, cpsr

eor r0, r0, #(\mode ^ SVC_MODE)

msr spsr_cxsf, r0 @為后面進入svc模式做準備

@

@ the branch table must immediately follow this code

@

and lr, lr, #0x0f @進入中斷前的mode的后4位

@#define USR_MODE 0x00000010

@#define FIQ_MODE 0x00000011

@#define IRQ_MODE 0x00000012

@#define SVC_MODE 0x00000013

@#define ABT_MODE 0x00000017

@#define UND_MODE 0x0000001b

@#define SYSTEM_MODE 0x0000001f

mov r0, sp

ldr lr, [pc, lr, lsl #2] @如果進入中斷前是usr,則取出PC+4*0的內(nèi)容,即__irq_usr @如果進入中斷前是svc,則取出PC+4*3的內(nèi)容,即__irq_svc

movs pc, lr @ 當指令的目標寄存器是PC,且指令以S結束,則它會把@ spsr的值恢復給cpsr branch to handler in SVC mode

.endm

.globl __stubs_start

__stubs_start:

/*

* Interrupt dispatcher

*/

vector_stub irq, IRQ_MODE, 4

.long __irq_usr @ 0 (USR_26 / USR_32)

.long __irq_invalid @ 1 (FIQ_26 / FIQ_32)

.long __irq_invalid @ 2 (IRQ_26 / IRQ_32)

.long __irq_svc @ 3 (SVC_26 / SVC_32)

用“irq, IRQ_MODE, 4”代替宏vector_stub中的“name, mode, correction”,找到了我們中斷處理的入口位置為vector_irq(宏里面的vector_\name)。

從上面代碼中的注釋可以看出,根據(jù)進入中斷前的工作模式不同,程序下一步將跳轉(zhuǎn)到_irq_usr 、或__irq_svc等位置。我們先選擇__irq_usr作為下一步跟蹤的目標。

3.3 __irq_usr的實現(xiàn) arch\arm\kernel\entry-armv.S

__irq_usr:

usr_entry @后面有解釋

kuser_cmpxchg_check

#ifdef CONFIG_TRACE_IRQFLAGS

bl trace_hardirqs_off

#endif

get_thread_info tsk @獲取當前進程的進程描述符中的成員變量thread_info的地址,并將該地址保存到寄存器tsk等于r9(在entry-header.S中定義)

#ifdef CONFIG_PREEMPT//如果定義了搶占,增加搶占數(shù)值

ldr r8, [tsk, #TI_PREEMPT] @ get preempt count

add r7, r8, #1 @ increment it

str r7, [tsk, #TI_PREEMPT]

#endif

irq_handler @中斷處理,我們最關心的地方,3.4節(jié)有實現(xiàn)過程。

#ifdef CONFIG_PREEMPT

ldr r0, [tsk, #TI_PREEMPT]

str r8, [tsk, #TI_PREEMPT]

teq r0, r7

strne r0, [r0, -r0]

#endif

#ifdef CONFIG_TRACE_IRQFLAGS

bl trace_hardirqs_on

#endif

mov why, #0

b ret_to_user @中斷處理完成,返回中斷產(chǎn)生的位置,3.7節(jié)有實現(xiàn)過程

上面代碼中的usr_entry是一個宏,主要實現(xiàn)了將usr模式下的寄存器、中斷返回地址保存到堆棧中。

.macro usr_entry

sub sp, sp, #S_frame_SIZE @ S_FRAME_SIZE的值在arch\arm\kernel\asm-offsets.c

@ 中定義 DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));實際上等于72

stmib sp, {r1 - r12}

ldmia r0, {r1 - r3}

add r0, sp, #S_PC @ here for interlock avoidance

mov r4, #-1 @ "" "" "" ""

str r1, [sp] @ save the "real" r0 copied

@ from the exception stack

@

@ We are now ready to fill in the remaining blanks on the stack:

@

@ r2 - lr_<exception>, already fixed up for correct return/restart

@ r3 - spsr_<exception>

@ r4 - orig_r0 (see pt_regs definition in ptrace.h)

@

@ Also, separately save sp_usr and lr_usr

@

stmia r0, {r2 - r4}

stmdb r0, {sp, lr}^

@

@ Enable the alignment trap while in kernel mode

@

alignment_trap r0

@

@ Clear FP to mark the first stack frame

@

zero_fp

.endm

上面的這段代碼主要在填充結構體pt_regs ,這里提到的struct pt_regs,在include/asm/ptrace.h中定義。此時sp指向struct pt_regs。

struct pt_regs {

long uregs[18];

};

#define ARM_cpsr uregs[16]

#define ARM_pc uregs[15]

#define ARM_lr uregs[14]

#define ARM_sp uregs[13]

#define ARM_ip uregs[12]

#define ARM_fp uregs[11]

#define ARM_r10 uregs[10]

#define ARM_r9 uregs[9]

#define ARM_r8 uregs[8]

#define ARM_r7 uregs[7]

#define ARM_r6 uregs[6]

#define ARM_r5 uregs[5]

#define ARM_r4 uregs[4]

#define ARM_r3 uregs[3]

#define ARM_r2 uregs[2]

#define ARM_r1 uregs[1]

#define ARM_r0 uregs[0]

#define ARM_ORIG_r0 uregs[17]

3.4 irq_handler的實現(xiàn)過程,arch\arm\kernel\entry-armv.S

.macro irq_handler

get_irqnr_preamble r5, lr

@在include/asm/arch-s3c2410/entry-macro.s中定義了宏get_irqnr_preamble為空操作,什么都不做

1: get_irqnr_and_base r0, r6, r5, lr @判斷中斷號,通過R0返回,3.5節(jié)有實現(xiàn)過程

movne r1, sp

@

@ routine called with r0 = irq number, r1 = struct pt_regs *

@

adrne lr, 1b

bne asm_do_IRQ @進入中斷處理。

……

.endm

3.5 get_irqnr_and_base中斷號判斷過程,include/asm/arch-s3c2410/entry-macro.s

.macro get_irqnr_and_base, irqnr, irqstat, base, tmp

mov \base, #S3C24XX_VA_IRQ

@@ try the interrupt offset register, since it is there

ldr \irqstat, [ \base, #INTPND ]

teq \irqstat, #0

beq 1002f

ldr \irqnr, [ \base, #INTOFFSET ] @通過判斷INTOFFSET寄存器得到中斷位置

mov \tmp, #1

tst \irqstat, \tmp, lsl \irqnr

bne 1001f

@@ the number specified is not a valid irq, so try

@@ and work it out for ourselves

mov \irqnr, #0 @@ start here

@@ work out which irq (if any) we got

movs \tmp, \irqstat, lsl#16

addeq \irqnr, \irqnr, #16

moveq \irqstat, \irqstat, lsr#16

tst \irqstat, #0xff

addeq \irqnr, \irqnr, #8

moveq \irqstat, \irqstat, lsr#8

tst \irqstat, #0xf

addeq \irqnr, \irqnr, #4

moveq \irqstat, \irqstat, lsr#4

tst \irqstat, #0x3

addeq \irqnr, \irqnr, #2

moveq \irqstat, \irqstat, lsr#2

tst \irqstat, #0x1

addeq \irqnr, \irqnr, #1

@@ we have the value

1001:

adds \irqnr, \irqnr, #IRQ_EINT0 @加上中斷號的基準數(shù)值,得到最終的中斷號,注意:此時沒有考慮子中斷的具體情況,(子中斷的問題后面會有講解)。IRQ_EINT0在include/asm/arch-s3c2410/irqs.h中定義.從這里可以看出,中斷號的具體值是有平臺相關的代碼決定的,和硬件中斷掛起寄存器中的中斷號是不等的。

1002:

@@ exit here, Z flag unset if IRQ

.endm

3.6 asm_do_IRQ實現(xiàn)過程,arch/arm/kernel/irq.c

asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)

{

struct pt_regs *old_regs = set_irq_regs(regs);

struct irq_desc *desc = irq_desc + irq;//根據(jù)中斷號找到對應的irq_desc

/*

* Some hardware gives randomly wrong interrupts. Rather

* than crashing, do something sensible.

*/

if (irq >= NR_IRQS)

desc = &bad_irq_desc;

irq_enter();//沒做什么特別的工作,可以跳過不看

desc_handle_irq(irq, desc);// 根據(jù)中斷號和desc進入中斷處理

/* AT91 specific workaround */

irq_finish(irq);

irq_exit();

set_irq_regs(old_regs);

}

static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc)

{

desc->handle_irq(irq, desc);//中斷處理

}

上述asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)使用了asmlinkage標識。那么這個標識的含義如何理解呢?

該符號定義在kernel/include/linux/linkage.h中,如下所示:

#include <asm/linkage.h>//各個具體處理器在此文件中定義asmlinkage

#ifdef __cplusplus

#define CPP_ASMLINKAGE extern "C"

#else

#define CPP_ASMLINKAGE

#endif

#ifndef asmlinkage//如果以前沒有定義asmlinkage

#define asmlinkage CPP_ASMLINKAGE

#endif

對于ARM處理器的<asm/linkage.h>,沒有定義asmlinkage,所以沒有意義(不要以為參數(shù)是從堆棧傳遞的,對于ARM平臺來說還是符合ATPCS過程調(diào)用標準,通過寄存器傳遞的)。

但對于X86處理器的<asm/linkage.h>中是這樣定義的:

#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

表示函數(shù)的參數(shù)傳遞是通過堆棧完成的。

3.7 描述3.3節(jié)中的ret_to_user 中斷返回過程,/arch/arm/kernel/entry-common.S

ENTRY(ret_to_user)

ret_slow_syscall:

disable_irq @ disable interrupts

ldr r1, [tsk, #TI_FLAGS]

tst r1, #_TIF_WORK_MASK

bne work_pending

no_work_pending:

/* perform. architecture specific actions before user return */

arch_ret_to_user r1, lr

@ slow_restore_user_regs

ldr r1, [sp, #S_PSR] @ get calling cpsr

ldr lr, [sp, #S_PC]! @ get pc

msr spsr_cxsf, r1 @ save in spsr_svc

ldmdb sp, {r0 - lr}^ @ get calling r0 - lr

mov r0, r0

add sp, sp, #S_FRAME_SIZE - S_PC

movs pc, lr @ return & move spsr_svc into cpsr

第三章主要跟蹤了從中斷發(fā)生到調(diào)用到對應中斷號的desc->handle_irq(irq, desc)中斷函數(shù)的過程。后面的章節(jié)還會繼續(xù)講解后面的內(nèi)容。

“本文由華清遠見http://www.embedu.org/index.htm提供”



華清遠見

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉