Перейти к содержанию
    

VladislavS

Свой
  • Постов

    1 240
  • Зарегистрирован

  • Посещение

  • Победитель дней

    9

Сообщения, опубликованные VladislavS


  1. 4 минуты назад, SDFV сказал:

    У Cortex-M4 регистры только AFR[0] и AFR[1] ?

    Это косяк STM. В документации эти регистры называются AFRL и AFRH, а в поставляемом заголовочном файле описаны как массив из двух регистров. Примите это как есть и не создавайте проблему там где её нет.

  2. Странное сравнение. Либо оба компилятора на оптимизацию по размеру и сравнивать размер, либо оба на скорость и сравнивать скорость. Сравнивать размер при оптимизации по скорости, по меньшей мере, странно.

    Для GCC -fno-exceptions -fno-rtti  -flto для embedded еще уместно.

  3. В 15.07.2022 в 15:36, locale сказал:

    Возможно такое?

    Возможно. Один из каналов АЦП заведён на внутренний опорник. По нему и калибруешься. Есть ли подобное в вашем чипе - читайте даташит.

     

    PS: Всё гораздо проще. АЦП от внутреннего референса умеет работать.

    image.thumb.png.ad804a09d86c0b9a318f81d471aea639.png

  4. У меня 99% отладок вообще в ОЗУ происходит. Если это действительно контроллер для суровых режимов, а не GUI какой-нибудь, то в современых чипах ОЗУ обычно хватает. А если это GUI, то и суровых условий не будет. Отладил, прошил во флэш и в продакшн. 

  5. В 06.06.2022 в 17:11, razrab83 сказал:

    А если завтра вам нужно перейти на ПЛИС? Зачем вам знания перефирии стм32?

    Ох, как же вы заблуждаетесь. Докладываю - в ПЛИС сейчас такое же кубоводство. Открываете Vivado, накидываете туда кубиками микропроцессор, периферию к нему, синтезируете схему. Запускаете Vitis, чтобы всё это дело программировать, а там вместо HAL уже XIL с нагенерённым под вашу схему кодом. Вроде всё зашибись, но начинаете дрыгать ногой, а оно ТОРМОЗИТ. На ПЛИС торомозит. Спрашиваешь у коллег-плисоводов, что за на? В ответ - так GPIO в плис медленный. Как так? Ну вот так. И живут с этим. Начинаем разбираться, а чего же оно тормозит то? Оказывается, порт не имеет регистров, хранящих своё состояние. Вместо этого функции библиотеки XIL  для работы c портом хранят его состояние в ОЗУ. Чтобы дёрнуть ногой надо прочитать из ОЗУ состояние порта, изменить его, сохранить обратно на будущее и записать новое состояние в порт. Еще и обернуть это всё средствами обеспечения атомарности. Упасть не встать. Ну ладно, выгоняем плисоводов, берём в руки Verilog и пишем свой порт на подобии STM32-шного с BSRR-ами, куртизанками и toggle, благо тут мы ограничены только фантазией. В результате ускоряемся раз в 10 минимум. Но всё равно, как-то не шустро получается - 4-6 тактов запись в порт. Смотрим, а висит то этот порт на AXI-шине, которая простая и удобная, но медленная. Берём в руки Verilog вторично и перевешиваем порт на шину процессора. Вуаля, 1-2 такта на дрыганье ноги. Так что, везде одно и то же. Кто-то кубики собирает, а кто-то понимает как оно устроено под капотом.

  6. 2 часа назад, uni сказал:

    - заменить файлы из папки cpp;

    Ну, лезть в заголовочные файлы, поставляемые с компилятором, это совсем не дело. Такие вещи надо в своём коде делать.

    #ifdef __ICCARM__
    namespace std
    {
    
    template< class T >
    inline constexpr bool is_enum_v = is_enum<T>::value;
    
    template< class T, class U >
    inline constexpr bool is_same_v = is_same<T, U>::value;
    
    template< class Base, class Derived >
    inline constexpr bool is_base_of_v = is_base_of<Base, Derived>::value;
    
    template <typename T>
    inline constexpr size_t alignment_of_v = alignment_of<T>::value;
      
    }
    #endif

     

  7. Я вообще не понямаю какого рожна там происходит. Ну загрузили два 32-битных беззнаковых аргумента, вызвали функцию. От результа надо взять один байт. Что там за хрень вместо этого происходит?

  8. 1 час назад, jcxz сказал:

    А если немного подумать, то наверняка можно и в compile-time его посчитать.

    Как-то посчитать, конечно же, можно. Есть даже готовые библиотеки - gcem

    Но тут только и жди где ногу прострелишь.

    #include "gcem.hpp"
    
    constexpr float volt  = 630.5f;
    constexpr float volt_max  = volt/0.707f;
    
    void foo5() // Так тоже можно
    {
      if constexpr (gcem::log(volt_max)>10.0f) __NOP(); else __BKPT(0);
    }

     

  9. 18 часов назад, natsu сказал:

    Вот как с этим бороться? 

    В простых случаях стоит переползать не плюсы и пользоваться constexpr.  В примере foo1 гарантировано выберет нужную ветку на этапе компиляции. В foo2 это  уже зависит от оптимизации. Препроцессор, как вы уже поняли, с плавучкой вообще не работает.

    18 часов назад, natsu сказал:

    А ведь дальше у меня ветвление в зависимости от логарифма подобной константы

    А вот тут всё плохо. foo3 будет вычислять log в рантайме, а в foo4 ошибка компиляции. Выбирайте что хуже. К сожалению, это так и на сегодня ничего с этим не сделать.

    #include <cmath>
    
    #define VOLT 630.5f
    #define VOLT_MAX (VOLT/0.707f)
    
    constexpr float volt  = 630.5f;
    constexpr float volt_max  = volt/0.707f;
    
    void foo1() // Всё хорошо
    {
      if constexpr(volt_max > 1000.0f) __NOP(); else __BKPT(0); 
    }
    
    void foo2() // Зависит от оптимизации
    {
      if (VOLT_MAX > 1000.0f) __NOP(); else __BKPT(0); 
    }
    
    void foo3() // Вычисление log во время выполнения
    {
      if (log(VOLT_MAX)>10.0f) __NOP(); else __BKPT(0);
    }
    
    void foo4() // Ошибка компиляции
    {
      if constexpr (log(volt_max)>10.0f) __NOP(); else __BKPT(0);
    }

     

    9 часов назад, Darth Vader сказал:

    И главное. Файлы .h - это НЕ ФАЙЛЫ ОПРЕДЕЛЕНИЙ!

    Это файлы объявлений. В них ничего не определяется (т.к. нет выделения памяти), а только объявляется.

    Вообще говоря, это не так.

  10. Какие-то странные у вас критерии хорошо/плохо. За 10 минут создать проект, прошить и посмотреть как работает - хорошо. Несколько дней трахаться с софтом не понимая как оно должно и почему не работает - плохо.

  11. 2 часа назад, Arlleex сказал:

    только не факт, что в прерывании код действительно что-то будет писать в регистры периферии (кроме регистров таймера).

    Прерывание, которое не изменяет ни одной volatile сущности, не имеет смысла. Это не обязательно периферия, может просто флаг в памяти, например. Там не хватает задержки несколько тактов всего, её можно получить разными способами. 

    2 часа назад, Arlleex сказал:

    Ну, то есть аргументов нет.

    Барьеры работают на уровне ядра процессора, а сбрасываемый флаг гуляет по внешним шинам.

  12. 1 час назад, Arlleex сказал:

    Почему чтение SR будет бесполезно?

    Потому что не является "полезным" действием. Вместо него можно было дрыгнуть ногой или ещё что-нибудь нужное для работы программы. Представляете, 1М бесполезных действий в секунду на ровном месте.

    1 час назад, Arlleex сказал:

    Перетасует оптимизатор команды записи в регистры

    Компилятор не имеет права менять местами доступ к volatile сущностям, коими являются регистры периферии.

    1 час назад, Arlleex сказал:

    Вполне из этой оперы.

    Таки нет. Уже даже надоело это обсуждать.

×
×
  • Создать...