printk("Hello world!A string:%s and an integer:%d\n",a_string,an_integer);
printk()和printf()之間的一個顯著區別在於printk()允許通過指定一個標誌來設置優先級。syslog會根據這個優先級標 志來決定在什麼地方顯示這條系統信息。下面是一個使用這種優先級標誌的例子:
printk(KERN_ERR "this is an error!\n");
printk()函數是直接使用了向終端寫函數tty_write()。而printf()函數是調用write()系統調用函數向標準輸出設備寫。所以 在用戶態(如進程0)不能夠直接使用printk()函數,而在內核態由於他已是特權級,所以無需系統調用來改變特權級,因而能夠直接使用 printk()函數。
printf是使用了標準的C庫函數的時候才能使用的,而內核中無法使用標準的C庫函數,所以就連最常見的printf都不能使用。
例如子printk函數的字符串參數中使用了KERN_ALERT,它實際上擴展爲字符串:“<1>”,而這部分信息沒有輸出到終端。實際上,這部分是內核信息的日誌級別,只有超過了當前日誌級別的信息纔會輸出到終端。當前內核的日誌級別可以在/proc/sys/kernel/printk文件中看到。這個文件包含了四個整數,其中前兩個是控制檯的當前日誌級別和默認日誌級別。我們在printk的參數中使用較高的日誌級別就是要保證信息得到輸出。在<linux/kernel.h>頭文件裏一共定義了8個級別(0-7)的輸出,從高到低分別由如下常量表示:
KERN_EMERG : 最高級別,一般只用來打印崩潰信息
KERN_ALERT : 需要立即處理的信息
KERN_CRIT : 關鍵信息,一般用來顯示嚴重的硬件和軟件錯誤
KERN_ERR : 用來顯示硬件錯誤
KERN_WARNING : 顯示不會造成嚴重錯誤的警告信息
KERN_NOTICE : 顯示需要引起注意的信息
KERN_INFO : 顯示一般信息,例如驅動所發現的硬件列表
KERN_DEBUG : 用來顯示調試信息
printk與printf的一個區別printk是“行驅動”的,也就是說只有收到一個換行符數據纔會真正輸出到終端,否則就不會有任何信息輸出。
另一個值得注意的問題是我們在調試嵌入式設備的時候,經常是從串口獲得顯示信息,如果我們使用printk過於頻繁的話,串口的傳輸速度就會成爲瓶頸,這樣會造成系統的性能下降甚至停止反應。