qdebug 除錯 輸出亂碼 驅動除錯技巧點滴分享

2021-10-12 18:39:33 字數 3968 閱讀 3777

作為乙個算是合格的驅動工程師,總是有很多話想說。**看的多了總是有些小感悟。可能是吧。那就總結一下自己看的**的一些感悟和技巧。如何利用你看的這些**?如何體現在工作的除錯中?

作為驅動工程師,主要的工作就是移植各種驅動,接觸各種硬體。接觸最多的就是dts、中斷、gpio、sysfs、proc fs。如何利用sysfs、proc fs及核心提供的介面為我們降低除錯難度,快速解決問題呢?

注:部分**分析舉例基於linux-4.15。

如何利用dts?首先我們關注的主要是兩點,gpio和irq。其他的選擇忽略。先展示一下我期望的gpio和irq的使用方法。dts如下:

device ;}
對於以上的dts你應該再熟悉不過,當然這裡不是教你如何使用dts,而是關注gpio和irq最後乙個數字可以如何利用。

例如rst-gpio的of_gpio_active_low代表什麼意思呢?可以理解為低有效。什麼意思呢?舉個例子,正常情況下,我們需要乙個gpio口控制燈,我們認為燈開啟就是active狀態。

對於乙個程式設計師來說,我們可以封裝乙個函式,寫1就是開啟燈,寫0就是關燈。但是對於硬體來說,變化的是gpio口的電平狀態。如果gpio輸出高電平燈亮,那麼這就是高有效。如果硬體設計是gpio輸出低電平燈亮,那麼就是低有效。對於乙個軟體工程師來說,我們的期望是寫1就是亮燈,寫0就是關燈。

我可不管硬體工程師是怎麼設計的。我們可以認為dts是描述具體的硬體。因此對於驅動來說,硬體的這種變化,只需要修改dts即可。軟體不用任何修改。軟體可以如下實現:

int device_probe(struct platform_device *pdev)    irq = of_irq_get(np, 0);    trigger_type = irq_get_trigger_type(irq);    request_threaded_irq(irq, null, irq_handler, trigger_type, "irq", null);}
驅動按照以上**實現的話,如果修改中斷觸發型別或者電平有效狀態只需要修改dts即可。例如不同的ic復位電平是不一樣的,有的ic是高電平復位,有的ic卻是低電平復位。其實這就是乙個電平有效狀態的例子。

移植驅動階段或者除錯階段的工程中,難免想知道當前gpio的電平狀態。當然很easy。萬用表戳上去不就行了。是啊!硬體工程師的思維。作為軟體工程師自然是要軟體的方法。下面介紹兩個api介面。自己摸索使用吧。點到為止。

static inline int gpio_export(unsigned gpio, bool direction_may_change);static inline int gpio_export_link(struct device *dev, const char *name, unsigned gpio);
除錯的時候也難免會確定硬體是否產生中斷。我們該怎麼辦呢?也很easy。

cat /proc/interrupts
輸出資訊不想多餘的介紹。看**去。根據輸出的irq num,假設是irq_num。請進入以下目錄。看看下面都有什麼檔案。摸索這些檔案可以為你除錯帶來哪些方便。

曾經寫過一篇dts解析的文章最後一節其實說了乙個很有意思的東西。但是僅僅是寥寥結尾。並沒有展開。因為他不關乎我寫的文章的的主題。但是,他卻和除錯息息相關。

cd /sys/firmware/devicetree/base
該目錄的資訊就是整個dts。將整個dts的節點以及屬性全部展現在sysfs中。他對我們的除錯有什麼用呢?let me tell you。如果你的專案非常的複雜,例如一套**相容多種硬體配置。這些硬體配置的差異資訊主要是依靠dts進行區分。當編譯kernel的時候,你發現你很難確定就是你用的是哪個dts。可能你就會憑藉自己多年的工作經驗去猜測。

是的,你的經驗很厲害。但是,如何確定你的dts資訊是否新增到kernel使用的dts呢?我覺得你應該got it。就到這個目錄去查詢是否包含你新增的ndoe和property。dts中有status屬性可以設定某個devicec是否使能。當你發現你的driver的probe沒有執行的時候,我覺得你就需要確定一遍status是不是「ok」、「okay」或者沒有這個屬性。

遠不止我所說的這個功能,還可以判斷當前的硬體是匹配哪個dts檔案。你還不去探索一波原始碼的設計與實現嗎?節點為什麼出現在某些目錄?為什麼有些節點的屬性cat卻是亂碼?就是亂碼,你沒看錯。至於為什麼。點到為止。

sysfs有什麼用?sysfs可以看出device是否註冊成功、存在哪些device、driver是否註冊、device和driver是都匹配、device匹配的driver是哪個等等。先說第一項技能。deivce是否註冊。

就以i2c裝置為例說明。/sys/bus/i2c/devices該目錄下面全是i2c匯流排下面的devices。如何確定自己的device是否註冊呢?首先你需要確定自己的device掛接的匯流排是哪個i2c(i2c0, i2c1…)。假設裝置掛接i2c3,從位址假設0x55。那麼devices目錄只需要檢視是否有3-0055目錄即可。

進入3-0055目錄,其實你可以看到driver的符號鏈結。如果沒有,那麼就是沒有driver。driver是否註冊如何確定呢?方法類似。/sys/bus/i2c/drivers目錄就是所有註冊的i2c driver。方法如上。不再列舉。

你以為就這些簡單的功能了嗎?其實不是,還有很多待你**。主要是各種目錄之間的關係,device註冊會出現什麼目錄?那麼driver呢?各種符號鏈結會在哪些目錄?等等。

我想這類問題是移植過程中極容易出現的第乙個攔路虎。這裡需要宣告一點。可能有些驅動工程師認為probe沒有執行就是driver沒有註冊成功。其實這兩個沒有半毛錢關係。probe是否執行只和device和driver的是否匹配成功有關。我們有什麼思路排查這類問題呢?主要排查方法可以如下。

通過sysfs確定對應的device是否註冊成功。

通過sysfs確定對應的driver是否註冊成功。

通過sysfs中dts的展開資訊得到compatible屬性的值,然後和driver的compatible進行對比。

如果發現device沒有註冊,如何確定問題。首先通過sysfs中dts展開檔案檢視是否有你新增的device資訊。如果沒有的話,沒有device註冊就是正常的,去找到正確的dts新增正確的device資訊。如果發現sysfs有device的dts資訊。那麼就看看status屬性的值是不是ok的。

如果也是ok的。那麼就非常奇怪了。這種情況一般出現在kernel的device註冊路徑出錯了。曾經就有乙個小夥伴提出問題,現象就是這樣。最後我幫他確定問題原因是dts章reg屬性的位址是0xc0。這是乙個大於0x7f的值。在i2c匯流排註冊驅動的時候會解析當前匯流排下的所有device。然後註冊所有的從裝置。就是這裡的位址檢查出了問題,因此這個device沒有註冊上。

如果發現driver沒有註冊,那麼去看看對應的makefile是否參與編譯。如果參與了編譯,就檢視log資訊,是不是驅動註冊的時候有錯誤資訊。

最後一點的compatible屬性的值只需要cat一下,然後compare即可, 不多說。

sysfs還有很多的其他的除錯資訊可以檢視。因此,我建議驅動工程師都應該掌握sysfs的使用和原理。看看**實現。我始終堅信只有更好地掌握技術的原理才能更好地利用技術。

文章內容不想展開。我告訴你的結果,你永遠記憶不深刻,而且我說的也不一定對。還是需要自己專研。我只是給你指條明路,剩下的就需要自己去走。最後說一句,**不會騙你,還會告訴你別人不能告訴你的。

-完-

驅動除錯技巧點滴分享

引言 作為乙個算是合格的驅動工程師,總是有很多話想說。看的多了總是有些小感悟。可能是吧。那就總結一下自己看的 的一些感悟和技巧。如何利用你看的這些 如何體現在工作的除錯中?作為驅動工程師,主要的工作就是移植各種驅動,接觸各種硬體。接觸最多的就是dts 中斷 gpio sysfs proc fs。如何...

驅動除錯技巧點滴分享

作為乙個算是合格的驅動工程師,總是有很多話想說。看的多了總是有些小感悟。可能是吧。那就總結一下自己看的 的一些感悟和技巧。如何利用你看的這些 如何體現在工作的除錯中?作為驅動工程師,主要的工作就是移植各種驅動,接觸各種硬體。接觸最多的就是dts 中斷 gpio sysfs proc fs。如何利用s...

輸出除錯資訊qDebug的應用

1 基本語法 qdebug 1111111111111111 int i 0 qstring s ss bool bl true qdebug 1111111111111111 d,s,d i,s,bl 布林型輸出的是0或1 在字元介面上執行程式時,會將資訊直接輸出到介面上。2 可以在正式執行時禁止...