历史上的今天
今天是:2025年01月31日(星期五)
2020年01月31日 | ARM Linux 如何--注册和触发--软中断
2020-01-31 来源:eefocus
1. 注册软中断当然是通过open_softirq
例子如下:
void __init init_timers(void)
{
int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,
(void *)(long)smp_processor_id());
init_timer_stats();
BUG_ON(err == NOTIFY_BAD);
register_cpu_notifier(&timers_nb);
open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
}
void open_softirq(int nr, void (*action)(struct softirq_action *))
{
softirq_vec[nr].action = action;
}
软中断TIMER_SOFTIRQ的中断处理函数为:run_timer_softirq
之所以成为softirq,是因为这些中断是由硬件中断来间接触发的,如何间接触发的呢:
硬件中断处理函数-->对软中断的相应位置位-->唤醒ksoftirqd线程-->执行软中断的中断处理函数
2. 硬件中断如何通过置位唤醒ksoftirqd线程
timer interrupt handler->
timer_tick->
update_process_times->
run_local_timers->
hrtimer_run_queues()和raise_softirq(TIMER_SOFTIRQ)->
raise_softirq_irqoff->
__raise_softirq_irqoff { or_softirq_pending(1UL << (nr)); }
即(local_softirq_pending() |= (x))
3. 如何执行软中断的action<中断处理函数>
对于TIMER_SOFTIRQ来说,每次system clock产生中断时,即一个tick 到来时,在system clock的中断处理函数中会调用run_local_timers来设置TIMER_SOFTIRQ触发条件;也就是当前CPU对应的irq_cpustat_t结构体中的__softirq_pending成员的第TIMER_SOFTIRQ个BIT被置为1。 而当这个条件满足时,ksoftirqd线程(入口函数run_ksoftirqd,cpu_callback:kthread_create(run_ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu);)会被唤醒,然后按照下面的流程调用TIMER_SOFTIRQ在数组softirq_vec中注册的action,即run_timer_softirq。
run_ksoftirqd--->do_softirq--->__do_softirq--->softirq_vec[TIMER_SOFTIRQ].action
static int run_ksoftirqd(void * __bind_cpu)
{
set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) {
preempt_disable();
if (!local_softirq_pending()) {
preempt_enable_no_resched();
schedule();
preempt_disable();
}
__set_current_state(TASK_RUNNING);
while (local_softirq_pending()) {
/* Preempt disable stops cpu going offline.
If already offline, we'll be on wrong CPU:
don't process */
if (cpu_is_offline((long)__bind_cpu))
goto wait_to_die;
do_softirq();
preempt_enable_no_resched();
cond_resched();
preempt_disable();
rcu_sched_qs((long)__bind_cpu);
}
preempt_enable();
set_current_state(TASK_INTERRUPTIBLE);
}
__set_current_state(TASK_RUNNING);
return 0;
wait_to_die:
preempt_enable();
/* Wait for kthread_stop */
set_current_state(TASK_INTERRUPTIBLE);
while (!kthread_should_stop()) {
schedule();
set_current_state(TASK_INTERRUPTIBLE);
}
__set_current_state(TASK_RUNNING);
return 0;
}
史海拾趣
|
本帖最后由 paulhyde 于 2014-9-15 09:21 编辑 引言 开关稳压电源被誉为“新型高效节能电源”,它代表着稳压电源的发展方向。由于内部器件工作在高频开关状态,因此本身消耗的能量极低,电源效率可以达到80%以上,比串连调整线性稳压电源的效率提 ...… 查看全部问答> |
|
idea6410开发板WinCE6.0、Linux等系统安装使用指导手册 idea6410开发板是一款低功耗、高性能、高性价比的ARM11处理器开发板;专为消费类电子、工业控制、车载导航、行业PDA等电子产品的开发而设计,主要供广大企业用户进行产品前期软硬件性能评估验证、设计参考用,其小巧、紧凑、一体式的人性化外观设计 ...… 查看全部问答> |
|
最近遇到个问题。系统通过响应GPIO口例如GPIO0这个IO口中断实现一个低功耗休眠的动作。一些机器上正常,功耗小于5mA,12M晶振工作停止,32.768正常工作。但是现在的一个案子上休眠都休眠下去了。但是12M晶振没有停止,一直有个50mA在,程序上已经试 ...… 查看全部问答> |
|
我想了解一下,CE6.0和MOBILE2003具体上的区别是什么?比如说调用的基本类库等; 现在如果已经开发了一套基于MOBILE2003的应用程序,如何将其应用于CE6.0的平台上?是否要进行很复杂的修改?… 查看全部问答> |
|
我的笔记本前几天一直无线上网(自动连接到无线路由器上),今天无线连接显示未连接状态并且无法刷新网络列表,路由器运行正常且别人的笔记本用无线是正常的,这是怎么回事啊? 我已经试过重新安装无线网卡的驱动,仍然没有网络列表且无线网卡灯 ...… 查看全部问答> |
|
本帖最后由 dontium 于 2015-1-23 13:09 编辑 Multisim - 2010-12-27 09:04:58 ERC [AGV_2_1] <2010-12-27 09:05:06> 错误: 正在连接 \'Power 到 Bidirectional\'; [VCC 引脚 VCC, AGV_2_1] ...… 查看全部问答> |
|
看到别的论坛有人问过,但是没人回答,就是放在中断向量表里中断入口地址之前的 自己猜那应该是个跳转之类的指令,但是反汇编看了一下竟然是INT,不知道什么东西,查汇编手册也没这个指令,有人解释一下不?… 查看全部问答> |
|
介绍一种新型的能探测微震动、微晃动、微移动等多种微动特性的无源电子器件——微动传感器 最大特点: 一、 有连续实时探测功能。从传感器被“微动”开始,以连续脉宽为数十微秒至百毫秒的音频速度输出近电源幅值脉冲,且始终能跟随“微动”输出 ...… 查看全部问答> |




