Безопасны ли прерывания uint16_t и uint32_t в архитектуре Cortex M? - PullRequest
0 голосов
/ 12 июня 2019

Я работаю над некоторыми встроенными вещами. У меня было несколько прерываний, возможно, работающих с одними и теми же данными, и поэтому мне было интересно, являются ли типы данных uint16_t и uint32_t безопасными от прерываний.

Если прерывание обрабатывает данные uint16/32_t и на полпути прерывается другим прерыванием, которое пытается прочитать эти данные, оно увидит поврежденные данные. Это возможный сценарий?

Спасибо

Ответы [ 2 ]

2 голосов
/ 13 июня 2019

Чтобы развернуть ответ из @DinhQC, все инструкции с одним результатом для 16- и 32-битных типов данных являются «атомарными» по отношению к прерываниям в Cortex-M, если данныеправильно выровнен (и вы должны очень стараться, чтобы компилятор C выдал вам невыровненные данные, потому что невыровненный доступ медленный и требует особой обработки).Операции с несколькими результатами, такие как LDM и STM, могут прерываться и возобновляться в большинстве реализаций, но гарантируется целостность каждой отдельной 32-битной передачи в пределах LDM или STM.

Важно понимать, являются ли выполняемые вами операции отдельными инструкциями на уровне машины или нет.Например, если вы увеличиваете разделяемую переменную, для этого потребуются три инструкции: чтение, изменение и запись.Если между чтением и записью возникает прерывание, а подпрограмма обслуживания прерываний изменяет одну и ту же переменную, эта модификация будет перезаписана при возврате ISR.

Безопасный способ - использовать какое-то оборудование-поддерживаемый механизм для обеспечения атомарности или взаимного исключения ваших общих данных.Однако в Cortex-M есть более мощные, более гибкие и более быстрые подходы к взаимному исключению, чем отключение и повторное включение прерываний, в частности, инструкции STREX и LDREX (которые также доступны в C).Посмотрите на мой ответ на этот другой вопрос для получения дополнительной информации.

0 голосов
/ 13 июня 2019

Процессоры Cortex-M не повреждают и дают вашим данным неопределенное значение. Значение всегда будет детерминированным. Однако существует много условий, которые влияют на значение данных в случае прерываний. Данные uint16/32_t могут находиться в памяти или только внутри регистров процессора. Если в памяти, он может быть выровнен 16/32-битным или не выровнен 16/32-битным Процессор, например M0 или M4, и операция, выполняемая с данными, например, добавить или умножить, также имеет значение. Все они определяют, является ли инструкция, используемая для обработки данных, атомарной или нет.

Вы можете найти больше деталей в этом обсуждении и этом ответе Джозефа Юи.

Вообще говоря, если инструкция является атомарной (один цикл выполнения), прерывание не может помешать операции с данными. Однако на уровне кода C операция uint16/32_t data может занять более 1 инструкции. Поэтому трудно гарантировать, что программа работает так, как ожидалось. Это также относится к uint8_t данным. Вы можете отключить прерывания перед началом работы с общими данными и впоследствии разрешить прерывания. Техника хорошо описана в этом ответе (см. Пункт 2).

...