Вынудить компилятор / компоновщик группировать переменные (физически в последовательных местах ОЗУ), как определено - PullRequest
0 голосов
/ 27 апреля 2018

Как я могу принудить компилятор (с предполагаемыми переключателями опций) сгруппировать переменные в физическом последовательном расположении ОЗУ в определенном порядке? Мне действительно все равно, где он начинается (то есть - где он помещает MinWaitTime. Однако FaultCode должен быть расположен сразу после MinWaitTime в ОЗУ. Он не может поместить его где-то еще.

Я думал о создании раздела, но это будет гарантировать только то, что они размещены вместе, и не обязательно в том порядке, в котором они были определены.

Я знаю, что мог бы создать и создать массив, чтобы вызвать проблему, но я бы хотел ее избежать.

Есть предложения?

Например, если MinWaitTime был по адресу 0x20000000, я хочу, чтобы FaultCode был определен в 0x20000002, а все остальные переменные в этом порядке.

unsigned short  MinWaitTime;        // reg 450

unsigned short  FaultCode;          // reg 451

unsigned short  FaultReg1;          // reg 452

unsigned short  FaultReg2;          // reg 453

unsigned short  Reserved2;          // reg 454

unsigned short  Reserved3;          // reg 455

unsigned short  SystemStatusReg1;   // reg 456

unsigned short  SystemStatusReg2;   // reg 457

Компилятором является GCC.

1 Ответ

0 голосов
/ 28 апреля 2018

Есть несколько способов подойти к этому.

struct + макросы

Самый простой способ - просто использовать структуру, возможно, с макросами:

struct {
    unsigned short MinWaitTime;
    unsigned short FaultCode;
    ...
} vars;

#define MinWaitTime (vars.MinWaitTime)
#define FaultCode (vars.FaultCode)
...

Это хорошо, потому что это именно то, для чего предназначена структура, но макросы не очень хороши.

Теоретически, " глобальная анонимная структура " сделает это так, что вы можете сделать это без макросов, но этого не существует.

Мнение: Я бы использовал структуру, но без макросов.

сборка

Другой способ сделать это - с небольшой помощью сборки. Вы можете создать отдельный исходный файл сборки со следующим кодом:

    .data
    .align 2

    .globl MinWaitTime
MinWaitTime:
    .zero 2

    .globl FaultCode
FaultCode:
    .zero 2

    .globl FaultReg1
FaultReg1:
    .zero 2

    .globl FaultReg2
FaultReg2:
    .zero 2

Это определяет переменные по последовательным адресам. Затем вы можете получить к ним доступ из C, просто объявив их extern где-нибудь в вашем исходном коде C:

extern unsigned short MinWaitTime;
extern unsigned short FaultCode;
extern unsigned short FaultReg1;
extern unsigned short FaultReg2;

extern необходим только для того, чтобы вы не получили повторяющиеся определения.

Затем скомпилируйте и свяжите файлы C и сборки вместе.

Примечания

Обратите внимание, что здесь мы явно не заинтересованы в переносимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...