--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 调用会静默丢弃所有输出
