将部分拆分为多个内存区域
Split section into multiple memory regions
我正在 ARM Cortex-M 微控制器上开发一个应用程序,它有两个 64kB 的 RAM 组。内存映射中第一个 bank 紧跟第二个 bank。
内存库目前在我的链接描述文件中分为两个区域。第一个区域包含部分 .bss
和 .data
。第二个存储区用于 .heap
和 .stack
,每个只占用 1kB(我在 FreeRTOS 中使用不同的堆栈,它也管理自己的堆)。
我的问题是,.bss
对于第一家银行来说太大了。因此我想将它的一些内容移动到第二个银行。
实现此目的的一种方法是创建一个新部分,我们称之为 .secondbss
,它链接到第二家银行。然后可以使用 __attribute__((section(".secondbss")))
将单个变量添加到该部分。
我没有使用这个解决方案的原因是
我真的很想保持源代码的可移植性
可能有很多变量需要此属性,我不想为每个变量都选择部分
有更好的解决办法吗?我已经将两个内存视为一个区域,但我不知道如何防止链接器在两个存储区之间的边界上错位数据。
如何在不使用 __attribute__
标志的情况下解决我的问题?
谢谢!
例如,您在 0x20000000
和 0x20010000
有 2 家银行。您希望将 Bank2 用于堆和(主)堆栈。我假设你的 .bss
很大,因为 FreeRTOSConfig.h 中有 configTOTAL_HEAP_SIZE
。现在在 FreeRTOS/Source/portable/MemMang/ 中查看堆源。 pvPortMalloc()
有 5 个执行内存分配的实现。
查看 heap_X.c 中您使用的行
/* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS
heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */
因此您可以将 configAPPLICATION_ALLOCATED_HEAP
设置为 1 并让链接器将 ucHeap
设置为 0x20010000
。
另一种方法是为每个设备写入 headers,其中包括堆和堆栈的地址以及编辑源。
对于 heap_1.c 我们可以进行下一步更改:
// somewhere in devconfig.h
#define HEAP_ADDR 0x20010000
// in heap_1.c
// remove code related ucHeap
//
// remove static uint8_t *pucAlignedHeap = NULL;
// and paste:
static uint8_t *pucAlignedHeap = (uint8_t *)HEAP_ADDR;
对于heap_2.c和heap_4.c也编辑函数prvHeapInit()
。
注意 heap_5.c 其中包括 vPortDefineHeapRegions()
.
现在 pvPortMalloc()
将 returns 指向 Bank2 中的内存。 pvPortMalloc()
用于任务、TCB 和用户变量的分配堆栈。阅读来源。主堆栈的位置取决于您的 device/architecture。对于 stm32 (ARM),请参阅 vector table 或如何更改 MSP 寄存器。
我正在 ARM Cortex-M 微控制器上开发一个应用程序,它有两个 64kB 的 RAM 组。内存映射中第一个 bank 紧跟第二个 bank。
内存库目前在我的链接描述文件中分为两个区域。第一个区域包含部分 .bss
和 .data
。第二个存储区用于 .heap
和 .stack
,每个只占用 1kB(我在 FreeRTOS 中使用不同的堆栈,它也管理自己的堆)。
我的问题是,.bss
对于第一家银行来说太大了。因此我想将它的一些内容移动到第二个银行。
实现此目的的一种方法是创建一个新部分,我们称之为 .secondbss
,它链接到第二家银行。然后可以使用 __attribute__((section(".secondbss")))
将单个变量添加到该部分。
我没有使用这个解决方案的原因是
我真的很想保持源代码的可移植性
可能有很多变量需要此属性,我不想为每个变量都选择部分
有更好的解决办法吗?我已经将两个内存视为一个区域,但我不知道如何防止链接器在两个存储区之间的边界上错位数据。
如何在不使用 __attribute__
标志的情况下解决我的问题?
谢谢!
例如,您在 0x20000000
和 0x20010000
有 2 家银行。您希望将 Bank2 用于堆和(主)堆栈。我假设你的 .bss
很大,因为 FreeRTOSConfig.h 中有 configTOTAL_HEAP_SIZE
。现在在 FreeRTOS/Source/portable/MemMang/ 中查看堆源。 pvPortMalloc()
有 5 个执行内存分配的实现。
查看 heap_X.c 中您使用的行
/* Allocate the memory for the heap. */
#if( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS
heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */
因此您可以将 configAPPLICATION_ALLOCATED_HEAP
设置为 1 并让链接器将 ucHeap
设置为 0x20010000
。
另一种方法是为每个设备写入 headers,其中包括堆和堆栈的地址以及编辑源。 对于 heap_1.c 我们可以进行下一步更改:
// somewhere in devconfig.h
#define HEAP_ADDR 0x20010000
// in heap_1.c
// remove code related ucHeap
//
// remove static uint8_t *pucAlignedHeap = NULL;
// and paste:
static uint8_t *pucAlignedHeap = (uint8_t *)HEAP_ADDR;
对于heap_2.c和heap_4.c也编辑函数prvHeapInit()
。
注意 heap_5.c 其中包括 vPortDefineHeapRegions()
.
现在 pvPortMalloc()
将 returns 指向 Bank2 中的内存。 pvPortMalloc()
用于任务、TCB 和用户变量的分配堆栈。阅读来源。主堆栈的位置取决于您的 device/architecture。对于 stm32 (ARM),请参阅 vector table 或如何更改 MSP 寄存器。