第10章 嵌入式linux的调试技术
一、????? 防止函數printk降低linux性能:
利用C語言中的編譯指令(#if、#else、#endif等)。
現在修改printk_demo驅動代碼,通過編譯指令定義了一個pr_debug宏,并通過修改編譯指令的條件值來控制是否調用printk函數。如下:
# if 1//此處為1,使用printk函數,為0,忽略printk函數
? #define pr_debug(x,…)? do { } while(0)
#endif
除此之外,我們還需要了解兩個知識點:1.可變參數的宏:可變參數的宏與固定參數的宏之間的區別:可變參數的宏需要通過_VA_ARGS_宏【不支持可變參數個數為0的情況】獲取可變參數的宏的可變參數。定義可變參數宏與定義可變參數函數的方法相同,都使用3個點(…)來表示可變參數,可變參數必須是宏和函數最后的參數。
二、????? 通過虛擬文件系統(/proc)進行數據交互:
必要性:在linux文件系統中,/proc經常被用來作為內核空間進行數據交互的工具。/proc是虛擬文件系統,也就是說,/proc并不是真正的文件系統,而是內存映射。所有讀寫/proc的操作軍事對內存讀寫的操作。所以讀寫/proc文件系統的速度遠比讀寫/dev要快。因此,/proc文件系統也可作為linux驅動與用戶空間程序交互的工具。
很多信息就是通過/proc文件系統由內核空間的程序向外屆提供的。例如:當前系統內存資源就是通過/proc/meminfo文件讀取的,讀者可以使用如下命令:查看/proc/meminfo文件的內容:Cat /proc/meminfo.我們可以通過執行free命令看看顯示的信息是否和meminfo文件中的部分內容相匹配。
在linux驅動程序中可以使用內核函數在/proc目錄中創建和刪除虛擬文件,也可以建立和刪除虛擬目錄。
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,struct proc_dir_entry *parent);
name:?要創建的文件名稱;
mode:?該文件的保護掩碼;
parent:?確定文件所在目錄,如果置NULL?,則位置為/proc?下。
/*?該函數在父目錄parent?下創建一個目錄name* */
struct proc_dir_entry * proc_mkdir (const char *name,struct proc_dir_entry *parent);
@name :?要創建的目錄名
@parent :?這個目錄的父目錄
3.remove_proc_entry 刪除文件或目錄
/*?這個函數從proc?文件系統中刪除一個文件或目錄。
*?注意:1?.是通過參數name?,而不是通過創建時返回的指針來刪除的。
* 2?.該函數不會遞歸刪除目錄下的文件。
* 3?.data?變量保存了分配的內存,要先釋放對應內存,再刪除該文件。
* */
void remove_proc_entry (const char *name,struct proc_dir_entry *parent);
@name :?要刪除的文件或目錄名
@parent :?所在的父目錄?
?4.create_proc_read_entry?創建只讀proc?文件
struct proc_dir_entry * create_proc_read_entry (const char
*name,mode_t mode,struct proc_dir_entry *parent,read_proc_t*
read_proc,void *data);
@name :?要創建的文件名
@mode :?要創建的文件的屬性 默認0755
@parent :?這個文件的父目錄
@read_proc :?當用戶讀這個文件時,內核調用的函數
@data :?傳給read_proc?的參數
注意:刪除虛擬文件目錄之前,要先刪除目錄中的虛擬文件。
執行build.sh腳本文件,會將proc_demo驅動安裝在Ubuntu Linux、開發板或Android虛擬機上。然后執行下面的命令查看/proc/proc_demo目錄中的內容。
Ls –al /proc/proc_demo/bin2dec
Cat /proc/proc_demo/bin2dec
Cat /proc_demo/readonly
三、????? 調試工具:
Gdb可以跟蹤調試用戶空間的程序。
對于一個用于測試的可執行程序(gdb_debug.c),我們可以直接運行build.sh腳本文件,但注意加上命令參數-g,完整的編譯命令如下:
#gcc –static –g –o gdb_debug /root/drivers/debug/gdb_debug.c
現在使用下面的命令來調試:
Gdb gdb_debug
Gdb包含的命令:
1>???????? quit:用于退出gdb調試界面
2>???????? ?list:用于列出程序中的代碼。有三種調用格式:list:顯示上一次調用list命令輸出的最后一行后面的10行。 list-: 顯示上一次調用list命令輸出的第一行前面的10行,第一次調用list命令什么都不會顯示。list n:顯示第n行附近的10行,一般會顯示第n行前面5 行和后面4行,加上第n行,正好是10行。
3>???????? Break n:將指定行設置為斷點,n表示行號
4>???????? Clear n:清除指定行的斷點。
5>???????? Tbreak n:將指定行設置為斷點,斷點只能使用一次,使用完成后自動清零。
6>???????? Cont/continue:跳過當前斷點繼續執行。[cont:跳過當前斷點繼續執行;cont n:跳過n次斷點繼續前行]
7>???????? Next:繼續執行下面的語句,但跳過這程序。等價于step over。[同上有兩種格式next 及next n]
8>???????? Nexti:單步執行語句,和next的區別:它會跟蹤到子程序的內部,但不打印出子程序內部的語句。
9>???????? Print var_name:查看變量值.
1.與GDB的區別:gdb用于PC上進行測試,而gdbserver測試運行于開發板、手機、Android模擬器上。
2.在開發板上使用gdbserver打開測試程序,然后通過串口、有線、無線網絡可以在PC上進行測試。
3.第一步:進入Android模擬器的終端,然后進入data/local目錄,并執行如下命令:gdbserver :4321 ./gdb_debug啟動gdbserver監聽程序。其中4321表示使用本機的4321端口號進行監聽。
? 第二步:開啟另一個Linux終端,將外部訪問模擬器的4321端口的數據包轉發到Android模擬器內部的4321端口:adb –s emulator-5544 forword tcp:4321[有多個Android設備時要加-s命令行參數指定具體的Android設備]。
第二個方法[映射端口]:1.進入telent:telent localhost 5554 2.映射端口:redir add tcp:4321:4321
第三步:進入gdb控制臺:arm-none-linux-guneabi-gdb gdb_debug
第四步:連接Android模擬器:(gdb) target remote localhost:4321
??????????? 最后:輸入gdb命令進行調試。
??????? 通過IP方式連接開發板上的gdbserver:1.gdbserver localhost:4321 ./gdb_debug? 2.在linux終端的gdb控制臺鏈接開發板的gdbsrever:(gdb) target remote 192.168.17.103 ./gdb_debug.
??????? 通過串口方式:對應的應該是:1.gdbserver /dev/s3c2410_serial0 ./gdb_debug? 2.(gdb) target remote /dev/ttyUSB0
Kgdb除了提供類似printk函數的日志輸出功能,還允許開發人員直接在PC上通過GDB鏈接目標設備。
Kgdb包含兩個部分:kgdb內核和一套鏈接接口【目前支持串口tty設備鏈接和以太網連接】。其中串口連接需要通過內核參數kgdboc指定要鏈接的串口tty設備:以太網連接通過內核參數kgdboc指定IP和端口號。
要想用kgdb調試內核,首先需要配置linux內核。使用make menuconfig命令進入Linux內核的配置菜單。【Kernel hacking--àKGDB:kernel debugger】
???? 配置內核參數時,這些參數通知Linux內核要如何進行調試。假設要通過USB轉COM口數據線進行調試,需要將kgdboc參數值折為ttyUSB0,傳輸效率為115200,一般會指定kdbwait。這些參數需要在S3C開發板過程中按回車進入Uboot模式,然后使用setenv命令設置Linux內核的啟動參數,然后使用saveenv和rest命令保存和重新啟動Linux內核。
在設置完成后,主機就可以使用gdb命令像調試普通嵌入式應用程序一樣調試Linux內核,執行的命令如下:
#gdb? ./vmlinux
完成后,使用如下的命令設置傳輸速率和連接也要調試的Linux內核。
(gdb) set remoteband 115200
(gdb) target remote /dev/ttyUSB0
最后使用各種gdb命令進行Linux內核調試。
?
轉載于:https://www.cnblogs.com/beatrice/p/5656055.html
總結
以上是生活随笔為你收集整理的第10章 嵌入式linux的调试技术的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 闲暇处才是生活
- 下一篇: C#正则表达式提取文本中以逗号间隔的数据