Пытаюсь написать процедуру задержки для микроконтроллера FE310. Мне нужно написать эту процедуру, потому что я использую среду выполнения с нулевым объемом памяти (ZFP), которая не обеспечивает собственных задержек Ады.
Процедура основана на 64-битном аппаратном таймере. Таймер увеличивается 32768 раз в секунду. Процедура считывает показания таймера, вычисляет конечное значение, добавляя значение к считанному значению, а затем считывает значение таймера, пока оно не достигнет своего конечного значения.
Я переключаю пин до и после выполнения и проверяю задержку с помощью логического анализатора. Задержки довольно точны, за исключением первого выполнения, где они на 400–600 мкс длиннее, чем запрошено.
Вот моя процедура:
procedure Delay_Ms (Ms : Positive)
is
Start_Time : Machine_Time_Value;
End_Time : Machine_Time_Value;
begin
Start_Time := Machine_Time;
End_Time := Start_Time + (Machine_Time_Value (Ms) * Machine_Time_Value (LF_Clock_Frequency)) / 1_000;
loop
exit when Machine_Time >= End_Time;
end loop;
end Delay_Ms;
Machine_Time
— это функция чтения аппаратного таймера. Machine_Time_Value
— это 64-битное целое число без знака.
Я уверен, что аппаратный аспект верен, потому что я написал тот же алгоритм на C, и он ведет себя именно так, как ожидалось.
Я думаю, что GNAT добавляет некоторый код, который выполняется только в первый раз. Я искал в Интернете упоминания о подобном поведении, но не нашел ничего подходящего. Я нашел некоторую информацию о коде уточнения и о том, как его можно удалить, но после некоторых исследований я понял, что код уточнения выполняется перед основным и не должен быть причиной моей проблемы.
Вы знаете, почему первое выполнение такой процедуры, как моя, может занять больше времени? Можно ли избежать такого поведения?
gcc
/gnatmake
аргумент-S
, чтобы получить дамп ассемблера скомпилированного исходного текста. - person Jacob Sparre Andersen   schedule 14.04.2018