Расширение макроса на один уровень в C - PullRequest
1 голос
/ 27 марта 2020

Я работаю в библиотеке, которая является интерфейсом к другим библиотекам с несколькими определенными макросами, такими как:

#define GPIOx  some stuff
#define __HAL_RCC_GPIOx_CLK_ENABLE() some other stuff

, где x - это буква (A, B, C, ...) .

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

В библиотеке, в которой я работаю, я пытаюсь определить некоторые другие макросы, которые пользователь может изменять, например:

#define DHT_GPIO_Port  GPIOx

И я хочу определить макрос, который использует такое определение для генерации другого имени макроса:

#define __HAL_DHT_CLK_ENABLE(DHT_GPIO_Port)  __HAL_RCC_## DHT_GPIO_Port ##_CLK_ENABLE()

Это потому, что я хочу использовать макрос для моей библиотеки вместо __HAL_RCC_GPIOx_CLK_ENABLE (), поскольку он будет отличаться в зависимости от того, какой GPIO определен пользователем.

Однако, когда я пытаюсь использовать мой макрос __HAL_DHT_CLK_ENABLE (DHT_GPIO_Port), он расширяется до __HAL_RCC_DHT_GPIO_Port_CLK_ENABLE (), а не __HAL_RCC_GPIOx_CLK_ENABLE ().

С другой стороны, я пытался поместить его в другой макрос, однако он расширяет и GPIOx, который мне не нужен.

Возможно, это вопрос новичка, но не могли бы вы помогите раскрыть только первый уровень макроса DHT_GPIO_Port в конкатенации другого макроса?

Ответы [ 2 ]

1 голос
/ 27 марта 2020

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

#define SINLINE static inline __attribute__((always_inline))

SINLINE void  __HAL_DHT_CLK_ENABLE(GPIO_TypeDef * const gpio)
{
    switch((uint32_t)gpio)
    {
        case (uint32_t)GPIOA:
            __HAL_RCC_GPIOA_CLK_ENABLE();
            break;
        case (uint32_t)GPIOB:
            __HAL_RCC_GPIOA_CLK_ENABLE();
            break;
        case (uint32_t)GPIOC:
            __HAL_RCC_GPIOA_CLK_ENABLE();
            break;
    }
}

Когда вы включаете оптимизацию и вызываете ее с постоянным выражением (например, GPIOA. GPIOB et c switch ... case будет оптимизировано. Вы также сможете вызывать его с неконстантным параметром - что нельзя сделать с макросом.

Избегайте таких макросов, как табличка.

0 голосов
/ 27 марта 2020

Должно работать следующее:

#define __HAL_DHT_CLK_ENABLE_(DHT_GPIO_Port)  __HAL_RCC_## DHT_GPIO_Port ##_CLK_ENABLE()

определить __HAL_DHT_CLK_ENABLE (DHT_GPIO_Port) __HAL_DHT_CLK_ENABLE_ (DHT_GPIO_Port)

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

__HAL_DHT_CLK_ENABLE(GpioA)
: * *1007* 1009 *
__HAL_RCC_GpioA_CLK_ENABLE()
...