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

    

AHTOXA

Свой
  • Публикаций

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

  • Посещение

Репутация

0 Обычный

1 Подписчик

Информация о AHTOXA

  • Звание
    фанат дивана
  • День рождения 04.09.1970

Контакты

  • Сайт
    https://github.com/antongus/

Информация

  • Город
    Уфа

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

11 788 просмотров профиля
  1. Тогда уж nEw_КаКоЙ-тО тАм РеГиСтР_VaLuE Моё предложение: mySuperRegisterCachedValue
  2. stm8, где VREFINT_Factory_CONV

    В даташите на L151, например, указан в разделе 5.2 Register map.
  3. Инициализация и работа с USART1

    Если отладка, то может быть вы смотрите на UART3->DR? Тогда отладчик этим чтением сбрасывает флаги.
  4. OS::get_tick_count()

    Тогда предлагаю оставить как есть. Системные тики мы уже соптимизировали (вернее, теперь есть способ их оптимизировать путём объявления дефайна в проекте), остальное, скажем так, оптимизации особо не требует :)
  5. OS::get_tick_count()

    Наверняка у Сергея есть ещё кандидаты на оптимизацию. Давай подождём, что он скажет.
  6. OS::get_tick_count()

    Ну почему же. В TEventFlag уберутся критические секции в функциях clear() и is_signaled(). Полной автоматизации не выйдет, но небольшой кусочек будет оптимальнее.
  7. OS::get_tick_count()

    Я ведь уже ответил на этот твой вопрос:) В TEventFlag::wait() нужно оставить общую критическую секцию и использовать функции без CS (getNoCs()/setNoCs()).
  8. OS::get_tick_count()

    Ну, лично я сразу принял вариант с макросом:) А Сергей сказал, что надо что-то универсальнее. Вот и придумываем:)) Вот, я имел в виду что-то типа такого: template <typename T, size_t atomicSize = 4> class AtomicVar { public: void set(T value) { CS cs; val = value; } void setForceCs(T value) { TCritSect cs; val = value; } void setNoCs(T value) { val = value; } T get() { CS cs; return val; } T getNoCs() { return val; } T getForceCs() { TCritSect cs; return val; } void inc(); // -- для тиков private: struct FakeCriticalSection {}; using CS = typename std::conditional<sizeof(T) <= atomicSize, FakeCriticalSection, TCritSect>::type; T val; }; Можно использовать вместо Kernel.SysTickCount, TEventFlag::Value и в других подобных местах. По крайней мере позволит убрать все ненужные критические секции почти автоматом, и не придумывая на каждый случай макрос. ЗЫ. Вот мини-тест: https://wandbox.org/permlink/zmJsh7mWUj1oQ2JH
  9. OS::get_tick_count()

    В таких местах использовать функции чтения/записи, которые без критической секции.
  10. OS::get_tick_count()

    Я не очень понял, почему будут вложенные критические секции. Скажем, сейчас у нас есть в TEventFlag переменная volatile TValue Value; а будет volatile AtomicReadWrite<TValue> Value; Соответственно, все места, где были чтения с созданием критических секций, заменятся на Value.read(), а места, где были места с записью - на Value.set(). Для пущей гибкости можно добавить функции для чтения-записи без критических секций (безусловно), и наоборот, с обязательным созданием крит. секции. Получится уже вполне гибкий класс, который можно применить во многих местах.
  11. OS::get_tick_count()

    Здесь будет так: INLINE tick_count_t get_tick_count() { return Kernel.SysTickCounter.get(); } А уже унутре этого get() будет вся магия. То есть, в TKernel вместо tick_count_t SysTickCount будет TickCounter<tick_count_t> SysTickCounter;
  12. OS::get_tick_count()

    По месту, думаю, должен использоваться класс-счётчик, типа TickCounter<T>. У него внутри уже будет спрятана вся эта магия. А снаружи - инкремент и чтение.
  13. OS::get_tick_count()

    Если используется #include <type_traits> и auto, то это уже c++11. А если можно c++11, то незачем городить эти шаблоны вручную, там есть std::conditional. Но вообще, лучше бы, наверное, наоборот, вычистить c++11. Потому что, например, AVR-GCC на godbolt не понимает "-std=c++11". Что там сейчас используется от с++11? std::is_arithmetic и std::is_enum. Думаю, можно обойтись без. Ещё такой момент. max_atomic_size = 4 - это же для ARM-ов. Для AVR-ок будет иначе. Надо как-то унифицировать. Или наоборот, вынести новый класс критической секции в порты, чтобы под каждую архитектуру был свой. ЗЫ. Я, если честно, не представляю, как сейчас всё это тестировать. С IAR-ом большой напряг, AVR-овец и STM8-овец уже давным-давно не появлялся... MSP-GCC у меня вроде есть, не знаю, насколько актуальный.
  14. OS::get_tick_count()

    Мне было интересно, какие накладные добавятся для типа, который по идее атомарен. Вижу - барьеры (может, у нас они и не нужны, но в компиляторе так заложено, для чипов с кешами и несколькими ядрами). Вижу - аккуратный инкремент с использованием функций исключительного доступа (нам тоже не всегда нужен, например, для tick_count - не нужен). Получается, что именно в плане оптимизации (начальный посыл этой темы) - std::atomic не очень подходит. Попробовал atomic<uint64_t> - не скомпилировалось (undefined reference to `__atomic_load_8'). Наверное у меня компилятор старый. Так что я не смог увидеть, во что выливается atomic в случае, когда для доступа к переменной нужно несколько операций.
  15. OS::get_tick_count()

    Треды - они и в Африке треды. Конкурентные потоки исполнения. Атомики как раз для этого придуманы. Но надо смотреть, как они конкретно реализованы. Посмотрел сейчас, во что выливается работа с std::atomic<uint32_t> на кортексах. Чтение: барьер, чтение, барьер. Запись: барьер, запись, барьер. А вот с инкрементом уже посложнее: 80029c6: f3bf 8f5b dmb ish 80029ca: e853 2f00 ldrex r2, [r3] 80029ce: 3201 adds r2, #1 80029d0: e843 2100 strex r1, r2, [r3] 80029d4: 2900 cmp r1, #0 80029d6: d1f8 bne.n 80029ca <test1()+0x26> 80029d8: f3bf 8f5b dmb ish Да, думаю, что для тиков это будет перебор.