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

Библиотека атомарных операций для STM32

Кто-нибудь встречал в природе готовую библиотеку для атомарных операций над целочисленными значениями? Интересуют стандартные операции типа "сравнить и обменять", арифметические операции (сложить и вернуть предыдущее значение), битовые и т.д.

Изменено пользователем ArtDenis

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Атомарная, тоесть выполняющаяся за один машинный цикл? Может лучше использовать ассемблер для конкретного контроллера?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто-нибудь встречал в природе готовую библиотеку для атомарных операций над целочисленными значениями? Интересуют стандартные операции типа "сравнить и обменять", арифметические операции (сложить и вернуть предыдущее значение), битовые и т.д.

 

STM32 мало чем отличается от других чипов на архитектуре ARMv7-M

поэтому вам подойдет и такое - http://mintomic.github.io/

 

Кстати, спасибо что напомнили. Самому уже надоело запрещение прерываний расставлять по всем углам.

В том проекте только один файл и интересен. Это - https://github.com/mintomic/mintomic/blob/m.../mintomic_gcc.c

Там несколько примеров ассемблерных функций сравнения, сложения и логические, но и их хватает чтобы полностью понять тему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

STM32 мало чем отличается от других чипов на архитектуре ARMv7-M

поэтому вам подойдет и такое - http://mintomic.github.io/

Отличия то есть поскольку STM32 это Cortexы не совсем ARMv7-M. То что подойдет, это да.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто-нибудь встречал в природе готовую библиотеку для атомарных операций над целочисленными значениями? Интересуют стандартные операции типа "сравнить и обменять", арифметические операции (сложить и вернуть предыдущее значение), битовые и т.д.

Не то, чтобы библиотека, но часть примитивов там точно есть: тынц.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не то, чтобы библиотека, но часть примитивов там точно есть: тынц.

 

Ну это уж совсем низкий уровень.

Там в SoC-ах на ARM Cortex столько нюансов, что писать это на C значит просто "прострелить себе ногу".

Лучше тогда дать ссылку на первоисточник: http://infocenter.arm.com/help/index.jsp?t...008a/index.html

Где выяснится, что реализация эксклюзивных мониторов зависит от производителя SoC-а.

От него же зависит и такая вещь как Exclusives Reservation Granule.

Совершенно темной остается тема конфликтов с DMA.

Помнить надо и о типе памяти (normal, device, ordered), т.е. совершенно четко его знать. И проч.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот моя реализация инкремента/декремента, обмена и сравнения-обмена для разных типов:

PUBLIC   _Z9AtomicIncPVh, _Z9AtomicDecPVh
PUBLIC   _Z10AtomicSwapPVhj, _Z10AtomicSwapPVtj _Z10AtomicSwapPVjj
PUBLIC   _Z13AtomicCmpSwapPVhjj, _Z13AtomicCmpSwapPVtjj, _Z13AtomicCmpSwapPVjjj

;uint AtomicInc(u8 volatile *);
_Z9AtomicIncPVh:
aInc8_01:      LDREXB   R3, [R0]
              ADDS     R1, R3, #1
              STREXB   R2, R1, [R0]
              CMP      R2, #0
              BNE      aInc8_01
              MOV      R0, R3
              BX       LR

;uint AtomicDec(u8 volatile *);
_Z9AtomicDecPVh:
aDec8_01:      LDREXB   R3, [R0]
              SUBS     R1, R3, #1
              STREXB   R2, R1, [R0]
              CMP      R2, #0
              BNE      aDec8_01
              MOV      R0, R3
              BX       LR

;АтомарнаЯ операциЯ "обмен" длЯ типа u8.
;uint AtomicSwap(u8 volatile *, uint);
_Z10AtomicSwapPVhj:
aSwap8_01:     LDREXB   R3, [R0]
              STREXB   R2, R1, [R0]
              CMP      R2, #0
              BNE      aSwap8_01
              MOV      R0, R3
              BX       LR

;АтомарнаЯ операциЯ "обмен" длЯ типа u16.
;uint AtomicSwap(u16 volatile *, uint);
_Z10AtomicSwapPVtj:
aSwap16_01:    LDREXH   R3, [R0]
              STREXH   R2, R1, [R0]
              CMP      R2, #0
              BNE      aSwap16_01
              MOV      R0, R3
              BX       LR

;АтомарнаЯ операциЯ "обмен" длЯ типа u32.
;u32  AtomicSwap(u32 volatile *, u32);
_Z10AtomicSwapPVjj:
aSwap32_01:    LDREX    R3, [R0]
              STREX    R2, R1, [R0]
              CMP      R2, #0
              BNE      aSwap32_01
              MOV      R0, R3
              BX       LR

;АтомарнаЯ операциЯ "сравнение и обмен" длЯ типа u8.
;uint AtomicCmpSwap(u8 volatile *ptr, uint newVal, uint cmpVal);
_Z13AtomicCmpSwapPVhjj:
aCmpSwap8_01:  LDREXB   R12, [R0]
              CMP      R12, R2
              ITT      EQ
              STREXBEQ R3, R1, [R0]
              CMPEQ    R3, #1
              BEQ      aCmpSwap8_01
              MOV      R0, R12
              BX       LR

;АтомарнаЯ операциЯ "сравнение и обмен" длЯ типа u16.
;uint AtomicCmpSwap(u16 volatile *ptr, uint newVal, uint cmpVal);
_Z13AtomicCmpSwapPVtjj:
aCmpSwap16_01: LDREXH   R12, [R0]
              CMP      R12, R2
              ITT      EQ
              STREXHEQ R3, R1, [R0]
              CMPEQ    R3, #1
              BEQ      aCmpSwap16_01
              MOV      R0, R12
              BX       LR

;АтомарнаЯ операциЯ "сравнение и обмен" длЯ типа u32.
;u32  AtomicCmpSwap(u32 volatile *ptr, u32 newVal, u32 cmpVal);
_Z13AtomicCmpSwapPVjjj:
aCmpSwap32_01: LDREX    R12, [R0]
              CMP      R12, R2
              ITT      EQ
              STREXEQ  R3, R1, [R0]
              CMPEQ    R3, #1
              BEQ      aCmpSwap32_01
              MOV      R0, R12
              BX       LR

си++ - хидеры:

uint AtomicInc(u8 volatile *);
uint AtomicDec(u8 volatile *);
uint AtomicSwap(u8 volatile *, uint);
uint AtomicSwap(u16 volatile *, uint);
u32  AtomicSwap(u32 volatile *, u32);
uint AtomicCmpSwap(u8 volatile *, uint newVal, uint cmpVal);
uint AtomicCmpSwap(u16 volatile *, uint newVal, uint cmpVal);
u32  AtomicCmpSwap(u32 volatile *, u32 newVal, u32 cmpVal);

Все остальные операции сможете сами реализовать если прочитаете доку о командах LDREX/STREX.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Объясните, на какой диапазон памяти распространяется мониторинг LDREX/STREX - на то слово, с которым работаем, или на больший?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот моя реализация инкремента/декремента, обмена и сравнения-обмена для разных типов:

 

А оно работает?

Тут самое интересное как это тестировалось и на чем или ком. ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А оно работает?

Тут самое интересное как это тестировалось и на чем или ком. ;)

Работает. На LPC17xx в нескольких проектах, под uCOS. Хотя довольно редко использую.

А что там тестировать? Три строчки...

Совместно с DMA не использую конечно, да и не нужно это. А для взаимодействия между разными задачами ОС и ISR - вполне подходит. И тип памяти никакой роли не играет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Работает. На LPC17xx в нескольких проектах, под uCOS. Хотя довольно редко использую.

А что там тестировать? Три строчки...

Совместно с DMA не использую конечно, да и не нужно это. А для взаимодействия между разными задачами ОС и ISR - вполне подходит. И тип памяти никакой роли не играет.

 

Т.е. даете честное слово? Без тестирования?

Но при этом ни Exclusives Reservation Granule, ни влияние DMA не знаете?

 

Смысл то этой штуки быть быстрой, а какой толк если задача на ней застрянет пока не исполнится все, что так или иначе использует RAM.

А если есть код в RAM? Вообще капец?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но при этом ни Exclusives Reservation Granule, ни влияние DMA не знаете?

Зачем тут DMA??? Это средство синхронизации задач/ISR. Вы задачи между собой при помощи DMA синхронизируете???

Зачем к переменным, служащим для синхронизации задач, обращаться через DMA???

 

Смысл то этой штуки быть быстрой, а какой толк если задача на ней застрянет пока не исполнится все, что так или иначе использует RAM.

А если есть код в RAM? Вообще капец?

Тогда используйте обычный запрет прерываний.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Атомарная, тоесть выполняющаяся за один машинный цикл? Может лучше использовать ассемблер для конкретного контроллера?

Атомарная - это "выглядящая" как одно изменение для кода, который придерживается правил использования атомарных операций.

 

В общем, судя по ответам, с этим довольно-таки грустно у STM32. Для начала попробую встроенные в gcc функции, которые тут посоветовали: https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gc...c-Builtins.html

Их кто-нибудь проверял для STM32? Насколько надёжно они работают?

 

Ещё в C++11 в стандартную библиотеку добавлена поддержка атомарности через шаблон std::atomic. Интересно есть ли его реализация для STM32?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Их кто-нибудь проверял для STM32? Насколько надёжно они работают?

 

Да, не все так гладко.

Недаром в RTOS этот финт не используют. Нет детерминизма.

Фича явно планировалаcь для мультипроцессорных систем, а не для RTOS.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может особо не париться с атомарными операциями, и по старинке на короткий промежуток запрещать прерывания? Как я понимаю, если какое-то одно или несколько прерываний разных типов не произошли во время запрета, то после разрешения прерываний, они должны выполнится?

Изменено пользователем ArtDenis

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

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