<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    ARM Linux 如何--注冊和觸發--軟中斷

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    1. 注冊軟中斷當然是通過open_softirq

    例子如下:

    [cpp] view plain copy  
    1. void __init init_timers(void)  
    2. {  
    3.     int err = timer_cpu_notify(&timers_nb, (unsigned long)CPU_UP_PREPARE,  
    4.                 (void *)(long)smp_processor_id());  
    5.   
    6.     init_timer_stats();  
    7.   
    8.     BUG_ON(err == NOTIFY_BAD);  
    9.     register_cpu_notifier(&timers_nb);  
    10.     open_softirq(TIMER_SOFTIRQ, run_timer_softirq);  
    11. }  
    12.   
    13. void open_softirq(int nr, void (*action)(struct softirq_action *))  
    14. {  
    15.     softirq_vec[nr].action = action;  
    16. }  

    軟中斷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


     

    [cpp] view plain copy  
    1. static int run_ksoftirqd(void * __bind_cpu)  
    2. {  
    3.     set_current_state(TASK_INTERRUPTIBLE);  
    4.   
    5.     while (!kthread_should_stop()) {  
    6.         preempt_disable();  
    7.         if (!local_softirq_pending()) {  
    8.             preempt_enable_no_resched();  
    9.             schedule();  
    10.             preempt_disable();  
    11.         }  
    12.   
    13.         __set_current_state(TASK_RUNNING);  
    14.   
    15.         while (local_softirq_pending()) {  
    16.             /* Preempt disable stops cpu going offline. 
    17.                If already offline, we'll be on wrong CPU: 
    18.                don't process */  
    19.             if (cpu_is_offline((long)__bind_cpu))  
    20.                 goto wait_to_die;  
    21.             do_softirq();  
    22.             preempt_enable_no_resched();  
    23.             cond_resched();  
    24.             preempt_disable();  
    25.             rcu_sched_qs((long)__bind_cpu);  
    26.         }  
    27.         preempt_enable();  
    28.         set_current_state(TASK_INTERRUPTIBLE);  
    29.     }  
    30.     __set_current_state(TASK_RUNNING);  
    31.     return 0;  
    32.   
    33. wait_to_die:  
    34.     preempt_enable();  
    35.     /* Wait for kthread_stop */  
    36.     set_current_state(TASK_INTERRUPTIBLE);  
    37.     while (!kthread_should_stop()) {  
    38.         schedule();  
    39.         set_current_state(TASK_INTERRUPTIBLE);  
    40.     }  
    41.     __set_current_state(TASK_RUNNING);  
    42.     return 0;  
    43. }  


     

     

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全