keil 用MicroLIB

串口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.o

Example 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.o

Example 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 stack

Example 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 heap

Example 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 不兼容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章