Вызов функции с символом «&» перед именем функции - PullRequest
0 голосов
/ 15 января 2019

Я использую NXP SDK для проекта. SDK содержит несколько примеров кодов. Один из этих примеров называется «lpuart_interrupt». В этом примере функция LPUART_GetStatusFlags используется следующим образом:

    /* If new data arrived. */
    if ((kLPUART_RxDataRegFullFlag)&LPUART_GetStatusFlags(DEMO_LPUART))
    {
      ...

Чего я не понимаю, так это почему перед именем функции стоит символ «&»? Как должна работать функция, когда она вызывается таким образом?

Прототип функции выглядит следующим образом:

    uint32_t LPUART_GetStatusFlags(LPUART_Type *base);

kLPUART_RxDataRegFullFlag является частью следующего перечисления:

    enum _lpuart_flags
    {
        kLPUART_TxDataRegEmptyFlag = (LPUART_STAT_TDRE_MASK),
        kLPUART_TransmissionCompleteFlag = (LPUART_STAT_TC_MASK),
        kLPUART_RxDataRegFullFlag = (LPUART_STAT_RDRF_MASK),
        ...
    }

и LPUART_STAT_RDRF_MASK определены следующим образом:

    #define LPUART_STAT_RDRF_MASK (0x200000U)

1 Ответ

0 голосов
/ 15 января 2019

Амперсанд используется в этом случае для вызова побитового оператора И между возвращаемым значением функции LPUART_GetStatusFlags и константой LPUART_STAT_RDRF_MASK.

Использование побитового оператора AND, подобного этому, является обычным способом проверить, установлен ли определенный флаг.

В вашем случае значение kLPUART_RxDataRegFullFlag равно 0x200000, соответствующее битовой комбинации 0000 0000 0010 0000 0000 0000 0000 0000.

Таким образом, побитовая операция И оценивается как ноль, если бит 32 не установлен в 32-битном возвращаемом значении функции LPUART_GetStatusFlags. Если он установлен, результат будет ненулевым, и будет выполнен код, защищенный предложением if.

Путем введения вспомогательной функции, такой как эта, цель предложения if будет легче понять.

static int RxDataRegisterIsFull(LPUART_Type *const uart)
{
    const uint32_t flags = LPUART_GetStatusFlags(uart);
    const uint32_t mask = kLPUART_RxDataRegFullFlag;
    return (flags & mask) ? 1 : 0;
}

/* If new data arrived. */
if (RxDataRegisterIsFull(DEMO_LPUART))
{
    ...
...