关于Keil中MicroLIB的说明

关于Keil中MicroLIB的说明

一、Keil 官方文档中对MicroLIB的介绍

MicroLIB是标准C库的裁剪版本,一般用于存储空间非常小的嵌入式应用,不在操作系统下运行。
MicroLIB和标准 C 库最主要差异是:
①MicroLIB不兼容 ISO C 库标准。一些 ISO 特性不被支持,另一些功能相对少一些。一些函数运行比较慢,如memcpy()。
②MicroLIB不兼容 IEEE 754 二进制浮点算法标准。
③MicroLIB优化了代码量。
④语言环境不可配置。默认的 C 语言环境是唯一可用的。
⑤main() 不必被声明来获取变量,也不必返回。
⑥stdio 不被支持,除了无缓冲的 stdin、stdout 和 stderr。
⑦MicroLIB对 C99 函数提供了有限的支持。
⑧MicroLIB不支持操作系统函数。
⑨MicroLIB不支持位置独立代码。
⑩MicroLIB不提供互斥锁定来预防代码线程不安全。
⑪MicroLIB不支持宽字符或多字节串。
⑫MicroLIB不同于标准库,MicroLIB不支持可选的单或两区存储模式。MicroLIB只提供分离的栈和堆区域的两区存储模式。
⑬MicroLIB对使用使用–fpmode=std 或 --fpmode=fast敏感。

二、用MicroLIB建立应用程序(官方)

MicroLIB中的函数负责:
①建立一个C程序可以执行的环境。
它包含:建立一个栈;建立一个堆(如果需要);初始化程序所用的库部分。
②调用main()函数开始执行。
用MicroLIB建立一个程序,必须使用命令行选项
‑‑library_type=microlib
此选项作为必需可以被编译器、汇编程序或链接程序的不同文件使用。链接器用此选项来覆盖其他的选项。(armcc 是keil中安装的AC5编译器)

2.1 C语言编程中的命令行操作

armcc ‑‑library_type=microlib ‑c main.c
armcc ‑c extra.c
armlink ‑o image.axf main.o extra.o

2.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

2.3 链接器命令行使用MicroLIB

armcc ‑c main.c
armcc ‑c extra.c
armlink ‑‑library_type=microlib ‑o image.axf main.o extra.o

刚开始,必须为栈指定一个开始指针。此指针必须8字节对齐。利用堆函数(例如: malloc、calloc、realloc)时,必须指定堆区域的位置和大小。

三.创建栈(stack)

3.1 汇编语言中创建

定义符号__initial_sp (相当于栈头)指定初始栈指针。此初始指针8字节对齐。
EXPORT __initial_sp
__initial_sp EQU 0x100000
; equal to the top of the stack

3.2 C语言中嵌入汇编语言创建

__asm void dummy_function(void)
{
    EXPORT __initial_sp
__initial_sp EQU 0x100000        
; equal to the top of the stack
}  

四.创建堆(heap)

分别定义符号 __heap_base 和 __heap_limit 来指定堆的开头和结尾。然后就可以正常地使用堆函数了。__heap_limit 必须指向堆区域中远离最后一个字节的字节。

4.1 汇编语言创建堆

    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

4.2 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
}

五.进入/退出程序

用 main() 来开始你的程序。不带参数声明,无返回。
MicroLIB不支持:操作系统的命令行变量调用 exit()的程序。

裁减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(),则必须执行这个基本函数。在MicroLIB中不被支持的转换为%lc, %ls 和 %a.

MicroLIB中缺少的 ISO C 特性(ISO C90)(官方)

①宽位字符和多字节支持
所有的有关宽位字符或多字节串的函数在MicroLIB中都不被支持。如果使用会出现一个链接错误。例如mbtowc()、wctomb()、mbstowcs() 和 wcstombs()。
②操作系统交互作用
所有与操作系统结合的函数在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异常而是返回一个不可预知的结果。另外,0符号不被MicroLIB认为有意义并产生不可预知的输出。
⑦独立位置和线程安全代码
MicroLIB没有可重入变量。MicroLIB不提供互斥锁定来预防代码线程不安全。用MicroLIB不兼容RWPI编辑模式,虽然ROPI代码可以链接MicroLIB,但其二元结果却并不完全兼容ROPI。

一般在Keil中MicroLIB的用法(经验)

在Keil中进行单片机程序开发(裸机开发,无嵌入式操作系统),需要用到串口输出,一般有两种办法:
①编写USART串口写字符串函数,然后调用该函数,使得串口输出数据或者字符;
②Printf重定向。在单片机编程中,链接器检查到与标准C库函数名字相同的,则会优先调用用户的函数实现。标准C库的printf()函数是一个宏定义,最终的实现函数是fputc()函数,所以一般在串口相关的C文件中,重写fputc()函数,就可以实现printf(“xxxxxxxxx”)在串口中打印。

需要注意的是:串口C文件中,要包含stdio.h头文件(stdio.h文件在MicroLIB中),其他需要调用printf的C文件中,同样包含stdio.h和usart.h头文件即可。
另一方面,在target-code generation中,勾选Use MicroLIB,使用微库中的标准文件I/O流,stdin和stdout。
③ scanf()重定向。Scanf()一般不用,自己写字符串输入解析会更方便
如果使用scanf(),则需要重定向fgetc()函数;

int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART0, (uint8_t)ch);
    while (RESET == usart_flag_get(USART0, USART_FLAG_TBE));
    return ch;
}
int fgetc(FILE *f)
{
	(unit8_t) tmp;
    while(RESET==usart_flag_get(USART0,USART_FLAG_RBNE));
    tmp = usart_data_receive(USART0);
    if(tmp == 13) tmp = 10;//当接收到回车键,就替换成换行键
    return (usart_data_transmit(USART0,tmp));//回显
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值