一、测量抖动与延时
在实时编程中,人们通常必须保证一定的最后期限总是能够满足。因此,时间的可预测性至关重要。我们通过测量调度抖动和中断延迟来研究可预测性的几个方面。
通过测量调度抖动和中断延迟来研究Xenomai的可预测性和定时特性。
中断延迟(Interrupt latency: ):中断发生到中断处理程序开始之间的时间。
调度器延迟(Scheduler latency):处理程序完成后和执行调度器之前经过的时间。
调度延迟(Scheduling latency):也称为任务延迟,使睡眠任务再次运行的中断发生到任务恢复之间的时间,就是当一个事件从引起一个更高优先级的任务就绪到这个任务开始运行之间的时间,任务被触发到开始运行之间的时间,
调度抖动(Scheduling jitter):周期性任务的开始运行时间被系统分配了不同的时间片,影响其启动时间。抖动是基于时间的信号的不规则性。它可以用不同的方式来描述,比如期望发布时间的间隔、期望时间点的最大偏差,或者平均值的标准偏差。指应开始任务与开始任务时之间的延迟。例如,考虑某个任务应在10毫秒后开始,但无论出于何种原因,它都应在15毫秒后开始。在我们的示例中,抖动为5ms!
实验一:
编写一个程序,定期调度的一个任务收集任务调度的抖动情况并用散点图绘制这些数据。
流程:
1、编写一个周期性的实时任务,该任务每100微秒调度一次,执行10,000次。先阻塞主linux程序,例如,通过信号量。
2、在任务的每次运行开始时,使用rt_timer_read读取当前时间(它返回一个类型为RTIME的值),并将其存储在一个全局数组中。
3、在存储了10,000个值之后,让主linux程序运行计算每对连续时间之间的差值(应该接近100,000 ns)并将其存储在另一个数组中。
将时间差数组写入以逗号分隔的文件(.csv),格式如下:
0,value[0]
1,value[1]
2,value[2]
…
可通以下方式写入:
void write_RTIMES(char * filename, unsigned int number_of_values,
RTIME *time_values){
unsigned int n=0;
FILE *file;
file = fopen(filename,“w”);//写打开
while (n<number_of_values) {
fprintf(file,"%u,%llu\n",n,time_values[n]);
n++;
}
fclose(file);
}
4、计算时间差的平均值并打印结果。
5、 在电子表格中打开.csv文件(例如,在Excel中),并以图形(例如散点图)的形式绘制数据,显示y轴上的测量值和x轴上的测量数。注意.csv文件中的逗号应该指向两列;如果这不起作用,可能是由于语言设置的原因,请尝试用“;”替换逗号。
注意:为了避免启动效果的影响,可以通过省略前几个值来改进结果
#include <stdio.h>
#include<stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <alchemy/task.h>
#include <sys/mman.h>
#include <alchemy/timer.h>
#include <math.h>
#include <alchemy/sem.h>
unsigned int nsamples=10000;
unsigned long long value[10000];
RT_SEM sem1;
RT_SEM sem2;//设置信号量以阻塞Linux程序
RT_TASK task;
unsigned long long average;
// function to be executed by task
void write_RTIMES(char * filename, unsigned int number_of_values,
RTIME *time_values)
{
unsigned int n=0;
FILE *file;
file = fopen(filename,"w");
while (n<number_of_values) {
fprintf(file,"%u,%llu\n",n,time_values[n]);
n++;
}
fclose(file);
}
unsigned long long calc_average_time(unsigned int number,RTIME *time_values)//计算平均值
{
rt_sem_p(&sem2,TM_INFINITE);
unsigned long long add=0;
unsigned int i=0;
while(i< (number-1))
{
add=add+time_values[i];
i=i+1;
}
add=add/(number-1);
return add;
}
void calc_time_diffs(RTIME *time_diff)//计算差值抖动