串口printf()函數問題——Use MicroLIB
keil應用小貼士:microLIB[Z] Use MicroLIB
在keil (我用的是realview mdk3.11)建立ARM的工程時其中有一項是選 use MicroLIB由於對KEIL不是很熟悉,於是就查了查,得到了以下信息:microlib 是缺省 C 庫的備選庫。 它旨在與需要裝入到極少量內存中的深層嵌入式應用程序配合使用。 這些應用程序不在操作系統中運行。microlib 進行了高度優化以使代碼變得很小。 它的功能比缺省 C 庫少,並且根本不具備某些 ISO C 特性。 某些庫函數的運行速度也比較慢,例如,memcpy()。與缺省 C 庫之間的差異
microlib 與缺省 C 庫之間的主要差異是:
microlib 不符合 ISO C 庫標準。 不支持某些 ISO 特性,並且其他特性具有的功能也較少。
microlib 不符合 IEEE 754 二進制浮點算法標準。
microlib 進行了高度優化以使代碼變得很小。
無法對區域設置進行配置。 缺省 C 區域設置是唯一可用的區域設置。
不能將main()聲明爲使用參數,並且不能返回內容。
不支持stdio,但未緩衝的stdin、stdout和stderr除外。
microlib 對 C99 函數提供有限的支持。
microlib 不支持操作系統函數。
microlib 不支持與位置無關的代碼。
microlib 不提供互斥鎖來防止非線程安全的代碼。
microlib 不支持寬字符或多字節字符串。
與 stdlib 不同,microlib 不支持可選擇的單或雙區內存模型。 microlib 只提供雙區內存模型,即單獨的堆棧和堆區。
可以合理地將 microlib 與--fpmode=std或--fpmode=fast配合使用。microlib 中的函數負責:
創建一個可在其中執行 C 程序的環境。 這包括:
創建一個堆棧
創建一個堆(如果需要)
初始化程序所用的庫的部分組成內容。
調用main()以開始執行程序。
要使用 microlib 構建程序,必須使用命令行選項??library_type=microlib。 根據需要,編譯器、彙編程序或鏈接器可使用此選項處理不同的文件。 將此選項與鏈接器配合使用時,將覆蓋所有其他選項。Example 3.1說明了編譯器使用此選項的情形,它僅爲main.c文件選擇了 microlib。
Example 3.1. 編譯器選項
armcc ??library_type=microlib ?c main.c armcc ?c extra.c armlink ?o image.axf main.o extra.oExample 3.2說明了彙編程序使用此選項的情形,它僅爲more.s文件選擇了 microlib。
Example 3.2. 彙編程序選項
armcc ?c main.c armcc ?c extra.c armasm ??library_type=microlib more.s armlink ?o image.axf main.o extra.o more.oExample 3.3說明了鏈接器使用此選項的情形,它爲main.c和extra.c文件均選擇了 microlib。
Example 3.3. 鏈接器選項
armcc ?c main.c armcc ?c extra.c armlink ??library_type=microlib ?o image.axf main.o extra.o使用MicroLIB: 3.3.1. 創建堆棧可通過將符號 __initial_sp 定義爲與堆棧頂部相等來指定初始堆棧指針。 初始堆棧指針的對齊邊界必須爲 8 字節的倍數。
Example 3.4 說明了如何使用彙編語言來設置初始堆棧指針。
Example 3.4. 彙編語言
EXPORT __initial_sp __initial_sp EQU 0x100000 ; equal to the top of the stackExample 3.5 說明了如何使用 C 中的嵌入式彙編程序來設置初始堆棧指針。
Example 3.5. C 中的嵌入式彙編程序
__asm void dummy_function(void) { EXPORT __initial_sp __initial_sp EQU 0x100000 ; equal to the top of the stack } 3.3.2. 創建堆可通過定義符號 __heap_base 和 __heap_limit 來分別指定堆的開頭和結尾。 完成後,您可以按通常方式使用堆函數。
Note__heap_limit 必須指向堆區中最後一個字節後面的字節。
Example 3.6 說明了如何使用彙編語言來設置堆指針。
Example 3.6. 彙編語言
EXPORT __heap_base __heap_base EQU 0x400000 ; equal to the start of the heap EXPORT __heap_limit __heap_limit EQU 0x800000 ; equal to the end of the heapExample 3.7 說明了如何使用 C 中的嵌入式彙編程序來設置堆指針。
Example 3.7. C 中的嵌入式彙編程序
__asm void dummy_function(void) { EXPORT __heap_base __heap_base EQU 0x400000 ; equal to the start of the heap EXPORT __heap_limit __heap_limit EQU 0x800000 ; equal to the end of the heap } 3.3.3. 進入和退出程序應在程序開頭使用 main()。 不要將 main() 聲明爲使用參數。
Note程序不能從 main() 返回內容。
microlib 不支持以下內容:
操作系統中的命令行參數
調用 exit() 的程序
3.4. 調整 microlib 輸入/輸出函數
microlib 提供了一個有限的 stdio 子系統,它僅支持未緩衝的 stdin、stdout 和 stderr。 這樣,即可使用 printf() 來顯示應用程序中的診斷消息。
要使用高級 I/O 函數,您必須提供自己實現的以下基本函數,以便與您自己的 I/O 設備配合使用。
fputc()爲所有輸出函數實現此基本函數。 例如,fprintf()、printf()、fwrite()、fputs()、puts()、putc() 和 putchar()。
fgetc()爲所有輸入函數實現此基本函數。 例如,fscanf()、scanf()、fread()、read()、fgets()、gets()、getc() 和 getchar()。
__backspace()如果輸入函數使用 scanf() 或 fscanf(),則實現此基本函數。
Notemicrolib 中不支持的轉換爲 %lc、%ls 和 %a。
3.5. microlib 中缺少的 ISO C 特性
本節提供了 microlib 不支持的主要 ISO C90 特性的列表。
寬字符和多字節支持microlib 不支持所有處理寬字符或多字節字符串的函數。 如果使用這些函數,則會產生鏈接器錯誤。 例如,mbtowc()、wctomb()、mbstowcs() 和 wcstombs()。 microlib 不支持在標準附錄 1 中定義的所有函數。
操作系統交互microlib 不支持與操作系統交互的所有函數。 例如,abort()、exit()、atexit()、clock()、time()、system() 和 getenv()。
文件 I/O與文件指針交互的所有 stdio 函數將返回錯誤(如果已實現)。 唯一的例外情況是以下三個標準流:stdin、stdout 和 stderr。
可配置的區域設置缺省 C 區域設置是唯一可用的區域設置。
信號雖然提供了 signal() 和 raise() 函數,但 microlib 不會生成信號。 唯一的例外情況是程序顯式地調用 raise()。
浮點支持浮點支持不符合 IEEE 754 標準。
產生不可預測的輸出的運算是指:
涉及 NaN、無窮大或非正規數
依照正確的 IEEE 754 規則,並非通過不精確結果產生 IEEE 異常。 但是,microlib 不會產生 IEEE 異常,而是返回不可預測的結果。
另外,microlib 不會將零的符號視爲有效位,並且會產生不可預測的輸出。
與位置無關且線程安全的代碼microlib 沒有可重入變體。 microlib 不提供互斥鎖來防止非線程安全的代碼。 microlib 的使用與 FPIC 或 RWPI 編譯模式不兼容,但可以將 ROPI 代碼與 microlib 進行鏈接,生成的二進制文件總體上與 ROPI 不兼容。