我遇到了一个关于堆内存的奇怪问题——如果我将 UART 传输缓冲区的大小从 256 字节增加到 1024 字节,堆似乎会损坏。 第一次调用 malloc () 返回 NULL。 但是,据我所知,UART组件和堆之间没有任何关系,因为UART组件不使用动态内存。 我想知道如何才能调试这个问题。
在应用程序中,我正在使用两个 UART,将 printf () 重定向到 UART_1,将 stderr 重定向到 UART_2,但是对 malloc () 的调用是在进行任何打印之前完成的,并且请求的大小远低于堆大小。 以下是我的项目设置:
SRAM used: 7601 of 65536 bytes (11,6 %). Stack: 2048 bytes. Heap: 2048 bytes.
我试图弄清楚 TESTBOARD_150PC_OUT Tx 缓冲区是否以某种方式在堆部分内,但情况似乎并非如此:
extern uint8_t __cy_heap_start;extern uint8_t __cy_heap_end;extern uint8_t __cy_stack;extern uint8_t __cy_stack_limit;extern vola
tile uint8 UART_1_txBuffer[UART_1_TX_BUFFER_SIZE];extern volatile uint8 UART_2_txBuffer[UART_2_TX_BUFFER_SIZE];int main(void) { CyGlobalIntEnable; /* Enable global interrupts. */ /* Place your initialization/startup code here (e.g. MyInst_Start()) */ setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); UART_1_Start(); UART_2_Start(); //doing some other initialization, etc including the 1st malloc() printf("Heap start at %p, heap end at %pn", __cy_heap_start, __cy_heap_end); printf("Stack start at %p, stack end at %pn", __cy_stack, __cy_stack_limit); printf("UART1 Tx buffer start at %p, end at %p, size %d bytesn", UART_1_txBuffer, UART_1_txBuffer[UART_1_TX_BUFFER_SIZE - 1], UART_1_TX_BUFFER_SIZE); printf("UART2 Tx buffer start at %p, end at %p, size %d bytesn", UART_2_txBuffer, UART_2_txBuffer[UART_2_TX_BUFFER_SIZE - 1], UART_2_TX_BUFFER_SIZE); while(1);}其中 TX 缓冲区大小为 256 字节,可以正常工作并提供以下输出:
Heap start at 0x1fff8db8, heap end at 0x20007800Stack start at 0x20008000, stack end at 0x20007800UART1 Tx buffer start at 0x1fff8b94, end at 0x1fff8c93, size 256 bytesUART2 Tx buffer start at 0x1fff8cb4, end at 0x1fff8db3, size 256 bytes堆栈大小完全等于系统设计设置中的设置,链接器脚本似乎为堆提供了所有未使用的内存:0x20007800-0x1fff8db8 = 0xea48 = > 59976 字节。
如果我将 UART_2 (stderr) 的 TX 缓冲区大小增加到 1024 字节,则第一个请求 256 字节的 malloc () 将失败。 如果我 TESTBOARD_150PC_OUT malloc() 请求离开,堆栈/堆信息为:
Heap start at 0x1fff8f98, heap end at 0x20007800Stack start at 0x20008000, stack end at 0x20007800UART1 Tx buffer start at 0x1fff8a70, end at 0x1fff8b6f, size 256 bytesUART2 Tx buffer start at 0x1fff8b90, end at 0x1fff8f8f, size 1024 bytes所以,我看不出有什么问题。 仍然没有重叠之处。 我可以成功请求 76 字节,如果 TX 缓冲区大小为 1024,以上任何内容都会失败。 如果我将其减少到原始的256字节,它将再次起作用。 我还没有检查过最初的 256 字节请求在哪个 Tx 缓冲区大小下失败。
由于UART缓冲区(仅是全局数组)与堆内存之间没有明显的关系,因此我对如何调试和修复这个问题有点困惑。 欢迎提出想法。 目前,我正在尝试设置一个最低限度的工作示例项目来追踪该问题,如果我能设法重现该问题,我会提供的。