Задержки блокировки STM32 несовместимы с отключенными прерываниями

Я работаю на микроконтроллере STM32F0xx, и у меня есть следующий код, который просто переключает контакт с помощью задержек блокировки (да, я знаю, что задержки блокировки плохи, не указывайте здесь).

uint32_t ticks = 0;
// Disable interrupts
__disable_irq();
for (int bit = 0; bit < 10; bit++) {
  // Toggle pin high
  WritePin(GPIO_PIN_SET);
  ticks = 500;
  while (ticks--) {
    __NOP();
  }
  // Toggle pin low
  WritePin(GPIO_PIN_RESET);
  ticks = 500;
  while (ticks--) {
    __NOP();
  }
  // Repeat
  WritePin(GPIO_PIN_SET);
  ticks = 500;
  while (ticks--) {
    __NOP();
  }
  WritePin(GPIO_PIN_RESET);
  ticks = 500;
  while (ticks--) {
    __NOP();
  }
}
__enable_irq();

Я отключаю прерывания, чтобы убедиться, что в этот момент больше ничего не происходит. Когда я смотрю на эти сигналы, я вижу 10 тактов; однако не все периоды этих сигналов совпадают. Все четные сигналы (0, 2, 4, 6, 8) имеют одинаковый период, и все нечетные сигналы (1, 3, 5, 7, 9) имеют одинаковый период, но четные и нечетные сигналы значительно различаются. (% 12). Четные сигналы соответствуют первому переключению задержки, а нечетные — второму в цикле for. Я понятия не имею, почему они будут отличаться по периоду. У кого-нибудь есть понимание здесь?


person ryeager    schedule 16.02.2017    source источник
comment
Я также проверил разборку, и сборка выглядит идентично для всех реализаций цикла while.   -  person ryeager    schedule 16.02.2017


Ответы (1)


См. эту документацию о NOP на ядре ARM Cortex-M0:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CHDJJGFB.html

Операция

NOP не выполняет никаких действий и не гарантирует, что займет много времени. Процессор может удалить его из конвейера до того, как он достигнет этапа выполнения.

Используйте NOP для заполнения, например, чтобы поместить последующие инструкции на 64-битную границу.

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

Единственный надежный способ выполнить точную задержку — использовать таймер.

person Freddie Chopin    schedule 16.02.2017