STM32 без HAL и SPL

Комментарии 9

  • 11.09.17 в 11:40

    +1

    Офигеть.
  • 6682d3c164487203cfdf90371c1e02db_small.j

    11.09.17 в 11:57

    +2

    В чем смысл, Бэрримор?!
    Одноразовый вызов функции или «две строчки», кроме повышенной когнитивной нагрузки как на писателя, так и на будущего читателя — разницы нет.
    Так ради чего?

  • 11.09.17 в 12:22

    +2

    Можно и через регистры, но какие будут плюсы?
    Я вижу только минусы:
     — Переносимость кода никакая, по сравнению с HAL. Вот прибежит завтра начальник и скажет: давай свой код, который ты писал по STM32F4 запусти на STM32F2, срок до вечера. И все, копай инициализацию по новой.
     — Читаемость регистрового кода — никакая, нужно постоянно смотреть в ДШ
  • 11.09.17 в 12:23

    +2

    Помнить регистры между семействами это ещё та задача, а они разные, да да разные регистры, не говоря уже про биты. Удобство подобной манипуляции очень сомнительно ввиду того, что стандартный хидер от стм не даёт никакой информации о том что это к примеру за биты: почему их 3, зачем мне нужны именно они? нет никакой информации о запрещённых комбинациях (а их к слову очень много, и порой можно сделать так и так, но нельзя сделать вот так и ещё 10 раз как).

    Неудобно писать:

    // Alternate function mode
    GPIOA->MODER &= ~GPIO_MODER_MODER8_0; //0
    GPIOA->MODER |= GPIO_MODER_MODER8_1; //1
    

    Зато какое удовольствие писать вот так (код взят из реального проекта, и на выходе по ассемблерному выхлопу он даёт тоже самое что и выше, при одинаковых флагах оптимизации):

    // enable usart3 pins,
        // connect to alternative func 7 (usart)
        hal::gpiod::set_mode();
        hal::gpiod::set_alt_func();
    

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

  • e010f70940a5e28f22a7a1c44d3f8326_small.j

    11.09.17 в 12:31

    +2

    Основной смысл библиотек SPL и HAL — не снизить порог вхождения (хотя и это тоже), а отделить друг от друга низкоуровневую и высокоуровневую части ПО.

    Хорошо, железо вы проинициализировали прямой записью в регистры. А обращаться к этому железу в процессе работы так же будете? Нужно в программе поднять ногу порта — пишем

    GPIOA->BSRR = (1<<15);
    в сотне разных мест. А потом понадобилось сменить ногу с 15 на 16, например. Искать все эти 100 мест в коде и менять везде? Конечно, нет. Надо написать функцию-обёртку (или макрос) для управления портом. И ещё пару для UART. И еще штуки три для таймеров. И несколько для DMA…

    Вот и написали собственную библиотеку для работы с периферией. От чего убегали, к тому и пришли.

    • 11.09.17 в 13:13

      0

      Для управления пинами обычно использую такой дефайн:
      #define Work_Led_ON GPIOB→BSRR = GPIO_BSRR_BS_2; //Port B Set bit 2
      #define Work_Led_OFF GPIOB→BSRR = GPIO_BSRR_BR_2; //Port B Reset bit 2
      • 11.09.17 в 13:22

        0

        А чем это лучше библиотеки? Ответ: ничем. Так как это мало того что макрос (кстати без изоляции от побочных эффектов). Так и ещё макрос с кучей зафиксированных значений, что опять же снижает понятность кода при отладке и превращает в лапшу итоговый код.
      • 11.09.17 в 13:58

        0

        А чем не устраивает HAL_GPIO_WritePin (GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
        ?
        Под капотом
        void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
        {
          /* Check the parameters */
          assert_param(IS_GPIO_PIN(GPIO_Pin));
          assert_param(IS_GPIO_PIN_ACTION(PinState));
        
          if(PinState != GPIO_PIN_RESET)
          {
            GPIOx->BSRR = GPIO_Pin;
          }
          else
          {
            GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
          }
        }
  • 11.09.17 в 12:43

    0

    Когда по какой-либо причине не использую библиотеки, для улучшения читаемости кода использую макросы, как, к примеру, предлагает уважаемый ZiB: ziblog.ru/2012/09/09/linii-vvoda-vyivoda-stm32-chast-3.html
    В этом случае мы работаем напрямую с регистрами, но пишем вполне прозрачный код:
    #define PIN_LED	D, 12, LOW, MODE_OUTPUT_PUSH_PULL_PULL_DOWN, SPEED_2MHZ, AF_NO
    // Здесь все просто:	D - порт, 12 - пин, режимы и т. д.
    
    void main(void)
    {
    	PIN_ON(PIN_LED);
    	// И т. д.
    }
    

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

© Habrahabr.ru