驅動調試技巧點滴分享

2020-08-25 韋東山嵌入式Linux


本文轉載於網絡

引言

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

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

註:部分代碼分析舉例基於linux-4.15。

如何利用dts?

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

device { rst-gpio = <&gpioc_ctl 10 OF_GPIO_ACTIVE_LOW>; irq-gpio = <&gpioc_ctl 11 0>; interrupts-extended = <&vic 11 IRQF_TRIGGER_RISING>; };}

對於以上的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){ rst_gpio = of_get_named_gpio_flags(np, &34;, 0, &flags); if (flags & OF_GPIO_ACTIVE_LOW) { struct gpio_desc *desc; desc = gpio_to_desc(rst_gpio); set_bit(FLAG_ACTIVE_LOW, &desc->flags); } irq = of_irq_get(np, 0); trigger_type = irq_get_trigger_type(irq); request_threaded_irq(irq, NULL, irq_handler, trigger_type, &34;, NULL);}

驅動按照以上代碼實現的話,如果修改中斷觸發類型或者電平有效狀態只需要修改dts即可。例如不同的IC復位電平是不一樣的,有的IC是高電平復位,有的IC卻是低電平復位。其實這就是一個電平有效狀態的例子。

如何調試gpio?

移植驅動階段或者調試階段的工程中,難免想知道當前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);

在你的driver中調用以上api後,編譯下載。去/sys/class/gpio目錄看看有什麼發現。

如何調試irq?

調試的時候也難免會確定硬體是否產生中斷。我們該怎麼辦呢?也很easy。

cat /proc/interrupts

輸出信息不想多餘的介紹。看代碼去。根據輸出的irq num,假設是irq_num。請進入以下目錄。看看下面都有什麼文件。摸索這些文件可以為你調試帶來哪些方便。

cd /proc/irq/irq_num


dts和sysfs有什麼關聯 ?

曾經寫過一篇dts解析的文章http://www.wowotech.net/device_model/dt-code-file-struct-parse.html。最後一節其實說了一個很有意思的東西。但是僅僅是寥寥結尾。並沒有展開。因為他不關乎我寫的文章的的主題。但是,他卻和調試息息相關。

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有什麼用?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目錄即可。


如何確定device是否匹配了驅動?

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

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


如何排查driver的probe沒有執行問題?

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

  1. 通過sysfs確定對應的device是否註冊成功。
  2. 通過sysfs確定對應的driver是否註冊成功。
  3. 通過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的使用和原理。看看代碼實現。我始終堅信只有更好地掌握技術的原理才能更好地利用技術。

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

可以點擊「了解更多」與韋東山老師交流

相關焦點

  • 實用Javascript 調試技巧分享
    本文原載於SegmentFault專欄「半路出家老菜鳥」作者:MudOnTire整理編輯:SegmentFault見過太多同學調試Javascript只會用簡單的console.log甚至alert,看著真為他們捉急。因為大多數同學追求優雅而高效地寫代碼,卻忽略了如何優雅而高效地調試代碼,不得不說是有點「偏科」了。
  • 機器人放膜片的調試技巧分享
    最近公司有些用機器人放膜片的項目,調試的過程中出現了很多問題,有些東西跟想像的不一樣。項目背景:用機器人控制臂端具的吸盤,在上料臺上將膜片吸取,然後放入到注塑機模腔內。項目的動作流程和邏輯其實很簡單,主要就難在位置要求精準,而注塑機內的有些空間是看不到的,而且模具的模腔和臂端具都是不規則的,完全只能憑經驗去對位和調試。
  • Javascript之實用debug調試技巧分享
    見過太多同學調試Javascript只會用簡單的 console.log甚至 alert,看著真為他們捉雞。。因為大多數同學追求優雅而高效地寫代碼,卻忽略了如何優雅而高效地調試代碼,不得不說是有點「偏科」了。
  • 經驗分享:C++編程中的四個調試小技巧
    經驗分享:C++編程中的四個調試小技巧 本文介紹的是C++中的一些編程的小技巧,希望對你有幫助,一起來看。作者:佚名來源:網際網路|2011-07-12 13:41 下面介紹C++編程的四個小技巧
  • IDEA 調試技巧,比 Eclipse 強太多了
    ,斷點過去了,想回過頭看看剛才的變量值,如果不知道該技巧,只能再跑一遍。三、多線程調試多線程同時運行時,誰先執行,誰後執行,完全是看CPU心情的,無法控制先後,運行時可能沒什麼問題,但是調試時就比較麻煩了,最明顯的就是斷點亂跳,一會兒停這個線程,一會兒停在另一個線程,比如下圖:
  • 分享一個python調試程序BUG的技巧,有誰會不出BUG呢
    今天就分享一個調試python程序的小技巧:用input中斷程序用print輸出可疑的變量一:什麼情況下可疑調試學過Matlab的同學應該很容易理解我的意思,Matlab中有一個功能是專門用來調試程序的,可以讓程序在特定的位置中斷。
  • Visual Studio 調試技巧之即時窗口的妙用
    默認會在你啟動調試時在 VS 編輯器中彈出來。下面總結幾個即時窗口的實用技巧。然後在即時窗口編寫調用代碼,它會直接使用當前上下文進行調試。不需要中斷 VS 調試再重新啟動。直接列印是這樣的:結束本文分享的這幾個即時窗口的技巧,在調試時很實用,在工作中我經常使用,希望它也可以幫助你提高開發效率。
  • 關於Scrapy爬蟲項目運行和調試的小技巧(下篇)
    前幾天給大家分享了關於Scrapy爬蟲項目運行和調試的小技巧上篇,沒來得及上車的小夥伴可以戳超連結看一下。今天小編繼續沿著上篇的思路往下延伸,給大家分享更為實用的Scrapy項目調試技巧。
  • gdb實用的調試技巧:啟動方式、堆棧信息、單步調試
    對於很多開發者來說,開發過程中難免會遇到各種各樣的bug, 所以,每個開發者應該考慮如何快速高效定位問題原因,而gdb是linux上很實用的調試工具,熟練掌握其調試技巧,將有助於提高解決問題的效率,也是開發者應該掌握的基本技能。
  • gdb實用的調試技巧:啟動方式、堆棧信息、單步調試
    對於很多開發者來說,開發過程中難免會遇到各種各樣的bug, 所以,每個開發者應該考慮的如何快速高效定位問題原因,而gdb是linux上很實用的調試工具,熟練掌握其調試技巧,將有助於提高解決問題的效率,也是開發者應該掌握的基本技能。
  • IDEA 調試技巧,比 Eclipse 強太多了!
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫一、條件斷點循環中經常用到這個技巧,比如:遍歷1個大List的過程中,想讓斷點停在某個特定值。
  • 14個你可能不知道的JavaScript調試技巧
    以更快的速度和更高的效率來調試JavaScript。熟悉工具可以讓工具在工作中發揮出更大的作用。儘管江湖傳言 JavaScript 很難調試,但如果你掌握了幾個技巧,就能用很少的時間來解決錯誤和bug.文中已經列出了14個你可能不知道的調試技巧,但是可能需要你牢記在心,以便在下次需要調試JavaScript代碼時使用!1. debugger除了console.log, debugger是我們最喜歡、快速且骯髒的調試工具。執行代碼後,Chrome會在執行時自動停止。
  • IDEA調試技巧,簡直爽到爆
    調試,是每一個開發者必備的技能軟體調試技能是很好的區分程式設計師水平高低的一桿秤。下面為大家介紹幾個用起來爽到爆的調試技巧。0x01 條件斷點調試過程中,循環語句經常用到的一個技巧,比如:遍歷一個比較大的List的過程,想讓斷點停在某個特定值。如果你還停留在循環中間設置斷點,然後不停地下一步,下一步......那麼,請繼續看下去!
  • 從fail到pass,DDR調試到底經歷了什麼?
    因此對於我們高速先生來說,每一塊算力卡的DDR設計都是不同的,當然設計加工出來之後,我們和客戶配合著去調試的難度也是不一樣的。這一塊高速先生在近幾年的研討會上也和大家分享過一些經典的案例,讓大家對DDR的設計和調試難度都有了新的認識,AI產品的一些特點關於它的設計使得比以往任何產品的DDR難度都要大一點,當然我們也就會有很多測試和仿真的案例了。
  • WiFi驅動程序調試過程
    接下來面臨的問題是WiFi驅動程序問題,這也是本文的重點,以下是記錄的調試過程。 1. 對於校準完成的板子,依次加載ath9k_hw.ko,ath9k_common.ko,ath9k.ko,使用ifconfig -a命令,卻看不到wlan0網卡。 2.
  • 快速驅動調試之軸分配功能(840Dsl調試篇)
    上期中我們介紹了828D的軸分配功能,本期我們重點介紹一下新版本的840Dsl的軸分配和828D的區別,具體調試步驟如下:1.
  • 小程序之調試技巧
    有兩種辦法:真機調試:點擊真機調試,然後使用手機操作,同時在PC上彈出的窗口中觀察。手機上查看Console:在手機上查看Console有兩種方式,第一種適用於debug版本的小程序。點擊右上方的菜單按鈕,在彈出的頁面中點擊打開調試。
  • 你不知道的 Chrome 調試技巧,直接提升工作效率!
    這裡都是關於 Chrome DevTools 使用技巧的介紹,從不同的情景來說明,應該如何搭配使用 Chrome DevTools 中的小技巧,一個技巧可以幫我們節省很多的時間,直接提升工作效率!你會學到什麼?
  • 這些調試技巧都不會,不要說會VBA編程
    程序調試是編程過程的重要組成部分,程序調試可以讓我們修正程序的語法錯誤和邏輯錯誤,並能儘可能地減少程序中的bug。Excel的VBE也提供了豐富的調試工具,如斷點調試,立即窗口和監視窗口等。下面將介紹幾個常用的VBA編程調試技巧。
  • IntelliJ IDEA 2020的調試技巧,真的比eclipse強太多了
    一、條件斷點循環中經常用到這個技巧二、回到&34;該技巧最適合特別複雜的方法套方法的場景,好不容易跑起來,一不小心手一抖,斷點過去了,想回過頭看看剛才的變量值,如果不知道該技巧,只能再跑一遍。三、多線程調試多線程同時運行時,誰先執行,完全是看CPU行情的,無法控制先後,運行時可能沒什麼問題,但是調試時就比較麻煩了,最明顯的就是斷點亂跳,一會兒停這個線程,一會兒停在另一個線程