我正在运行一个带有 ARM Cortex-M3 (STM32F205) 的裸机嵌入式系统。当我尝试使用snprintf()
浮点数时,例如:
float f;
f = 1.23;
snprintf(s, 20, "%5.2f", f);
我把垃圾放进去s
。该格式似乎受到尊重,即垃圾是一个格式良好的字符串,带有数字、小数点和两个尾随数字。但是,如果我重复snprintf
,字符串可能会在两次调用之间发生变化。
浮点数学似乎以其他方式工作,并且snprintf
适用于整数,例如:
snprintf(s, 20, "%10d", 1234567);
我将newlib-nano
实现与-u _printf_float
链接器开关一起使用。编译器是arm-none-eabi-gcc
.
我确实非常怀疑内存分配问题,因为整数的打印没有任何问题,但浮点数的行为就好像它们在这个过程中被破坏了一样。printf
系列函数使用浮点数调用,而malloc
不是整数。
在此上下文中使用的唯一不属于newlib
我的代码是 my _sbrk()
,这是malloc
.
caddr_t _sbrk(int incr)
{
extern char _Heap_Begin; // Defined by the linker.
extern char _Heap_Limit; // Defined by the linker.
static char* current_heap_end;
char* current_block_address;
// first allocation
if (current_heap_end == 0)
current_heap_end = &_Heap_Begin;
current_block_address = current_heap_end;
// increment and align to 4-octet border
incr = (incr + 3) & (~3);
current_heap_end += incr;
// Overflow?
if (current_heap_end > &_Heap_Limit)
{
errno = ENOMEM;
current_heap_end = current_block_address;
return (caddr_t) - 1;
}
return (caddr_t)current_block_address;
}
据我所知,这应该有效。似乎没有人用负增量调用它,但我想这是由于 newlib 的设计malloc
。唯一有点奇怪的是,第一次调用_sbrk
的增量为零。(但这可能只是malloc
对堆起始地址的好奇。)
堆栈不应与堆发生冲突,因为两者大约有 60 KiB RAM。链接描述文件可能很疯狂,但至少堆和堆栈地址似乎是正确的。