Linux的notifier機制的應用

来源:https://www.cnblogs.com/linhaostudy/archive/2018/11/05/9909267.html
-Advertisement-
Play Games

在linux內核系統中,各個模塊、子系統之間是相互獨立的。Linux內核可以通過通知鏈機制來獲取由其它模塊或子系統產生的它感興趣的某些事件。 notifier_block結構體在include/linux/notifier.h中定義: priority用來定義優先順序,高優先順序的處理常式將被優先執行, ...


在linux內核系統中,各個模塊、子系統之間是相互獨立的。Linux內核可以通過通知鏈機制來獲取由其它模塊或子系統產生的它感興趣的某些事件。

notifier_block結構體在include/linux/notifier.h中定義:

struct notifier_block {
    notifier_fn_t notifier_call;
    struct notifier_block __rcu *next;
    int priority;
};

priority用來定義優先順序,高優先順序的處理常式將被優先執行,數值越大,優先順序越高。

回到函數的原型定義:

typedef    int (*notifier_fn_t)(struct notifier_block *nb,
            unsigned long action, void *data);

TP屬於輸入子系統,可以通過獲取framebuffer子系統來實現亮屏和滅屏時觸發相應的事件。

fb_register_client和fb_unregister_client函數定義在drivers/video/fb_notify.c:

/**
 *  fb_register_client - register a client notifier
 *  @nb: notifier block to callback on events
 */
int fb_register_client(struct notifier_block *nb)
{
    return blocking_notifier_chain_register(&fb_notifier_list, nb);
}
 
/**
 *    fb_unregister_client - unregister a client notifier
 *    @nb: notifier block to callback on events
 */
int fb_unregister_client(struct notifier_block *nb)
{
    return blocking_notifier_chain_unregister(&fb_notifier_list, nb);
}

當framebuffer子系統發生事件時,調用notifier_call_chain()來觸發相應的處理函數。

/**
 * fb_notifier_call_chain - notify clients of fb_events
 *
 */
int fb_notifier_call_chain(unsigned long val, void *v)
{
    return blocking_notifier_call_chain(&fb_notifier_list, val, v);
}

下麵是一個實例:

struct msg21xx_ts_data {
    struct input_dev *input;
    struct hrtimer timer;
    struct work_struct work;
    int irq;
    struct dentry *dir;
    char *ts_info;
    u8 addr;
    int fw_major;
    int fw_minor;
#ifdef CONFIG_FB
    struct notifier_block fb_notif;
#endif
    bool suspended;
    struct i2c_client *client;
    struct regulator *vdd;
    struct regulator *vcc_i2c;
    struct msg21xx_platform_data *pdata;
    struct workqueue_struct *msg21xx_wq;
    struct mutex msg21xx_mutex;
};

probe函數中與notifier相關部分實現:

struct msg21xx_ts_data *data;
 
data = kzalloc(sizeof(struct msg21xx_ts_data), GFP_KERNEL);
if (!data) {
    dev_err(&client->dev, "%s: Alloc mem fail!", __func__);
    err = -ENOMEM;
    goto exit;
}
 
#ifdef CONFIG_FB
data->fb_notif.notifier_call = fb_notifier_callback;
err = fb_register_client(&data->fb_notif);
if (err)
    dev_err(&client->dev, "Unable to register fb_notifier: %d\n",
        err);
#endif

fb_notifier_callback實現:


#ifdef CONFIG_FB
static int fb_notifier_callback(struct notifier_block *self,
            unsigned long event, void *data)
{
    struct fb_event *evdata = data;
    int *blank;
    struct msg21xx_ts_data *msg21xx_data =
        container_of(self, struct msg21xx_ts_data, fb_notif);
 
    if (evdata && evdata->data && event == FB_EVENT_BLANK &&
            msg21xx_data && msg21xx_data->client) {
        blank = evdata->data;
        if (*blank == FB_BLANK_UNBLANK)
            msg21xx_ts_resume(&msg21xx_data->client->dev);
        else if (*blank == FB_BLANK_POWERDOWN)
            msg21xx_ts_suspend(&msg21xx_data->client->dev);
    }
 
    return 0;
}
#endif

msg21xx_ts_suspend和msg21xx_ts_resume實現如下,主要是操作TP的電源和RST腳,LCD滅屏時,為了降低系統的功耗,需要將TP的power關閉,同時將TP的複位腳拉低,讓TP自身進入低功耗模式。

#if defined(CONFIG_PM) || defined(CONFIG_PM_RUNTIME)
static int msg21xx_ts_suspend(struct device *dev)
{
    struct msg21xx_ts_data *data = dev_get_drvdata(dev);
    int err;
 
    if (data->suspended) {
        dev_info(dev, "Already in suspend state\n");
        return 0;
    }
 
    disable_irq(data->client->irq);
 
    err = msg21xx_power_on(data, false);
    if (err)
        dev_err(dev, "power off failed");
 
    gpio_set_value_cansleep(data->pdata->reset_gpio, 0);
 
    data->suspended = true;
    return 0;
}
 
static int msg21xx_ts_resume(struct device *dev)
{
    struct msg21xx_ts_data *data = dev_get_drvdata(dev);
    int err;
 
    if (!data->suspended) {
        dev_dbg(dev, "Already in awake state\n");
        return 0;
    }
 
    err = msg21xx_power_on(data, true);
    if (err) {
        dev_err(dev, "power on failed");
        return err;
    }
 
    enable_irq(data->client->irq);
    gpio_set_value_cansleep(data->pdata->reset_gpio, 1);
    data->suspended = false;
    return 0;
}
#endif

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 昨晚更新了一下內核,今晚開機就無法進系統了...提示如下圖: 解決方案:開機啟動時按Esc,然後選擇下麵的舊版本的內核啟動即可。 (成功進入系統後,你可以選擇改變開機預設選擇的內核)。 uname -r 查看當前內核版本 rpm -qa|grep kernel 查看系統已安裝的內核 vim /boo ...
  • 什麼是Shell     簡單來說Shell其實就是一個 命令解釋器 ,而它的作用就是解釋並執行用戶輸入的命令及程式。用戶每輸入一條命令,Shell就解釋執行一次。這種方式很容易讓大家想起在Windows環境中使用的command命令,我們在cmd視窗輸入一條命令,按下Enter ...
  • nl命令在linux系統中用來計算文件中行號。nl 可以將輸出的文件內容自動的加上行號!其預設的結果與 cat n 有點不太一樣, nl 可以將行號做比較多的顯示設計,包括位數與是否自動補齊 0 等等的功能。 一.命令格式: nl [參數]... [文件]... 二.命令參數: |參數|描述| | ...
  • 1. 主從複製1.1. mysql主從的原理1.1.1. Replication 線程Mysql的 Replication 是一個非同步的複製過程(mysql5.1.7以上版本分為非同步複製和半同步兩種模式),從一個 Mysql instace(我們稱之為 Master)複製到另一個 Mysql ins ...
  • 一 PIP簡介 pip類似RedHat裡面的yum,使用PIP安裝軟體非常便捷快速。 二 PIP下載安裝 方式一: 方式二: 三 PIP常見使用 3.1 pip安裝軟體 如:安裝Redis 附PIP批量安裝軟體: 如果需要安裝的包比較多的時候,單獨安裝比較繁瑣,可通過一次安裝的方法。首先新建一個文本 ...
  • 操作步驟 32位操作系統: 1、將2003系統C:\WINDOWS\system32目錄下的mstsmhst.dll、mstsmmc.dll、tsmmc.msc拷貝到Windows7系統中的C:\WINDOWS\system32目錄下; 2、使用管理員許可權運行cmd,註冊dll文件: regsvr3 ...
  • 一、命令介紹 我們使用man cat命令,可以看到cat命令的用途是連接文件或標準輸入並列印,簡單來說cat命令是用來查看純文本文件(通常為內容較少的文件),與重定向符號配合使用,可以實現創建文件與合併文件。 二、實例 1.使用 cat命令查看文件 我們使用cat命令查看study.txt這個文件 ...
  • kvm安裝 1、在宿主機上準備好yum(只需要本地鏡像yum就可以) 2、查看CPU是否支持inter或AMD的虛擬技術 3、安裝kvm 4、確認是否有裝在kvm模塊,沒有裝載可以使用modprobe kvm來裝載 5、啟動並設置為開機自啟動 kvm安裝虛擬機 圖形安裝 第一步、 安裝方式: --我 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...