异常及中断处理汇总

异常及中断处理汇总
异常及中断处理汇总

一.ARM异常中断处理概述

1、中断的概念

中断是一个过程,是CPU在执行当前程序的过程中因硬件或软件的原因插入了另一段程序运行的过程。因硬件原因引起的中断过程的出现是不可预测的,即随机的,而软中断是事先安排的。

2、中断源的概念

我们把可以引起中断的信号源称之为中断源。

3、中断优先级的概念

ARM处理器中有7种类型的异常,按优先级从高到低的排列如下:复位异常(Reset)、数据异常(Data Abort)、快速中断异常(FIQ)、外部中断异常(IRQ)、预取异常(Prefetch Abort)、软件中断(SWI)和未定义指令异常(Undefined instruction)

二.ARM体系异常种类

下面是ARM的7种异常

当异常发生时,处理器会把PC设置为一个特定的存储器地址。这一地址放在被称为向量表(vector table)的特定地址范围内。向量表的入口是一些跳转指令,跳转到专门处理某个异常或中断的子程序。

当异常产生时, ARM core:

拷贝CPSR 到SPSR_

设置适当的CPSR 位:

改变处理器状态进入ARM 状态

改变处理器模式进入相应的异常模式

设置中断禁止位禁止相应中断(如果需要)

保存返回地址到LR_

设置PC 为相应的异常向量

返回时, 异常处理需要:

从SPSR_恢复CPSR

从LR_恢复PC

Note:这些操作只能在ARM 态执行.

当异常发生时,分组寄存器r14和SPSR用于保存处理器状态,操作伪指令如下。

R14_ = return link

SPSR_ = CPSR

CPSR[4∶0] = exception mode number

CPSR[5] = 0 /*进入ARM状态*/

If = = reset or FIQ then

CPSR[6] = 1 /*屏蔽快速中断FIQ*/

CPSR[7] = 1 /*屏蔽外部中断IRQ*/

PC = exception vector address

异常返回时,SPSR内容恢复到CPSR,

连接寄存器r14的内容恢复到程序计数器PC。

注:cortex-A8系统中支持通过设置CP15的c12寄存器将异常向量表的首地址设置在任意地址。例如:mcr p15, 0, r0, c12, c0, 0

1.复位异常

当处理器的复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行。复位异常中断通常用在下面两种情况下。

系统上电。

系统复位。

当复位异常时,系统执行下列伪操作:

R14_svc = UNPREDICTABLE value

SPSR_svc = UNPREDICTABLE value

CPSR[4∶0] = 0b10011 /*进入特权模式*/

CPSR[5] = 0 /*处理器进入ARM状态*/

CPSR[6] = 1 /*禁止快速中断*/

CPSR[7] = 1 /*禁止外设中断*/

If high vectors configured then

PC = 0xffff0000

Else

PC = 0x00000000

复位异常中断处理程序的主要功能:

?设置异常中断向量表。

?初始化数据栈和寄存器。

?初始化存储系统,如系统中的MMU等。

?初始化关键的I/O设备。

?使能中断。

?处理器切换到合适的模式。

?初始化C变量,跳转到应用程序执行。

2.未定义指令异常

当ARM处理器执行协处理器指令时,它必须等待一个外部协处理器应答后,才能真正执行这条指令。若协处理器没有相应,则发生未定义指令异常

当未定义异常发生时,系统执行下列的伪操作:

r14_und = address of next instruction after the undefined instruction

SPSR_und = CPSR

CPSR[4∶0] = 0b11011 /*进入未定义指令模式*/

CPSR[5] = 0 /*处理器进入ARM状态*/

/*CPSR[6]保持不变*/

CPSR[7] = 1 /*禁止外设中断*/

If high vectors configured then

PC = 0xffff0004

Else

PC = 0x00000004

3.软中断SWI

软中断异常发生时,处理器进入特权模式,执行一些特权模式下的操作系统功能。软中断异常发生时,处理器执行下列伪操作。

r14_svc = address of next instruction after the SWI instruction

SPSR_und = CPSR

CPSR[4∶0] = 0b10011 /*进入特权模式*/

CPSR[5] = 0 /*处理器进入ARM状态*/

/*CPSR[6]保持不变*/

CPSR[7] = 1 /*禁止外设中断*/

If high vectors configured then

PC = 0xffff0008

Else

PC = 0x00000008

4.预取指令异常

预取指令异常是由系统存储器报告的。当处理器试图去取一条被标记为预取无效的指令时,发生预取异常。

如果系统中不包含MMU时,指令预取异常中断处理程序只是简单地报告错误并退出。若包含MMU,引起异常的指令的物理地址被存储到内存中。

预取异常发生时,处理器执行下列伪操作:

r14_svc = address of the aborted instruction + 4

SPSR_und = CPSR

CPSR[4∶0] = 0b10111 /*进入特权模式*/

CPSR[5] = 0 /*处理器进入ARM状态*/

/*CPSR[6]保持不变*/

CPSR[7] = 1 /*禁止外设中断*/

If high vectors configured then

PC = 0xffff000C

Else

PC = 0x0000000C

5.数据访问中止异常

数据访问中止异常是由存储器发出数据中止信号,它由存储器访问指令Load/Store产生。当数据访问指令的目标地址不存在或者该地址不允许当前指令访问时,处理器产生数据访问中止异常。

当数据访问中止异常发生时,处理器执行下列伪操作。

r14_abt = address of the aborted instruction + 8

SPSR_abt = CPSR

CPSR[4∶0] = 0b10111

CPSR[5] = 0

/*CPSR[6]保持不变*/

CPSR[7] = 1 /*禁止外设中断*/

If high vectors configured then

PC = 0xffff000C10

Else

PC = 0x00000010

当数据访问中止异常发生时,寄存器的值将根据以下规则进行修改:

①返回地址寄存器r14的值只与发生数据异常的指令地址有关,与PC值无关

②如果指令中没有指定基址寄存器回写,则基址寄存器的值不变

③如果指令中指定了基址寄存器回写,则寄存器的值和具体芯片的Abort Models有关,由芯片的生产商指定

④如果指令只加载一个通用寄存器的值,则通用寄存器的值不变

⑤如果是批量加载指令,则寄存器中的值是不可预知的值

⑥如果指令加载协处理器寄存器的值,则被加载寄存器的值不可预知

6.外部中断IRQ

当处理器的外部中断请求引脚有效,而且CPSR寄存器的I控制位被清除时,处理器产生外部中断IRQ异常。系统中各外部设备通常通过该异常中断请求处理器服务。

当外部中断IRQ发生时,处理器执行下列伪操作。

r14_irq = address of next instruction to be executed + 4

SPSR_irq = CPSR

CPSR[4∶0] = 0b10010 /*进入特权模式*/

CPSR[5] = 0 /*处理器进入ARM状态*/

/*CPSR[6]保持不变*/

CPSR[7] = 1 /*禁止外设中断*/

If high vectors configured then

PC = 0xffff0018

Else

PC = 0x00000018

7.快速中断FIQ

当处理器的快速中断请求引脚有效且CPSR寄存器的F控制位被清除时,处理器产生快速中断请求FIQ异常。

当快速中断异常发生时,处理器执行下列伪操作。

r14_fiq = address of next instruction to be executed + 4

SPSR_fiq = CPSR

CPSR[4∶0] = 0b10001 /*进入FIQ模式*/

CPSR[5] = 0

CPSR[6] = 1

CPSR[7] = 1

If high vectors configured then

PC= 0xffff001c

Else

PC = 0x0000001c

三.ARM异常的优先级

四.ARM 处理器模式和异常

ARM处理器异常及其对应的模式:

每一种异常都会导致内核进入一种特定的模式。也可以通过编程改变CPSR,进入任何一种ARM处理器模式。

注:用户模式和系统模式是仅有的不可以通过异常进入的两种模式,也就是说,要进入这两张模式必须通过编程改变CPSR

五.ARM 异常响应和处理程序返回

1.中断响应的概念

中断响应大致可以分为以下几个步骤:

1、保护断点,即保存下一将要执行的指令的地址,就是把这个地址送入堆栈。

Sub lr, lr, #4

Stmfd sp!, {r0-r12, lr}

2、寻找中断入口,根据不同的中断源所产生的中断,查找不同的入口地址。

Bl c_irq_handler

3、执行中断处理程序。

可以写在main函数中

4、中断返回:执行完中断指令后,就从中断处返回到主程序,继续执行。

Ldmfd sp!, {r0-r12, pc}^

2.ARM异常响应流程

1.判断处理状态

2.向量表

跳转指令B的跳转范围为±32MB,但很多情况下不能保证所有的异常处理函数都定位在向量的32MB范围内,需要更大范围的跳转,而且由于向量表空间的限制,只能由一条指令完成。具体实现方法有下面两种。

(1)MOV PC,#imme_value 这种办法将目标地址直接赋值给PC。但这种方法受格式限制不能处理任意立即数。这个立即数由一个8位数值循环右移偶数位得到。

(2)LDR PC,[PC+offset] 把目标地址先存储在某一个合适的地址空间,然后把这个存储器单元的32位数据传送给PC来实现跳转。这种方法对目标地址值没有要求。但是存储目标地址的存储器单元必须在当前指令的±4KB空间范围内。

注意:在计算指令中引用offset数值的时候,要考虑处理器流水线中指令预取对PC值的影响。

3.从异常处理程序中返回

1.恢复被中断程序的处理器状态

PC和CPSR的恢复可以通过一条指令来实现,下面是3个例子。

?MOVS PC,LR

?SUBS PC,LR,#4

?LDMFD SP!,{PC}^

这几条指令是普通的数据处理指令,特殊之处在于它们把程序计数器寄存器PC作为目标寄存器,并且带了特殊的后缀“S”或“^”。其中“S”或“^”的作用就是使指令在执行时,同时完成从SPSR到CPSR的拷贝,达到恢复状态寄存器的目的。

2.异常的返回地址

六.S5PC100中断相关的寄存器

如果你要想通过VIC(中断控制器)控制一个外设,首先查下面的中断源表,找到其中断号,然后去看中断控制器中的寄存器对应哪位来控制这个中断。

如果你需要在片外连接一个外设,并且这个外设也需要申请中断怎么办呢?对了,用外部中断管脚。也就是上图对应的从0 号到16号中断源,其中需要注意到是有16 根中断管脚共用一根中断请求线,怎么共用呢?

我们看下图外部中断管理模块,从SOC 共有32 个管脚引出来,这些管脚是复用的,可以配置成通用输入/输出IO,也可以配置成唤醒中断的模式(及内部会连接到中断控制器电路)。GPIO 模块内部有三个寄存器对这32 根管线的中断功能进行管理。

(1).功能寄存器如图,对管脚的电平激发方式进行管理,可以配置成高电平激发中断,低电平、上升沿、下降沿、双边沿等。

相关寄存器如下:

WKUP_INT0_7_CON

WKUP_INT8_15_CON

WKUP_INT16_24_CON

WKUP_INT25_31_CON

图为中断控制器

(2)Mask 寄存器外部管脚EINT16 到EINT31 共16 根线共用一根线EINT(16-31)连接到中断控制器,也就是共用一个中断号(中断号16),可能需要在某一个时刻只能有一根管脚线的信号通过模块顺利进入中断控制器,这个时候就需要将其余的管脚信号屏蔽起来,如何屏蔽呢?就是设置mask 里的对应位。

相关寄存器如下:

WKUP_INT0_7_MASK

WKUP_INT8_15_MASK

WKUP_INT16_24_MASK

WKUP_INT25_31_MASK

(3)Pend 寄存器记录中断信号标志。如果信号通过了前面的关口,送入了VIC,就是将对应线上的pend 寄存器的对应位值1,如果在某一时刻,中断控制器来不起处理当前信号线上的中断请求,那么pend 位会一直保持着这个请求,哪怕硬件中断线上的中断激发状态已经过去。同样,需要注意是,如果当前线上的中断已经处理,这个pend 位也不会自动清零,需要人为的清零。

相关寄存器如下:

WKUP_INT0_7_PEND

WKUP_INT8_15_PEND

WKUP_INT16_24_PEND

WKUP_INT25_31_PEND

中断信号请求的流程是:

1 使外设有中断激发的功能(如果为外部中断,设置电平激发方式)。

2 设置子模块下的mask 寄存器,让需要监控的中断信号能通过,而不需要监控的则

被屏蔽。

3 开启中断控制器中对应每个中断源的使能位。

1.S5PC100的中断相关的寄存器

中断状态寄存器VIC0IRQSTATUS

中断源模式选择寄存器VIC0INTSELECT

中断源使能寄存器VIC0INTENABLE

中断源向量地址寄存器VIC0VECTADDR0 ... VIC0VECTADDR31

中断源入口地址寄存器VIC0ADDRESS

一.ARM的SWI异常中断处理程序设计

汇编:

_start:

b reset_handler

nop

b swi_handler

nop

nop

nop

nop

swi_handler:

stmfd sp!, {r0-r12, lr}

ldr r0, [lr, -4]

bic r0, r0, #0xff000000 @获取软中断的中断号

bl c_swi_handler

ldmfd sp!, {r0-r12, pc}^ @SPSR ->CPSR 并出栈

c_swi_handler:

stmfd sp!, {r0-r12, lr}

cmp r0, #5

bleq sys_open

cmp r0, #6

bleq sys_close

ldmfd sp!, {r0-r12, pc}

二.ARM的IRQ异常中断处理程序设计

汇编:

_start:

b reset_handler @reset 异常

nop

nop

nop

nop

nop

b irq_handler @中断异常

nop

irq_handler:

sub lr, lr, #4 @调整返回地址

stmfd sp!, {r0-r12, lr} @压栈保存寄存器

bl c_irq_handler @跳转到C 中中断处理函数执行执行完返回ldmfd sp!, {r0-r12, pc}^ @出栈并回复cpsr

reset_handler:

/****将异常向量表搬到 20008000****/

ldr r0, =0x20008000

mcr p15, 0, r0, c12, c0, 0

/****初始化svc栈顶指针****/

ldr r0, =0x30000000

mov sp, r0

sub r0, r0, #0x1000

/****到irq模式下初始化irq模式栈顶指针,开irq fiq****/ msr cpsr_c, #0x12

mov sp, r0

sub r0, r0, #0x100

/****到user模式并且初始化user的栈顶指针****/

msr cpsr_c, #0x10

mov sp, r0

/****清bss段****/

clear_bss:

mov r2, #0

ldr r0, =__bss_start

ldr r1, =__bss_end

bss_loop:

cmp r0, r1

strne r2, [r0], #4

bne bss_loop

/****跳转到****/

b main

.end

(一)key中断

/*****key_IRQ*****/

void c_irq_handler(void)

{

void (*pfunc)(void);

pfunc =(void *)VIC0ADDRESS;

pfunc();

printf("c_irq_handler!!!!!!!!! \r\n ");

VIC0ADDRESS = 0;

VIC1ADDRESS = 0;

VIC2ADDRESS = 0;

}

void key1_irq_init(void)

{

//设置IO 为激发中断功能

GPH0.GPH0CON = GPH0.GPH0CON & ~(0xf<<4) | (0x2<<4);

//设置外部中断管脚为下降沿激发方式

WU_INT0_7_CON = WU_INT0_7_CON & ~(0x7<<4) | (0x2<<4);

//enable mask 位

WU_INT0_7_MASK = WU_INT0_7_MASK & ~(1<<1);

//注册中断处理函数因为按键1 链接的为EINT1 所以将处理函数放在对应第0组第

一个地址寄存器里

VIC0VECTADDR.VIC0VECTADDR1 = (unsigned int)key1_down;

//enable 中断控制器中对应中断源的使能位

VIC0INTERRUPT.VIC0INTENABLE= VIC0INTERRUPT.VIC0INTENABLE| (1<<1); }

void key2_irq_init(void)

{

GPH0.GPH0CON = GPH0.GPH0CON & ~(0xf<<8) | (0x2<<8);

WU_INT0_7_CON = WU_INT0_7_CON & ~(0x7<<8) | (0x2<<8);

WU_INT0_7_MASK = WU_INT0_7_MASK & ~(1<<2);

VIC0VECTADDR.VIC0VECTADDR2 = (unsigned int)key2_down;

VIC0INTERRUPT.VIC0INTENABLE= VIC0INTERRUPT.VIC0INTENABLE| (1<<2); }

void key1_down(void)

{

printf("*****key1_down*******\r\n");

WU_INT0_7_PEND = (1<<1);

}

void key2_down(void)

{

printf("*****key2_down*******\r\n");

WU_INT0_7_PEND = (1<<2);

}

void main(void)

{

uart0_init();

key1_irq_init();

key2_irq_init();

uart0_sendstring("hello farsight !!\n\r ");

int a = 100;

printf("a = %d\n\r", a);

while(1);

}

(二)UART中断

/*****uart0_IRQ*****/

void c_irq_handler(void)

{

void (*pfunc)(void);

pfunc = (void *)VIC0ADDRESS;

pfunc();

uart0_sendstring("c_irq_handler!!!!!!!!! \r\n ");

VIC0ADDRESS = 0;

VIC1ADDRESS = 0;

VIC2ADDRESS = 0;

}

void uart0_recvchar_irq(void)

{

uart0_sendchar(UART0.URXH0);

//清标志位写1清0

UART0.UINTP0 = UART0.UINTP0;

UART0.UINTSP0 = UART0.UINTSP0;

}

void main(void)

{

uart0_init();

uart0_sendstring("hello farsight !!\n\r ");

//注册中断处理函数

UART0.UINTM0 = ~0x1;

VIC1VECTADDR.VIC1VECTADDR10 = (unsigned int)uart0_recvchar_irq;

VIC1INTERRUPT.VIC1INTENABLE= VIC1INTERRUPT.VIC1INTENABLE| (1<<10);

while(1);

}

(三)ADC中断

/*****ADC_IRQ*****/

void c_irq_handler(void)

{

void (*pfunc)(void);

pfunc = (void *)VIC0ADDRESS;

pfunc();

uart0_sendstring("c_irq_handler!!!!!!!!! \r\n ");

VIC0ADDRESS = 0;

VIC1ADDRESS = 0;

VIC2ADDRESS = 0;

}

void adc_init(void)

// 精度12位| 开启分频| 分频得1M | 读转换

//ADC.ADCCON = (1<<16) | (1<<14) | (65<<6) | (1<<1);

ADC.ADCCON = (1<<16) | (1<<14) | (65<<6) | (1); //手动开启转换ADC.ADCMUX = 0; //选择第0通道

}

void adc_read_handler(void)

{

adc_val = ADC.ADCDAT0 & 0xfff;

printf("adc_val = %d \r\n", adc_val);

ADC.ADCCLRINT = 0; //填任意值,清ADC中断标志

}

void main(void)

{

uart0_init();

uart0_sendstring("hello farsight !\n\r ");

//注册中断处理函数人口

VIC2VECTADDR.VIC2VECTADDR23 = (unsigned int)adc_read_handler;

VIC2INTERRUPT.VIC2INTENABLE = VIC2INTERRUPT.VIC2INTENABLE | (1<<23);

adc_init();

int m;

while(1)

{

for(m=0; m<0x1000000;m++);

ADC.ADCCON = ADC.ADCCON | (1); //手动开启转换

}

}

(四)ALARM中断

/*****RTC_ALARM*****/

void c_irq_handler(void)

{

void (*pfunc)(void);

pfunc = (void *)VIC0ADDRESS;

pfunc();

uart0_sendstring("c_irq_handler!!!!!!!!! \r\n ");

VIC0ADDRESS = 0;

VIC1ADDRESS = 0;

VIC2ADDRESS = 0;

}

void rtc_init(void)

RTCCON = 1; //开启修改权限

RTCBCD.BCDYEAR = 0x13;

RTCBCD.BCDMON = 0x10;

RTCBCD.BCDDATE = 0x21;

RTCBCD.BCDHOUR = 0x16;

RTCBCD.BCDMIN = 0x06;

RTCBCD.BCDSEC = 0x55;

RTCCON = 0;

}

void rtc_alarm_init(void)

{

RTALM.RTCALM = 1<<6 | 1<<2 | 1<<1;

RTALM.ALMHOUR = 0x16;

RTALM.ALMMIN = 0x07;

}

void rtc_alarm_handler(void)

{

uart0_sendstring("alarm signal\n\r");

alarm_beep_on();

RTCINTP = (1<<1);//清除中断标志

}

void main(void)

{

uart0_init();

uart0_sendstring("hello farsight !!\r\n ");

rtc_init();

rtc_alarm_init();

VIC0VECTADDR.VIC0VECTADDR28 = (unsigned int)rtc_alarm_handler;

VIC0INTERRUPT.VIC0INTENABLE = VIC0INTERRUPT.VIC0INTENABLE | (1<<28);

while(1);

}

(五)TICK中断

/*****RTC_ALARM_TICK*****/

void c_irq_handler(void)

{

void (*pfunc)(void);

pfunc = (void *)VIC0ADDRESS;

pfunc();

VIC0ADDRESS = 0;

VIC1ADDRESS = 0;

VIC2ADDRESS = 0;

}

void rtc_init(void)

{

RTCCON = 1; //开启修改权限

RTCBCD.BCDYEAR = 0x13;

RTCBCD.BCDMON = 0x10;

RTCBCD.BCDDATE = 0x21;

RTCBCD.BCDHOUR = 0x16;

RTCBCD.BCDMIN = 0x06;

RTCBCD.BCDSEC = 0x55;

RTCCON = 0;

}

void rtc_alarm_init(void)

{

RTALM.RTCALM = 1<<6 | 1<<2 | 1<<1;

RTALM.ALMHOUR = 0x16;

RTALM.ALMMIN = 0x07;

}

void rtc_alarm_handler(void)

{

uart0_sendstring("alarm signal\n\r");

alarm_beep_on();

rtc_tick_init();

VIC0VECTADDR.VIC0VECTADDR29 = (unsigned int)rtc_tick_handler;

VIC0INTERRUPT.VIC0INTENABLE = VIC0INTERRUPT.VIC0INTENABLE | (1<<29);

RTCINTP = (1<<1);//清除alarm中断标志

}

void rtc_tick_init(void)

{

RTCCON = RTCCON | 1<<8 | 0b0000<<4 | 1;

TICCNT = 32768;

}

void rtc_tick_handler(void)

{

uart0_sendchar((RTCBCD.BCDHOUR >> 4) + '0');

uart0_sendchar((RTCBCD.BCDHOUR & 0xf) + '0');

uart0_sendstring(":");

uart0_sendchar((RTCBCD.BCDMIN >> 4) + '0');

uart0_sendchar((RTCBCD.BCDMIN & 0xf) + '0');

uart0_sendstring(":");

uart0_sendchar((RTCBCD.BCDSEC >> 4) + '0');

uart0_sendchar((RTCBCD.BCDSEC & 0xf) + '0');

uart0_sendstring("\r\n");

RTCINTP = 1;//清除tick中断标志

}

void main(void)

{

uart0_init();

uart0_sendstring("hello farsight !!\r\n ");

rtc_init();

rtc_alarm_init();

VIC0VECTADDR.VIC0VECTADDR28 = (unsigned int)rtc_alarm_handler;

VIC0INTERRUPT.VIC0INTENABLE = VIC0INTERRUPT.VIC0INTENABLE | (1<<28);

while(1);

}

中断异常处理流程

计算机体系结构中,异常或者中断是处理系统中突发事件的一种机制,几乎所有的处理器都提供这种机制。异常主要是从处理器被动接受的角度出发的一种描述,指意外操作引起的异常。而中断则带有向处理器主动申请的意味。但这两种情况具有一定的共性,都是请求处理器打断正常的程序执行流程,进入特定程序的一种机制。若无特别说明,对“异常”和“中断”都不作严格的区分。本文结合经过实际验证的代码对ARM9中断处理流程进行分析,并设计出基于S3C2410芯片的外部中断处理程序。 1.异常中断响应和返回 系统运行时,异常可能会随时发生。当一个异常出现以后,ARM微处理器会执行以下几步操作: 1) 将下一条指令的地址存入相应连接寄存器LR,以便程序在处理异常返回时能从正确的位置重新开始执行。 2)将CPSR复制到相应的SPSR中。 3)根据异常类型,强制设置CPSR的运行模式位。 4) 强制PC从相关的异常向量地址取下一条指令执行,从而跳转到相应的异常处理程序处。 这些工作是由ARM内核完成的,不需要用户程序参与。异常处理完毕之后,ARM微处理器会执行以下几步操作从异常返回: 1)将连接寄存器LR的值减去相应的偏移量后送到PC中。 2)将SPSR复制回CPSR中。 3) 若在进入异常处理时设置了中断禁止位,要在此清除。 这些工作必须由用户在中断处理函数中实现。为保证在ARM处理器发生异常时不至于处于未知状态,在应用程序的设计中,首先要进行异常处理。采用的方式是在异常向量表中的特定位置放置一条跳转指令,跳转到异常处理程序。当ARM处理器发生异常时,程序计数器PC会被强制设置为对应的异常向量,从而跳转到异常处理程序。当异常处理完成以后,返回到主程序继续执行。可以认为应用程序总是从复位异常处理程序开始执行的,因此复位异常处理程序不需要返回。 2.异常处理程序设计 2.1 异常响应流程

程序设计异常处理机制

异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地方出现,那么你每个地方都要做相同处理,感觉相当的麻烦!Java 语言在设计的当初就考虑到这些问题,提出异常处理的框架的方案,所有的异常都可以用一个类型来表示,不同类型的异常对应不同的子类异常(这里的异常包括错误概念),定义异常处理的规范,在1.4版本以后增加了异常链机制,从而便于跟踪异常!这是Java语言设计者的高明之处,也是Java语言中的一个难点,下面是我对Java异常知识的一个总结,也算是资源回收一下。 一、Java异常的基础知识 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的。比如说,你的代码少了一个分号,那么运行出来结果是提示是错误https://www.360docs.net/doc/b710953680.html,ng.Error;如果你用System.out.println(11/0),那么你是因为你用0做了除数,会抛出https://www.360docs.net/doc/b710953680.html,ng.ArithmeticException的异常。 有些异常需要做处理,有些则不需要捕获处理,后面会详细讲到。 天有不测风云,人有旦夕祸福,Java的程序代码也如此。在编程过程中,首先应当尽可能去避免错误和异常发生,对于不可避免、不可预测的情况则在考虑异常发生时如何处理。Java中的异常用对象来表示。Java对异常的处理是按异常分类处理的,不同异常有不同的分类,每种异常都对应一个类型(class),每个异常都对应一个异常(类的)对象。 异常类从哪里来?有两个来源,一是Java语言本身定义的一些基本异常类型,二是用户通过继承Exception类或者其子类自己定义的异常。Exception 类及其子类是Throwable的一种形式,它指出了合理的应用程序想要捕获的条件。 异常的对象从哪里来呢?有两个来源,一是Java运行时环境自动抛出系统生成的异常,而不管你是否愿意捕获和处理,它总要被抛出!比如除数为0的异常。二是程序员自己抛出的异常,这个异常可以是程序员自己定义的,也可以是Java语言中定义的,用throw 关键字抛出异常,这种异常常用来向调用者汇报异常的一些信息。 异常是针对方法来说的,抛出、声明抛出、捕获和处理异常都是在方法中进行的。 Java异常处理通过5个关键字try、catch、throw、throws、finally进行管理。基本过程是用try语句块包住要监视的语句,如果在try语句块内出现异常,则异常会被抛出,你的代码在catch语句块中可以捕获到这个异常并做处理;还有以部分系统生成的异常在Java运行时自动抛出。你也可以通过throws关键字在方法上声明该方法要抛出异常,然后在方法内部通过throw抛出异常对象。finally语句块会在方法执行return之前执行,一般结构如下: try{ 程序代码 }catch(异常类型1 异常的变量名1){ 程序代码 }catch(异常类型2 异常的变量名2){ 程序代码 }finally{ 程序代码 } catch语句可以有多个,用来匹配多个异常,匹配上多个中一个后,执行catch语句块时候仅仅执行匹配上的异常。catch的类型是Java语言中定义的或者程序员自己定义的,表示代

异常处理机制

异常的基本概念 异常是导致程序终止运行的一种指令流,如果不对异常进行正确的处理,则可能导致程序的中断执行,造成不必要的损失。 在没有异常处理的语言中如果要回避异常,就必须使用大量的判断语句,配合所想到的错误状况来捕捉程序中所有可能发生的错误。 Java异常处理机制具有易于使用、可自行定义异常类、处理抛出的异常同时又不会降低程序运行的速度等优点。因而在java程序设计时应充分地利用java的异常处理机制,以增进程序的稳定性及效率。 当程序中加入了异常处理代码,所以当有异常发生后,整个程序并不会因为异常的产生而中断执行。而是在catch中处理完毕之后,程序正常的结束。 在整个java异常的结构中,实际上有两个最常用的类,分别为Exception和Error 这两个类全都是Throwable的子类。 Exception:一般表示的是程序中出现的问题,可以直接使用try……catch处理。 Error:一般值JVM错误,程序中无法处理。 Java异常处理机制。 在整个java的异常处理中,实际上也是按照面向对象的方式进行处理,处理的步骤如下: 1)一旦产生异常,则首先会产生一个异常类的实例化对象。 2)在try语句中对此异常对象进行捕捉。 3)产生的异常对象与catch语句中的各个异常类型进行匹配,如果匹配成功则执行catch语句中的代码。 异常处理 在定义一个方法时可以使用throws关键字声明,表示此方法不处理异常,而交给方法的调用处进行处理,在方法调用处不管是否有问题,都要使用try……catch块进行异常的捕获与处理。 如果在主方法中使用throws关键字,则程序出现问题后肯定交由jvm处理,将导致程序中断。 与throws关键字不同的是,throw关键字人为的抛出一个异常,抛出时直接抛出异常类的实例化对象即可。 Exception在程序中必须使用try……catch进行处理。RuntimeException可以不使用try……catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。(建议RuntimeException的子类也使用try……catch进行处理,否则产生的异常交给jvm处理会导致程序中断。) 继承关系: Exception》RuntimeException》lllegalArgumentException》NumberFormatException; 异常类必须继承于Exception 建议:继承Exception一般要添加全部父类型一样的构造器! class NameOrPwdException extends Exception { public NameOrPwdException() {

uCOS中断处理过程详解

再看3处代码: 在uCOS_II.H中有如下定义: OS_EXT OS_TCB *OSTCBPrioTbl[OS_LOWEST_PRIO + 1];//定义指向任务控制块的指针数//组,且每个优先级在同一时刻只对应一个任务 OS_EXT INT8U OSPrioCur;//用于保存目前任务的优先级 OS_EXT INT32U OSCtxSwCtr;//32位无符号全局整型变量,作为任务切换计数器 OS_EXT OS_TCB *OSTCBHighRdy;//指向最高优先级任务任务控制块的指 针 if (OSPrioHighRdy != OSPrioCur) //就绪态任务中的最高优先级已不是目前任务的优先级,则进行中断级的任务//切换 { OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy]; //将最高优先级任务控制块指针指向当前优先级最高的任务的任务控制块 OSCtxSwCtr++;//任务切换计数器加1 OSIntCtxSw();//调用中断级任务切换函数 } 此段代码体现出了可剥夺型实时操作系统内核的特点.

OSIntCtxSw()在80x86上的移植代码,此代码在OS_CPU_A.ASM中,代码如下: _OSIntCtxSw PROC FAR ; CALL FAR PTR _OSTaskSwHook ; 调用OSTaskSwHook()函数,此函数在 ;OS_CPU_C.C中只是个空函数,留给用户 ;在代码移植时自定义 ; MOV AX, SEG _OSTCBCur ;由于发生了段转移,恢复刚才(当前任务)数 MOV DS, AX;据段 ; MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ;AH=_OSTCBHighRdy+3 ;AL=_OSTCBHighRdy+2 MOV DX, WORD PTR DS:_OSTCBHighRdy ;DH=_OSTCBHighRdy+1 ;DL=_OSTCBHighRdy MOV WORD PTR DS:_OSTCBCur+2, AX ;_OSTCBCur+3=AH ;_OSTCBCur+2=AL MOV WORD PTR DS:_OSTCBCur, DX ;_OSTCBCur+1=DH ;_OSTCBCur=DL

异常情况处理制度及流程

山西煤炭运销集团 蒲县昊锦塬煤业有限公司异常情况处理制度为认真贯彻落实国家、省、市关于集中开展安全生产大检查的工作安排要求,加强我矿信息监控系统管理水平,做好矿井生产过程中井下环境参数的有效监控,保障矿井安全生产,加强煤矿安全生产管理水平及抗灾能力,特制定本矿异常情况处理制度如下: 一、值班人员按《中心岗位责任制》规定,浏览查询煤矿安全信息,发现异常情况及时处理,并认真填写《异常情况报告处理表》,传真至县监控中心。 二、监控室值班人员发现系统发出异常报警后,值班人员必须立即通知监控室主任、分管领导,同时立即通知矿井调度部门,由监控室主任或分管领导组织相关人员对本次异常报警进行原因分析,并按规定程序及时报上一级网络中心。处理结果应记录备案。调度值班人员接到报警、断电信息后,应立即向矿值班领导汇报,矿值班领导按规定指挥现场人员停止工作,断电时撤出人员。处理过程应记录备案。当系统显示井下某一区域瓦斯超限并有可能波及其他区域时,矿井有关人员应按瓦斯事故应急预案手动遥控切断瓦斯可能波及区域的电源。值班人员接到网络中心发出的报警处理指令后,要立即处理落实,并将处理结果向网络中心反馈。 当工作面瓦斯浓度达到报警浓度时,值班人员应立即通知矿值班领导及监控室主任,并填写异常情况处理报告表传真上报至

县监控中心

;由分管领导或监控室主任安排相关人员进行原因分析,按照瓦斯超限分析原则:①按人工检测值与甲烷传感器对比分析; ②按报警地点的历史曲线对比分析;③按报警地点上风侧检测值对比分析。根据分析结果立即将处理措施下达至矿调度中心按处理措施严格执行。报警期间要采取安全措施,报警消除后将报警的起止时间、分析报告、采取措施和处理结果上报县监控室并存档备案。 三、当煤矿通讯中断、无数据显示时,值班人员要通过传真(或电话)向县监控中心报告,并查明原因,恢复通讯。情况紧急的,由值班人员立即向矿领导汇报,对因故造成通讯中断未及时上报的,要通过电话联系移动公司或长途线务局进行抢修。

如何使用异常处理机制

如何使用异常处理机制 《PHP核心技术与最佳实践》第1章面向对象思想的核心概念,本章将就面向对象一些概念展开讨论,其中重点讨论PHP特色的面向对象的风格和语法,并通过相互借鉴和对比,使读者认识PHP自身的特点,尤其是和其他语言中不同的地方。本节为大家介绍如何使用异常处理机制。 1.6.1 如何使用异常处理机制(1) 异常的思想最早可以追溯到20世纪60年代,其在C++、Java中发扬光大,PHP则部分借鉴了这两种语言的异常处理机制。 PHP里的异常,是程序运行中不符合预期的情况及与正常流程不同的状况。一种不正常的情况,就是按照正常逻辑不该出错,但仍然出错的情况,这属于逻辑和业务流程的一种中断,而不是语法错误。PHP里的错误则属于自身问题,是一种非法语法或者环境问题导致的、让编译器无法通过检查甚至无法运行的情况。 在各种语言里,异常(exception)和错误(error)的概念是不一样的。在PHP里,遇到任何自身错误都会触发一个错误,而不是抛出异常(对于一些情况,会同时抛出异常和错误)。PHP一旦遇到非正常代码,通常都会触发错误,而不是抛出异常。在这个意义上,如果想使用异常处理不可预料的问题,是办不到的。比如,想在文件不存在且数据库连接打不开时触发异常,是不可行的。这在PHP里把它作为错误抛出,而不会作为异常自动捕获。 以经典的除零问题为例,如代码清单1-16所示。 代码清单1-16 exception.php 1.// exception.php 2.getMessage(); 9.$a=-1; 10.}

护理不良事件管理详解

非惩罚性护理不良事件报告制度及激励机制 一、不良事件的定义 是指在护理过程中发生的、不在计划内的跌倒、坠床、压疮、用药错误、走失、误吸或窒息、烫伤及其他与患者安全相关的非正常的护理意外事件。 二、不良事件报告的意义 通过报告不良事件,及时发现潜在的不安全因素,可有效避免护理差错与纠纷的发生,保障病人安全,不良事件的全面报告,有利于发现医院安全系统存在的不足,提高医院系统安全水平,促进医院及时发现安全事故隐患,不断提高对错误的识别能力,不良事件报告后的信息共存,可以使相关人员从他人的过失中吸取经验教训,以免重蹈覆辙。 三、护理不良事件的范围 1、患者在住院期间发生压疮、坠床、跌倒、导管滑脱、用药失误、走失、误吸或窒息、烫伤及其他与患者安全相关的护理意外。 2、因护理操作失误导致患者出现严重并发症、住院时间延长或住院费用增加等。 3、严重药物不良反应或输血不良反应。 4、严重院内感染。 四、不良事件报告原则 非惩罚性、主动性报告的原则:护理部鼓励护理人员主动、自愿报告不良事件,包括本人的或本科室的,也可报告其他人或其他科室的,可以实名报告,也可匿名报告,对主动报告的科室和个人的有关信息,护理部将严格保密。 五、上报内容 包括患者一般资料,不良事件发生的时间地点、不良事件项目分类、发生的主要原因、采取的措施、患者损害的严重程度及后果和改进措施。上报形式以个人或科室为上报单位。 六、上报形式 1、口头报告:发生严重不良事件时,护理人员应立即向护士长、科主任、总值班、护理部口头报告事件情况。 2、书面报告:护理人员书面填写《护理不良事件报告单》。 3、网络报告:护理人员登录内网,填写《护理不良事件报告单》电子表格,

ARM中异常中断处理概述

异常中断处理概述 1.ARM中异常中断处理概述 1)在正常程序执行过程中,每执行一条ARM指令,程序计数器寄存器PC的值加4个字 节;每执行一条Thumb指令,程序计数器寄存器PC的值加两个字节.整个过程是顺序执行. 2)通过跳转指令,程序可以跳转到特定的地址标号处执行,或者跳转到特定的子程序处 执行; B指令用于执行跳转操作; BL指令在执行跳转操作的同时,保存子程序的返回地址; BX指令在执行跳转操作的同时,根据目标地址的最低位可以将程序状态切换到Thumb状态; BLX指令执行3个操作:跳转到目标地址处执行,保存子程序的返回地址(R15保存在R14中),根据目标地址的最低位可以将程序状态切换到Thumb状态. 3)当异常中断发生时,系统执行完当前指令后,将跳转到相应的异常中断处理程序处执 行.在当异常中断处理程序执行完成后,程序返回到发生中断的指令的下一条指令处执行. 4)在进入异常中断处理程序时,要保存被中断的程序的执行现场,在从异常中断处理程 序退出时,要恢复被中断的程序的执行现场.本章讨论ARM体系中的异常中断机制. 2.ARM体系中异常中断种类. ARM体系中的异常中断如下表所示:

3. 中断向量表中指定了各异常中断及其处理程序的对应关系.它通常存放在存储地址的低端.在ARM体系中,异常中断向量表的大小为32字节.其中,每个异常中断占据4个字节大小,保留了4个字节空间. 每个异常中断对应的中断向量表的4 .通过这两种指令,程序将跳转到相应的异常中断处理程序处执行. 当几个异常中断同时发生时,就必须按照一定的次序来处理这些异常中断.在ARM 中通过给各异常中断富裕一定的优先级来实现这种处理次序.当然有些异常中断是不坑能同时发生的,如指令预取中止异常中断和软件中断(SWI)异常中断是有同一条指令的执行触发的,他们是不可能同时发生的.处理器执行某个特定的异常中断的过程中,称为处理器处于特定的中断模式.各异常中断的中断向量地址以及中断的处理优先级如表2所示. 4.异常中断使用的寄存器 各异常中断对应着一定的处理器模式.应用程序通常运行在用户模式下.ARM中的处理器模式如表3所示. 各种不同的处理器模式可能有对应于该处理器模式的物理寄存器组,如表4所示,其中,R13_svc表示特权模式下的R13寄存器,R13_abt表示中止模式下的R13寄存器,其余的各寄存器名称含义类推. 表4 各处理器模式的物理寄存器组

设备故障处置过程中的九大错误与解决办法

设备故障 处置过程中的九大错误与解决办法设备故障处理是设备管理和维修人员经常会面对的问题之 O 维修人员在日常的设备故障检查处理过程中,外部受时间、环境、人员等方面的压力,内部受维修人员本身的技术水平、经验、设备熟悉程度、人员身体精神状态等的影响,这些因素,会对故障快速、准确的处置造成一定的影响。 维修人员对设备故障的排查和处置不当,会导致故障处置时间、人力、成本等的增加,或为下次故障留下隐患。 问题一.不能正确判断分析故障,盲目大拆大卸 1、现象: —些维修人员由于对机械结构、原理不清楚,未认真分析清楚故障原因,不能准确判断故障部位,凭着〃大概、差不多〃的思想盲目对机械大拆大卸,结果不但原故障未排除,而且由于维修技能和工艺较差,又出现新的问题。 2、解决办法: 当机械出现故障后,要通过检测设备进行检测,如无检测设备,可通过"问、看、查、试〃等传统的故障判断方法和手段,结合工程机

械的结构和工作原理,确定最可能发生故障的部位。在判定工程机械故障时,一般常用〃排除法〃和〃比较法",按照从简单到复杂、先外表后内部、先总成再部件的顺序进行,切忌"不问青红皂白,盲目大拆大卸"。 问题二■盲目更换零部件,一味"换件修理" 1、现象: 有些维修人员一贯采用换件试验的方法,不论大件小件,只要认为可能是导致故障的零部件,一个一个更换试验,结果非但故障没排除,且把不该更换的零部件随意更换了,增加了消费者的开支。还有些故障零部件完全可以通过修理恢复其技术性能,不需要复杂修理工艺即可修复,但维修人员却要求用户更换新件,一味采取〃换件修理"的方法,造成严重的浪费。 2、解决办法: 在维修时,应根据故障现象认真分析判断故障原因及部位,对能修复的零部件要采取修理的方法恢复技术性能,杜绝盲目更换零部件的做法。 问题三、不检查新件质量,装配后出现故障 1、现象: 在更换配件前,有些维修人员对新配件不做技术检查,皇来后直接安装到设备上,这种做法是不科学的。目前市场上出售的零配件质量良

uCOSii中断处理过程详解(一)

一. UCOSII的中断过程简介 系统接收到中断请求后,如果CPU处于开中断状态,系统就会中止正在运行的当前任务,而按中断向量的指向去运行中断服务子程序,当中断服务子程序运行完成后,系统会根据具体情况返回到被中止的任务继续运行,或转向另一个中断优先级别更高的就绪任务。 由于UCOS II是可剥夺型的内核,所以中断服务程序结束后,系统会根据实际情况进行一次任务调度,如果有优先级更高的任务,就去执行优先级更高的任务,而不一定要返回被中断了的任务。 二.UCOSII的中断过程的示意图 三.具体中断过程 1.中断到来,如果被CPU识别,CPU将查中断向量表,根据中断向量表,获得中断服务子程序的入口地址。 2.将CPU寄存器的内容压入当前任务的任务堆栈中(依处理器的而定,也可能压入被压入被中断了的任务堆栈中。

3.通知操作系统将进入中断服务子程序。即:调用OSIntEnter()或OSIntNesting直接 加1。 4.If(OSIntNesting==1){OSTCBCur->OSTCBStrPtr=SP;} //如果是第一层中断,则将堆栈指针保存到被中断任务的任务控制块中 5.清中断源,否则在开中断后,这类中断将反复的打入,导致系统崩贵 6.执行用户ISR 7.中断服务完成后,调用OSIntExit().如果没有高优先级的任务被中断服务子程序激活而进入就绪态,那么就执行被中断了的任务,且只占用很短的时间. 8.恢复所有CPU寄存器的值. 9.执行中断返回指令.

四.相关代码 与编译器相关的数据类型: typedef unsigned char BOOLEAN; typedef unsigned char INT8U; typedef unsigned int OS_STK; //堆栈入口宽度为16 位(一) void OSIntEnter (void)的理解 uCOS_II.H中定义:

异常情况处理流程说明

异常情况处理流程说明 一、“异常情况”包括 1、质量不合格问题。主要包括制程质量问题、售后质量问题、技术设计或图纸下发后出现问题、调试中 质量问题、外购设备物资质量问题等; 2、交货期延误问题、采购交期延误问题及其他有关生产进度的问题等; 3、生产物料损耗异常问题; 4、生产设备损坏问题; 5、员工违纪问题; 6、其它异常问题。 二、员工出现异常问题,应及时按规定报于部门领导; 三、企管部(质检部)在日常工作中发现员工出现异常问题时,应作出《整改通知》或《整改报告》,由 责任部门签收; 四、员工所属部门部长应及时落实责任人并对问题组织处理。责任人是指直接或间接造成各类问题发生的 员工包括各级管理人员。 五、责任部门部长应督促责任人填写《异常情况处理报告》,责任人应根据问题发生的原因、经过、问题 的现象或后果、问题发生的时间和发现时间,进行详细如实填写,并随后签字确认; 六、责任人填写完毕交直接主管进行原因分析,提出解决措施,并填写《异常情况处理报告》,上交部门 负责人。 1、责任人的直接主管为班长的,该班长应根据问题的具体情况认真分析,确定属于哪种原因,并分析自 己在问题中所负的责任,必须认真填写明白,不得包庇、隐瞒; 2、责任人的直接主管为部长的,则由责任人所属部门部长填写; 3、责任人为部长的,责任人可以不填写此栏,只填写“问题描述”和“责任部门处理意见”; 4、责任人为副总的,责任人填写“问题描述”和“处理意见”; 七、责任人所属部门部长应详细调查、分析问题,确定解决措施,并填写处理报告,依据公司的有关规定 并分析自己在问题中所负的责任,做出公平、公正的处理意见;该部长应本着认真客观的态度对待问题,反思自己工作的欠缺,及时纠正并预防问题的再次发生。 八、责任部门将报告交分管副总,分管副总分析问题发生原因和相关负责人的处理意见,根据公司的有关 规定,对责任人做出处理意见;并由责任部门部长将报告交企管部(质检部); 九、企管部长(质检部长)实施监督职责,本着公平、公正地原则,对问题深入分析,不确定的问题应重 新调查,并分析责任部门的处理建议是否符合公司的有关规定。若符合规定则填写问题处理报告,做出企管部(质检部)的处理意见;若不符合有关规定,或责任部门的处理意见有失公平、公正,则需

IRQ0中断处理全过程

IRQ0中断处理全过程 1:系统注册IRQ0(时钟中断)的下半部分的处理过程。 在\kernel\sched.c的sched_init函数中 init_bh(TIMER_BH, timer_bh);/*TIMER_BH==0*/ init_bh(TQUEUE_BH, tqueue_bh);/*TQUEUE_BH==2*/ init_bh(IMMEDIATE_BH, immediate_bh);/*IMMEDIATE_BH==11*/ init_bh(TIMER_BH, timer_bh)把timer_bh函数注册为定时器的下半部分。 来看看init_bh是怎么处理的。 去掉一些加琐解琐的东西,就变成以下了。 void init_bh(int nr, void (*routine)(void)) { bh_base[nr] = routine; atomic_set(&bh_mask_count[nr], 0); bh_mask |= 1 << nr; } 就是简单的设置bh_base和bh_mask. 看看这些的定义: atomic_t bh_mask_count[32]; unsigned long bh_active = 0; unsigned long bh_mask = 0; void (*bh_base[32])(void); bh_base[] 31 bh_active 0 Bottom half handler(timer_bh) 31 bh_mask 0 不好意思,画的这么难看:P 如果bh_mask的第N位被置为1,则表明bh_base[]中的第N个指针指向了一个Bottom half 例程。 如果bh_active的第N位被置为1,则表明一旦调度进程许可,立即调用第N个Bottom hal f 例程。 bh_mask_count[]跟踪为每个下半部分提出的enable/disable请求嵌套对的数组。2.系统初始化时钟中断(IRQ0) ①先看看start_kernel(\init\main.c)吧 有几个跟时钟中断(IRQ0)相关的函数。 init_IRQ(); sched_init(); time_init(); sched_init()就是注册时钟中断的下半部分,其实IRQ0两个下半部分,一个前面已经看 到,还有一个下半部分init_bh(TQUEUE_BH, tqueue_bh);下面会看到。 ②init_IRQ函数在\arch\i386\kernel\irq.c 比较重要的调用就是init_ISA_irqs();

[重点]设备异常处理流程及规定

[重点]设备异常处理流程及规定 设备异常处理流程 序流程图责任人表单作业内容号 班组长/线长不能处生产异常出现时,生产部门/设备生产异常理或异常会导致停产时间超过30分钟 1 相关部门/ 时,应立即上报,或开出《生产异常发现者报告单》进行处理。 生产部负责人接到报告后应在10分钟生产部门/内赶赴现场;必要时可同时通知相关相关人员 2 相关部门/ 部门负责人,相关部门负责人接到通赶赴现场负责人知后应在10分钟内赶到现场( 相关部门负责人到达现场后立即对异相关部门异常分析 3 常进行分析,若部门负责人不能到场负责人应在10分钟内派人到达现场( 如不能立即处理应作出是否停产的意确定是总经办/总4 见,并注明预计恢复生产的时间(停否停产经理产应由总经理批准( 相关部门负责人针对问题应在30分钟制定应急相关部门生产异常 5 内制定出应急处理措施,制定措施时处理措施负责人报告单应尽可能地降低影响生产部门生产异常生产部门按应急措施进行生产按照处理6 负责人报告单调整生产措施生产 生产部/品 质部 NG 应急措施的有效性由生产部与品质部生产异常责任人措施7 共同验证,如验证不符合则重新制定报告单验证相关措施( YES 验证结果符合生产及品质相关要求,生产部负责恢复正8 可以在恢复生产后由品质部和生产部人常生产对异常进行跟进确认(

相关责任部生产恢复正常后相关部门应对问题的生产异常 9 制定长期门深层次的原因加以分析,并在两个工报告单预防措施负责人作日内制定出长期预防措施( 生产部生产异常生产部应协同品质部对责任部门的长10 负责人报告单期预防措施执行结果进行跟踪预防措施跟踪 异常处理规定 1(目的 为了更好的规范和完善公司生产异常处理作业,使生产问题发生后,各部门人员迅速、有效的处理,减免停工时间,提高生产效率,特制定本流程。 2(适用范围 适用于公司所有生产异常的处理。 3(职责 3(1 生产部门负责生产异常的反馈和处理措施验证。 3(2 品质部负责品质异常的处理及验证。 3(3 设备组负责设备异常的处理。 3(4 计控部负责物料异常的处理。 3(5 技术部负责技术、关键工序设备、工装模具、工艺异常的处理。 4(作业规范 4.1 生产异常反馈 4.1.1 当生产发生异常或有出现异常的趋势时,生产部发现人员和现场管理人员(如班组长)应即时给予分析,并主动积极寻求解决方法,包括与相关人员联系,如能及时解决则不在本流程规定内。

货物异常应急处置制度

货物异常应急处置制度 一、目的 确保公司在进行货物运输、装卸、存储等过程中对货物多货、少货、货损、污染、霉变、虫害、火灾、被盗、丢失及其他异常情况进行及时调查分析和处置,并遵守国家相关安全要求。 二、范围 1、本制度适用于货物运输、装卸、存储数量及质量控制; 2、本制度使用货物异常分析及处置。 三、主要职责和权限 1、理货员负责核实出入库货物数量、质量、单据和记录的控制; 2、统计员负责提供货物单据及盘点数量; 3、业务员负责货物异常的追溯、调查及对接客户的处理方案; 4、仓库经理负责处理异常货物。 四、工作程序 1、入库货物多货、少货 (1)货物拆箱时,由理货员依据入库单,清单货物数量。如发现多货或少货,首先与统计员、操作员确认入库单数量是否正确; (2)如确认的确为装箱货物数量异常,则须拍照取证,并及时上报仓库经理、操作员; (3)操作员须及时与客户沟通确认是否继续卸货,待客户确认实际到货数量,并同意卸货后,方可安排叉车工予以卸货; (4)操作员留存客户确认实际到货数量的邮件、微信等截图。 2、出库货物多货、少货 (1)货物装箱时,由理货员依据出库单,查找对应提单号货物存储位置,并检查货物状态,是否有货损、污染、霉变、虫害等情况; (2)如存储期间出现货损、污染、霉变、虫害等情况,则及时报告仓库经理,对异常情况进行调查,必要情况下,须及时通知客户以便出具处理意见; (3)货物检查无异常的,安排并监督叉车工进行装车工作,清点装货数量。 (4)如出库货物到达客户仓库后,被告知货物多货或少货的,则由仓库经理负责调取监控,查看装车视频,清点装车数量,确定为装货时数量异常还是运输过程中数量异常; (5)如装货时少货的,除上报公司外,与客户沟通单独送货还是待下批次货物一同运输; (6)如装货时多货的,除上报公司外,与客户沟通单独退货还是待下批次货物扣除同等数量。 (7)操作员留存客户确认实际到货数量、处理意见的邮件、微信等截图。 3、入库货物货损 (1)货物拆箱时,由理货员依据入库单,检查货物包装。如发现货损情况,则须拍照取证,并及时上报仓库经理、操作员; (2)由仓库经理负责调取监控,查看车辆入场、拆箱视频,确认货损出现原因;

Linux中断处理流程

Linux中断处理流程 先从函数注册引出问题吧。 一、中断注册方法 在linux内核中用于申请中断的函数是request_irq(),函数原型在Kernel/irq/manage.c中定义: int request_irq(unsigned int irq, irq_handler_t handler, unsigned long irqflags, const char *devname, void *dev_id) irq是要申请的硬件中断号。 handler是向系统注册的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递给它。 irqflags是中断处理的属性,若设置了IRQF_DISABLED (老版本中的SA_INTERRUPT,本版zhon已经不支持了),则表示中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程 序不屏蔽;若设置了IRQF_SHARED (老版本中的SA_SHIRQ),则表示多个设备共享中断,若设置了IRQF_SAMPLE_RANDOM(老版本中的 SA_SAMPLE_RANDOM),表示对系统熵有贡献,对系统获取随机数有好处。(这几个flag是可以通过或的方式同时使用的) dev_id在中断共享时会用到,一般设置为这个设备的设备结构体或者NULL。devname设置中断名称,在cat /proc/interrupts中可以看到此名称。 request_irq()返回0表示成功,返回-INVAL表示中断号无效或处理函数指针为NULL,返回-EBUSY表示中断已经被占用且不能共享。 关于中断注册的例子,大家可在内核中搜索下request_irq。 在编写驱动的过程中,比较容易产生疑惑的地方是: 1、中断向量表在什么位置?是如何建立的? 2、从中断开始,系统是怎样执行到我自己注册的函数的? 3、中断号是如何确定的?对于硬件上有子中断的中断号如何确定? 4、中断共享是怎么回事,dev_id的作用是? 本文以2.6.26内核和S3C2410处理器为例,为大家讲解这几个问题。 二、异常向量表的建立 在ARM V4及V4T以后的大部分处理器中,中断向量表的位置可以有两个位置:一个是0,另一个是0xffff0000。可以通过CP15协处理器c1寄存器中V位(bit[13])控制。V和中断向量表的对应关系如下: V=0 ~ 0x00000000~0x0000001C V=1 ~ 0xffff0000~0xffff001C arch/arm/mm/proc-arm920.S中 .section ".text.init", #alloc, #execinstr __arm920_setup: ...... orr r0, r0, #0x2100 @ ..1. ...1 ..11 (1) //bit13=1 中断向量表基址为0xFFFF0000。R0的值将被付给CP15的C1.

1.异常处理机制(精)

1. 异常机制 异常机制是指当程序出现错误后,程序如何处理。具体来说,异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。 传统的处理异常的办法是,函数返回一个特殊的结果来表示出现异常(通常这个特殊结果是大家约定俗称的),调用该函数的程序负责检查并分析函数返回的结果。这样做有如下的弊端:例如函数返回-1代表出现异常,但是如果函数确实要返回-1这个正确的值时就会出现混淆;可读性降低,将程序代码与处理异常的代码混爹在一起;由调用函数的程序来分析错误,这就要求客户程序员对库函数有很深的了解。 异常处理的流程: ①遇到错误,方法立即结束,并不返回一个值;同时,抛出一个异常对象。 ②调用该方法的程序也不会继续执行下去,而是搜索一个可以处理该异常的异常处理器,并执行其中的代码。 2 异常的分类 异常的分类: ①异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception,具体的RuntimeException继承RuntimeException。 ② Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。 每个类型的异常的特点 Error体系: Error类体系描述了Java运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在进行程序设计时,应该更关注Exception体系。 Exception体系包括RuntimeException体系和其他非RuntimeException的体系: ① RuntimeException:RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现

Windows异常处理流程

Windows异常处理流程 作者:SoBeIt 出处:https://www.360docs.net/doc/b710953680.html,/articles/200412/761.html 日期:2005-01-06 先来说说异常和中断的区别。中断可在任何时候发生,与CPU正在执行什么指令无关,中断主要由I/O设备、处理器时钟或定时器等硬件引发,可以被允许或取消。而异常是由于CPU执行了某些指令引起的,可以包括存储器存取违规、除0或者特定调试指令等,内核也将系统服务视为异常。中断和异常更底层的区别是当广义上的中断(包括异常和硬件中断)发生时如果没有设置在服务寄存器(用命令号0xb向8259-1中断控制器0x20端口读出在服务寄存器1,用0xb向8259-2中断控制器的0xa0端口读出在服务寄存器2)相关的在服务位(每个在服务寄存器有8位,共对应IRQ 0-15)则为CPU的异常,否则为硬件中断。 下面是WINDOWS2000根据INTEL x86处理器的定义,将IDT中的前几项注册为对应的异常处理程序(不同的操作系统对此的实现标准是不一样的,这里给出的和其它一些资料不一样是因为这是windows的具体实现): 中断号名字原因 0x0 除法错误1、DIV和IDIV指令除0 2、除法结果溢出 0x1 调试陷阱1、EFLAG的TF位置位 2、执行到调试寄存器(DR0-DR4)设置的断点 3、执行INT 1指令 0x2 NMI中断将CPU的NMI输入引脚置位(该异常为硬件发生非屏蔽中断而保留) 0x3 断点执行INT 3指令 0x4 整数溢出执行INTO指令且OF位置位 0x5 BOUND边界检查错误BOUND指令比较的值在给定范围外 0x6 无效操作码指令无法识别 0x7 协处理器不可用1、CR0的EM位置位时执行任何协处理器指令 2、协处理器工作时执行了环境切换 0x8 双重异常处理异常时发生另一个异常 0x9 协处理器段超限浮点指令引用内存超过段尾 0xA 无效任务段任务段包含的描述符无效(windows不 使用TSS进行环境切换,所以发生该异常说明有其它问题) 0xB 段不存在被引用的段被换出内存 0xC 堆栈错误1、被引用内存超出堆栈段限制 2、加载入SS寄存器的描述符的present位置0 0xD 一般保护性错误所有其它异常处理例程无法处理的异常 0xE 页面错误1、访问的地址未被换入内存 2、访问操作违反页保护规则 0x10 协处理器出错CR0的EM位置位时执行W AIT或ESCape指令 0x11 对齐检查错误对齐检查开启时(EFLAG对齐位置位)访问未对齐数据

C51中断处理过程

C51中断处理过程 3 C51中断处理过程 C51编译器支持在C源程序中直接开发中断过程,因此减轻了使用汇编语言的繁琐工作,提高了开发效率。中断服务函数的完整语法如下: void函数名(void)[模式] [再入]interrupt n [using r] 其中n(0~31)代表中断号。C51编译器允许32个中断,具体使用哪个中断由80C51系列的芯片决定。r(0~3)代表第r组寄存器。在调用中断函数时,要求中断过程调用的函数所使用的寄存器组必须与其相同。"再入"用于说明中断处理函数有无"再入"能力。C51编译器及其对C语言的扩充允许编程者对中断所有方面的控制和寄存器组的使用。这种支持能使编程者创建高效的中断服务程序,用户只须在C语言下关心中断和必要的寄存器组切换操作。例3 设单片机的fosc=12MHz,要求用T0的方式1编程,在P1.0脚输出周期为2ms的方波。例3 设单片机的fosc=12MHz,要求用T0的方式1编程,在P1.0脚输出周期为2ms的方波。用C语言编写的中断服务程序如下: #include sbit P1_0=P1^0; void timer0(void)interrupt 1 using 1 { /*T0中断服务程序入口*/ P1_0=!P1_0; TH0=-(1000/256); /*计数初值重装*/ TL0=-(1000%256); } void main(void) { TMOD=0x01; /*T0工作在定时器方式1*/ P1_0=0; TH0=-(1000/256); /*预置计数初值*/ TL0=-(1000%256); EA=1; /*CPU开中断*/ ET0=1; /*T0开中断*/ TR0=1; /*启动T0*/ do{}while(1); } 在编写中断服务程序时必须注意不能进行参数传递,不能有返回值。 8051 系列 MCU 的基本结构包括:32 个 I/O 口(4 组8 bit 端口);两个16 位定时计数器;全双工串行通信;6 个中断源(2 个外部中断、2 个定时/计数器中断、1 个串口输入/输出中断),两级中断优先级;128 字节内置RAM;独立的 64K 字节可寻址数据和代码区。中断发生后,MCU 转到 5 个中断入口处之一,然后执行相应的中断服务 处理程序。中断程序的入口地址被编译器放在中断向量中,中断向量位于程序代码段的最低地址处,注意这里的串口输入/输出中断共用一个中断向量。8051的中断向量表如下: 中断源中断向量 --------------------------- 上电复位 0000H 外部中断0 0003H 定时器0 溢出 000BH 外部中断1 0013H 定时器1 溢出 001BH

生产异常处理机制

广东樱雪有限公司文件组装车间异常工时责任追究考核管理办法(修订版)为了确保制造部月度产量目标达成,确保公司生产经营紧张有序,生产压力在各生产支持主责模块间有效传递与分解,实现不停线、不断线、不下线,及时暴露生产异常并进行有效责任追究,经公司研究决定特制定本考核管理办法。一、总装车间生产支持主责模块及必须有效支持的项目

二、主要生产异常类型与主责模块责任界定

三、各类生产异常情况责任人分解 四、生产异常情况异常工时责任追究执行标准

五、生产异常责任追究运作模式 1、组装车间在生产过程中出现异常情况时由生产线线长、物料调度(指仓管 的方式通知主责模块第一责任 人,相关责任人收到异常信息后应立即(要求在接到信息的 现场进行处理和确认,如果不到现场处理和确认则视同默认车间反馈的异常事件及处理异常对车间生产影响的时间; 2、的形式通知主责模块第一责任 人(责任人到达现场除外),同时将异常工时与责任模块第一负责人进行口头初步确认; 3、的异常情况,由生产线线长(指发泡总装线)、物料 调度(指仓管员)在填写《异常工时责任追究反馈表》在上交车间主任审核,车间主任审核完后在各生产部部长审批; 4、《异常工时责任追究反馈表》审批流程:生产线线长、仓管员(填写)→ 车间主任(审核)→各生产部部长(审批); 5、各生产部部长将审批完后的《异常工时责任追究反馈表》在 的形式发送至相关责任人处进行公示; 6、相关责任人在收到《异常工时责任追究反馈表》后默认视同接受,如果有

各生产部部长进行沟通反馈,各生产部部长收到异议反馈后组织异议调查最终将以事实依据作为最终裁定; 7、最终裁定的《异常工时责任追究反馈表》将在事件发生日的 8、生产副总助理汇总上月所有异常工时责任追究统计表输出《异 常工时责任追究月度处罚明细表》,经制生产副总(审核)、总经理(审批)后报送行政部(执行扣罚); 9、异常工时责任追究月度处罚金额在责任人当月工资中扣除; 10、各班组负责人根据本班组异常工时产生的罚款额度以 形式提交申请,经各制造部部长(一审)、生产副总(二审),生产副总(批准)后报送各生产部车间统计员将罚款额度纳入受影响班组的当月工资总额; 六、其他事项 1、本考核管理办法由生产部负责起草、修订、解释、执行; 2、本考核管理办法从2013年*月*日起试行考核; 3、为了提高各主责模块对异常工时改进的重视程度,要求各主责模块每月收 到正式版《异常工时责任追究月度处罚明细表》后的三个工作日向生产部提交《异常工时改进方案》; 4、各主责模块提交的《异常工时改进方案》,要求要对产生的异常工时进行数 据分析、原因总结、明确改进措施、落实责任人与改善进度; 5、生产部对各部门的《异常工时改进方案》进行收集、审核、评价; 6、行政部对各主责模块《异常工时改进方案》的评价结果纳入部门月度绩效 考核,根据改进的效果对责任部门实行扣分或加分;

相关文档
最新文档