2014-10-02 2 views
0

Я пишу заголовочный файл со структурированной схемой. Моя цель - определить базовый адрес, который будет увеличиваться после вызова другого макроса. Цель этого заключается в том, чтобы сохранить текущий счет нового базового адреса и проверить во время компиляции, превышает ли он максимальный физический адрес.Непрерывно увеличивайте значение макроса после вызова другого макроса

Ранее я думал об использовании глобальной переменной для подсчета адреса, но это было бы разрешено во время выполнения, и я требую этого во время компиляции, прежде чем вывести любой двоичный код, чтобы предотвратить возможное повреждение памяти.

Вот что я имею в виду, например:

Ниже то, что я хочу заголовочный файл слишком похож на осмотр (или что-то эквивалент):

#define DRAM_DEFINE_PTR    0x30000000 
#define DRAM_DATA1_BASE    0x30000100 
#define DRAM_DATA1_SIZE    0x050 
#define DRAM_DATA2_SIZE    0x400 
#define DRAM_DATA3_BASE    0x30000600 
#define DRAM_DATA3_SIZE    0x300 

#define DRAM_DEFINES(x,y)   (...) 
// store base 'x' and size 'y' in a structure and increment DRAM_DEFINE_PTR accordingly 

1.  DRAM_DEFINES (DRAM_DATA1_BASE,  DRAM_DATA1_SIZE) 
2.  DRAM_DEFINES (0x0,     DRAM_DATA2_SIZE) //base is previous base + size 
3.  DRAM_DEFINES (DRAM_DATA3_BASE,  DRAM_DATA3_SIZE) 
// more DRAM_DEFINES 

В действительности, блок кода ниже, расширяющие линии 1 и 2, чтобы быть:

1.  DRAM_DEFINES (0x30000100,  0x50) 
     // DRAM_DEFINE_PTR now equals 0x30000150 

2.  DRAM_DEFINES (0x30000150, 0x400) 
     // DRAM_DEFINE_PTR now equals 0x30000550 

3.  DRAM_DEFINES (0x30000600 , 0x300) 
     // DRAM_DEFINE_PTR now equals 0x30000900 
and so on 

, а затем в конце файла есть проверка #error, чтобы гарантировать, что мы не переходили границу

#if (DRAM_DEFINE_PTR > 0x40000000) 
    #error "\nCAPACITY EXCEEDED by ", DRAM_DEFINE_PTR - 0x40000000, " bytes" 
#endif 

Как мы можем видеть выше, не все области памяти должны использоваться полностью. Как между 2 и 3, существует 50 байт буфера. Таким образом, это означает, что базовые адреса могут быть либо

  • трудно закодированных значений с помощью #define ИЛИ
  • смещения от базы предыдущего региона + размера

предыдущего региона Возможно ли это в компиляторе I» м с использованием (ARMCC RVCT 5.03)?

Заранее спасибо

ответ

1

Вы можете обновить значение макроса в процессе перевода одного устройства с использованием библиотеки ускорителя Preprocessor's evaluated slots functionality. Он определяет несколько «слотов», которые могут быть обработаны как изменяемые глобальные переменные кодом препроцессора, что позволит вам добавить к значению по мере продвижения, а не постоянно определять его с помощью одного фиксированного выражения. Это чистая стандартная совместимая C (или C++).

Основная синтаксическая неудобство заключается в том, что вам необходимо дать операции обновления двум линиям для себя, поскольку она питается от пары #define/#include.

#define DRAM_PTR_SLOT 2 // any slot 
#define DRAM_DEFINE_PTR BOOST_PP_SLOT(DRAM_PTR_SLOT) 
#define SET_DRAM_DEFINE_PTR BOOST_PP_ASSIGN_SLOT(DRAM_PTR_SLOT) 

#define BOOST_PP_VALUE 0x30000100 + 0x50 
#include SET_DRAM_DEFINE_PTR // DRAM_DEFINE_PTR now evals to 0x30000150 

#define BOOST_PP_VALUE DRAM_DEFINE_PTR + 0x50 
#include SET_DRAM_DEFINE_PTR // DRAM_DEFINE_PTR now evals to 0x300001A0 

Это не чрезвычайно элегантно - нет никакого способа, чтобы упаковать директиву внутри другого макроса, так что вы не можете скрыть это в синтаксисе, как в вопросе - но вы могли бы, по крайней мере, скрыть Увеличьте имена под некоторыми макросами обертки, специфичными для конкретной области.

+0

Ничего себе, это почти то, что я искал, кроме части директивы, но я взломал способ сделать это. Вместо того, чтобы использовать токен '#' для определения под-директивы, я использую бессмысленный, например, '@@', который затем заменяю на «#» после запуска CPP один раз. Это немного хаки, но это работает. Спасибо за вашу помощь @ Леушенко. – soplu

1

Почему бы вам не использовать глобальную переменную для хранения адреса?

+0

Я рассмотрел это ранее, но значения не будут разрешены до времени выполнения, и я требую эту проверку во время компиляции.Для любопытных в моем примере вы «#define DRAM_DEFINE_PTR globalVar», а затем выполните арифметику по мере необходимости в макросе. – soplu

0

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

Смежные вопросы