1. 概述
NIOS2 支持32个内部硬件中断,且有32级别的中断请求(irq0-irq31)。
软件通过ienable控制寄存器使能和取消中断源,还可以通过status控制寄存器的PIE位全局的开使能和取消所有中断。
硬件中断产生的条件:
status寄存器的PIE位为1
一个中断请求输入申请irq<n>
在ienable寄存器中对应的位置1
2. HAL接口API
1
2
3
4
5
6
7
|
<sys/alt_irq.h>
int
alt_ic_isr_register (alt_u32 ic_id, alt_u32 irq, alt_isr_func isr,
void
* isr_context,
void
* flags)
int
alt_ic_irq_enable (alt_u32 ic_id, alt_u32 irq)
int
alt_ic_irq_disable (alt_u32 ic_id, alt_u32 irq)
void
alt_irq_init (
void
* base)
//定义ISR中断处理函数:
typedef
void
(*alt_isr_func) (
void
* isr_context);
|
3. 按键中断
1) 在QSYS中添加PIO组件
设置PIO位宽为1,输入模式,勾选同步边沿capture,上升沿方式,使能IRQ生成,EDGE方式。
2)编写代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#include <stdio.h>
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include "sys/alt_irq.h"
alt_u8 key_flag =0;
void
ISR_handle_button(
void
* context ){
key_flag =~key_flag;
printf
(
"button interrupt!\n"
);
IOWR_ALTERA_AVALON_PIO_EDGE_CAP( PIO_0_BASE,0x0);
// clear the interrupt
}
void
init_button_pio(
void
){
IOWR_ALTERA_AVALON_PIO_IRQ_MASK( PIO_0_BASE,0x1);
// 使能按钮中断
IOWR_ALTERA_AVALON_PIO_EDGE_CAP( PIO_0_BASE,0x0);
// 清边沿捕获寄存器
alt_ic_isr_register(PIO_0_IRQ_INTERRUPT_CONTROLLER_ID, PIO_0_IRQ, ISR_handle_button,NULL,0x0);
}
int
main(){
init_button_pio();
while
(1);
return
0;
}
|
4. 自定义组件中断
在定义自己的Qsys组件时,可以添加自己的中断。
软件编写:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#include <stdio.h>
#include "system.h"
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#include "sys/alt_irq.h"
void
ISR_handle_FUNC(
void
* context){
...
//清除中断
}
int
main(){
volatile
int
i=0;
alt_irq_init(ALT_IRQ_BASE);
if
(!alt_ic_isr_register(ALT_IRQ_INTERRUPT_CONTROLLER_ID, ALT_IRQ, ISR_handle_FUNC,NULL,0x0))
printf
(
"The IRQ is set\n"
);
while
(1);
return
0;
}
|
5. 总结
NIOS2中断系统中,中断号越小中断优先级越高。
尽量不要在中断处理函数中使用不可重入的函数,否则可能死锁,比如printf函数。
使用全局变量时,使用volatile,确保每次都能从内存中获得变量值。
本文转自 shugenyin 51CTO博客,原文链接:http://blog.51cto.com/shugenyin/1884986