www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > > 充電吧
[導(dǎo)讀]在嵌入式開(kāi)發(fā)中,常常會(huì)通過(guò)串口打印一些信息到PC終端,這就需要實(shí)現(xiàn)自己的printf函數(shù)。我們先通過(guò)man 3 printf來(lái)看一下printf函數(shù)的聲明: int printf(const char

在嵌入式開(kāi)發(fā)中,常常會(huì)通過(guò)串口打印一些信息到PC終端,這就需要實(shí)現(xiàn)自己的printf函數(shù)。

我們先通過(guò)man 3 printf來(lái)看一下printf函數(shù)的聲明:
int printf(const char *format, ...);
format:固定參數(shù)
… ? :可變參數(shù)(變參) 下面解析printf函數(shù)的使用:

x86平臺(tái)VC6.0編譯器中,stdarg.h頭文件內(nèi)變參宏定義如下,本次實(shí)現(xiàn)也printf函數(shù)也采用此定義:

變參宏根據(jù)堆棧生長(zhǎng)方向和參數(shù)入棧特點(diǎn),從最靠近第一個(gè)可變參數(shù)的固定參數(shù)開(kāi)始,依次獲取每個(gè)可變參數(shù)的地址。

typedef?char?*?va_list;

#define?_INTSIZEOF(n)???????(?(sizeof(n)+sizeof(int)-1)?&?~(sizeof(int)-1)?)

#define?va_start(ap,v)????????(?ap?=?(va_list)&v?+?_INTSIZEOF(v)?)

#define?va_arg(ap,?type)????(?*(type?*)((ap?+=?_INTSIZEOF(type))?-?_INTSIZEOF(type))?)

#define?va_end(ap)?????????????(?ap?=?(va_list)0?)

各宏的含義如下:
_INTSIZEOF宏考慮到某些系統(tǒng)需要內(nèi)存地址對(duì)齊。從宏名看應(yīng)按照sizeof(int)即堆棧粒度對(duì)齊,即參數(shù)在內(nèi)存中的地址均為sizeof(int)=4的倍數(shù)。例如,若在1≤sizeof(n)≤4,則_INTSIZEOF(n)=4;若5≤sizeof(n)≤8,則_INTSIZEOF(n)=8。
為便于理解,簡(jiǎn)化該宏為:

#define?_INTSIZEOF(n)??((sizeof(n)?+?x)?&?~(x))

x?=?sizeof(int)?-?1?=?3?=?0b’0000?0000?0000?0011

~x?=?0b’1111?1111?1111?1100

一個(gè)數(shù)與(~x)相與的結(jié)果是sizeof(int)的倍數(shù),即_INTSIZEOF(n)將n圓整為sizeof(int)的倍數(shù)。

② va_start宏根據(jù)(va_list)&v得到第一個(gè)可變參數(shù)前的一個(gè)固定參數(shù)在堆棧中的內(nèi)存地址,加上_INTSIZEOF(v)即v所占內(nèi)存大小后,使ap指向固定參數(shù)后下個(gè)參數(shù)(第一個(gè)可變參數(shù)地址)。
固定參數(shù)的地址用于va_start宏,因此不能聲明為寄存器變量(地址無(wú)效)或作為數(shù)組類(lèi)型(長(zhǎng)度難定)。
③va_arg宏取得type類(lèi)型的可變參數(shù)值。首先ap+=_INTSIZEOF(type),即ap跳過(guò)當(dāng)前可變參數(shù)而指向下個(gè)變參的地址;然后ap-_INTSIZEOF(type)得到當(dāng)前變參的內(nèi)存地址,類(lèi)型轉(zhuǎn)換后返回當(dāng)前變參值。
va_arg宏的等效實(shí)現(xiàn)如下:

#define?va_arg(ap,t)????(ap?=?ap?+?_INTSIZEOF(t),?*(t?*)(ap?-?_INTSIZEOF(t)))

④va_end宏使ap指針指向空,防止野指針

代碼下載地址:https://gitee.com/zgdy/0_printf

my_printf.c函數(shù)的實(shí)現(xiàn)在注釋中已經(jīng)很清晰了。

一、在PC端來(lái)測(cè)試:


①:pc機(jī)中有操作系統(tǒng)所以測(cè)試時(shí),my_printf.h中使用stdio.h中的putchar函數(shù)

#ifndef?_MY_PRINTF_H
#define?_MY_PRINTF_H

//#include?"uart.h"
#include?"stdio.h"
#define??__out_putchar??putchar


#define??MAX_NUMBER_BYTES??64

extern?int?my_printf_test(void);
int?printf(const?char?*fmt,?...);

#endif?/*?_MY_PRINTF_H?*/

② main.c:

#include?"my_printf.h"

int?main(int?argc,char?**argv)
{
????printf("CZG~n");
????my_printf_test();
????return?0;

}

結(jié)果:

二、在JZ2440上面來(lái)測(cè)試:

關(guān)于為什么要加lib1funcs.S文件說(shuō)明:
?http://blog.csdn.net/czg13548930186/article/details/78797744

①由于ARM裸機(jī)中沒(méi)有操作系統(tǒng)環(huán)境,所以要自己實(shí)現(xiàn)putchar函數(shù)(并在uart.h中聲明):

② 將lib1funcs.S和my_printf.c放在Makefile中一同編譯進(jìn)去:

結(jié)果:

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

C語(yǔ)言的格式化字符串函數(shù)(如printf、sprintf、syslog等)因參數(shù)解析機(jī)制的設(shè)計(jì)缺陷,成為內(nèi)存攻擊中最經(jīng)典的漏洞類(lèi)型之一。攻擊者可通過(guò)構(gòu)造惡意格式化字符串,讀取任意內(nèi)存地址、篡改棧數(shù)據(jù)甚至執(zhí)行代碼。本文將從...

關(guān)鍵字: C語(yǔ)言 printf

在 20 世紀(jì) 90 年代,在實(shí)際硬件上調(diào)試嵌入式軟件主要有兩種基于工具的解決方案:一種是監(jiān)控調(diào)試器,它是在嵌入式系統(tǒng)內(nèi)存中編程的軟件,可響應(yīng)來(lái)自外部的調(diào)試器軟件的請(qǐng)求。另一種是在線(xiàn)仿真器,它是一塊(大型)硬件,可通過(guò)適...

關(guān)鍵字: 硬件調(diào)試 printf

在實(shí)際項(xiàng)目中,我們經(jīng)常需要提取一個(gè)數(shù)值的某些位的數(shù)碼,比如用數(shù)碼管來(lái)顯示數(shù)值或?qū)⒁粋€(gè)數(shù)值轉(zhuǎn)成字符串,都會(huì)涉及到這一操作。

關(guān)鍵字: 數(shù)值 數(shù)碼 printf

最近在忙活搞別的事情(太難受了),嚴(yán)重影響了硪那一顆自由飛翔的芯~~所以今天打算分享一個(gè)麻省理工小伙寫(xiě)的printf家族的函數(shù)~說(shuō)是號(hào)稱(chēng)目前網(wǎng)上嵌入式最好的printf喔.在嵌入式中printf這種功能強(qiáng)大的函數(shù)可謂是c...

關(guān)鍵字: printf 嵌入式

大伙估計(jì)在多任務(wù)程序中使用printf打印一些信息是非常歡樂(lè)的一件事,運(yùn)氣不錯(cuò)的話(huà)偶爾錯(cuò)幾個(gè)數(shù)據(jù)、亂幾個(gè)碼也不是什么大問(wèn)題,倒霉點(diǎn)的可能就直接掛機(jī)、卡死了,那這些到底是什么原因?qū)е碌哪兀?/p> 關(guān)鍵字: printf 可重入函數(shù)

SWO串行線(xiàn)輸出是單引腳、異步串行通信,可在Cortex-M3/M4/M7上使用,并由主調(diào)試器探測(cè)支持,它是利用Cortex內(nèi)核中ITM模塊來(lái)實(shí)現(xiàn)此功能。

關(guān)鍵字: printf 嵌入式

目的:在串口0上實(shí)現(xiàn)printf、scanf等函數(shù),它使用scanf、sscanf、printf等函數(shù)從串口接收一個(gè)十進(jìn)制數(shù)字序列,然后將它轉(zhuǎn)化為十六進(jìn)制輸出。 大致內(nèi)容和uart實(shí)驗(yàn)類(lèi)

關(guān)鍵字: printf 函數(shù)

使用IAR驅(qū)動(dòng)CC2530的串口0,串口1,實(shí)現(xiàn)數(shù)據(jù)發(fā)送以及printf,中斷接收數(shù)據(jù)uart.c/**************************************************

關(guān)鍵字: printf 串口

一、什么是可變參數(shù)我們?cè)贑語(yǔ)言編程中有時(shí)會(huì)遇到一些參數(shù)個(gè)數(shù)可變的函數(shù),例如printf()函數(shù),其函數(shù)原型為:?int?printf(?const?char*?format,?...);?它除了有一個(gè)

關(guān)鍵字: C語(yǔ)言 printf 編程

USART1需要事先進(jìn)行較為麻煩配置,配置之后發(fā)現(xiàn)即使用HAL函數(shù)發(fā)送語(yǔ)句還要事先以字符串方式定義,實(shí)在是麻煩,雖然后面另外自己寫(xiě)了一個(gè)簡(jiǎn)單的庫(kù)來(lái)操作串口,但看到了更簡(jiǎn)單的方法,修改標(biāo)準(zhǔn)庫(kù)中printf相關(guān)的兩個(gè)函數(shù)

關(guān)鍵字: printf STM32 串口通信 usart打印
關(guān)閉