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

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

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

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

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

變參宏根據(jù)堆棧生長方向和參數(shù)入棧特點,從最靠近第一個可變參數(shù)的固定參數(shù)開始,依次獲取每個可變參數(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)存地址對齊。從宏名看應(yīng)按照sizeof(int)即堆棧粒度對齊,即參數(shù)在內(nèi)存中的地址均為sizeof(int)=4的倍數(shù)。例如,若在1≤sizeof(n)≤4,則_INTSIZEOF(n)=4;若5≤sizeof(n)≤8,則_INTSIZEOF(n)=8。
為便于理解,簡化該宏為:

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

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

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

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

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

一、在PC端來測試:


①:pc機中有操作系統(tǒng)所以測試時,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上面來測試:

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

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

② 將lib1funcs.S和my_printf.c放在Makefile中一同編譯進去:

結(jié)果:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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