我尝试为FE310微控制器编写延迟程序。我需要编写这个程序,因为我使用的是零足迹运行时(ZFP),它不能提供原生的Ada延迟。
该过程依赖于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正在添加一些仅在第一次执行的代码。我在网上搜索了类似行为的提及,但没有发现任何相关内容。我找到了一些关于精化代码以及如何删除它的信息,但经过一些研究后,我意识到精化代码是在主要代码之前执行的,并不应该成为我的问题。
你知道为什么第一次执行像我这样的程序需要更长的时间吗?是否有可能避免这种行为?
答案 0 :(得分:1)
正如Simon Wright建议的那样,不同的首次执行时间是因为MCU在首次执行时从SPI闪存中读取代码,但在后续执行时从指令缓存中读取代码。
默认情况下,FE310 SPI时钟是处理器内核时钟的8分频。当我将SPI时钟分频器设置为2时,执行时间的差异除以4.