我无法获得稳定的HID报告率为惯性鼠标/键盘应用。
乌利希期刊指南。:主要主题问题从3d主题信息开始。
http://support.dialog-semiconductor.com/comment/5942#comment-5942
=======================================================================================
你好。我正在实现键盘+鼠标在单个设备与DA14580。
鼠标是通过加速度计/陀螺仪实现的,所有的处理都必须在船上完成。设备必须表示为通用键盘+鼠标组合HID设备。我的参考点最初是你的键盘参考项目,我已经实现了自定义HID报告,并能够发送键盘和鼠标报告。
但目前我的问题是可用的空闲内存放置运动融合过滤器。我检查了这个算法的速度,知道处理器的速度足以处理实时滤波。但是只有32kb的内存可用。我已经关闭了一切(MULTI BONDING, DEBUG消息等),但我仍然需要大约1kB来适应我的算法。
我发现我可以尝试关闭CFG_PRF_SPOTAR。目前的设计不需要这个功能。代码将存储在外部闪存中,如果需要,将通过SMART SNIPPETS和UART加载程序更新。然后我有足够的自由代码内存来实现这个算法。项目代码似乎是这样写的,这应该工作,因为在代码中我可以看到#if预编译条件语句打开/关闭代码部分专用于SPOTA,也关闭BLE_SPOTA_RECEIVER。使用宏定义BLE_SPOTA_RECEIVER == 0代码不应该执行SPOTA数据库构建,也不应该打开SPOTA配置文件。事实上它是这样做的。代码构建得很好,但不能工作。它重新引导(或转到主引导加载程序,并尝试从外部flash(它是空的)加载代码)。
代码滞留在rwip_schedule();从这一点上,它失去了控制,我可以看到从调试器。
链接器声称错过了“spotar_patch_area”部分(链接器警告)。我试图填补这一节,因为它是从代码完成(把一些零初始变量到这一节),但它也不起作用。
那么我如何正确地禁用这个特性并释放一些内存呢?请帮助。
我将试着自己回答。
据我所知,我想我找到了解决办法。当CFG_PRF_SPOTAR被注释,因此SPOTAR特性被禁用时,在参考项目中有一个替代数据库堆大小的声明(低值大约400字节)。当我把它更改为默认状态,因为是与SPOTAR功能上的应用程序工作。
但我还有一个关于鼠标HID报告频率的问题。正如我说的,我的参考点是键盘项目,我修改了它的代码,因为这个项目需要某种功能齐全的键盘。我添加了鼠标隐藏报告通道的另一个实例,可以通过请求消息HOGPD_REPORT_UPD_REQ扔鼠标报告到TASK_HOGPD。问题是鼠标包传输速率很低(我想我做错了什么),传输频率不是恒定的。
我做鼠标报告的架构如下:
1)如果应用程序确定L或R鼠标按钮按下事件,它配置timer0与加速计解析频率(我想要100Hz);
2) Timer0处理程序从加速度计获取数据并调用鼠标惯性滤波器更新。然后它接收到新的鼠标增量。这些增量然后安全地(饱和)添加到XY增量缓冲区,以积累新的增量,直到下一次传输;
鼠标隐藏报告从app_asynch_trm() (HOOK#1)发送-键盘报告传输也是从那里通过参考设计。只有在有鼠标按钮事件或积累缓冲区中有非零的X或Y增量时,才传输鼠标隐藏报告。在其他情况下,鼠标报告不会发送到内核。
我在板上调试GPIO引脚,每次产生新的报告时触发。GPIO触发调用放置在鼠标报告函数中使用HOGPD_REPORT_UPD_REQ的ke_msg_send(req)之后。我可以在示波器上看到,在运动中这个ke_msg_send()以所需的频率被调用。所以,据我所知,OS在蓝牙连接的另一边(主机)应该得到这个报告与相同的频率。然而,事实并非如此。传输频率是不稳定的,在100Hz我也得到突然断开。我认为这些断开是由蓝牙堆栈本身发起的,因为我在断开事件回调中得到断点,而不是在引用应用程序的断开例程中。70Hz足以保持连接始终活跃而不会突然断开,但报告频率稳定性很差。
我开发和移植的惯性鼠标滤波算法从测试板与另一个微控制器(也皮质m0)和相同的MEMS芯片。该板适用于惯性鼠标算法的调试。将100Hz频率的鼠标报告数据流通过UART馈送给主机。然后python脚本通过os调用将此流直接转换为鼠标移动。据我所知,100Hz对于舒适的鼠标用户反馈来说已经足够了。Dialog的鼠标引用应用程序也利用了100Hz的鼠标报告率。
那么我需要做什么来得到稳定的鼠标报告流?
拜托,我需要一些帮助来解决这个问题。
支持。请。我将非常高兴的任何信息,这可能的情况下,鼠标报告率不稳定的问题。
嗨me9atherion,
确保你不要禁用中断proccessing来自传感器的数据时,没有理由的da断开,也许你proccessing时禁用中断或阅读来自传感器的数据,当祝福发送一个连接的时间间隔不能禁用中断。当缓冲区中有可用数据时,还要确保继续在app_asynch_trm和app_asynch_proc中发送数据,如果有更多数据则返回true,以便召回调度程序。除此之外,鼠标参考设计也是一个很好的例子。
由于MT_dialog
谢谢你的回复。
我不禁止中断。然而,大约1.7毫秒(对于所需的100Hz Timer0中断处理程序周期为10毫秒)程序花费在Timer0处理程序回调例程上。
然而,在Timer0初始化例程中有:
NVIC_SetPriority (SWTIM_IRQn 3);/* set Priority for TIM0 Interrupt to the lowest */设置TIM0中断优先级为最低*/
所以定时器有最低的优先级,就我所知,更高级别的BLE堆栈中断不应该受到影响。也许我的假设是错误的?
从HOOK#1发送鼠标报告的代码利用了检查低级缓冲区,就像键盘报告一样:
If (app_kbd_check_conn_status() && l2cm_get_nb_buffer_available()) {
send_mouse_keyreport ()
}
我还把调试引脚切换例程到低级操作系统调用在prf_server_send_event(…),以查看操作系统是如何被直接请求发送通知后,从更高级别的请求到HOGPD配置文件的所有回调。这些电话的频率是我需要的。
我也尝试调试蓝牙流与wireshark在linux。wireshark捕获输出会有较大的时间增量。两个通知之间通常有70毫秒的时间差值。然后通常有1-2个通知,时间增量低于1ms,然后又有~70ms的差距。我附上了PDF格式的帧率图表。图形显示平均报告频率主机30Hz,看起来像真的。
好。我在Timer0中断例程中删除了从mems芯片收集数据。现在Timer0 ISR的执行时间非常短- 4.5微秒。看起来平均包速率现在是根据wireshark捕获统计(现在我有80Hz通知速率和wireshark统计显示我大约80包每秒),但报告速率是不稳定的。
在这些软件修改后,通知包之间有许多非常短的时间差值,小于1ms,每个5-6包之间有延迟~70ms的间隔。通知包应每10毫秒送达。
DA14580 app.中发送通知报文调用的操作系统例程以期望的稳定频率执行。可以在示波器上看到。我放置调试引脚切换例程后发送gattc_send_evt_cmd操作系统内核。也许有一些同步例程在BLE堆栈,我错过了?
为了测试目的,我试图删除所有传感器过滤。我现在只有Timer0,它产生100Hz的中断和更改全局标志。从HOOK#1 (app_async_trm())调用鼠标报告发送例程,它从Timer0中断检查标志并发送零鼠标报告,之前检查BLE缓冲区中的空闲空间和关键报告的连接状态。
然后我有100Hz的调试输出(从低电平GATT通知发送例程)。在实际分配内存并通过HOGPD配置文件发送鼠标报告后,app_asynch_trm()返回'true',因此再次调用rwip_schedule()。
Wireshark输出显示每秒约100Hz的包速率。但是帧率是不稳定的。在很低的时间增量(小于1ms,实际上是600-700ms)的突发数据包之间仍然有一个很大的间隔~70ms。
嗨me9atherion,
你的假设是正确的,通过设置计时器中断的低优先级,你不允许任何中断干扰BLE中断,但是也许在你的通信接口中有一些关键点禁用了你的中断,你可以检查一下吗?当有来自传感器的数据时,请确保保持活动状态,这意味着当需要开始读取传感器时,应禁用睡眠。另外,请检查您的连接间隔,我认为您将您的间隔设置为小,但请确保主机接受这个间隔,不忽略您的设置。
由于MT_dialog
谢谢你的回复。
我不禁用项目中的任何中断。在转动MEMS芯片后,我调用force_wakeup函数。休眠模式被禁用,直到禁用鼠标报告计时器。现在我甚至在app_init中没有使用sleep选项来进行调试。连接间隔MIN和MAX是7.5ms(6*1.25)作为键盘参考项目。
我如何检查主机是否接受我的间隔?
好。一个小更新。
您已经指出检查由主机接受的延迟参数。据我所知,设备发送它的首选连接参数,但主机可能拒绝他们,并发送自己的连接参数。我启用了调试消息,现在我可以在linux主机的UART终端中看到这个:
Gap_le_create_conn_req_cmp_evt_handler () (56, 0, 42, 1)
这是android主机的响应:
Gap_le_create_conn_req_cmp_evt_handler () (39, 0, 700, 5)
正如我所理解的,app_connection_func()用于在连接后通过Host更新连接参数,它的调试输出显示新的连接参数:
dbg_printf (DBG_ALL“gap_le_create_conn_req_cmp_evt_handler () (% d % d % d % d) \ r \ n”,
(int)参数- > con_interval,
(int)参数- > con_latency,
(int)参数- > sup_to,
(int)参数- > clk_accuracy
);
所以56 * 1.25 = 70ms -这是我在Wireshark捕获中看到的低延迟数据包之间的延迟。
主机是否根据调试输出拒绝我的连接延迟参数?
我已经找到了解决办法。
这是我的错。在搜索代码内存减少解决方案时,我注释掉了USE_PREF_CONN_PARAMS_ON,并且不允许它返回。所以设备甚至没有发送它自己的更好的连接参数。
我还有一个关于连接参数更新超时的问题。有什么理由在连接到主机40秒后更新它们吗?icchanged这个值为5秒,因为1秒延迟Wireshark捕获显示没有更新参数的数据包在连接后交换。
嗨me9atherion,
很高兴您发现了这个问题,延迟连接参数的原因是为了确保主机已经完成了参数的发送,并为安全起见。
由于MT_dialog