Allocate two global arrays in contiguous memory in C99

126 Views Asked by At

I want to write some unit tests for a flash access module. I have

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

I thought that is perfect to inject my own array as flash content since in the application these symbols are provided via linker file. In my test I would like something like:

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

But I need the second array to start exactly after the first one. I tried a lot but I could not get it to work for me. Is there a way to fulfill the given declaration and have consecutive arrays in memory?

[Edit 1/2021]

I need _internal_flash_end to be located at the address of _internal_flash_start + sizeof(_internal_flash_start) since the code MUST reference the arrays through these names.

1

There are 1 best solutions below

5
On

I need the second array to start exactly after the first one.

Form a struct

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

Still it is possible that there is padding between members: certainly unlikely with char_t [2048].

An implementation specific packed would insure no padding.


A pedantic solution would create one array and use pointers to sections of it. Yet now we have 2 pointers, not two arrays. Their sizeof will differ from above.

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

OP adds:

I need _internal_flash_end to be located at the address of _internal_flash_start + sizeof(_internal_flash_start) since the code MUST reference the arrays through these names.

Solvable with a union and define. _internal_flash_start remains an array.

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)

Usage

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

Output

0x10040b020
0x10040b820
2048
  

Should code require _internal_flash_end as an array and not just a pointer, use an implementation specific packed as available.

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)