ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx

上传人:b****4 文档编号:16642739 上传时间:2022-11-25 格式:DOCX 页数:11 大小:21.01KB
下载 相关 举报
ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx_第1页
第1页 / 共11页
ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx_第2页
第2页 / 共11页
ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx_第3页
第3页 / 共11页
ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx_第4页
第4页 / 共11页
ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx

《ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx(11页珍藏版)》请在冰豆网上搜索。

ARM Linux中断分析以s3c2410为例Word文档下载推荐.docx

*setsigreturntobeapointertothese.

memcpy((void*)KERN_SIGRETURN_CODE,sigreturn_codes,

sizeof(sigreturn_codes));

flush_icache_range(vectors,vectors+PAGE_SIZE);

modify_domain(DOMAIN_USER,DOMAIN_CLIENT);

init_IRQ对irq进行初始化时,又调用了init_arch_irq对于具体平台体系的中断进行初始化。

而init_arch_irq是在start_kernel里调用setup_arch函数设定的

/*arch/arm/kernel/irq.cn*/

void__initinit_IRQ(void)

intirq;

for(irq=0;

irq<

NR_IRQS;

irq++)

irq_desc[irq].status|=IRQ_NOREQUEST|IRQ_NOPROBE;

#ifdefCONFIG_SMP

bad_irq_desc.affinity=CPU_MASK_ALL;

bad_irq_desc.cpu=smp_processor_id();

#endif

init_arch_irq();

setup_arch里指定了具体平台体系的中断初始化函数,其中mdesc是一个machine_desc结构体指针

/*arch/arm/kernel/setup.c*/

void__initsetup_arch(char**cmdline_p)

init_arch_irq=mdesc->

init_irq;

machine_desc是用于描述平台体系(处理器芯片)的结构体,其定义如下:

/*include/asm/mach/arch.h*/

structmachine_desc{

*Note!

Thefirstfourelementsareused

*byassemblercodeinhead-armv.S

unsignedintnr;

/*architecturenumber*/

unsignedintphys_io;

/*startofphysicalio*/

unsignedintio_pg_offst;

/*byteoffsetforio

*pagetabeentry*/

constchar*name;

/*architecturename*/

unsignedlongboot_params;

/*taggedlist*/

unsignedintvideo_start;

/*startofvideoRAM*/

unsignedintvideo_end;

/*endofvideoRAM*/

unsignedintreserve_lp0:

1;

/*neverhaslp0*/

unsignedintreserve_lp1:

/*neverhaslp1*/

unsignedintreserve_lp2:

/*neverhaslp2*/

unsignedintsoft_reboot:

/*softreboot*/

void(*fixup)(structmachine_desc*,

structtag*,char**,

structmeminfo*);

void(*map_io)(void);

/*IOmappingfunction*/

void(*init_irq)(void);

structsys_timer*timer;

/*systemticktimer*/

void(*init_machine)(void);

};

*Setofmacrostodefinearchitecturefeatures.Thisisbuiltinto

*atablebythelinker.

#defineMACHINE_START(_type,_name)\

staticconststructmachine_desc__mach_desc_##_type\

__used\

__attribute__((__section__("

.arch.info.init"

)))={\

.nr=MACH_TYPE_##_type,\

.name=_name,

#defineMACHINE_END\

对于s3c2410处理器芯片,其machine_desc变量的定义如下:

/*arch/arm/mach-s3c2410/mach-smdk2410.c*/

MACHINE_START(SMDK2410,"

SMDK2410"

)/*@TODO:

requestanewidentifierandswitch

*toSMDK2410*/

/*Maintainer:

JonasDietsche*/

.phys_io=S3C2410_PA_UART,

.io_pg_offst=(((u32)S3C24XX_VA_UART)>

>

18)&

0xfffc,

.boot_params=S3C2410_SDRAM_PA+0x100,

.map_io=smdk2410_map_io,

.init_irq=s3c24xx_init_irq,

.init_machine=smdk2410_init,

.timer=&

s3c24xx_timer,

MACHINE_END

接下来,我们看看s3c2410处理器芯片的irq初始化函数

/*arch/arm/plat-s3c24xx/irq.c*/

/*s3c24xx_init_irq

*

*InitialiseS3C2410IRQsystem

/*s3c24xx系列芯片中断初始化函数*/

void__inits3c24xx_init_irq(void)

unsignedlongpend;

unsignedlonglast;

intirqno;

inti;

irqdbf("

s3c2410_init_irq:

clearinginterruptstatusflags\n"

);

/*first,clearallinterruptspending...*/

/*清空各个中断请求信号*/

last=0;

for(i=0;

i<

4;

i++){

pend=__raw_readl(S3C24XX_EINTPEND);

if(pend==0||pend==last)

break;

__raw_writel(pend,S3C24XX_EINTPEND);

printk("

irq:

clearingpendingextstatus%08x\n"

(int)pend);

last=pend;

pend=__raw_readl(S3C2410_INTPND);

__raw_writel(pend,S3C2410_SRCPND);

__raw_writel(pend,S3C2410_INTPND);

clearingpendingstatus%08x\n"

pend=__raw_readl(S3C2410_SUBSRCPND);

clearingsubpendingstatus%08x\n"

__raw_writel(pend,S3C2410_SUBSRCPND);

/*registerthemaininterrupts*/

/*注册主要中断*/

registerings3c2410interrupthandlers\n"

for(irqno=IRQ_EINT4t7;

irqno<

=IRQ_ADCPARENT;

irqno++){

/*setallthes3c2410internalirqs*/

switch(irqno){

/*dealwiththespecialIRQs(cascaded)*/

caseIRQ_EINT4t7:

caseIRQ_EINT8t23:

caseIRQ_UART0:

caseIRQ_UART1:

caseIRQ_UART2:

caseIRQ_ADCPARENT:

set_irq_chip(irqno,&

s3c_irq_level_chip);

/*设置中断操作函数集(电平)*/

set_irq_handler(irqno,handle_level_irq);

/*设置中断的高层流处理函数(电平)*/

caseIRQ_RESERVED6:

caseIRQ_RESERVED24:

/*noIRQhere*/

default:

//irqdbf("

registeringirq%d(s3cirq)\n"

irqno);

s3c_irq_chip);

/*默认中断为边缘触发*/

set_irq_handler(irqno,handle_edge_irq);

set_irq_flags(irqno,IRQF_VALID);

/*setupthecascadeirqhandlers*/

/*设置中断的高层流处理函数*/

set_irq_chained_handler(IRQ_EINT4t7,s3c_irq_demux_extint4t7);

set_irq_chained_handler(IRQ_EINT8t23,s3c_irq_demux_extint8);

set_irq_chained_handler(IRQ_UART0,s3c_irq_demux_uart0);

set_irq_chained_handler(IRQ_UART1,s3c_irq_demux_uart1);

set_irq_chained_handler(IRQ_UART2,s3c_irq_demux_uart2);

set_irq_chained_handler(IRQ_ADCPARENT,s3c_irq_demux_adc);

/*externalinterrupts*/

for(irqno=IRQ_EINT0;

=IRQ_EINT3;

registeringirq%d(extint)\n"

s3c_irq_eint0t4);

for(irqno=IRQ_EINT4;

=IRQ_EINT23;

registeringirq%d(extendeds3cirq)\n"

s3c_irqext_chip);

/*registertheuartinterrupts*/

s3c2410:

registeringexternalinterrupts\n"

for(irqno=IRQ_S3CUART_RX0;

=IRQ_S3CUART_ERR0;

registeringirq%d(s3cuart0irq)\n"

s3c_irq_uart0);

for(irqno=IRQ_S3CUART_RX1;

=IRQ_S3CUART_ERR1;

registeringirq%d(s3cuart1irq)\n"

s3c_irq_uart1);

for(irqno=IRQ_S3CUART_RX2;

=IRQ_S3CUART_ERR2;

registeringirq%d(s3cuart2irq)\n"

s3c_irq_uart2);

for(irqno=IRQ_TC;

=IRQ_ADC;

registeringirq%d(s3cadcirq)\n"

s3c_irq_adc);

registeredinterrupthandlers\n"

接着,我们来看一下中断处理过程

/*arch/arm/kernel/irq.c*/

*do_IRQhandlesallhardwareIRQ'

s.DecodedIRQsshouldnot

*comeviathisfunction.Instead,theyshouldprovidetheir

*own'

handler'

asmlinkagevoid__exceptionasm_do_IRQ(unsignedintirq,structpt_regs*regs)

structpt_regs*old_regs=set_irq_regs(regs);

/*保存寄存器中的内容*/

structirq_desc*desc=irq_desc+irq;

/*获取中断源*/

*Somehardwaregivesrandomlywronginterrupts.Rather

*thancrashing,dosomethingsensible.

if(irq>

=NR_IRQS)

desc=&

bad_irq_desc;

irq_enter();

desc_handle_irq(irq,desc);

/*调用已安装的中断高层流处理函数*/

/*AT91specificworkaround*/

irq_finish(irq);

irq_exit();

set_irq_regs(old_regs);

接下来,我们以IRQ_UART2(s3c2410串口2中断)为例,看看中断是如何分流到我们通过request_irq注册的中断处理函数

在s3c24xx_init_irq里IRQ_S3CUART_TX2中断的中断高层流处理函数被设置为s3c_irq_demux_uart2。

s3c_irq_demux_uart2主要工作是调用s3c_irq_demux_uart对串口中断进行分流处理,因为串口中断包含Rx(接收)中断、Tx(发送)中断和Rxerror(接收错误)中断

/*arch/arm/plat-s3c2410/irq.c*/

staticvoids3c_irq_demux_uart2(unsignedintirq,structirq_desc*desc)

irq=irq;

s3c_irq_demux_uart(IRQ_S3CUART_RX2);

s3c_irq_demux_uart通过副中断源引脚寄存器的值,判断中断源并执行相应的中断处理函数

/*start:

标示发出该中断信号的是哪个uart,即其值应为

*IRQ_S3CUART_RX0、IRQ_S3CUART_RX1或IRQ_S3CUART_RX2

staticvoids3c_irq_demux_uart(unsignedintstart)

unsignedintsubsrc,submsk;

unsignedintoffset=start-IRQ_S3CUART_RX0;

/*获取该UART中断源在副中断屏蔽寄存器中的偏移量*/

structirq_desc*desc;

/*readthecurrentpendinginterrupts,andthemask

*forwhatitisavailable*/

subsrc=__raw_readl(S3C2410_SUBSRCPND);

/*读取副中断源引脚寄存器*/

submsk=__raw_readl(S3C2410_INTSUBMSK);

/*读取副中断屏蔽寄存器*/

irqdbf2("

s3c_irq_demux_uart:

start=%d(%d),subsrc=0x%08x,0x%08x\n"

start,offset,subsrc,submsk);

subsrc&

=~submsk;

/*只留下已使能(未屏蔽)的中断源*/

subsrc>

=offset;

/*截取发送中断的uart源到subsrc低3位*/

=7;

if(subsrc!

=0)

desc=irq_desc+start;

if(subsrc&

1)/*Rx中断*/

desc_handle_irq(start,desc);

desc++;

2)/*Tx中断*/

desc_handle_irq(start+1,desc);

4)/*Rxerror中断*/

desc_handle_irq(start+2,desc);

desc_handle_irq实际上只是调用了de

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1