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

Только, если такие прерывания будут не одиночные по отношению к уже обрабатываемому прерыванию - будет потеря событий, что говорит о неверном дизайне системы. Хотя, не обязательно. Если это какая-нибудь кнопка, то дребезг, породивший N событий, не так страшен.

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


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

14 минут назад, adnega сказал:

Насколько мне известно на Cortex-M такое невозможно.

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

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


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

И самое забавное, что если быстро в конце обработчика скинуть запрос прерывания от периферии, то при выходе из прерывания NVIC может не успеть на это среагировать и будет повторное вхождение. Поэтому в обработчике я всегда проверяю установку флага от периферии, сбрасываю флаг от периферии подальше от конца обработчика, ну, еще и барьер можно влепить после сброса флага от периферии.

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


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

Только что, adnega сказал:

И самое забавное, что если быстро в конце обработчика скинуть запрос прерывания от периферии, то при выходе из прерывания NVIC может не успеть на это среагировать и будет повторное вхождение.

Именно об этом я и пишу:wink:
 

Цитата

ну, еще и барьер можно влепить после сброса флага от периферии.

В большинстве случаев барьеры на Cortex-M - бесполезны. Лучше - неинтрузивное обратное чтение какой-нибудь памяти или регистра.

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


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

Вот натурный эксперимент при тактовой 8 МГц и генерации трех сигналов с частотой 16 кГц, затем 18, 25 и 5020230828_135351.thumb.png.4037723d7bf41443c14ada6ada9c544c.png20230828_135356.thumb.png.b6797cf4d3af970abb16e3b0a95b6c98.png20230828_135346.thumb.png.3264f9f67bec1e056dab0a70b3614ebe.png20230828_135400.thumb.png.409901be86f1c2780a2a876118bfe436.png

При 50 кГц начинается пропуск одного-двух импульсов, а при 60 кГц уже не успевает обрабатывать. Но это - при 8 МГц тактовой! Если её задать в 9 раз, то все будет норм. 

Никакой битбандинг в EXTI для сброса флагов не нужен, они сбрасываются записью 1 в регистр SR. Запись 0 не влияет на флаг. 

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


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

А вот что будет сигнале при 100 кГц, но при более высоком приоритете прерывания, отсчитывающего секундный интервал. 

2023-08-28141809.png.02f3d369fcda8a4469298b035f48aed7.png

Барьеры в случае прерывания от EXTI не работают по причине другого механизма проблемы. 

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


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

При тактовой 72 МГц и частоте входных импульсов 20 кГц получается интервал в 3600 маш. тактов. Одна маш.инструкция выполняется в среднем примерно за полтора такта, то есть получается интервал примерно в 2,5 тыс маш.инструкций между одним и тем же прерыванием. 

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

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


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

12 часов назад, dOb сказал:

Не польуйтесь HALами.

HAL не атомарен!

На мой взгляд, вы придираетесь не по делу.

Функция из HAL'а, которую я использовала в приведенном мной отрывке кода

 __HAL_GPIO_EXTI_CLEAR_IT( GPIO_PIN_1);

как и многие из тех, которые начинаются двумя подчеркиваниями, является чистым дефайном, который определен так:

#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))

при подстановке моих значений он в превращается в выражение:

EXTI->PR = 2

Где вы тут разглядели неатомарность?

 

А во-вторых то явление, которое я описала, представляет собой парадокс, когда одни линии прерывания работают без сбоев до частоты 16 КГц, несмотря на то, что их соседки, считающие более высокие частоты, захлёбываются, не успевая сосчитать все импульсы. Тогда как если бы захлёбывание было вызвано нехваткой ресурсов, то эта нехватка отразилась бы на всех линиях, а не только на тех, которые считают на высоких частотах.

Тогда как неатомарность не обладает лечебными свойствами.

9 часов назад, Arlleex сказал:

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

А какой момент времени считать выходом из текущего прерывания? На этот счет могут существовать два разных мнения:

Первое: момент снятия флага.

Второй: завершение обработчика оператором return.

Который их этих двух случае вы имели виду, когда давали мне свой совет?

Лично я придерживалась первого мнения, а потому и опасалась, что прерывание окажется законченным в момент снятия флага, и боялась, что не успела завершить процедуру обработки до этого момента.

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


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

26 минут назад, Xenia сказал:

На этот счет могут существовать два разных мнения

У ARM на этот счет мнений нет, есть только строго регламентированное поведение:wink:

Если очень коротко, то выходом из прерывания считается момент снятия флага Active у этого прерывания.

А снятие Active у прерывания запускается, в том числе, return-ом из обработчика (но это не единственный способ).

Снятие флага в периферийном регистре никак не влияет на тот самый Active-статус. Обработчик, если не прервется более приоритетным прерыванием, выполнится до конца, как и обычная функция.

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


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

В мануале описано:

Exception return
Exception return occurs when the processor is in Handler mode and executes one of the following instructions to load the EXC_RETURN value into the PC:
• A POP instruction that includes the PC
• A BX instruction with any register.
• An LDR or LDM instruction with the PC as the destination
EXC_RETURN is the value loaded into the LR on exception entry. The exception mechanism relies on this value to detect when the processor has completed an exception handler. The lowest four bits of this value provide information on the return stack and processor mode. Table 17 shows the EXC_RETURN[3:0] values with a description of the exception return behavior.
The processor sets EXC_RETURN bits[31:4] to 0xFFFFFFF. When this value is loaded into the PC it indicates to the processor that the exception is complete, and the processor initiates the exception return sequence.

Return
This occurs when the exception handler is completed, and:
• There is no pending exception with sufficient priority to be
serviced
• The completed exception handler was not handling a latearriving
exception.
The processor pops the stack and restores the processor state to the state it had before the interrupt occurred. See Exception return on page 38 for more information.

То есть, когда есть какой-то вопрос, какие-то непонятки, не стоит гадать, а лучше заглянуть в документацию. И если уж там не найдете ответа или он окажется непонятен, тогда уже и придется размышлять.

Ну а к загадке EXTI - можно проверить, переткнув провода, поменяв выходы таймеров и входы EXTI. Да и в конце концов, подать один и тот же сигнал на все входы. И лучше даже от отдельного генератора. А то может быть, вы эти импульсы формируете не аппаратным способом через PWM, а программно через флаг UEV

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


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

В 27.08.2023 в 14:14, Xenia сказал:

Один раз в секунду (чтобы число на счетчике численно равнялось частоте в Гц) счетчик подвергается ревизии, а переменная, в которой шло накопление, занулялась.

Показывайте процедуру "ревизии и зануления".  Не стесняйтесь 🧑‍⚕️ :smile:

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


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

2 часа назад, Xenia сказал:

А во-вторых то явление, которое я описала, представляет собой парадокс, когда одни линии прерывания работают без сбоев до частоты 16 КГц, несмотря на то, что их соседки, считающие более высокие частоты, захлёбываются, не успевая сосчитать все импульсы. Тогда как если бы захлёбывание было вызвано нехваткой ресурсов, то эта нехватка отразилась бы на всех линиях, а не только на тех, которые считают на высоких частотах.

А Вы, кстати, на какие из EXTI подавали более высокие частоты (относительно 16 кГц)?

Коллега @EdgeAligned выше подтвердил документальное поведение системы прерываний: при равных приоритетах прерывания не будут запускаться по "карусельному" признаку, т.к. будет сформирован неявный приоритет в зависимости от номера прерывания. Чем он меньше, тем выше (логический) приоритет. Там выше, кстати, на картинках видно, что 100 кГц с EXTI1 считываются без потерь.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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