我安排一个带有"延迟的循环,直到" 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的函数中的某些连接)
我是否被迫手动使用本机MCU定时器,或者系统中是否提供了更高速的调度功能? 我是Ada的初学者,所以答案可能很明显。
答案 0 :(得分:2)
您可以通过将更改的文件放在您自己的代码目录中并使用gnatmake -a
重建程序来使用更改的系统库组件(gprbuild
无法在命令行上识别此开关,虽然有可能将其包含在GNAT项目文件中)。请注意,库文件重新编译是使用需要与GNAT编码样式严格一致的开关完成的(例如,编译器警告被视为错误,如C的-Werror
。
所以你可以说
Tick_Period : constant Timer_Interval := Clock_Frequency / 10_000;
毫无疑问,您还需要访问Tick_Period
用于确定等待给定Duration
的刻度数的地方!