Добрый день.
В программе используются прерывания, прерывание может прервать другое прерывание =)
Основная проблема - malloc() , случается иногда что попадает именно в момент выделения памяти, но и в другом прерывании так же есть выделение памяти. И когда случаются совпадения, то бывает коллапс.
Так вот, что бы не проставлять кучу __disable_irq(); __enable_irq();
как можно некоторые функции целиком защитить от прерывания (но что бы оно было вызвано после выполнения самой функции)? Под целиком я подразумеваю не писать внутри функции команды, а как-то снаружи что ли...
С учётом того, что оборачивать сам вызов функции не вариант (костыль).
Использование __disable_irq(); и __enable_irq(); то же может быть проблемным, т.к. если в вызывающей эту функцию прерывания уже отключены мы можем случайно их включить, чего очень не хочется.
P.S. выделение памяти в прерываниях зло и т.д. ага.
P.P.S. можно настроить, что бы прерывания одно другое не прерывали, но это не подходит, т.к. нужно только некоторые функции, которые вызываются в прерывании.
Для таких целей вводятся дополнительные обертки над disable_irq и enable_irq, которые вычисляют "глубину" запрета прерываний. По факту просто есть глобальный счетчик, который увеличивается при каждом вызове ext_disable_irq и уменьшается при ext_enable_irq. Настоящее включение прерываний происходит в самом конце ext_enable_irq и только если счетчик в этот момент равен нулю
Думал, может есть какой хак...
Тогда придётся все функции переделывать, если в них больше одного ретурна, что бы не забыть включить прерывания обратно...
Kalombyr, обычно функциями отключения и включения прерываний выделяется лишь небольшой участок кода. Рассматривайте это как фигурные скобки, окаймляющие критическую секцию. Если у вас прерывания только выключаются - возможно стоит задуматься над рефакторингом.
15432, насколько плохо вообще то, что использую __disable_irq(); и enable_irq(); ну то есть это ведь не означает, что код полностью говно как только появляется такая необходимость?
Над рефакторингом подумаю...
Kalombyr, если вы абсолютно уверены, что случайно не включите прерывания, когда не надо - всё ок. Зависит от разработанной архитектуры. Большинство решений, с которыми я сталкивался, использовали ту или иную обёртку, чтобы учитывать предыдущее состояние прерываний.
Он вызывает функцию, когда переменная выходит из области видимости (этакий RAII в C). Оберните ваш ext_enable_irq в макрос, который выховет её и создаст переменную, у которой cleanup - ext_disable_irq, и в результате ваши функции будут выглядеть как-то так:
void* func(size_t size)
{
IRQ_GUARD;
//Код собственно функции
}
Написано
Войдите на сайт
Чтобы задать вопрос и получить на него квалифицированный ответ.