日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

看printk引发的一点思考

發(fā)布時(shí)間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 看printk引发的一点思考 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在源碼位置

kernel/printk/

函數(shù)原型

asmlinkage?__visible?int?printk(const?char?*fmt,?...) {printk_func_t?vprintk_func;va_list?args;int?r;va_start(args,?fmt);/**?If?a?caller?overrides?the?per_cpu?printk_func,?then?it?needs*?to?disable?preemption?when?calling?printk().?Otherwise*?the?printk_func?should?be?set?to?the?default.?No?need?to*?disable?preemption?here.*/vprintk_func?=?this_cpu_read(printk_func);r?=?vprintk_func(fmt,?args);va_end(args);return?r; } EXPORT_SYMBOL(printk);

fmt,...用法舉個(gè)例子

#include?"stdio.h"void?tfunc(const?int?fmt,...) {printf("tfunc...\n"); }?int?main(void) {tfunc(12);tfunc(12,13);tfunc(12,13,14);return?0; }?

輸出

tfunc... tfunc... tfunc...-------------------------------- Process?exited?after?0.04347?seconds?with?return?value?0 請(qǐng)按任意鍵繼續(xù).?.?.

再舉個(gè)例子

#include?<stdlib.h> #include?<stdio.h> #include?<stdarg.h> int?maxof(int,?...); void?f(void);/*主函數(shù)*/ int?main() {f();exit(EXIT_SUCCESS); }int?maxof(int?n_args,?...) {register?int?i;int?max=0,?a=0;va_list?ap;va_start(ap,?n_args);max?=?va_arg(ap,?int);printf("max:%d?a:%d?n_args:%d\n",max,a,n_args);for(i?=?1;?i?<?n_args;?i++){if((a?=?va_arg(ap,?int))?>?max){max?=?a;}printf("[%d]?max:%d?a:%d\n",i,max,a);}va_end(ap);return?max; }void?f(void)? {int?i?=?5;int?j?=?26;printf("\nmax:%d\n",maxof(3,i,j,13)); }

輸出

max:5?a:0?n_args:3 [1]?max:26?a:26 [2]?max:26?a:13max:26-------------------------------- Process?exited?after?0.0439?seconds?with?return?value?0 請(qǐng)按任意鍵繼續(xù).?.?.

說(shuō)點(diǎn)自己的理解

作為初學(xué)者,第一次看到

fmt,...

這樣的寫(xiě)法,心里就會(huì)有點(diǎn)懵逼,但是實(shí)際上,你把它作為C語(yǔ)言的一個(gè)知識(shí)點(diǎn),記下來(lái)了,就沒(méi)有那么困難了。既然作為可變參數(shù)標(biāo)識(shí),那么函數(shù)體里面,自然也需要解析的方法,我上面寫(xiě)的那個(gè)例子,就是解析的方法。

不管是Linux 內(nèi)核里面的printk函數(shù),還是我們平時(shí)調(diào)試打印的printf函數(shù),他們都是一樣的原理。

解析可變參數(shù)

解析就離不開(kāi)這三個(gè)宏

va_list?ap; va_start(ap,?n_args); va_end(ap);

這里面需要涉及到一些技巧,這篇文章里面就不解析說(shuō)明了,printf 和printk里面使用的還有些差異,無(wú)非就是C語(yǔ)言的奇淫異巧,把這種普通人理解不了的東西形容為降龍十八掌,九陰真經(jīng),我覺(jué)得并不為過(guò)。

Linux 驅(qū)動(dòng)打印日志加上自己的TAG

好了,直接上代碼就好了,我們平時(shí)打印的時(shí)候都是直接用一個(gè)printk,也沒(méi)有經(jīng)過(guò)封裝,代碼這種東西,你要是把它看作是一個(gè)藝術(shù)品也并不為過(guò),所以很多人談到一個(gè)詞,叫做技藝,你自己把這種知識(shí)點(diǎn)都掌握了,自己的技藝也就會(huì)得到提升了。

#define?LOG_TAG?"[ES7243]:?%s()?line:?%d?"? #define?Log(fmt,?args...)??printk(KERN_INFO?LOG_TAG?fmt,?__FUNCTION__,?__LINE__,??##args)

## 這個(gè)符號(hào)的作用

在C語(yǔ)言里面,## 有兩個(gè)作用

  • 在函數(shù)里面和可變參數(shù)一起使用,如果可變參數(shù)沒(méi)有傳參,這個(gè)符號(hào)就把前面的 「,」去掉,這樣編譯就不會(huì)出錯(cuò)。

  • 如果是宏里面使用,就起到一個(gè)拼接字符的作用

舉個(gè)例子

#include<stdio.h>#define?LOG_TAG?"[ES7243]:?%s()?line:?%d?"? #define?func(fmt,?...)?printf(LOG_TAG?fmt,?__FUNCTION__,?__LINE__,??##__VA_ARGS__) #define?acpi_handle_debug(?fmt,?...)?printf(?fmt,?##__VA_ARGS__) #define?debug(...)?printf(__VA_ARGS__)#define?_TEST_(x)?x##2 int?main() {int?i?=?23;func("adf:%d\n",++i);debug("123:%d\n",++i);acpi_handle_debug("4444\n");func("%d\n",_TEST_(1));return?(0); }

輸出

[ES7243]:?main()?line:?12?adf:24 123:25 4444 [ES7243]:?main()?line:?16?12-------------------------------- Process?exited?after?0.03505?seconds?with?return?value?0 請(qǐng)按任意鍵繼續(xù).?.?.

推薦閱讀:

專輯|Linux文章匯總

專輯|程序人生

專輯|C語(yǔ)言

嵌入式Linux

微信掃描二維碼,關(guān)注我的公眾號(hào)

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的看printk引发的一点思考的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。