Linux内核实时机制x - 中断响应测试 Cyclictest分析1

Linux内核实时机制x - 中断响应测试Cyclitest

1 实时性测试工具 rt-test

1.1 源码下载

 1.下载源码: 
~/0-code/5.15$ git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git
正克隆到 'rt-tests'...
remote: Enumerating objects: 5534, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 5534 (delta 1), reused 0 (delta 0), pack-reused 5527
接收对象中: 100% (5534/5534), 1.08 MiB | 654.00 KiB/s, 完成.
处理 delta 中: 100% (3569/3569), 完成.

1.2 源码编译

 2. cd rt-tests  && git checkout stable/v1.0
 3. make all && make install 
 4. ./cyclictest -p 90 -m -n -c 0 -t 4 -D5m -b 60 --tracemark

1.3 实测图

在这里插入图片描述

2 Cyclitest详解

2.1 中断响应、延时概念:

  • 无论系统运行在任何代码路径,当事件发生时,系统响应 该事件的时间即为延时
  • 延时在不同的上下文有不同的含义,而Cyclitest所测得的延时是中断响应延时 和 调度延时,如下图:
    • 中断延时(interrupt latency),即中断发生到进入中断处理程序ISR的延时。
    • 调度延时(scheduing latency),即当前任务被唤醒到任务真正获得CPU使用权中间的延时。
      中断延时测量

2.2 Cyclitest 原理

  • 1、首先通过启动一个master的普通进程

  • 2、然后matser进程在启动指定数量,指定优先级的实时进程,
    -实时进程会设置一个timer周期性的唤醒自己
    -从timer溢出触发中断并进入ISR调用 wake_up_process唤醒实时进程,到进程真正能被运行,这中间的时间即我们需要测量的延时。

  • 3、并通过共享内存将该值传递给master进程进行统计,如此周而复始,最终由master进程将结果输出。

  • 当造成延时的事件发生在timer溢出之前,那么这样的延时将不会被捕捉到,所以我们需要足够久的运行cyclitest才能更大概率的抓取全面的延时数据。

master线程逻辑

  • 先创建num_threads个指定优先级的实时线程,然后在while循环中读取实时线程放在共享内存中的数据。
	for (i = 0; i < num_threads; i++) {
		pthread_attr_t attr;
		int node;
		struct thread_param *par;
		struct thread_stat *stat;
		par->prio = priority;	 //设置线程优先级,由-p参数指定
 
 
		par->clock = clocksources[clocksel];	//由-c 设置
		par->mode = mode;
		//默认为static int timermode = TIMER_ABSTIME;,可由-r指定
		//当使用 TIMER_ABSTIME 模式时,定时器的时间值是一个绝对时间点。
		//也就是说,定时器将在指定的确切时间点触发,适用于需要定时器在特定的日期和时间点触发的场景
		//当使用 TIMER_RELTIME 模式时,定时器的时间值是一个相对当前时间的偏移量。
		//定时器将在从当前时间开始经过指定的时间间隔后触发。适用于需要定时器在当前时间之后的一段时间内触发的场景
		par->timermode = timermode;			
	 	//默认睡眠时间为DEFAULT_INTERVAL或者 -i 10000 参数指定
		par->interval = interval;			
		
 
		par->max_cycles = max_cycles;
		par->stats = stat;
		par->node = node;
		par->tnum = i;
		switch (setaffinity) {
		case AFFINITY_UNSPECIFIED: par->cpu = -1; break;
		case AFFINITY_SPECIFIED:
			par->cpu = cpu_for_thread(i, max_cpus);	//设置CPU亲和性
			if (verbose)
				printf("Thread %d using cpu %d.\n", i,
					par->cpu);
			break;
		case AFFINITY_USEALL: par->cpu = i % max_cpus; break;
		}
		stat->min = 1000000;
		stat->max = 0;
		stat->avg = 0.0;
		stat->threadstarted = 1;
		stat->smi_count = 0;
		status = pthread_create(&stat->thread, &attr, timerthread, par);	//创建线程
  • cyclictest应该是实时系统验证的领域中最常用的一个工具,主要用于测试实时系统的中断响应延时。
    在这里插入图片描述
  • 1、cyclictest首先根据参数创建若干个实时任务,每一个实时任务做同样的测试工作。
    • 实时任务首先根据参数设置一个timer,在本例中,这个timer的时间为1000微秒,
    • 然后通过系统调用将自己变为休眠状态,同时设置时钟寄存器,期待1000微秒后唤醒。
    • 此后,该CPU开始运行其他任务。
  • 2、正常情况下,1000微秒以后,时钟中断会到达CPU,CPU马上停下手里的工作,
    • 进入中断上下文,开始处理这个时钟中断。
    • 时钟中断例程判断cyclictest所设置的timer到时,唤醒cyclictest的测试实时任务,将其放入到rt调度器的调度队里中。
    • 从中断上下文退出后,调度器发现实时任务比当前任务的优先级高,所以发生了抢占,实时任务被唤醒。
  • 3、实时任务记录当前时间,然后减去开始时间和睡眠时间,得到了本次时钟中断处理的延时。

由此可见,cyclictest利用CPU的时钟中断,测试并记录了中断预计到来的时间与实际发生时间的差值,由于cyclictest工作在用户空间,所以测试结果也包括了任务抢占的时间和任务切换的时间。在这里插入图片描述

  • 1、获取当前时间。
  • 2、设置睡眠时间。
  • 3、通过clock_nanosleep将自己设置为睡眠状态,并且设置时钟中断。
  • 4、唤醒后记录当前时间。
  • 5、计算延时,即jitter = (end - start) - interval。
  • 6、记录测试数据,包括响应延时的最大值,最小值和平均值。
  • 7、设置下一个测试的睡眠时间。
  • 8、如果测试达到设定循环的次数,则退出,测试结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值