klen (13.02.2020 12:27 - 12:30, просмотров: 507) ответил Крок на Да нет, что называется в части инициализации этого цапа. Сравниваю побитно содержимое регистров в двух проектах - совпадает. Скорее всего важна последовательность включения бит.
последовательность очень важна, этож железка. чтоб компиллер и оптимизировал и не перетасовывал трассу именно там где нужно программисту в GCC есть стандартный метод барьер записи(памяти), это логическая штука не имеющая отношения к железу в своем sdk в части обращения к регистрам сдеал вот такую штуку.
// запрещение оптимизации трасс ассембленрных инструкций в инлайн вызовах по их границам.
// данная мера необходима для исключения "мержа" трасс вызовов, что может нарушать
// логику W/R операций в регистры периферии
// данный барьер необходим в каждом вызове с обращением к переферии
struct nro_t // "NO call asm ROUTE gcc OPTIMIZE
{
nro_t () { asm volatile ("") ; }
~nro_t () { asm volatile ("" : : : "memory") ; }
} ;
template<typename T, typename Y>
struct read_t
{
inline read_t() {}
// read 32bit. версия для атомарного чтения через переферийеый регистр, функция c барьера памяти
T inline read() const { nro_t nro; return (*((volatile T*)this)) ; }
template <typename U> typename U::enum_t inline rd(const size_t offset) const { nro_t nro; return static_cast<typename U::enum_t>(((*((volatile T*)this)) >> offset) & U::mask) ; }
template <typename U> typename U::enum_t inline rd() const { nro_t nro; return static_cast<typename U::enum_t>(((*((volatile T*)this)) >> U::offset) & U::mask) ; }
template <typename U> inline auto rd2(const size_t offset) const { nro_t nro; return static_cast<U>(((*((volatile T*)this)) >> offset) & ((const T)U::mask)) ; }
template <typename U> inline auto rd2() const { nro_t nro; return static_cast<U>(((*((volatile T*)this)) >> ((const T)U::offset)) & ((const T)U::mask)) ; }
union
{
T reg_value ;
struct
{
Y reg_low_value ;
Y reg_high_value ;
};
};
};