Linux kernel中断子系统之(五):驱动申请中断API
背景:用linux的gpio的中断去捕获并计算一系列1ms~2ms左右的脉宽(在中断中利用ktime_get获得时间并相减获得)
测试1:利用linux的两个gpio来测试中断latency,短接2个pin,然后利用hrtimer定期产生1ms的timer来toggle pin1的状态;然后pin2申请上升沿和下降沿中断。进入pin2中断的时间减去pin1状态改变的时间即为latency,统计多次取平均值,结果如下:
CPU HZ Version times latency
4*A53 1.8G 4.14.78 10000 passes, avg. 1429 nsecs
Pi 700mhz 3.6.11+ 1024 passes. avg. 3770 nsecs
【初步结论】linux虽然不是实时操作系统,但是中断延时似乎还是很小的,但是这里是平均值,可能平滑掉了一些延时非常大的凸点,于是做了第二个实验
测试2:利用linux的两个gpio来测试中断latency,短接2个pin,然后利用hrtimer定期产生us级别的timer来toggle pin1的状态;然后pin2申请上升沿和下降沿中断,记录下pin2连续两次进入中断时间间隔T2,这个T2应该近似于timer的周期T1,测试结果如下:
+ hrtimer 10 us toggle pin1引脚,pin2 中断间500000 次间隔超出周期 10 us +/- 5 us的 次数有 20-49/499977-499997 time range(4us-306us)
+ hrtimer 500 us toggle pin1引脚,pin2 中断 10000 次间隔超出周期 500 us +/- 5us的 次数有 5~8/9996~10000 time range(486 us-1006 us)
+ hrtimer 100 us toggle pin1引脚,pin2 中断 50000 次间隔超出周期 100 us +/- 5 us的 次数有 7~20/49990 time range(6 us- 619 us)
+ hrtimer 50 us toggle pin1引脚,pin2 中断 100000 次间隔超出周期 50 us +/- 5 us的 次数有 14/(100000) times 34-67 us
+ hrtimer 1000 us toggle pin1引脚,pin2 中断 5000 间隔超出周期 1000 us +/- 5 us的 次数有 5-16/5000 time range(489-1006)
【结论】虽然有丢中断,但是总体来说中断延时还是很小的,us基本的,基于以上两个测试,我觉得linux的gpio中断延时还是比想象中的小,于是我打算用gpio来进行IR的解码,于是有了测试3
测试3:利用一个pin接到ir信号输出,并用单边沿触发,测试脉宽周期T(IR的T的主要有1.15ms/2.25ms/9ms/13ms等,最小的都大于1ms,基于上面测试我认为正确捕获时间应该没问题), 但是结果如下:
+ 每隔3s发送一个IR信号(每隔IR信号包含33个周期的IO中断),IO捕获的T打印出来,每次捕获的T都有凸点,比如T=9us
+ 每隔1s发送一个IR信号,大概30%概率都有凸点
+ 每隔40ms发送一个IR信号,就第一个IR信号有异常的凸点,从第二个IR信号开始都是正常的T
+ 每隔20ms发送一个IR信号,就第一个IR信号有异常的凸点,从第二个IR信号开始都是正常的T
【结论】中断时间越长,linux越难准确捕获到,现象类似于需要一个激活状态,前面几个不准确的中断导致后面的中断都是准确的,难道底层有runtime的中断处理优化? 另外也怀疑不是睡眠以及dvfs之类的,但是好像没有类似事件发生