ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
24 ноября
1042009 Топик полностью
teap0t (04.10.2020 15:21 - 16:05, просмотров: 947) ответил teap0t на Несколько интервью по личным вопросам. Продолжение_5. Продолжение_4 по ссылке.
#15 Разбирая библиотеки обнаружил такой вид адресной арифметики. Насколько такой метод подходит/не_подходит под понятие "говнокод"? Имеем такой фрагмент (коменты мои): (UPD подправил слегка) 
   EXTI_InitTypeDef     EXTI_InitStructure;
   <заполняем структуру>
   EXTI_Init( &EXTI_InitStructure );

Далее библиотека:

typedef struct
{
   uint32_t             EXTI_Line;      /* !< Specifies EXTI lines need for configuration. This is a combination of @ref EXTI_Lines */
   EXTIMode_TypeDef     EXTI_Mode;      /* !< Specifies interrupt or event mode for the EXTI lines. (offset to reg) */
   EXTITrigger_TypeDef  EXTI_Trigger;   /* !< Specifies active edge for the EXTI lines. (offset to reg) */
   FunctionalState      EXTI_LineCmd;   /* !< Specifies the new state of the selected EXTI lines. (ENABLE or DISABLE) */
} EXTI_InitTypeDef;

typedef enum
{
   EXTI_Mode_Interrupt  = 0x00,         /* Offset to EXTI_IMR reg */
   EXTI_Mode_Event      = 0x04          /* Offset to EXTI_EMR reg */
} EXTIMode_TypeDef;

И собственно функция:

void     EXTI_Init( EXTI_InitTypeDef* EXTI_InitStruct )
{
   uint32_t tmp;
   tmp = (uint32_t)EXTI_BASE;           /* 0x40010400 */
   <...>
   tmp += EXTI_InitStruct->EXTI_Mode;   /* Долго зависал здесь и хотел задать вопрос залу, но таки превозмог */
   *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
   <...>

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


Вопрос: правильно ли это?

Дальше, кстати, идёт такое:

      /* Select the trigger for the selected external interrupts */
      if (EXTI_InitStruct->EXTI_Trigger == EXTI_Trigger_Rising_Falling) {
         /* Both edges. Use direct modification for both regs. */
         EXTI->RTSR |= EXTI_InitStruct->EXTI_Line;
         EXTI->FTSR |= EXTI_InitStruct->EXTI_Line;
      } else {
         /* One edge: use indirect modification */
         tmp = (uint32_t)EXTI_BASE;
         tmp += EXTI_InitStruct->EXTI_Trigger;

         *(__IO uint32_t *) tmp |= EXTI_InitStruct->EXTI_Line;
      }

Почему, собственно, и спросил. Они в одной функции применяю два вида обращения к регистрам: прямую запись и косвенное обращение и использованием адресной арифметики. Когда разобрался, понятно, но глаз/мозг корябает.

Это я, здравствуйте. http://the-epic-file.com/bookshelf.htm