亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

嵌入式Linux內核tasklet機制(附實測代碼)

發布時間:2020-02-25 11:46:28 來源:網絡 閱讀:345 作者:sinlinx123 欄目:系統運維

Linux 中斷編程分為中斷頂半部,中斷底半部

中斷頂半部: 做緊急,耗時短的事情,同時還啟動中斷底半部。
中斷底半部: 做耗時的事件,這個事件在執行過程可以被中斷。
中斷底半部實現方法: tasklet,工作隊列,軟中斷等機制實現。實際上是把耗時事件推后執行,不在中斷程序執行。

什么是tasklet?

Tasklet 一詞的原意是“小片任務”的意思,這里是指一小段可執行的代碼,且通常以函數的形式出現。這個 tasklet 綁定的函數在一個時刻只能在一個 CPU 上運行 ,tasklet(小任務)機制是中斷處理下半部分最常用的一種方法,其使用也是非常簡單的。一個使用 tasklet 的中斷程序首先會通過執行中斷處理程序來快速完成上半部分的工作,接著通過調用 tasklet 使得下半部分的工作得以完成。可以看到,下半部分被上半部分所調用,至于下半部分何時執行則屬于內核的工作。

tasklet 機制核心數據結構

Interrupt.h linux-3.5\include\Linux
struct tasklet_struct
{
      struct tasklet_struct *next; // tasklet_struct 結構鏈表
      unsigned long state; //當前這個 tasklet 是否已經被調度
      atomic_t count; 
      void (*func)(unsigned long); //指向 tasklet 綁定的函數的指針
      unsigned long data; //傳遞給tasklet 綁定的函數的參數
};

tasklet 相關 API

  • 初始化相關

    • 1) 靜態初始化 DECLARE_TASKLET(name, func, data)
      作用:定義一個名字為 name 的 tasklet_struct 結構變量,并且初始化這個結構。 所定義的這個 tasklet 是可以被調度,默認是處于被使能狀態。

    • 2 ) 靜態初始化 DECLARE_TASKLET_DISABLED(name, func, data)
      作用:定義一個名字為 name 的 tasklet_struct 結構變量,并且初始化這個結構。所定義的這個 tasklet 是不能被調度,默認是處于被禁能狀態。 要調度這個 tasklet 需要先使能。

    • 3 )動態初始化
      void tasklet_init(struct tasklet_struct *t,void (*func)(unsigned long), unsigned long data)
      作用:初始化一個 tasklet_struct 結構變量,初始化的結構默認是處于激活狀態,可以被調度。

tasklet_disable使能函數

1. void tasklet_disable(struct tasklet_struct *t)
作用:函數激活給定的 tasklet被 tasklet_schedule 調度
2. void tasklet_enable (struct tasklet_struct *t)
作用:函數禁止給定的 tasklet被 tasklet_schedule 調度

tasklet 調度函數

void tasklet_schedule (struct tasklet_struct *t)
作用:調用 tasklet_schedule 函數去通知內核幫我們調度所綁定的函數
void tasklet_kill(struct tasklet_struct *t);
作用:取消調度函數

編程步驟

Step1 定義并靜態初始化tasklet_struct 結構變量

Step2 編寫tasklet服務函數

Step3 在適當的地地方進行調度

Step4 在適當的地地方取消調度

開發平臺

芯靈思SinlinxA33開發板

淘寶店鋪: [https://sinlinx.taobao.com/]()

嵌入式Linux內核tasklet機制(附實測代碼)

嵌入式linux 開發板交流 QQ:641395230

驅動代碼:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>

void tasklet_fun(unsigned long data);
//Step1 定義并靜態初始化tasklet_struct 結構變量
DECLARE_TASKLET(mytasklet, tasklet_fun, 651);
//Step2 tasklet服務函數
void tasklet_fun(unsigned long data)
{
    static unsigned long count = 0;
    printk("count:%lu,%s is call! data:%lu\r\n",count++,__FUNCTION__,data);
    tasklet_schedule(&mytasklet); //在工作函數中重新調度自己,這樣會循環調用tasklet_fun
}
static int __init mytasklet_init(void)
{
    //Step3 開始調度 mytasklet
    tasklet_schedule(&mytasklet);
    printk("%s is call!\r\n",__FUNCTION__);
    return 0;
}
static void __exit mytasklet_exit(void) //Module exit function specified by module_exit()
{
    //Step4 刪除 tasklet
    tasklet_kill(&mytasklet);
}
module_init(mytasklet_init);
module_exit(mytasklet_exit);
MODULE_LICENSE("GPL");

Makefile 代碼

KERN_DIR = /work/lichee/linux-3.4
all:
    make -C $(KERN_DIR) M=`pwd` modules 
    arm-none-linux-gnueabi-gcc  btntest.c -o btntest
clean:
    make -C $(KERN_DIR) M=`pwd` modules clean
    rm -rf modules.order
obj-m        += tasklet_drv.o

實驗現象

循環調用tasklet_fun函數

嵌入式Linux內核tasklet機制(附實測代碼)

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

准格尔旗| 介休市| 东光县| 大邑县| 诸暨市| 杨浦区| 海林市| 阿鲁科尔沁旗| 攀枝花市| 米林县| 华阴市| 安宁市| 台前县| 武平县| 安达市| 屏东市| 德钦县| 新野县| 准格尔旗| 阿拉善盟| 深水埗区| 太白县| 陆河县| 灵丘县| 平罗县| 莱阳市| 乌鲁木齐县| 弥勒县| 兰溪市| 万源市| 库尔勒市| 项城市| 长宁县| 扎赉特旗| 姚安县| 大丰市| 商丘市| 禹州市| 英德市| 大悟县| 蒙城县|