编译选项 –specs=nano.specs /newlib-nano的影响
–specs=nano.specs (newlib-nano) 的影响
1. printf / sprintf 格式化限制
| 格式符 | 默认nano | 加 -u _printf_float |
|---|---|---|
| %d %x %s | ✅ 正常 | ✅ 正常 |
| %f %e %g | ❌ 输出空/乱码 | ✅ 正常 |
| %lld (64位整数) | ❌ 不支持 | ❌ 需另加 -u _printf_long_long |
2. 堆内存相关
-
malloc / free 使用的是**精简版分配器**
-
没有线程安全保护(裸机无所谓,FreeRTOS下需注意)
-
_sbrk 需要你自己实现,否则 malloc 会 HardFault
3. 本地化 / 宽字符
-
不支持 wprintf / wchar_t 相关函数
-
setlocale() 无效,中文字符处理受限
4. 文件 I/O
-
fopen / fread 等是**空桩**(配合 nosys.specs)
-
需要自己实现 _write / _read 才能让 printf 输出到串口
5. 数学库
-
libm 体积同样缩减,部分精度受影响
-
建议显式链接:-lm
⚠️ 最容易踩的坑,嵌入式中一定要自己重定向输出函数
/* [ARMCC] retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
USART_Data_Send(USART2, (uint8_t)ch);
while (USART_Flag_Status_Get(USART2, USART_FLAG_TXDE) == RESET)
;
return (ch);
}
/* [GCC] retarget the C library printf function to the USART */
int _write(int file, char *data, int len)
{
// if ((file != STDOUT_FILENO) && (file != STDERR_FILENO))
// {
// errno = EBADF;
// return -1;
// }
for (int i = 0; i < len; i++) {
USART_Data_Send(USART2, data[i]);
while (USART_Flag_Status_Get(USART2, USART_FLAG_TXDE) == RESET)
;
}
return 0;
}
如果 _write 没有实现或者实现有误,printf 调用会**静默丢弃**所有输出
