返回> 网站首页
microlib
yoours2021-07-13 21:45:37
简介一边听听音乐,一边写写文章。
1.选上”Use MicroLIB”这是KEIL自带的一个简易的库
2.microlib 是缺省 C 库的备选库。
它用于必须在极少量内存环境下运行的深层嵌入式应用程序,并进行了高度优化以使代码变得很小。它的功能比缺省C库少,并且根本不具备某些 ISO C 特性。某些库函数的运行速度也比较慢,例如memcpy()。
3.
1) 使用C++,不能再使用MicroLIB,MicroLIB不支持C++,会报错;
2) 使用MicroLIB,会自动关闭半主机模式,重定向仅实现putc和getc即可
3) 不使用MicroLIB,需要手动关闭半主机模式;
4) 关闭半主机模式(ARM Compiler 5版本):#pragma import(__use_no_semihosting_swi)
5) 关闭半主机模式(ARM Compiler 6版本):__asm(".global __use_no_semihosting\n\t");
6) ARM Compiler 6版本关闭半主机模式需要实现retarget.c中的好几个函数,下面会贴出代码
7) C++模板使用Template,需要使用ARM Compiler 6版本
4.
1) 如果你的程序中使用了C++全局变量,那么*不要*使用MicroLIB,否则Keil会说某某Symbol找不到
2) 不使用MicroLIB带来的一个问题是KEIL会使用semihosting SWI完成sys_io(例如printf的时候),我们需要一个retarget.c来禁止semihosting。KEIL提供该文件的模版(包括最小版和完全版,见下文),改改就是了
3) retarget.c也有最小版和完全版;最小版除实现fputc及辅助函数用于printf外,只实现了sys_io中的_sys_close;完全版还实现了_sys_open,_sys_read,_sys_write,等等。如果实现了sys_io中除_sys_close以外的任意一个,那么就必须同时实现其他函数。即,要么最小版,要么完全版,不存在中间版。当使用C++标准库时可能需要完全版:例如使用complex template时就必须使用完全版的retarget.c,因为complex class实现了“<<”和“>>”运算符重载,需要_sys_open等函数。当然我们一般不需要完整的函数内容,只要让编译器看到函数定义就行了。
4) 使用new和delete:参考帮助文件的Libraries and floating point support guide -> The ARM C and C++ libraries -> Stack pointer initialization and heap bounds
一般来说KEIL或厂家(如ST)提供的启动文件已包含该项支持;将汇编启动文件中的heap size项改改就好了。
5) 顺便说下如何动态控制printf的精度(同样用于snprintf,etc):使用%*控制。例如printf("%.*f ", 2, 1.234)
6) 科学记数法打印:%e
retarget.c 文件代码
typedef int FILEHANDLE;
// Disable semihosting
// Note:
// Use microlib will disable semihosting
// If not, disable semihosting using folllow code
//#pragma import(__use_no_semihosting_swi) // ARM Compiler 5
__asm(".global __use_no_semihosting\n\t"); // ARM Compiler 6
int fputc(int ch, FILE *f)
{
stdio_io_write((uint8_t*)&ch, 1);
return ch;
}
int fgetc(FILE *f)
{
int ch = 0;
stdio_io_read((uint8_t*)&ch, 1);
return ch;
}
void _ttywrch(int ch)
{
ch = ch;
}
int ferror(FILE *f)
{
(void)f;
return EOF;
}
void _sys_exit(int return_code)
{
(void)return_code;
while (1) {
};
}
FILEHANDLE _sys_open(const char *name, int openmode)
{
return 1;
}
int _sys_close(FILEHANDLE fh)
{
return 0;
}
int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode)
{
return 0;
}
int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode)
{
return -1;
}
int _sys_istty(FILEHANDLE fh)
{
return 0;
}
int _sys_seek(FILEHANDLE fh, long pos)
{
return -1;
}
long _sys_flen(FILEHANDLE fh)
{
return -1;
}