【问题标题】:Allocate two global arrays in contiguous memory in C99在 C99 中的连续内存中分配两个全局数组
【发布时间】:2020-12-20 17:56:48
【问题描述】:

我想为闪存访问模块编写一些单元测试。我有

extern char_t _internal_flash_start[]; /**< Exported from ICF file. */
extern char_t _internal_flash_end[]; /**< Exported from ICF file. */

我认为将我自己的数组作为闪存内容注入是完美的,因为在应用程序中这些符号是通过链接器文件提供的。在我的测试中,我想要这样的东西:

char_t _internal_flash_start[2048]; /**< Exported from ICF file. */
char_t _internal_flash_end[1];

但我需要第二个数组在第一个数组之后开始。我尝试了很多,但我无法让它为我工作。有没有办法实现给定的声明并在内存中有连续的数组?

[编辑 1/2021]

我需要_internal_flash_end 位于_internal_flash_start + sizeof(_internal_flash_start) 的地址,因为代码必须通过这些名称引用数组。

【问题讨论】:

  • 我仍然在给定的答案中看不到有效的解决方案。我需要 _internal_flash_end 位于 _internal_flash_start + sizeof(_internal_flash_start) 的地址,因为代码必须通过这些名称引用数组。
  • 这样的任务通常不会在 C 中完成,而是通过指示链接器定义符号或使用汇编语言来完成。

标签: arrays c static-memory-allocation


【解决方案1】:

我需要第二个数组在第一个数组之后开始。

形成struct

struct my_data {
  char_t _internal_flash_start[2048]; /**< Exported from ICF file. */
  char_t _internal_flash_end[1];
} x;

仍然可能成员之间存在填充:char_t [2048] 肯定不太可能。

特定于实现的packed 将确保没有填充。


一个迂腐的解决方案会创建一个数组并使用指向它的各个部分的指针。然而现在我们有 2 个指针,而不是两个数组。他们的sizeof 会与上面不同。

char_t _internal_flash[2048+1];
char_t *_internal_flash_start = &_internal_flash[0];
char_t *_internal_flash_end   = &_internal_flash[2048];

OP 补充:

我需要_internal_flash_end 位于_internal_flash_start + sizeof(_internal_flash_start) 的地址,因为代码必须通过这些名称引用数组。

可以用uniondefine 解决。 _internal_flash_start 仍然是一个数组。

union {
  char_t both[2048 + 1];
  char_t start[2048];
} _internal_flash;
#define _internal_flash_start (_internal_flash.start)
#define _internal_flash_end (_internal_flash_start + sizeof _internal_flash_start)

用法

int main() {
  printf("%p\n", _internal_flash_start);
  printf("%p\n", _internal_flash_end);
  printf("%zu\n", sizeof _internal_flash_start);
}

输出

0x10040b020
0x10040b820
2048
  

如果代码需要 _internal_flash_end 作为数组而不仅仅是指针,请尽可能使用特定于实现的 packed

struct __attribute__((packed)) { // gcc specific
  char_t start[2048];
  char_t end[1];
} _internal_flash;
#define _internal_flash_start (_internal_flash.start)
#define _internal_flash_end   (_internal_flash.end)

【讨论】:

  • 谢谢。好吧,您的第一种方法将这两个符号放在一个结构中。但是这样我就不能通过他们的名字直接访问它们,这在我的场景中当然是必要的。您的第二种方法有效。确实,我已经试过了。它对我不起作用,因为在我的第一次测试中,我只需要数组地址而不是它们的内容。 Visual Studio 优化了整个数组,我很想知道为什么 start 和 end 的地址仅以 4 个字节分隔 - 指针本身的大小。
  • 对不起,一开始我以为它会这样工作,但事实并非如此。我在测试中得到了所需的数组。但是到生产代码中的两个数组(数组,而不是指针)的映射不起作用。进入测试代码,我看到测试代码中的数组与生产代码中的两个符号位于不同的地址。但我只在地图文件中看到过一次符号。我很生气。
  • @AlexanderStippler “但是这样我就不能通过他们的名字直接访问它们,这在我的场景中当然是必要的”——代码可以通过x._internal_flash_startx.internal_flash_end 直接访问它们。
  • 当然是在结构内部。但是我想要的是使用在生产代码中声明的两个符号作为外部符号并且未定义,因为在生产代码中这些值是由链接描述文件提供的。我想创建一个用于测试的存根闪存区域内容。因此,我无法将名称封装在结构中。
  • @AlexanderStippler 代码可以使用 2 个返回数组地址的函数吗?函数的实现将访问公共的struct
猜你喜欢
  • 2016-12-30
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 2018-02-03
  • 2013-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多