Pull to refresh

Comments 9

https://github.com/kvasir-io/Kvasir/tree/master/Lib/Register вроде бы решает ту же задачу, с прицелом на эффективность (если требуется выставить набор флагов, но не требуется при этом строгий порядок их выставления, то они выставляются "скопом" внутри одного регистра, и в оптимальном порядке в разных регистрах)

Изучил. Интересный проект. Но он решает немного иную задачу. Он оптимизирует логику доступа к регистрам с целью повышения быстродействия. В моем же случае мне нужно просто получить маски регистров определенных полей регистров. Логика доступа к регистрам (оптимизация и последовательность) это тема уже отдельной статьи. В этой просто было рассказано, как получить маски (константы типа uint32_t) для объектов. А как ими пользоваться, уже дело объекта.

Пожалуйста, не нужно рисовать подобные диаграммы. Ничего не понятно. Если хотите показать структуру кода, используйте всем понятный UML.

Ахахах))) Лол, да) Но, нет. В нулевых, свой велосипед дороже (шука). У автора значительно отличается подход, это раз. У него нет той архитектуры, под которую пишу я, это два. Ну и я мельком глянул реализацию, тот код написан немного с другими приоритетами, еже ли у меня. Моя библиотека пишется в упор на проекты, в которых я собираюсь ее использовать. Об этой библиотеке будет отдельно, когда ее будет не стыдно показать. Пока что хранилище на github-е только с целью дублирования исходников. Никому не советую пока там копаться)
Почему у вас все функции константные, даже те, которые меняют логическое состояние ?)
Он предназначен для открытия доступа к методу, когда экземпляр объекта для которого метод вызывается — константный. Без этого модификатора нельзя вызывать методы на константных объектах.
class C {
public:
  void m1() {}
  void m2() const {}
};

C c1;
const C c2;

c1.m1(); // можно
c1.m2(); // можно
c2.m1(); // нельзя, потому что c1 объявлен как const, а m1() - нет
c2.m2(); // можно, потому что c1 объявлен как const и m2() объявлена как const

Пример отсюда (не мой).
Просто, как говорилось в статье, все объекты библиотеки должны будут объявляться как const constexpr (помним, что в C++14 constexpr != const).
Сейчас заметил. Структуру, которую вы оборачиваете в template должна быть объявлена примерно таким образом:
/*
 * Перечень регистров физического порта ввода-вывода.
 */
struct pll_cfg_struct {
    const uint32_t              pllcfg_reg_msk;         // Маска конфигурации PLL целиком.
    const uint32_t              dev_bus_msk;            // Маска регистра RCCCFG (только части с делителями частоты шин).
    const uint32_t              flash_acr_msk;          // Маска всего регистра flash_acr (предсказатель + задержки обращения к Flash).
    const bool                  src;                    // true = HSE, false = HSI
};

Важно подчеркнуть: структура не должна иметь полей volatile! Иначе будет ошибка на подобии:
../ayplayer_clock.h:6:161: error: the type 'const pll_cfg<(EC_RCC_PLL_SOURCE)1, 25u, 240u, (EC_RCC_PLL_P)0, 15u, (EC_RCC_AHB_DIV)0, (EC_RCC_APB1_DIV)5, (EC_RCC_APB2_DIV)4, 3300ul>' of constexpr variable 'pll_max' is not literal

Причем ругаться будет на объект, объявленный так:
const constexpr pll_cfg< EC_RCC_PLL_SOURCE::HSE, 25, 240, EC_RCC_PLL_P::DIV_2, 15, EC_RCC_AHB_DIV::DIV_1, EC_RCC_APB1_DIV::DIV_4, EC_RCC_APB2_DIV::DIV_2, 3300 >pll_max;

Как по мне, это достаточно не очевидно. Т.к. ошибка в структуре, от которой идет наследование (и затем обратный cast).

Второй момент. Если при объявлении объекта написать const класс< параметры шаблона > имя_объекта, а не const constexpr < параметры шаблона > имя_объекта, то со случайной вероятностью при разных компиляциях объект может попадать либо во flash, либо в RAM (причем в RAM с левыми адресами, заполнеными нулями, за пределами bss и data секций...). Над последним долго маял голову const constexpr перед объявлением объекта решает.

Sign up to leave a comment.

Articles