单片机/MCU论坛
直播中

李泽坚

7年用户 1357经验值
私信 关注
[问答]

PSoC™ 5LP时增加TX缓冲区大小会损坏堆怎么解决?

我遇到了一个关于堆内存的奇怪问题——如果我将 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 volatile 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缓冲区(仅是全局数组)与堆内存之间没有明显的关系,因此我对如何调试和修复这个问题有点困惑。 欢迎提出想法。 目前,我正在尝试设置一个最低限度的工作示例项目来追踪该问题,如果我能设法重现该问题,我会提供的。


回帖(1)

李敏

2024-2-26 15:48:49
如果你增加了 TX 缓冲区的大小后遇到了堆破坏的问题,有几个可能的原因导致这个问题。

首先,确保你在堆中申请的内存大小没有超过堆的总大小。你提到的堆大小是65536字节,确保你请求的内存大小小于这个值。

其次,查看你的堆起始地址和堆结束地址之间是否有一些内存覆盖或冲突的情况。检查你的代码是否存在内存越界或者指针错误导致的堆破坏。

此外,UART 组件本身是不会使用到动态内存的,但是在使用 UART 过程中可能会有其他的操作或者使用到动态内存。确保你的代码中没有其他地方使用到了动态内存,或者修改你的代码使得 UART 组件和堆之间没有冲突。

最后,你可以使用调试工具来进行调试,例如在代码中加入打印语句来追踪堆破坏发生的位置,或者使用调试器来查看堆的状态和分配情况。这样可以帮助你定位问题。

总结一下,确保你请求的内存大小没有超过堆的总大小,检查代码中是否有内存越界或指针错误,确保 UART 组件和堆没有冲突,并使用调试工具来帮助你定位问题。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分