我正在 STM32F4 发现板上安排一个带有“延迟直到”子句的循环,当我增加频率时,它就不再遵守时间限制。经过一番挖掘后,我的印象是调度程序的粒度无法完成任务。迹象之一是,当我走得很慢时,时间基本上得到了尊重,而我走得越快,时间就越疯狂。但迟到似乎是离散的,就像落在调度频率限制上一样。
这是我的测试代码:
task body PWM is
onPeriod : Time_Span;
offPeriod : Time_Span;
period : Time_Span;
Next_Start : Time := Clock;
PWM_On : Boolean := True;
begin
loop
period := Microseconds (1_000_000) / PWMFrequency;
onPeriod := period / 3;
offPeriod := 2 * period / 3;
if (PWM_On) then
Off (Pattern (Next_LED));
PWM_On := False;
Next_Start := Next_Start + offPeriod;
else
On (Pattern (Next_LED));
PWM_On := True;
Next_Start := Next_Start + onPeriod;
end if;
delay until Next_Start;
end loop;
end PWM;
我没有显示示波器迹线,它太复杂了,足以说明频率越高,占空比越小,接近33.3%(甚至稳定)。
在浏览 gnat 发行版后,我在 s-bbbosu.adb 中发现:
-- We use the Sys_Tick timer as a periodic timer with 1 kHz rate. This
-- is a trade-off between accurate delays, limited overhead and maximum
-- time that interrupts may be disabled.
Tick_Period : constant Timer_Interval := Clock_Frequency / 1000;
(以及与 s-bbtime.adb 中名为 Delay_Until 的函数的一些连接)
我是否被迫手动使用 native MCU 计时器,或者系统中是否提供了一些更高速的调度工具? 我是 Ada 的初学者,所以答案可能是显而易见的。
最佳答案
您可以通过将更改的文件放在您自己的代码目录中并使用 gnatmake -a
重建程序来使用更改的系统库组件(gprbuild
不在命令行上识别此开关,尽管可以将其包含在 GNAT 项目文件中)。请注意,库文件重新编译是通过需要严格符合 GNAT 编码风格的开关完成的(例如,编译器警告被视为错误,如 C 的 -Werror
)。
所以你可以说
Tick_Period : constant Timer_Interval := Clock_Frequency / 10_000;
毫无疑问,您还需要访问使用 Tick_Period
来确定等待给定 Duration
的滴答数的地方!
关于embedded - 我可以更改 cortex-m4 上的 "delay until"粒度吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26287742/