This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

28377如何将一个数组或结构体定义到内存固定区域

Other Parts Discussed in Thread: CONTROLSUITE

最近在学习28377,想将一个数组或结构体定义到内存固定区域。

看了controlSuite中RAM_management的例程,该例程对数组的内存映射操作如下:

CPU1中:

uint16_t c1_r_array[256];   // mapped to GS0 of shared RAM owned by CPU02
uint16_t c1_r_w_array[256]; // mapped to GS1 of shared RAM owned by CPU01
#pragma DATA_SECTION(c1_r_array,"SHARERAMGS0");
#pragma DATA_SECTION(c1_r_w_array,"SHARERAMGS1");

CPU2中:

uint16_t c2_r_w_array[256];   // mapped to GS1 of shared RAM owned by CPU02
uint16_t c2_r_array[256];     // mapped to GS0 of shared RAM owned by CPU01
#pragma DATA_SECTION(c2_r_array,"SHARERAMGS1");
#pragma DATA_SECTION(c2_r_w_array,"0x0000c100");

看了两个CPU的map文件:

CPU1:

0000c000  _c1_r_array                          
0000d000  _c1_r_w_array

CPU2: 

 0000c000  _c2_r_w_array                  
0000d000  _c2_r_array

c1_r_array 和 c2_r_w_array的地址分配正好是一样的,c1_r_w_array和c2_r_array的地址正好是一样的,所以例程未做其他操作就可以在两个CPU间交换读写内存数据。

我不知道编译器的内存分配原则是什么,但是按照我的理解这样分配内存空间有“讨巧”的嫌疑,因为程序只是将c1_r_array分配到了SHARERAMGS0,而SHARERAMGS0是从 0x000c000开始的4K内存空间,照理说将c1_r_array随机分配到SHARERAMGS0中的任意位置应该都是合理的。只是因为这个程序中只定义了一个唯一的c1_r_array数组在GS0空间,所以在编译器中看上去无论怎么分配都是从0000c000开始。

我的疑问是:

1、以#pragma DATA_SECTION(c2_r_array,"SHARERAMGS1");语句为例,这样分配内存空间是否能保证每次c2_r_array分配的内存空间都是固定的?多次编译后会定义到该内存区段别的地方吗?(当然目前看,GS1中就这一个数组,每次都是从地址起始位置开始分配)

2、如果我加一个数组,比如c3_r_array,也定义到SHARERAMGS1,这样c2_r_array,c3_r_array的内存地址还会每次编译都一样吗?会不会出现不一样的情况?(我理解就算编译器每次分配的地址都一样,但是从理论上这俩数组的地址是可以随机改变的)

3、我可以用RAM_management中这种讨巧的内存分配方式吗?如果RAM_management中的内存定义操作不严谨,我应该如何操作才能将一个数组定义到内存的一个固定区域?

  • 在CMD文件中开出一块足够大的数据区,取个名字,如:buffRamPlace_cmd,然后在声明变量的地方这样声明一下:

    uint16_t c2_r_w_array[256];
    #pragma DATA_SECTION(c2_r_w_array,"buffRamPlace_cmd");

    这样就指定到这个区域了。
  • 这个方法我懂,您没看懂我的意思,我的问题是:
    您也说了,在CMD中开辟一个足够大的空间,比如空间名字叫buffRamPlace_cmd,起始地址和长度分别是origin =0x00A000, length = 0x001000 ,长度有4096 Word
    而我需要指定空间的数组uint16_t c2_r_w_array[256]只有256 Word长,远小于空间buffRamPlace_cmd大小。
    用#pragma DATA_SECTION(c2_r_w_array,"buffRamPlace_cmd");只是将c2_r_w_array指定到了这个内存区域,但是具体在内存的哪个区域如何确定?
    我理解这么指定空间,c2_r_w_array即可以是0x00A000+256,也可以是0x00A100+256,也可以是0x00A123+256。
    我需要的是确定的将c2_r_w_array定义到一个固定地址地址,0x00A000也可以,0x00A100也可以,0x00A123也可以
    #pragma DATA_SECTION(c2_r_w_array,"buffRamPlace_cmd");能实现这种功能吗?我觉得是有问题的,除非我开辟的空间buffRamPlace_cmd大小正好和c2_r_w_array一样
  • user3910573 说:
    这个方法我懂,您没看懂我的意思,我的问题是:
    您也说了,在CMD中开辟一个足够大的空间,比如空间名字叫buffRamPlace_cmd,起始地址和长度分别是origin =0x00A000, length = 0x001000 ,长度有4096 Word
    而我需要指定空间的数组uint16_t c2_r_w_array[256]只有256 Word长,远小于空间buffRamPlace_cmd大小。
    用#pragma DATA_SECTION(c2_r_w_array,"buffRamPlace_cmd");只是将c2_r_w_array指定到了这个内存区域,但是具体在内存的哪个区域如何确定?
    我理解这么指定空间,c2_r_w_array即可以是0x00A000+256,也可以是0x00A100+256,也可以是0x00A123+256。
    我需要的是确定的将c2_r_w_array定义到一个固定地址地址,0x00A000也可以,0x00A100也可以,0x00A123也可以
    #pragma DATA_SECTION(c2_r_w_array,"buffRamPlace_cmd");能实现这种功能吗?我觉得是有问题的,除非我开辟的空间buffRamPlace_cmd大小正好和c2_r_w_array一样

    是的,我认为就是你最后说的这种方法。

    除非我开辟的空间buffRamPlace_cmd大小正好和c2_r_w_array一样

    如果你希望很精确的确定数组的存放位置,就是要为每一个数组指定和它大小完全一致的存储空间,指定起始地址并命名,然后按照上面的语句来逐个声明。

    不知道这样做会对你的系统有什么不良的影响吗?你有何顾虑而不这样操作呢?