Linux驅動開發之使用dev dbg除錯裝置驅動

2021-07-02 02:18:46 字數 4586 閱讀 7202

gqb666

1、最近在寫i2c下eeprom的驅動程式,但發現使用i2c_new_probed_device函式無法列舉到裝置,於是想除錯該函式(位於driver/i2c/i2c-core.c內),看到其中有些除錯資訊如下:

[cpp]view plain

copy

i2c_new_probed_device(...)  

...  

}  

但載入驅動模組,該類除錯資訊並未列印出來(執行dmesg命令後同樣未找到除錯資訊)。

2、列出dev_dbg原始碼實現:(include/linux/device.h中)

[cpp]view plain

copy

#if defined(debug)

#define dev_dbg(dev, format, arg...)        \

dev_printk(kern_debug , dev , format , ## arg)  

問題找出,只需在引用標頭檔案#

include/linux/device.h前定義debug巨集即可。

在include/linux/i2c.h中修改**如下:

[cpp]view plain

copy

#define debug                  /* add for debug eeprom */

#include /* for struct device */

#undef debug                   /* add for debug eeprom */

載入驅動驅動模組後,並沒有除錯資訊列印出。如下圖:

但執行dmesg命令後

probing failed, no device found已經能夠列印出來,如下圖:

這是為什麼呢?

3、注意dev_printk的列印級別:

[cpp]view plain

copy

dev_printk(kern_debug , dev , format , ## arg)  

這裡有個kern_debug的列印級別,其他級別如下(include/linux/kern_levels.h中):

#define kern_emerg	kern_soh "0"	/* system is unusable */

#define kern_alert kern_soh "1" /* action must be taken immediately */

#define kern_crit kern_soh "2" /* critical conditions */

#define kern_err kern_soh "3" /* error conditions */

#define kern_warning kern_soh "4" /* warning conditions */

#define kern_notice kern_soh "5" /* normal but significant condition */

#define kern_info kern_soh "6" /* informational */

#define kern_debug kern_soh "7" /* debug-level messages */

可以看到kern_debug級別最低為7。

再看/include/linux/printk.h下的乙個巨集:

[cpp]view plain

copy

#define console_loglevel_default 7 /* anything more serious than kern_debug */

該行表示只有列印級別高於default_console_loglevel(值小於default_console_loglevel的值)的列印才會出現在終端上。而 kern_debug也為7,所以我們的除錯不會直接列印出來。

將該行修改為:

[cpp]view plain

copy

#define console_loglevel_default 8 /* anything more serious than kern_debug */

來保證kern_debu的值小於default_console_loglevel,然後載入eeprom驅動模組後:除錯資訊能夠正確列印出來。

在核心中經常見到一些除錯列印資訊。pr_debug,pr_err等。以前的理解是以為只有出錯才會將pr_err中的內容列印出來,現在看來是錯的。pr_err並不等同與perror。

關於pr_err,pr_debug的定義有兩種:

第一種(tools\perf\util\debug.h)

int eprintf(int level,

const char *fmt, ...) __attribute__((format(printf, 2, 3)));

#define pr_err(fmt, ...) \

eprintf(0, pr_fmt(fmt), ##__va_args__)

#define pr_warning(fmt, ...) \

eprintf(0, pr_fmt(fmt), ##__va_args__)

#define pr_info(fmt, ...) \

eprintf(0, pr_fmt(fmt), ##__va_args__)

#define pr_debug(fmt, ...) \

eprintf(1, pr_fmt(fmt), ##__va_args__)

#define pr_debugn(n, fmt, ...) \

eprintf(n, pr_fmt(fmt), ##__va_args__)

#define pr_debug2(fmt, ...) pr_debugn(2, pr_fmt(fmt), ##__va_args__)

#define pr_debug3(fmt, ...) pr_debugn(3, pr_fmt(fmt), ##__va_args__)

#define pr_debug4(fmt, ...) pr_debugn(4, pr_fmt(fmt), ##__va_args__)

第二種(tools\virtio\linux\kernel.h)

#define pr_err(format, ...) fprintf (stderr, format, ## __va_args__)

#ifdef debug

#define pr_debug(format, ...) fprintf (stderr, format, ## __va_args__)

#else

#define pr_debug(format, ...) do {} while (0)

#endif

#define dev_err(dev, format, ...) fprintf (stderr, format, ## __va_args__)

#define dev_warn(dev, format, ...) fprintf (stderr, format, ## __va_args__)

第一種定義,可以看出pr_err,pr_debug,pr_warning,pr_info實質上都是一樣的,eprintf就是printf函式。__attribute__((format(printf, 2, 3)));表示printf格式化字串從printf的第2個引數開始,可變引數從printf的第3個引數開始。關於attribute的介紹可以參加這裡

所以,對於核心**中出現pr_err,pr_debug,pr_warning,pr_info都是列印資訊到終端。

第二種定義,關鍵是對fprintf的理解了。

fprintf(stderr, "can't open it!\n");

fprintf(stdout, "can't open it!\n");

stdout -- 標準輸出裝置 (printf("..")) 同 stdout。

stderr -- 標準錯誤輸出裝置

兩者預設向螢幕輸出。

但如果用轉向標準輸出到磁碟檔案,則可看出兩者區別。stdout輸出到磁碟檔案,stderr在螢幕。

也就是說兩者都是要向終端螢幕列印資訊的。

【總結】:pr_err pr_debug等呼叫時,都會列印到終端螢幕的,不管之前的語句是否發生錯誤。之所以有幾種定義,是為了**清晰。

Linux驅動開發之DRM驅動

qq群 852283276 b站 主頁 drm 驅動程式開發 開篇 drm 驅動程式開發 vkms 最簡單的drm應用程式 single buffer drm 驅動是如何建立 fb device 的 linux中的drm 介紹 linux graphic dri 顯示子系統 介紹1 xilinx d...

linux驅動開發之demo

linux版本 uname r 2.6.18 1.2798.fc6 編譯 進入模組 所在目錄 make c usr src kernels 2.6.18 1.2798.fc6 m pwd modules 載入 insmod test.ko 檢視主裝置號 自動分配為no 253 dmesg 建立裝置 ...

linux裝置驅動之PCIE驅動開發

pcie pci express 是intel提出的新一代的匯流排介面,目前普及的pcie 3.0的傳輸速率為8gt s,下一代pcie 4.0將翻番為16gt s,因為傳輸速率快廣泛應用於資料中心 雲計算 人工智慧 機器學習 視覺計算 顯示卡 儲存和網路等領域。pcie插槽是可以向下相容的,比如p...