日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 嵌入式 > 嵌入式微處理器
[導(dǎo)讀]很多人在用 printf 函數(shù)進(jìn)行串口打印的時(shí)候,都會(huì)被告知需要重定向 fputc 函數(shù)(別的平臺(tái)可能不是這個(gè)函數(shù)),讓字符串?dāng)?shù)據(jù)輸出到指定串口,按照網(wǎng)上的教程也能很快解決。但是卻沒人告訴你為什么可以被重定向,為什么明明使用的是 printf 函數(shù),重定向的卻是

很多人在用 printf 函數(shù)進(jìn)行串口打印的時(shí)候,都會(huì)被告知需要重定向 fputc 函數(shù)(別的平臺(tái)可能不是這個(gè)函數(shù)),讓字符串?dāng)?shù)據(jù)輸出到指定串口,按照網(wǎng)上的教程也能很快解決。但是卻沒人告訴你為什么可以被重定向,為什么明明使用的是 printf 函數(shù),重定向的卻是 fputc 函數(shù)?

使用 51 的時(shí)候,我們也可以使用 printf 函數(shù),但是我們并沒有進(jìn)行重定向,也能使用,這又是為什么?

對(duì)于經(jīng)驗(yàn)豐富的人來說,這些問題心里應(yīng)該都有答案,但考慮到有一些道友可能并不了解,所以今天就稍微水那么一篇吧。

這些問題從大一到大三,一直困惑著魚鷹,直到魚鷹在代碼中看到這么個(gè)東西:

__attribute__((weak))  //  注意兩個(gè)括號(hào)

魚鷹一看,沒見過啊,不懂啊,所以魚鷹趕緊去網(wǎng)上查了一下,不查不要緊,一查嚇一跳,發(fā)現(xiàn) __attribute__ 這個(gè)東東了不得啊,很多C語言屬性都能修改,功能實(shí)在是太強(qiáng)大了,強(qiáng)大到魚鷹自認(rèn)為掌握得不錯(cuò)的C語言都還只是基礎(chǔ),也就只配在小白面前嘚瑟一下。

言歸正傳,為了突出重點(diǎn),今天只講 weak 屬性,以防分心。

我們都知道,函數(shù)名不可以重名,當(dāng)然不同文件內(nèi)聲明的 static 函數(shù)倒是可以解除該限制(可查看《C語言之static》)。

但是如果沒有使用 static ,那么編譯器就會(huì)給你報(bào)錯(cuò),告訴你函數(shù)名重復(fù)咯。

編譯器一共告訴你兩個(gè)信息:

1、重復(fù)的函數(shù)名是 func_name

2、重復(fù)的地方在 board.c 和 main.c 文件里面(后面 .o 表示目標(biāo)文件,由對(duì)應(yīng)的 .c 文件生成)

編譯器一發(fā)出這樣的信息,程序員很快就能找到問題并解決,所以看懂編譯信息很重要(如果有些編譯信息不常見,復(fù)制這條信息到網(wǎng)上一搜,一大堆文章就冒出來了)。

根據(jù)錯(cuò)誤信息,只要修改一處變量名,即可消除該錯(cuò)誤。

那么這個(gè)和printf重定向有什么關(guān)系?

我們知道,printf 最終會(huì)調(diào)用 fputc 進(jìn)行字符串輸出,但是這些函數(shù)是標(biāo)準(zhǔn)庫提供的,而標(biāo)準(zhǔn)庫沒有提供源碼給你,當(dāng)你需要用的時(shí)候添加 <stdio.h> 即可。

但是很多時(shí)候,fputc 輸出的位置可能需要改變,比如輸出到 LCD、串口1、串口2,我們總不可能去修改標(biāo)準(zhǔn)庫的源碼吧,但也沒有源碼提供啊,怎么才能在不修改源碼的情況下滿足這個(gè)需求呢?

方法是有的,比如你可以通過某個(gè)函數(shù)向printf中注冊(cè)一個(gè)回調(diào)函數(shù),讓printf調(diào)用這個(gè)回調(diào)函數(shù)進(jìn)行字符串輸出即可,但是標(biāo)準(zhǔn)庫并沒有提供這個(gè)東西,因?yàn)樗昧烁玫姆绞浇鉀Q這個(gè)問題。

那就是本文的主角,符號(hào)屬性弱化,weak。

假設(shè)我們拿到了標(biāo)準(zhǔn)庫的源碼,能清楚的看到實(shí)現(xiàn)原理,那么我們應(yīng)該能看到一個(gè)fputc的函數(shù)。然后你通過分析原理,發(fā)現(xiàn)它的輸出位置不是自己想要的,那么你會(huì)怎么做?

既然有源碼,好辦,直接修改fputc的實(shí)現(xiàn)即可,簡(jiǎn)單。

但現(xiàn)在沒有源碼,怎么辦?但你發(fā)現(xiàn)你在自己的文件里面直接實(shí)現(xiàn)fputc函數(shù)好像也沒事,為什么?就是因?yàn)闃?biāo)準(zhǔn)庫將fputc函數(shù)的屬性進(jìn)行了弱化,即:

這樣做有什么好處?

1、別人可以不需要給你源碼

2、即使沒有源碼,也能間接的達(dá)到修改源碼的目的

3、即使有源碼,通過該屬性設(shè)置,也不需要?jiǎng)h除別人的代碼去重新實(shí)現(xiàn),可以保留原來的代碼。

4、不需要使用回調(diào)函數(shù)的方式進(jìn)行注冊(cè),可以直接重新實(shí)現(xiàn)該函數(shù),非常簡(jiǎn)單

5、存在一個(gè)默認(rèn)函數(shù)實(shí)現(xiàn),如果說你不想重新實(shí)現(xiàn)函數(shù),那么編譯器就會(huì)使用該函數(shù)進(jìn)行編譯、鏈接,而不會(huì)在編譯時(shí)出現(xiàn)錯(cuò)誤或警告(這就是為什么即使你沒有重新寫一個(gè)fputc,編譯也不會(huì)報(bào)錯(cuò)的原因)

當(dāng)然,第五點(diǎn),既是好處也是壞處,因?yàn)榫幾g器沒有提示,你就不知道你到底有沒有重新實(shí)現(xiàn)函數(shù)了。

其實(shí)要查看編譯器鏈接的到底是哪一個(gè)函數(shù)很簡(jiǎn)單,打開map文件(關(guān)注了這么久,怎么打開的就不多說了),搜索對(duì)應(yīng)的函數(shù)名即可:

你會(huì)發(fā)現(xiàn),雖然 main.c 文件中雖然也有一個(gè) func_name 函數(shù),但實(shí)際上,編譯器鏈接的是 board.c 文件的,原因就是因?yàn)?main.c 文件的 func_name 函數(shù)屬性被弱化了。

這樣一來,即使函數(shù) func_name 在 main() 函數(shù)中被調(diào)用,但它沒有使用本文件的func_name,而是調(diào)用了 board.c 文件中的函數(shù)。

但你將 board.c 文件中的函數(shù)刪掉后,編譯后并不會(huì)出現(xiàn)錯(cuò)誤,并且會(huì)發(fā)現(xiàn) main() 調(diào)用的函數(shù)變成了 main.c 文件中的函數(shù)。

就是這么奇妙!

事實(shí)上,這個(gè)屬性弱化不僅僅在 printf 函數(shù)中體現(xiàn)了,在中斷處理函數(shù)中也做了這樣的處理,只不過這是匯編方式:

這就是為什么你可以在任何文件內(nèi)寫中斷處理函數(shù),而即使你沒有寫中斷處理函數(shù),編譯器也不會(huì)報(bào)錯(cuò)的原因!

當(dāng)然了,這種屬性設(shè)置雖然可以保證不同文件的函數(shù)名可以相同(同一個(gè)文件的函數(shù)名還是不可以相同),但是最終只有一個(gè)函數(shù)會(huì)被編譯器所鏈接!

哦,對(duì)了,如果你要實(shí)現(xiàn)多個(gè)不同的串口打印輸出,不如使用 vsprintf(建議 vsnprintf),好處就是這個(gè)函數(shù)的輸出位置不是fputc,而是你給定的緩存空間,這樣你就可以實(shí)現(xiàn)自己的printf函數(shù)了。

來源:公眾號(hào)【魚鷹談單片機(jī)】

作者:魚鷹Osprey

ID   :emOsprey

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!

嵌入式ARM

掃描二維碼,關(guān)注更多精彩內(nèi)容

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動(dòng)電源

在工業(yè)自動(dòng)化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動(dòng)力設(shè)備,其驅(qū)動(dòng)電源的性能直接關(guān)系到整個(gè)系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動(dòng)勢(shì)抑制與過流保護(hù)是驅(qū)動(dòng)電源設(shè)計(jì)中至關(guān)重要的兩個(gè)環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動(dòng)性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動(dòng)電源

LED 驅(qū)動(dòng)電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個(gè)照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動(dòng)電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動(dòng)電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動(dòng)電源的公式,電感內(nèi)電流波動(dòng)大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動(dòng)電源

電動(dòng)汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動(dòng)汽車的核心技術(shù)之一是電機(jī)驅(qū)動(dòng)控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動(dòng)系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動(dòng)汽車的動(dòng)力性能和...

關(guān)鍵字: 電動(dòng)汽車 新能源 驅(qū)動(dòng)電源

在現(xiàn)代城市建設(shè)中,街道及停車場(chǎng)照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢(shì)逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動(dòng)電源 LED

LED通用照明設(shè)計(jì)工程師會(huì)遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動(dòng)電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動(dòng)電源的電磁干擾(EMI)問題成為了一個(gè)不可忽視的挑戰(zhàn)。電磁干擾不僅會(huì)影響LED燈具的正常工作,還可能對(duì)周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動(dòng)電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動(dòng)電源

關(guān)鍵字: LED 驅(qū)動(dòng)電源 開關(guān)電源

LED驅(qū)動(dòng)電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動(dòng)LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動(dòng)電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動(dòng)電源
關(guān)閉