Структура внутри союза, статус UART - PullRequest
1 голос
/ 25 марта 2019

Я использую код MPLABX IDE MCC. В некоторый момент в драйвере UART есть следующий код для состояния UART.

typedef union {
    struct {
      unsigned perr : 1;
      unsigned ferr : 1;
      unsigned oerr : 1;
      unsigned reserved : 5;
    };
    uint8_t status;
}uart1_status_t;

Насколько я понимаю, в объединении есть 2 типа, 1 структура и 1 8-битная переменная без знака. У меня есть 2 вопроса:

  1. что на самом деле ... perr: 1; Что здесь сделано? тип не указан, только без знака написано и что такое ": 1"? Это не значение, данное perr? Когда я попробовал это на компиляторе C, я увидел, что это на самом деле биты переменной состояния. perr и ferr - 0-й и 1-й биты, но oerr - 4-й? Почему?
  2. Структура не имеет «экземпляра», так как я могу получить к нему доступ? Я запутался в этом разделе. Поскольку это объединение, эти биты и переменная состояния хранятся в одной и той же ячейке памяти, поэтому всякий раз, когда я пытаюсь получить доступ к состоянию, это также означает доступ к этим значениям perr, ferr, oerr? Это правильно?

Ответы [ 2 ]

3 голосов
/ 25 марта 2019
  1. Это распространенный (неправильный) способ объявления аппаратных регистров. Структура является битовым полем, и отдельные члены ссылаются на биты в 8-битном регистре. Синтаксис позволяет вам получить доступ либо к отдельным битам, либо ко всему регистру.

    В этом случае структура является анонимной, поэтому, если у вас есть uart1_status_t u1;, вы можете получить доступ к битам как u1.perr, а не u1.somename.perr. Анонимные структуры - это функция C11, хотя в данном случае это, вероятно, нестандартное расширение, которое они использовали до C11.

    Они используют unsigned, что означает unsigned int, поскольку это тип по умолчанию для битовых полей. Но обратите внимание, что этот код полностью непереносим и основан на определенной реализации компилятора битовых полей.

  2. В других местах у вас будет что-то вроде volatile uart1_status_t* UART1_STATUS = ..., указывающее на абсолютный адрес. (Вероятно, также с некоторым нестандартным синтаксисом, таким как @.) Поскольку это аппаратные регистры с отображением в памяти, они уже есть в MCU, и вы не выделяете для них место.

1 голос
/ 25 марта 2019
  1. Этот вопрос является дубликатом, ответ: «это битовые поля, числа после двоеточий указывают ширину поля в битах». Вот более ранний вопрос с хорошим ответом .
  2. Возможно, где-то есть макрос, который предоставляет адрес приведения регистра к нужному типу и получает имя из документации процессора.
...