Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Атомарная операция
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
cz_nikita
Как запрерить прерывания в STM32F10x?
Ну, и как разрешить прерывания в STM32F10x?
Нужно, для выполнения атомарной операции.
ssergy
В Кейле есть инструкции:
__disable_fiq();
__disable_irq();
__enable_fiq();
__enable_irq();
и их ASM варианты.

Иногда полезно использовать SWI режим.
IgorKossak
Код
save_sr:

       mrs    r0, PRIMASK
       cpsid  I
       bx     lr

restore_sr:

       msr    PRIMASK, r0
       bx     lr
abcdefg
Цитата(ssergy @ Dec 2 2008, 20:32) *
В Кейле есть инструкции:
__disable_fiq();
__disable_irq();
__enable_fiq();
__enable_irq();
и их ASM варианты.

Иногда полезно использовать SWI режим.


Учите матчасть, в кортексе нет ни fiq, ни swi
sonycman
Цитата(abcdefg @ Dec 3 2008, 14:35) *
Учите матчасть, в кортексе нет ни fiq, ни swi

Однако эти инструкции:
Код
__disable_fiq();
__disable_irq();
__enable_fiq();
__enable_irq();

с таким-же успехом применяются для управления прерываниями и в кортексе.
smile.gif
Dog Pawlowa
Цитата(cz_nikita @ Dec 2 2008, 16:59) *
Как запрерить прерывания в STM32F10x?
Ну, и как разрешить прерывания в STM32F10x?

В примерах использования библиотек есть макросы ENTR_CRT_SECTION() и EXT_CRT_SECTION().
sonycman
Цитата(Dog Pawlowa @ Dec 29 2008, 19:39) *
В примерах использования библиотек есть макросы ENTR_CRT_SECTION() и EXT_CRT_SECTION().

А можно подробнее - в каких библиотеках и где?
MALLOY2
Разрешение прерываний :
Код
asm("CPSIE i");


Запрещение прерываний:
Код
asm("CPSID i");


Если компилятор IAR подлючаем "intrinsics.h "
и юзаем функции
Код
__disable_interrupt(void);
__enable_interrupt(void);
unsigned long __get_PRIMASK( void );
void          __set_PRIMASK( unsigned long );
unsigned long __get_FAULTMASK( void );
void          __set_FAULTMASK(unsigned long);
unsigned long __get_BASEPRI( void );
void          __set_BASEPRI( unsigned long );


Если программа работает без операционки то атомарность нужно соблюдать относительно 1 какогото прерывания и лучше его запрещать/разрешать в NVIC.

Код
inline void EntrCritSection(void)
{
  if(CriticalSecCntr == 0)
  {
    asm("CPSID i");
  }
  // avoid lost of one count in case of simultaneously calling from both places
  ++CriticalSecCntr;
}

inline void ExtCritSection(void)
{
  if(--CriticalSecCntr == 0)
  {
    asm("CPSIE i");
  }
}
sergeeff
scmRTOS содержит прекрасный класс-обертку на С++, реализующий вход/выход в/из критической секции.

То, что выше приведено, это не критическая секция, а просто запрет/разрешение прерываний. Кардинальное отличие - при входе в критическую секцию вы запоминаете текущее состояние прерываний, запрещаете прерывания, а при выходе - восстанавливаете исходное состояние, которое изначально может быть и "запрещено".
Dog Pawlowa
Цитата(sonycman @ Dec 30 2008, 04:36) *
А можно подробнее - в каких библиотеках и где?

Да, я ошибся по памяти, почему-то подумал, что в библиотеках от STM32, но это в файле arm_comm.h от IAR.
" ** Common definition for IAR EW ARM ..."
Определения, приведенные MALLOY2, оттуда.
MALLOY2
Цитата
scmRTOS содержит прекрасный класс-обертку на С++, реализующий вход/выход в/из критической секции.

То, что выше приведено, это не критическая секция, а просто запрет/разрешение прерываний. Кардинальное отличие - при входе в критическую секцию вы запоминаете текущее состояние прерываний, запрещаете прерывания, а при выходе - восстанавливаете исходное состояние, которое изначально может быть и "запрещено".


Если запрещены прерывания тогда зачем критическая секция ? ведь программу нично прервать не может ? Если используется операционка то там они всегда разрешены, и достаточно счетчика как в выше приведенном примере...
sergeeff
Цитата(MALLOY2 @ Dec 30 2008, 20:02) *
Если запрещены прерывания тогда зачем критическая секция ? ведь программу нично прервать не может ? Если используется операционка то там они всегда разрешены, и достаточно счетчика как в выше приведенном примере...


Если прерывания глобально запрещены (т.е. не используются), то и критическая секция,естественно, не нужна. А если у вас используются, например, вложенные прерывания?
Dog Pawlowa
Цитата(sergeeff @ Dec 31 2008, 00:01) *
...А если у вас используются, например, вложенные прерывания?

А объясните плз, что за неатомарные операции в 32-разрядном контроллере?
Это еще нужно извратиться, чтобы проблема возникла.
Alex B._
Цитата(Dog Pawlowa @ Dec 31 2008, 10:25) *
А объясните плз, что за неатомарные операции в 32-разрядном контроллере?
Это еще нужно извратиться, чтобы проблема возникла.

При чем тут 32-бита? А не атомарные - любое чтение-модификация-запись.
Dog Pawlowa
Цитата(Alex B._ @ Dec 31 2008, 11:52) *
При чем тут 32-бита? А не атомарные - любое чтение-модификация-запись.

Да не любое. Банальная передача флага от одного "процесса" другому не требует атомарности. Ну опросит второй процесс флаг после чтения переменной из памяти первым процессом ? - ничего не изменится.
А вот инкремент переменной - требует. Поэтому разрядность влияет.
HARMHARM
Цитата(Alex B._ @ Dec 31 2008, 09:52) *
При чем тут 32-бита?

При том, что крайне редко используются переменные больше 32 бит. А для восьмибитника любое обрещение к переменной больше 8 бит сразу неатомарное.
Alex B._
Цитата(Dog Pawlowa @ Dec 31 2008, 11:07) *
Да не любое. Банальная передача флага от одного "процесса" другому не требует атомарности. Ну опросит второй процесс флаг после чтения переменной из памяти первым процессом ? - ничего не изменится.
А вот инкремент переменной - требует. Поэтому разрядность влияет.

Проблемы начнутся, когда эти "процессы" начнут взаимно синхронизироваться через этот флаг.
Про разрядность так и не понял. У любой RMW архитектуры существует подобная проблема, вне зависимости от разрядности.
sonycman
Цитата(Alex B._ @ Jan 2 2009, 01:33) *
Про разрядность так и не понял. У любой RMW архитектуры существует подобная проблема, вне зависимости от разрядности.

Но ведь всё просто.
К примеру, имеется ISR таймера с единственной инструкцией - counter++;
Если проц восьмибитный и counter имеет разрядность больше байта - перед чтением значения (в основном цикле) надо заходить в critical section, иначе, после чтения первого байта, может проскочить прерывание и второй байт будет изменён. Таким образом мы получим один байт от предыдущего значения счётчика, а второй и последующие - от нового.
Если разрядность проца 32 бита (а переменная counter в большинстве случаев не будет превышать такую разрядность), то считывать можно без всяких секций - проц в любом случае прочитает её целиком.
Сергей Борщ
Цитата(sonycman @ Jan 2 2009, 00:18) *
Но ведь всё просто.
А если эта переменная - структура? А если система команд не имеет команды "установить бит" для ячейки памяти (как AVR) - тогда для взведения флага один процесс (а) считывает переменную, накладывает маску, хочет записать результат назад и в это время возникает перепланировка или прерывание и другой участок кода (б) тоже считывает-модифицирует-записывает переменную, возвращая управление коду (а), который заканчивая RMW затирает изменение, только что внесенное кодом (б).
klop
Извините если не в тему но мне всегда казалось что когда говорят Атомарная операция относительно АРМ архитектуры то подразумевают SWP(SWPB) и только. Только ета инструкция покрытая HLOCK на AHB будет гарантированно атомарная.
sonycman
Цитата(Сергей Борщ @ Jan 2 2009, 02:52) *
А если эта переменная - структура? А если система команд не имеет команды "установить бит" для ячейки памяти (как AVR) - тогда для взведения флага один процесс (а) считывает переменную, накладывает маску, хочет записать результат назад и в это время возникает перепланировка или прерывание и другой участок кода (б) тоже считывает-модифицирует-записывает переменную, возвращая управление коду (а), который заканчивая RMW затирает изменение, только что внесенное кодом (б).

Тогда тоже всё просто - critical section smile.gif
sergeeff
Цитата(sonycman @ Jan 2 2009, 06:15) *
Тогда тоже всё просто - critical section smile.gif


Так вот именно про это выше по-русски и сказано : критическая секция, а не просто запрет/разрешение прерываний.
sonycman
Цитата(sergeeff @ Jan 2 2009, 15:06) *
Так вот именно про это выше по-русски и сказано : критическая секция, а не просто запрет/разрешение прерываний.

А кто спорит? Если задача не совсем простенькая, и прерывания в процессе динамически запрещаются/разрешаются в нескольких потоках, то нужно восстанавливать сохранённое значение PRIMASK/FAULMASK перед выходом из CS, а не просто тупо их разрешать.
KRS
а какая атомарная операция вам нужна?
у кортекса есть еще LDREX STREX (их можно и прямо из С использовать) и прерывания запрещать не понадобится
brag
Цитата(KRS @ Jan 2 2009, 15:36) *
а какая атомарная операция вам нужна?
у кортекса есть еще LDREX STREX (их можно и прямо из С использовать) и прерывания запрещать не понадобится

только толку от этих инстуркций мало
Cortex-M3 Device Generic User Guide:
Цитата
The result of executing a Store-Exclusive instruction to an address that is different from that used in the preceding Load-Exclusive instruction is unpredictable.

ARM®v7-M ArchitectureReference Manual
Цитата
If the local monitor is in its Exclusive Access state and a processor performs a Store-Exclusive to any address other than the last one from which it has performed a Load-Exclusive, it is IMPLEMENTATION DEFINED whether the store succeeds, but in all cases the local monitor is reset to its Open Access state. In ARMv7-M, the store must be treated as a software programming error.

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.