Макрос препроцессора: создание указателя из целочисленного содержимого - PullRequest
0 голосов
/ 14 апреля 2020

Я хотел бы создать макрос препроцессора, который преобразует целое число, представляющее адрес, в указатель. Это для разработки MCU.

Например, регистры определены как

#define SOME_REGISTER 0x05 // This the the address of SOME_REGISTER

Итак, я определил следующий макрос:

#define REG_ADDR(reg) (*((volatile uint8_t*) reg))

И когда я хочу ' t использовать его

volatile uint8_t * reg_ptr = REG_ADDR(SOME_REGISTER)

Но, конечно, я получаю предупреждение makes pointer from integer without a cast [-Wint-conversion] 1013 *

Есть ли чистый способ сделать это?

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

Ответы [ 2 ]

4 голосов
/ 14 апреля 2020

Обычно вы просто определяете такие регистры как #define SOME_REGISTER (*(volatile uint8_t*) 0x05) без дополнительного шага.

Сообщение компилятора приходит, потому что макрос написан с разыменованием *, чтобы его можно было использовать как обычная переменная. Таким образом, вы будете читать / писать напрямую в регистр, без локальной переменной указателя между ними.

Если это не то, что вам нужно, то либо не используйте регистр таким образом, либо измените код на этот :

volatile uint8_t* reg_ptr = &REG_ADDR(SOME_REGISTER);

& у вызывающего и * внутри макроса взаимно отменят друг друга.

1 голос
/ 14 апреля 2020

Вы можете повторно использовать уже существующий, проверенный код, выпущенный с соответствующей лицензией. Например, вы можете использовать код mmio.h от Arm, его можно найти в репозитории git для прошивки Arm Trusted, в каталоге include/lib.

В вашем примере , вы бы использовали функцию mmio_read_8() из mmio.h:

static inline uint8_t mmio_read_8(uintptr_t addr)
{
    return *(volatile uint8_t*)addr;
}

Результирующий код будет:

volatile uint8_t * reg_ptr = mmio_read_8((uintptr_t) SOME_REGISTER);
...