99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

嵌入式系統(tǒng)簡(jiǎn)易版本的printf滿足自己的需要

電子設(shè)計(jì) ? 來(lái)源:博客園 ? 作者:佚名 ? 2020-09-03 17:37 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

嵌入式中,調(diào)試手段通常有兩種,一是遠(yuǎn)程gdb,一是直接printf。如果是調(diào)試自己玩的小板子,用gdb有點(diǎn)大張旗鼓了,大多數(shù)情況下printf就可以搞定。不過(guò)printf的問(wèn)題是stdiolib的size太大,稍微有點(diǎn)程序,加上幾個(gè)常用的庫(kù),比如stdio和string,超過(guò)16k甚至32k(已經(jīng)大于一些低端芯片的flash容量了)是很正常的事情,而且通常比較慢,程序越多,越麻煩。道理很簡(jiǎn)單,標(biāo)準(zhǔn)C語(yǔ)言庫(kù)的規(guī)范中,Printf()必須處理大量的數(shù)據(jù)格式,包括字符串、字符、(各種長(zhǎng)度的有符號(hào)和無(wú)符號(hào))數(shù)字,以及浮點(diǎn)值。而且格式字符串還要包括用于更改文本對(duì)齊、基數(shù)、間距、字段寬度和精度的調(diào)節(jié)器和指示器。符合這個(gè)規(guī)范的代碼必然會(huì)是冗長(zhǎng)和繁重的。一些嵌入式系統(tǒng)庫(kù)倒是提供了一些之針對(duì)整數(shù)的printf,但還是有問(wèn)題,首先是還是太大,其次是你沒(méi)有自己的調(diào)整權(quán)限。

其實(shí)printf也就是IO的調(diào)用包裝而已,我們完全可以自己寫一個(gè)簡(jiǎn)易版本的printf滿足自己的需要,并隨時(shí)根據(jù)需要裁剪。具體來(lái)說(shuō),printf在這里要起的作用就是將調(diào)試字符串從嵌入式目標(biāo)空閑的串口壓出,并在運(yùn)行于宿主工作站的終端模擬器上顯示結(jié)果。下面就簡(jiǎn)單介紹一下,如何來(lái)自己寫一個(gè)簡(jiǎn)易printf函數(shù)。

要寫printf,首先要知道什么是可變參數(shù)傳遞,我們來(lái)看看標(biāo)準(zhǔn)庫(kù)里面,是如何定義可變參數(shù)實(shí)現(xiàn)的:

#define _AUPBND (sizeof (acpi_native_int) - 1)

#define _ADNBND (sizeof (acpi_native_int) - 1)

#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd)))

#define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T,_AUPBND))) - (_bnd (T,_ADNBND))))

#define va_end(ap) (void) 0

#define va_start(ap, A) (void) ((ap) = (((char *) &(A)) +(_bnd(A,_AUPBND))))

關(guān)于可變參數(shù)的原理,網(wǎng)上有一些文章,總結(jié)來(lái)說(shuō),就是我們可以通過(guò)Intel80×86機(jī)器的對(duì)齊特性來(lái)獲得所有的參數(shù),因?yàn)樵贗ntel80×86機(jī)器上,每個(gè)變量的地址都要是sizeof(int)的倍數(shù),這樣能提升CPU運(yùn)行的效率。也就是說(shuō),所有參數(shù)的首地址都要是4的倍數(shù),就算你是char型的,那浪費(fèi)3個(gè)byte也要安排你占第四個(gè)坑。

好,由于C語(yǔ)言傳遞參數(shù)時(shí)是用push指令從右到左將參數(shù)逐個(gè)壓棧,因此我們通過(guò)棧指針跳4n格來(lái)訪問(wèn)第n個(gè)參數(shù),不要忘了,參數(shù)的地址都是字對(duì)齊的。這里,我們用#define _bnd(X, bnd) (((sizeof (X)) + (bnd)) &(~(bnd)))來(lái)計(jì)算類型為X的參數(shù)在棧中占據(jù)的字對(duì)齊后的字節(jié)數(shù)。bnd是sizeof (acpi_native_int) –1,acpi_native_unit在32位機(jī)的定義是:

typedef u32 acpi_native_uint;

所以( ~(bnd))就是0xfffffffc 。 因此,_bnd(X,bnd) 宏在32位機(jī)下就是

( (sizeof(X) + 3)&0xfffffffc )

很明顯,其作用是–倘若sizeof(X)不是4的整數(shù)倍,將其變?yōu)?的整數(shù)倍。

va_start(ap,A) 負(fù)責(zé)初始化參數(shù)指針ap,將函數(shù)參數(shù)A右邊第一個(gè)參數(shù)的地址賦給ap,這個(gè)第一個(gè)參數(shù)通常就是printf里面的”%x%d%f%d”。

va_arg(ap,T) 可以獲得ap指向參數(shù)的值,并使ap指向下一個(gè)參數(shù),T用來(lái)指明當(dāng)前參數(shù)類型。

在這里,上述代碼還是麻煩,而且sizeof我們也不能直接用,所以我們不如干脆直接寫一個(gè)不那么麻煩而有針對(duì)性的可變參數(shù)操作定義:

有了這幾個(gè)定義,print函數(shù)就好寫了,為了節(jié)省空間,這個(gè)簡(jiǎn)單的print()只支持“%s”,“%d”和”%c”格式的分類符,暫時(shí)不需要其他功能,比如格式對(duì)齊之類的,當(dāng)然,可以根據(jù)自己的需要擴(kuò)展這個(gè)函數(shù)。

int print( const char *fmt, 。.. )

{

const char *s;

char c;

int d;

va_list ap;

va_start(ap, fmt);

while( *fmt != ‘\0’ )

{

if( *fmt != ‘%’ )

{

uart_putc(*fmt++);

continue;

}

switch(*++fmt)

{

case ‘s’:

{

s = va_arg(ap, const char *);

uart_puts(s);

break;

}

case ‘d’:

{

d = va_arg(ap, int);

uart_putints(d, 10);

break;

}

case ‘c’:

{

c = va_arg(ap, char);

uart_putc(c);

break;

}

default:

uart_putc(*fmt);

}

fmt++;

}

va_end(ap);

return 1;

}

這里面有一些函數(shù),uart_putc是串口驅(qū)動(dòng)程序,給串口送東西的,uart_puts是簡(jiǎn)單的多重putc包裝。uart_putints則需要做一些atoi的轉(zhuǎn)換,一個(gè)比較簡(jiǎn)單但是有效的atoi程序宏定義如下:

#define ATOI(X, result) \

do{ \

char *lptr = X; \

result = 0; \

while (1) \

{ \

if ((*lptr 》= ‘0’) && (*lptr 《= ‘9’)) \

{ \

result *= 10; \

result += *lptr - ‘0’; \

lptr++; \

} \

else \

{ \

break; \

} \

} \

}while(0)

責(zé)任編輯:gt

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5152

    文章

    19675

    瀏覽量

    317607
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7632

    瀏覽量

    141773
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    信號(hào)處理原理-簡(jiǎn)易版

    信號(hào)處理原理-簡(jiǎn)易版主要內(nèi)容信號(hào)的分類與定義隨機(jī)信號(hào)與確定性信號(hào)連續(xù)信號(hào)與離散信號(hào)周期信號(hào)與非周期信號(hào)確定性信號(hào)的特性時(shí)間特性頻率特性時(shí)間與頻率的聯(lián)系確定性信號(hào)分析時(shí)域分析頻域分析隨機(jī)信號(hào)特性及分析 [hide][/hide]
    發(fā)表于 11-04 10:16

    什么是嵌入式系統(tǒng)

    ,尤其是用于便攜的無(wú)線及移動(dòng)的計(jì)算和通信設(shè)備中靠電池供電的嵌入式系統(tǒng)更是如此,如需要功耗只有mW甚至μW級(jí)。
    發(fā)表于 08-12 14:37

    如何學(xué)習(xí)嵌入式系統(tǒng)

    這段時(shí)間很多關(guān)注者問(wèn)起怎樣學(xué)習(xí)嵌入式,對(duì)于一個(gè)剛開(kāi)始接觸嵌入式的朋友來(lái)說(shuō),這的確是個(gè)問(wèn)題。在這里筆者就給大家講講怎樣利用【IT指路燈】來(lái)學(xué)習(xí)嵌入式系統(tǒng)。  學(xué)習(xí)
    發(fā)表于 08-17 10:18

    FAT精減版(嵌入式應(yīng)用的版本)--嵌入式FAT文件系統(tǒng)源碼免費(fèi)下載

    FAT精減版(嵌入式應(yīng)用的版本)--嵌入式FAT文件系統(tǒng)源碼免費(fèi)下載本文件系統(tǒng)代碼兼容FAT16/FAT32兩種文件
    發(fā)表于 08-02 07:45

    嵌入式操作系統(tǒng)有哪些

    自己需要嵌入式系統(tǒng)?! ∑浯危琇inux具有強(qiáng)大的網(wǎng)絡(luò)支持功能。Linux誕生于因特網(wǎng)并具有UNIX的特性,這就保證了它支持所有標(biāo)準(zhǔn)因特網(wǎng)協(xié)議,并且可以利用Linux的網(wǎng)絡(luò)協(xié)議棧開(kāi)發(fā)
    發(fā)表于 06-20 15:13

    什么是嵌入式系統(tǒng)

    系統(tǒng)的核心課程,或者就講一下ARM編程基礎(chǔ);做嵌入式實(shí)驗(yàn)大部分也只是教學(xué)系統(tǒng)里現(xiàn)有的實(shí)驗(yàn)程序調(diào)出來(lái)運(yùn)行驗(yàn)證一下結(jié)果,屬于驗(yàn)證性實(shí)驗(yàn),很多學(xué)生做完了實(shí)驗(yàn)都不知道自己做了什么。根本就沒(méi)有機(jī)
    發(fā)表于 04-17 11:46

    如何滿足嵌入式系統(tǒng)的靈活需求?

    嵌入式程序開(kāi)發(fā)基本概念如何滿足嵌入式系統(tǒng)的靈活需求開(kāi)發(fā)高效程序的技巧是什么
    發(fā)表于 04-28 06:07

    單片機(jī)實(shí)現(xiàn)簡(jiǎn)易版shell的方法和原理是什么

    力氣將其移植出來(lái).于是我就自己寫了一個(gè)類似于這樣的插件.只需要把一對(duì).c/.h文件加入到你的工程,就可以實(shí)現(xiàn)這個(gè)簡(jiǎn)易版的shell.git: https://github.com/KimAlittleS...
    發(fā)表于 12-09 07:27

    什么是嵌入式系統(tǒng)?深嵌入式系統(tǒng)又是什么

    和Android的系統(tǒng)也可以稱為嵌入式系統(tǒng)。但是通常,這些通用操作系統(tǒng)需要應(yīng)用程序處理器,并具有其他功能,例如動(dòng)態(tài)應(yīng)用程序加載。這就是為什么
    發(fā)表于 12-21 06:48

    嵌入式系統(tǒng)是否需要操作系統(tǒng)

    嵌入式操作系統(tǒng)嵌入式應(yīng)用系統(tǒng)軟件運(yùn)行的管理內(nèi)核,嵌入式編程的大多數(shù)問(wèn)題可以因?yàn)槭褂貌僮?b class='flag-5'>系統(tǒng)而獲
    發(fā)表于 04-14 17:15 ?34次下載

    如何開(kāi)發(fā)自己嵌入式系統(tǒng)

            如何開(kāi)發(fā)自己嵌入式系統(tǒng) 嵌入式系統(tǒng)的悠久歷史 電
    發(fā)表于 04-02 23:46 ?1013次閱讀

    學(xué)習(xí)嵌入式系統(tǒng)需要涉及哪些工作

      同學(xué)們?cè)趯W(xué)習(xí)嵌入式的過(guò)程中要涉及很多內(nèi)容,就嵌入式系統(tǒng)的設(shè)計(jì)和實(shí)現(xiàn)而言,基本上需要四種不同的工作:系統(tǒng)設(shè)計(jì)工作,硬件設(shè)計(jì)工作,驅(qū)動(dòng)程序和
    發(fā)表于 10-15 10:17 ?546次閱讀

    嵌入式Linux中printf重定向到串口

    PC機(jī)上,printf輸出到顯示設(shè)備,在嵌入式linux系統(tǒng),一般利用printf輸出調(diào)試信息,需要重定向到串口。以AT91RM9200為例
    發(fā)表于 11-01 17:22 ?24次下載
    <b class='flag-5'>嵌入式</b>Linux中<b class='flag-5'>printf</b>重定向到串口

    號(hào)稱目前網(wǎng)上嵌入式最好的printf,用起來(lái)!

    號(hào)稱目前網(wǎng)上嵌入式最好的printf,用起來(lái)!
    發(fā)表于 12-09 10:51 ?11次下載
    號(hào)稱目前網(wǎng)上<b class='flag-5'>嵌入式</b>最好的<b class='flag-5'>printf</b>,用起來(lái)!

    嵌入式系統(tǒng)滿足物聯(lián)網(wǎng)應(yīng)用

      在許多方面,嵌入式系統(tǒng)是物聯(lián)網(wǎng)(IoT)的鼻祖 - 現(xiàn)在物聯(lián)網(wǎng)正在改變我們?cè)O(shè)計(jì)和構(gòu)建軍事嵌入式系統(tǒng)的關(guān)鍵方面。事實(shí)上,物聯(lián)網(wǎng)中嵌入式
    的頭像 發(fā)表于 11-01 11:42 ?962次閱讀