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

lamer0k

Участник
  • Постов

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

  • Посещение

Репутация

0 Обычный

Посетители профиля

407 просмотров профиля
  1. Может поможет, через указатель на член структуры, класса. См, способ 10 тут: https://m.habr.com/ru/post/459204/
  2. Самое то главное, монитор может скидываться "хоть как" , и это не зависит от вашего приложения. А зависит только от реализации монитора, которая может быть "любая", в рамках правил, обозначенных ARM. Поэтому предлагаю не париться, а просто использовать как рекомендуют, меньше инструкций между ними, не более 2048 байт и так далее.
  3. Но ведь тут указанное выше, не является первоисточником, поэтому может быть тоже далеко не всегда так. ARM architecture refence manual, говорит не так, как указано выше, а чётко регламентирует этот момент.
  4. Потому что он сбрасывается как при входе в прерывание, так и при выходе.
  5. Мое понимание такое, что если между LDREX и STREX было прерывание, то STREX не сработает, потому что при каждом входе и выходе из прерывания выполняется CLREX.
  6. Порт со списком пинов вообще по идее можно сгенерить на этапе компиляции, чтобы самому не писать руками, и ассерты для себя не вставлять: // template<std::size_t size, typename TPort, typename... Acc> struct CreateList { using type = typename CreateList<size - 1, TPort, Port<TPort, size>, Acc...>::type ; } ; template<typename TPort, typename... Acc> struct CreateList<0, TPort, Acc...> { using type = PinsPack<Port<TPort, 0>, Acc...> ; } ; template<std::size_t size, typename T> using GeneratePins = typename CreateList<size, T>::type ; // Сгенерируем список пинов для портов using GpiobPort = GeneratePins<15, GPIOB> ; // PinsPack<Port<GPIOB, 0>, Port<GPIOB, 1>, Port<GPIOB, 2>, Port<GPIOB, 3>, // Port<GPIOB, 4>, Port<GPIOB, 5>, Port<GPIOB, 6>, Port<GPIOB, 7>, Port<GPIOB, 8>, // Port<GPIOB, 9>, Port<GPIOB, 10>, Port<GPIOB, 11>, Port<GPIOB, 12>, Port<GPIOB, 13>, // Port<GPIOB, 14>, Port<GPIOB, 15> > // Тоже самое для порта А using GpioaPort = GeneratePins<15, GPIOA> ; // PinsPack<Port<GPIOA, 0>, Port<GPIOA, 1>, Port<GPIOA, 2>, Port<GPIOA, 3>, // Port<GPIOA, 4>, Port<GPIOA, 5>, Port<GPIOA, 6>, Port<GPIOA, 7>, Port<GPIOA, 8>, // Port<GPIOA, 9>, Port<GPIOA, 10>, Port<GPIOA, 11>, Port<GPIOA, 12>, Port<GPIOA, 13>, // Port<GPIOA, 14>, Port<GPIOA, 15> > https://onlinegdb.com/BkPrIMK1L С наступающим всех!!!!!
  7. Я имею ввиду, зачем вам делать частный случай, если можно сделать сразу общий. В вашем случае, например, можно задать только так Pack<P01, P02, P03, P04> ; Но вот так уже нельзя Pack<P01, P03, P04> И ваш ассерт сработает. Вопрос, почему? Или вам прямо нужно, чтобы они только подряд шли? А если кто-то нечаянно сделает так: constexpr Port CS{0} ; constexpr Port DS{1} ; constexpr Port MOSI{1} ; //ошибся 1 записал Pack<CS, DS, MOSI> ; Ну или я не понимаю вашей задачи :)
  8. Добавлю еще как вариант, считать количество единиц в установленном значении :) Если количество единиц совпадает с количеством аргументом, то все пины уникальны. struct Port { constexpr Port(int value): btn(value) { } const int btn; } ; template<auto& ...args> struct Pack { static constexpr size_t size = (sizeof...(args)) ; static constexpr auto value = ((1 << args.btn) | ...) ; constexpr static std::size_t GetOnesCount(size_t val) { auto count = 0; for (auto n = val ; n != 0 ; count++) { n &= (n - 1) ; } return count ; } static constexpr bool unique = (size == GetOnesCount(value)) ; } ; constexpr Port P00{0} ; constexpr Port P01{1} ; constexpr Port P02{2} ; constexpr Port P03{3} ; constexpr Port P04{4} ; constexpr Port P05{5} ; constexpr Port P06{6} ; constexpr Port P07{7} ; using PortLits = Pack<P00, P01,P01,P04,P05,P06,P07> ; //static_assert(PortLits::unique, "Беда, пины не разные") ; int main() { std::cout << PortLits::unique ; return 0 ; } https://onlinegdb.com/HkJRyOL1U
  9. Не совсем понял, что вы хотите, но в вашем случае можно сделать так: template<auto& ...args> struct Pack { static constexpr bool unique = (((1 << args.btn) | ...) == 0xFF); } ; using PortLits = Pack<P00, P01,P02,P03,P04,P05,P06,P07> ; static_assert(PortLits::unique, "Беда, пины не разные") ; https://gcc.godbolt.org/z/9CdBsR Но работать это будет только для конкретного количества пинов. Чтобы для любого количества работало, нужно итерационно бегать по параметрам и смотреть, если значение изменилось при этой итерации, значит Пин новый, если нет - то значит такой уже был...
  10. Отправил вам личное сообщение, чтобы в теме не мусорить.
  11. Спасибо, хорошо, что это не зря и кому то это кажется полезным :) Да, почту на которую был зарегистрирован уже заблокировали, а пароль не помню.
  12. Немного путано написал :) Попробую на примере, ниже функция Set является inline по определению (определение функции сразу в месте её объявления). Но без оптимизации компилятор её такой делать не будет, потому что отлаживать будет невозможно и он сделает обычный вызов. Если же вы все таки хотите, чтобы функция инлайнилась даже без оптимизации, то нужно об этом сказать компилятору, мол сделай её инлайн принудительно. В таком случае, без оптимизации она тоже станет инлайн: template <typename T> struct Port { __forceinline void Set(std::uint32_t value) { assert((value <= (1 << 16U))) ; T::BSRR::Write(static_cast<typename T::BSRR::Type>(value)) ; } } Если же вы сделаете так как ниже, то функция Set уже не inline (так определение функции вынесено из объявления класса), и тогда даже если принудительно скажете компилятору сделай её инлайн, он может этого и не сделать без включенной оптимизации, но постарается сделать это при оптимизации и если сможет - сделает. struct Port { void Set(std::uint32_t value) ; } ; __forceinline void Port::Set(std::uint32_t value) { assert((value <= (1 << 16U))) ; T::BSRR::Write(static_cast<typename T::BSRR::Type>(value)) ; } Сам __forceinline это просто макрос #define __forceinline _Pragma("inline=forced")
  13. Функции класса определенные сразу в объявления класса (в *.h) являются inline по определению, те которые определены в *.cpp таковыми не являются и компилятор может их сам заинлайнить при оптимизации. Так вот, если функция inline (определение сразу сразу в объявлении) компилятор по факту без оптимизации их так не делает, поскольку иначе невозможно будет отлаживать, но использование принудительного указания компилятору о том, чтобы они их все таки заинлайнил, заставит его это сделать даже без оптимизации. Specifying #pragma inline=forced will always inline the defined function. If the compiler fails to inline the function for some reason, for example due to recursion, a warning message is emitted. Inlining is normally performed only on the High optimization level. Specifying #pragma inline=forced will inline the function or result in an error due to recursion etc. В данном случае __forceinline это просто макрос для IAR, который применяется для inline функций (определенных в заголовочниках сразу при объявлении) #define __forceinline _Pragma("inline=forced")
×
×
  • Создать...