реклама на сайте
подробности

 
 
> STM32 - Атомарная операция в обработчике прерывания.
Alt.F4
сообщение Jan 7 2015, 22:20
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 1 468
Регистрация: 28-03-10
Из: Беларусь
Пользователь №: 56 256



Здравствуйте.

Настроено две группы прерываний, в группе с наименьшим приоритетом есть прерывание, в котором надо осуществить атомарно одну операцию. Я так понимаю, надо перед ней поставить disable_irq и после нее enable_irq, но в AVR такое действие приводило к вложенным прерываниям.
Подскажите, пожалуйста, не сможет ли глобальное разрешение прерываний в обработчике привести к ситуации, что данное прерывание будет прервано другим из одной и той же группы приоритетов?
Спасибо.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Alt.F4
сообщение Jan 12 2015, 14:37
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 468
Регистрация: 28-03-10
Из: Беларусь
Пользователь №: 56 256



Цитата
А Вы знаете, что работу с FIFO-буфером можно реализовать вообще без блокировок?
Подскажите, пожалуйста, как это можно реализовать?
Спасибо.
Go to the top of the page
 
+Quote Post
SSerge
сообщение Jan 12 2015, 14:59
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528



Цитата(Alt.F4 @ Jan 12 2015, 21:37) *
Подскажите, пожалуйста, как это можно реализовать?
Спасибо.

Как ни странно - легко и без затей.
Фокус в том, что если поразбираться, то окажется что каждая функция меняет только один указатель/индекс, а второй только читает. Поэтому при "внезапном" изменении значения этого второго индекса ничего страшного не происходит.
Единственное, что требуется - чтобы операции чтения и записи индексов были атомарны, по этой причине на 8-битниках индексы придётся сделать тоже uint8_t, но там и этого будет достаточно.
CODE
typedef struct
{
uint32_t PushIndx;
uint32_t PopIndx;
uint8_t Buffer[UART_FIFO_SIZE];
} UartFifo_t;

inline static bool FifoPush( UartFifo_t* Fifo, uint8_t Data)
{
// calculate next push index
uint32_t IndxTmp = Fifo->PushIndx + 1;
if( IndxTmp == UART_FIFO_SIZE )
IndxTmp = 0;

if (IndxTmp == Fifo->PopIndx) // Check FIFO state
return(false); // The FIFO is full

Fifo->Buffer[Fifo->PushIndx] = Data; // Push the data

Fifo->PushIndx = IndxTmp; // Updating the push's index
return(true);
}

static bool FifoPop( UartFifo_t *Fifo, uint8_t *pData)
{
if (Fifo->PushIndx == Fifo->PopIndx) // Check FIFO state
return(false);// The FIFO is empty

*pData = Fifo->Buffer[Fifo->PopIndx]; // Pop the data

// Calculate the next pop index
uint32_t IndxTmp = Fifo->PopIndx + 1;
if( IndxTmp == UART_FIFO_SIZE )
IndxTmp = 0;
Fifo->PopIndx = IndxTmp; // Updating of the pop's index
return(true);
}


--------------------
Russia est omnis divisa in partes octo.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 13:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.03249 секунд с 7
ELECTRONIX ©2004-2016