RK3288利用GPIO解析模拟脉冲信号

需求:外部有个脉冲发生器,输出<500HZ的方波给RK3288,CPU这边需要计算每秒内的脉冲数

分析:
1.大佬建议参考Linux RC框架实现:参考kernel/driver/media/rc(研究了下,没看明白)

2.个人想用用中断实现:
A.设置中断为上升沿触发,两个触摸为一个周期,计算两次中断的时间差,即使周期T,脉冲数f=1/T。
时间差计算使用kset_set()实现ns级别的时间差计算。(do_gettimeofday()只能实现ms级的的时间差计算)

B.在中断函数中,累计中断个数,然后用精准定时器没1S中读取中断数差值。

A:
代码段:
/获取当前时间/
if(flag == 0)
calltime = ktime_get();
flag++;
{
/获取当前时间/
rettime = ktime_get();
/计算时间差 ktime_sub(B,A) 计算A-B的时间差 这时候获取的时间是纳秒/
delta = ktime_sub(rettime,calltime);
calltime = rettime;
/转换成微秒/
duration = (unsigned long long) ktime_to_ns(delta) >> 10;//微秒
printk("%s after %lld usecs,ns=%lld\n",FUNCTION, duration,ktime_to_us(delta));
}
实际测试发现,用固定500HZ外部输入情况下,每个上升沿触发中断的时间差不固定,从1.72到2.2MS不等,理论值是T = 1/500 = 2ms
效果不太满意;

AT5:/ # cat /proc/kmsg
cat /proc/kmsg
<4>[ 577.658551] hw_gpio_switch_3tobserve_work after 360954181 usecs,ns=369617081
<4>[ 577.658627] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.660506] hw_gpio_switch_3tobserve_work after 1915 usecs,ns=1961
<4>[ 577.660575] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.662525] hw_gpio_switch_3tobserve_work after 1969 usecs,ns=2016
<4>[ 577.662601] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.664535] hw_gpio_switch_3tobserve_work after 1964 usecs,ns=2011
<4>[ 577.664612] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.666805] hw_gpio_switch_3tobserve_work after 2218 usecs,ns=2271
<4>[ 577.666878] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.670876] hw_gpio_switch_3tobserve_work after 2280 usecs,ns=2335
<4>[ 577.672503] hw_gpio_switch_3tobserve_work after 1589 usecs,ns=1627
<4>[ 577.672578] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.677201] hw_gpio_switch_3tobserve_work after 2566 usecs,ns=2627
<4>[ 577.677281] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.680491] hw_gpio_switch_3tobserve_work after 1935 usecs,ns=1982
<4>[ 577.680562] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.682461] hw_gpio_switch_3tobserve_work after 1927 usecs,ns=1974
<4>[ 577.682526] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.684515] hw_gpio_switch_3tobserve_work after 2005 usecs,ns=2053
<4>[ 577.684583] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.686636] hw_gpio_switch_3tobserve_work after 2070 usecs,ns=2119
<4>[ 577.686708] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.688605] hw_gpio_switch_3tobserve_work after 1920 usecs,ns=1966
<4>[ 577.688677] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.690577] hw_gpio_switch_3tobserve_work after 1927 usecs,ns=1974
<4>[ 577.690647] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.692534] hw_gpio_switch_3tobserve_work after 1912 usecs,ns=1958
<4>[ 577.692604] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.694504] hw_gpio_switch_3tobserve_work after 1922 usecs,ns=1968
<4>[ 577.694575] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.696632] hw_gpio_switch_3tobserve_work after 2079 usecs,ns=2129
<4>[ 577.696706] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.698465] hw_gpio_switch_3tobserve_work after 1791 usecs,ns=1834
<4>[ 577.698534] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.700562] hw_gpio_switch_3tobserve_work after 2045 usecs,ns=2095
<4>[ 577.700633] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.702977] hw_gpio_switch_3tobserve_work after 2358 usecs,ns=2415
<4>[ 577.703052] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.708538] hw_gpio_switch_3tobserve_work after 1925 usecs,ns=1971
<4>[ 577.708608] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.710541] hw_gpio_switch_3tobserve_work after 1954 usecs,ns=2001
<4>[ 577.710613] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.712484] hw_gpio_switch_3tobserve_work after 1895 usecs,ns=1941
<4>[ 577.712557] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.714487] hw_gpio_switch_3tobserve_work after 1956 usecs,ns=2003
<4>[ 577.714667] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.716512] hw_gpio_switch_3tobserve_work after 1977 usecs,ns=2025
<4>[ 577.716581] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.718564] hw_gpio_switch_3tobserve_work after 2000 usecs,ns=2048
<4>[ 577.718642] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.720520] hw_gpio_switch_3tobserve_work after 1915 usecs,ns=1961
<4>[ 577.720698] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.722620] hw_gpio_switch_3tobserve_work after 2049 usecs,ns=2098
<4>[ 577.722691] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.724520] hw_gpio_switch_3tobserve_work after 1856 usecs,ns=1900
<4>[ 577.724591] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.726471] hw_gpio_switch_3tobserve_work after 1905 usecs,ns=1951
<4>[ 577.726652] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.728539] hw_gpio_switch_3tobserve_work after 2018 usecs,ns=2067
<4>[ 577.728734] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.730548] hw_gpio_switch_3tobserve_work after 1960 usecs,ns=2007
<4>[ 577.730625] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.732556] hw_gpio_switch_3tobserve_work after 1961 usecs,ns=2008
<4>[ 577.732627] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.734757] hw_gpio_switch_3tobserve_work after 2149 usecs,ns=2200
<4>[ 577.734830] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.736483] hw_gpio_switch_3tobserve_work after 1687 usecs,ns=1728
<4>[ 577.736553] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.738763] hw_gpio_switch_3tobserve_work after 2224 usecs,ns=2277
<4>[ 577.738840] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.740488] hw_gpio_switch_3tobserve_work after 1686 usecs,ns=1726
<4>[ 577.740557] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.742475] hw_gpio_switch_3tobserve_work after 1937 usecs,ns=1983
<4>[ 577.742549] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.744522] hw_gpio_switch_3tobserve_work after 2001 usecs,ns=2049
<4>[ 577.744595] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.746469] hw_gpio_switch_3tobserve_work after 1900 usecs,ns=1946
<4>[ 577.746650] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.748504] hw_gpio_switch_3tobserve_work after 1987 usecs,ns=2034
<4>[ 577.748576] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.750504] hw_gpio_switch_3tobserve_work after 1953 usecs,ns=2000
<4>[ 577.750572] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.752550] hw_gpio_switch_3tobserve_work after 1996 usecs,ns=2044
<4>[ 577.752624] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.754563] hw_gpio_switch_3tobserve_work after 1966 usecs,ns=2013
<4>[ 577.754635] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.756622] hw_gpio_switch_3tobserve_work after 2011 usecs,ns=2060
<4>[ 577.756695] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.758530] hw_gpio_switch_3tobserve_work after 1863 usecs,ns=1908
<4>[ 577.760699] hw_gpio_switch_3tobserve_work after 2118 usecs,ns=2169
<4>[ 577.762490] hw_gpio_switch_3tobserve_work after 1751 usecs,ns=1793
<4>[ 577.762558] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.764462] hw_gpio_switch_3tobserve_work after 1922 usecs,ns=1968
<4>[ 577.764535] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.766576] hw_gpio_switch_3tobserve_work after 2067 usecs,ns=2117
<4>[ 577.766644] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.768514] hw_gpio_switch_3tobserve_work after 1892 usecs,ns=1938
<4>[ 577.768583] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.770500] hw_gpio_switch_3tobserve_work after 1936 usecs,ns=1983
<4>[ 577.770573] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.772541] hw_gpio_switch_3tobserve_work after 1992 usecs,ns=2040
<4>[ 577.772612] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.774604] hw_gpio_switch_3tobserve_work after 2017 usecs,ns=2065
<4>[ 577.774760] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.780518] hw_gpio_switch_3tobserve_work after 1902 usecs,ns=1947
<4>[ 577.780582] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.782522] hw_gpio_switch_3tobserve_work after 1953 usecs,ns=2000
<4>[ 577.782597] start_time = hw_gpio_switch_3tobserve_work
<4>[ 577.788530] hw_gpio_switch_3tobserve_work after 1904 usecs,ns=1950
<4>[ 577.788597] start_time = hw_gpio_switch_3tobserve_work
AT5:/ #

听大佬说参考RK 红外遥控的实现,绑定CPU core处理中断

cpumask_clear(&cpumask);
cpumask_set_cpu(cpu_id, &cpumask);
irq_set_affinity(hw_gpio_switch_1->irq[3], &cpumask);

依旧没有改善

换一种思路,由于脉冲脉宽是和车速有关系的,并不是唯一的,只计算脉冲跳转,然后用定时器(高精度定时器hrtime)每个1秒读取脉冲个数,
核心代码如下:

static struct hrtimer hrtimer_pluse_timer;
static int pluse_time_out_ms = 1000 ;//每隔1秒,定时器函数调用一次
static int pluse_count = 0;

//static ktime_t calltime;
//static int flag;
static enum hrtimer_restart hrtimer_pluse_timer_poll(struct hrtimer *timer)
{
#if 0
static ktime_t rettime;
static ktime_t delta;
unsigned long long duration;
/获取当前时间/
if(flag == 0)
calltime = ktime_get();
flag++;
//if(flag%10 == 0)
{
/获取当前时间/
rettime = ktime_get();
/计算时间差 ktime_sub(B,A) 计算A-B的时间差 这时候获取的时间是纳秒/
delta = ktime_sub(rettime,calltime);
calltime = rettime;
/转换成微秒/
//duration = (unsigned long long) ktime_to_ns(delta) >> 10;//微秒
duration = (unsigned long long )ktime_to_ns(delta);
printk("%s after %lld usecs,ns=%lld\n",FUNCTION, duration,ktime_to_us(delta));
}
#endif
printk("*simon%s:%d,pluse_count = %d\n",FUNCTION,LINE,pluse_count);
// hrtimer_forward(timer, timer->base->get_time(), m_kt);//hrtimer_forward(timer, now, tick_period);
hw_gpio_switch_1->status[4] = pluse_count;
switch_set_state(&hw_gpio_switch_1->sdev[4], hw_gpio_switch_1->status[4]);
pluse_count = 0;
hrtimer_start(&hrtimer_pluse_timer, ktime_set(pluse_time_out_ms / 1000, (pluse_time_out_ms % 1000) * 1000000),HRTIMER_MODE_REL);

return HRTIMER_RESTART;

}

hrtimer_init(&hrtimer_pluse_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hrtimer_pluse_timer.function = hrtimer_pluse_timer_poll;	
hrtimer_start(&hrtimer_pluse_timer, ktime_set(pluse_time_out_ms / 1000, (pluse_time_out_ms % 1000) * 1000000),HRTIMER_MODE_REL); 

实现效果还可以:
<4>[ 119.949466] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 121.950783] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 123.951533] *simonhrtimer_pluse_timer_poll:456,pluse_count = 501
<4>[ 125.952791] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 126.952911] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 127.953029] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 128.953149] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 129.953268] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 132.954622] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 140.958945] *simonhrtimer_pluse_timer_poll:456,pluse_count = 499
<4>[ 146.962185] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 147.962321] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500

<4>[ 148.962462] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 149.962595] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 152.963971] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 156.965962] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 157.966079] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 158.966194] *simonhrtimer_pluse_timer_poll:456,pluse_count = 500
<4>[ 160.966950] *simonhrtimer_pluse_timer_poll:456,pluse_count = 499

提交代码,发布版本测试。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九月天-深圳专业软硬件开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值