关于__irq 的使用

本文介绍了__irq关键字在不同编译器中的使用方式及其作用。它用于声明中断服务程序,编译器会自动添加中断现场保护代码。文章还讨论了在不同场景下是否使用__irq的情况。

关于__irq 的使用

__irq为一个标识,用来表示一个函数是否为中断函数。对于不同的编译器,__irq在函数名中的位置不一样,例如:

ADS编译器中 : void __irq IRQ_Eint0(void);

Keil编译器中 : void IRQ_Eint0(void) __irq;

但是其意义一样,它所完成的任务是标识该函数为中断函数,在编译器编译是调用此函数时,先保护函数入口现场,然后执行中断函数,函数执行完毕,恢复中断现场,这整个过程不需要用户重新编写代码来完成,由编译器自动完成。因而这也给不具备中断嵌套功能的ARM系统带来了问题,若使用 __irq 时有中断嵌套产生,这现场保护就会混乱。中断嵌套处理可以自己编写中断入口现场保护代码,并不使用 __irq 标识符号。(小呆:具体如何编写可以嵌套的中断这里暂时不做研究。

 

总结如下

1、若不想自己编写中断入口现场保护代码,而且使用中无中断嵌套,在中断函数中用 __irq 来标识我们的中断函数,否则出错;

2、若程序中要使用中断嵌套,对于无中断嵌套功能的ARM来说,一定要自己编写中断入口现场保护代码,而且不能用 __irq 标识我们的中断函数,否则出错。

 

__irq关键字

ADS编译器中,“__irq”专门用来声明IRQ中断服务程序,如果用“__irq”来声明一个函数,那么该函数表示一个IRQ中断服务程序,编译器便会自动在该函数内部增加中断现场保护的代码。同样一个函数,如果将关键字“__irq”去掉,那么编译器便不会增加现场保护的代码,而只是作为一个普通函数来处理。

 

现在大家应该对“__irq”关键字有了一定的了解,那么,是不是所有的IRQ中断服务程序都需要使用“__irq”关键字声明呢?其实,这取决于获取中断服务程序地址的方法:

如果在执行中断服务函数之前没有对中断现场进行保护,那么中断服务函数必须要使用“__irq”关键字进行声明。例如,在0x0000 0018处执行指令“LDR PC, [PC, #-0xff0]”,此时对应的中断服务函数必须要使用“__irq”关键字进行声明;如果在执行中断服务函数之前已经对中断现场进行了保护,那么中断服务函数不能使用“__irq”关键字进行声明。

static inline void tp_work_func(struct touchpanel_data *ts) { u32 cur_event = 0; if (!ts->ts_ops->trigger_reason) { TP_INFO(ts->tp_index, "not support ts_ops->trigger_reason callback\n"); return; } /* * trigger_reason:this callback determine which trigger reason should be * The value returned has some policy! * 1.IRQ_EXCEPTION /IRQ_GESTURE /IRQ_IGNORE /IRQ_FW_CONFIG --->should be only reported individually * 2.IRQ_TOUCH && IRQ_BTN_KEY --->should depends on real situation && set correspond bit on trigger_reason */ if (ts->ts_ops->trigger_reason) { cur_event = ts->ts_ops->trigger_reason(ts->chip_data, (ts->gesture_enable || ts->fp_enable), ts->is_suspended); } if (ts->health_monitor_support) { tp_healthinfo_report(&ts->monitor_data, HEALTH_IRQ_TYPE, &cur_event); } if (CHK_BIT(cur_event, IRQ_TOUCH) || CHK_BIT(cur_event, IRQ_BTN_KEY) || CHK_BIT(cur_event, IRQ_FW_HEALTH) || CHK_BIT(cur_event, IRQ_PEN) || \ CHK_BIT(cur_event, IRQ_FACE_STATE) || CHK_BIT(cur_event, IRQ_FINGERPRINT) || CHK_BIT(cur_event, IRQ_PALM) || CHK_BIT(cur_event, IRQ_PEN_REPORT)) { if (CHK_BIT(cur_event, IRQ_BTN_KEY)) { tp_btnkey_handle(ts); } if (CHK_BIT(cur_event, IRQ_PEN) && ts->pen_support) { tp_pen_handle(ts); } if (CHK_BIT(cur_event, IRQ_PALM) && ts->palm_to_sleep_enable && !ts->is_suspended && !ts->disable_touch_event) { tp_palm_to_sleep_inScreenLock(ts); } if (CHK_BIT(cur_event, IRQ_TOUCH)) { if (ts->en_touch_event_helper) { tp_touch_helper_handle(ts); } else { tp_touch_handle(ts); } } if (CHK_BIT(cur_event, IRQ_PEN_REPORT)) { touch_pen_uplink_msg_handle(ts); } if (CHK_BIT(cur_event, IRQ_FW_HEALTH) && (!ts->is_suspended)) { health_monitor_handle(ts); } if (CHK_BIT(cur_event, IRQ_FACE_STATE) && ts->fd_enable) { tp_face_detect_handle(ts); } if (CHK_BIT(cur_event, IRQ_FINGERPRINT) && ts->fp_enable) { tp_fingerprint_handle(ts); } } else if (CHK_BIT(cur_event, IRQ_GESTURE)) { tp_gesture_handle(ts); } else if (CHK_BIT(cur_event, IRQ_EXCEPTION)) { tp_exception_handle(ts); } else if (CHK_BIT(cur_event, IRQ_FW_CONFIG)) { tp_config_handle(ts); } else if (CHK_BIT(cur_event, IRQ_FW_AUTO_RESET)) { tp_fw_auto_reset_handle(ts); } else { TPD_DEBUG("unknown irq trigger reason\n"); } } 详细解释下这段函数
最新发布
12-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值