|
|
  |
Библиотека атомарных операций для STM32 |
|
|
|
Jun 18 2015, 19:27
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(ArtDenis @ Jun 18 2015, 19:31)  Кто-нибудь встречал в природе готовую библиотеку для атомарных операций над целочисленными значениями? Интересуют стандартные операции типа "сравнить и обменять", арифметические операции (сложить и вернуть предыдущее значение), битовые и т.д. STM32 мало чем отличается от других чипов на архитектуре ARMv7-M поэтому вам подойдет и такое - http://mintomic.github.io/Кстати, спасибо что напомнили. Самому уже надоело запрещение прерываний расставлять по всем углам. В том проекте только один файл и интересен. Это - https://github.com/mintomic/mintomic/blob/m.../mintomic_gcc.cТам несколько примеров ассемблерных функций сравнения, сложения и логические, но и их хватает чтобы полностью понять тему.
|
|
|
|
|
Jun 19 2015, 04:40
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(AHTOXA @ Jun 18 2015, 23:40)  Не то, чтобы библиотека, но часть примитивов там точно есть: тынц. Ну это уж совсем низкий уровень. Там в SoC-ах на ARM Cortex столько нюансов, что писать это на C значит просто "прострелить себе ногу". Лучше тогда дать ссылку на первоисточник: http://infocenter.arm.com/help/index.jsp?t...008a/index.htmlГде выяснится, что реализация эксклюзивных мониторов зависит от производителя SoC-а. От него же зависит и такая вещь как Exclusives Reservation Granule. Совершенно темной остается тема конфликтов с DMA. Помнить надо и о типе памяти (normal, device, ordered), т.е. совершенно четко его знать. И проч.
|
|
|
|
|
Jun 19 2015, 07:48
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Вот моя реализация инкремента/декремента, обмена и сравнения-обмена для разных типов: CODE 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.
|
|
|
|
|
Jun 19 2015, 08:27
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AlexandrY @ Jun 19 2015, 14:24)  А оно работает? Тут самое интересное как это тестировалось и на чем или ком.  Работает. На LPC17xx в нескольких проектах, под uCOS. Хотя довольно редко использую. А что там тестировать? Три строчки... Совместно с DMA не использую конечно, да и не нужно это. А для взаимодействия между разными задачами ОС и ISR - вполне подходит. И тип памяти никакой роли не играет.
|
|
|
|
|
Jun 19 2015, 08:34
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(jcxz @ Jun 19 2015, 11:27)  Работает. На LPC17xx в нескольких проектах, под uCOS. Хотя довольно редко использую. А что там тестировать? Три строчки... Совместно с DMA не использую конечно, да и не нужно это. А для взаимодействия между разными задачами ОС и ISR - вполне подходит. И тип памяти никакой роли не играет. Т.е. даете честное слово? Без тестирования? Но при этом ни Exclusives Reservation Granule, ни влияние DMA не знаете? Смысл то этой штуки быть быстрой, а какой толк если задача на ней застрянет пока не исполнится все, что так или иначе использует RAM. А если есть код в RAM? Вообще капец?
|
|
|
|
|
Jun 19 2015, 08:42
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(AlexandrY @ Jun 19 2015, 14:34)  Но при этом ни Exclusives Reservation Granule, ни влияние DMA не знаете? Зачем тут DMA??? Это средство синхронизации задач/ISR. Вы задачи между собой при помощи DMA синхронизируете??? Зачем к переменным, служащим для синхронизации задач, обращаться через DMA??? Цитата(AlexandrY @ Jun 19 2015, 14:34)  Смысл то этой штуки быть быстрой, а какой толк если задача на ней застрянет пока не исполнится все, что так или иначе использует RAM. А если есть код в RAM? Вообще капец? Тогда используйте обычный запрет прерываний.
|
|
|
|
|
Jun 19 2015, 12:40
|
Частый гость
 
Группа: Участник
Сообщений: 142
Регистрация: 10-11-12
Пользователь №: 74 318

|
Цитата(Gleb80 @ Jun 18 2015, 23:47)  Атомарная, тоесть выполняющаяся за один машинный цикл? Может лучше использовать ассемблер для конкретного контроллера? Атомарная - это "выглядящая" как одно изменение для кода, который придерживается правил использования атомарных операций. В общем, судя по ответам, с этим довольно-таки грустно у STM32. Для начала попробую встроенные в gcc функции, которые тут посоветовали: https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gc...c-Builtins.html Их кто-нибудь проверял для STM32? Насколько надёжно они работают? Ещё в C++11 в стандартную библиотеку добавлена поддержка атомарности через шаблон std::atomic. Интересно есть ли его реализация для STM32?
--------------------
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|