我无法为惯性鼠标/键盘应用程序获得稳定的HID报告率。
upd.:主题问题从3-D主题消息开始。
http://support.dialog-semiconductor.com/comment/5942#comment-5942
=======================================================================================.
你好。我正在使用DA14580在单个设备中实现键盘+鼠标。
鼠标是通过加速度计/陀螺仪实现的,所有的处理必须在机上完成。设备必须表示为通用键盘+鼠标组合HID设备。我的参考点最初是你的键盘参考项目,我已经实现了定制的HID报告,并能够发送键盘和鼠标报告。
但目前我遇到了可用的空闲内存放置运动融合过滤器的问题。我检查了这个算法的速度,知道处理器的速度足以实时处理过滤。但是它只有32kb的可用内存。我已经关闭了一切(MULTI BONDING, DEBUG MESSAGES等),但我仍然需要大约1kB来适合我的算法。
我发现我可以尝试关闭CFG_PRF_SPOTAR。当前设计不需要此功能。代码将存储在外部flash中,如果需要,将通过SMART SNIPPETS和UART加载器进行更新。然后我有足够的空闲代码内存来实现这个算法。项目代码似乎是以这种方式编写的,因为在代码中我可以看到#if预编译条件语句来打开/关闭专用于SPOTA的代码部分,这也关闭了BLE_SPOTA_RECEIVER。使用宏定义BLE_SPOTA_RECEIVER == 0代码不应该执行SPOTA db构造,也不应该打开SPOTA配置文件。实际上是这样的。代码可以很好地构建,但不能工作。它重新启动(或者转到主引导加载程序并尝试从外部flash(空的)加载代码)。
代码卡在rwip_schedule()上;从这一点上,它失去了控制,就我所看到的调试器。
链接器声称错过了“spotar_patch_area”部分(链接器警告)。我试图填写此部分,因为它从代码(将一些零init变量放到本节中),但它也不起作用。
那么我如何正确禁用此功能并释放一些内存?请帮忙。
我将试着回答我自己。
我想我据我所知,我发现了解决方案。在评论CFG_PRF_SPOTAR时,参考项目中有一个备用DB堆大小(大约400bytes)的备用DB堆大小(较低值),因此禁用Spotar功能。当我将其更改为默认状态时,使用Spotar Featerne on - 应用程序工作。
但我也有关于鼠标HID报告频率的另一个问题。正如我所说,我的参考点是键盘项目,我修改了它的代码,因为这个项目需要某种齐全的键盘。我添加了另一个鼠标HID报告通道实例,并可以通过请求消息hogpd_report_upd_req将鼠标报告抛出到task_hogpd。问题是鼠标分组传输速率低(我认为我做错了什么),传输频率不是恒定的。
我要做鼠标报告的架构如下:
1)如果App确定L或R鼠标按钮按事件,它会使用加速度计解析频率(我想要100Hz)配置TIMER0;
2) Timer0处理程序例程从加速度计获取数据并调用鼠标惯性滤波器更新。然后它接收新的鼠标增量。然后将这些增量安全地(带饱和)添加到XY增量缓冲区中,以便积累新的增量,直到下一次传播;
3)鼠标HID报告从App_Asynch_trm()发送(挂钩#1) - 键盘报告传输也来自参考设计。仅当有鼠标按钮事件时才会传输鼠标HID报告,或者累计缓冲区中有非零x或y delta。在其他情况下,鼠标报告不会发送到内核。
我在板上调试了GPIO管脚,每次生成新的报告时都会触发它。这个GPIO触发调用被放置在ke_msg_send(req)和鼠标报告函数中的HOGPD_REPORT_UPD_REQ之后。我可以在示波器上看到,在运动中,这个ke_msg_send()以所需的频率被调用。所以据我所知,蓝牙连接另一边的OS (Host)应该以同样的频率得到这个报告。然而,事实并非如此。传输频率不稳定,在100Hz时我也会突然断开连接。我认为这些断开是由蓝牙栈本身发起的,因为我在断开事件回调中得到断点,而不是在参考应用程序的断开例程中。70Hz的频率足以保持连接始终有效而不会突然断开,但据报道频率稳定性很差。
我通过另一个微控制器(也是Cortex-M0)和相同的MEMS芯片,从测试板开发并移植了惯性鼠标过滤算法。该板非常适合调试惯性鼠标藻类。通过UART将具有100Hz频率的鼠标报告数据流送到主计算机。然后,Python脚本将此流直接转换为OS调用的鼠标运动。据我所知,100Hz是足够的频率,以便舒适的鼠标用户反馈。对话框的鼠标参考应用程序还利用了100Hz的鼠标报告速率。
那么我需要做什么来获得稳定的鼠标报告流呢?
请帮我解决这个问题。
支持。请。对于可能的鼠标报告速率的这个问题可能的情况,我会非常高兴。
嗨me9atherion,
确保在从传感器中加工数据时不禁用中断,没有原因只是断开连接,也许您正在禁用中断或从传感器读取数据以及它的时间来发送时,您正在禁用中断由于禁用中断而导致的连接间隔失败。还要确保在缓冲区中可用的数据可用时,请在App_Asynch_trm和App_Asynch_Proc中继续发送数据,并且如果有更多数据以调用调度程序,则返回True。除了鼠标ref设计之外是一个相当偏好的榜样。
由于MT_dialog
谢谢你的回复。
我不禁止中断。然而,Timer0处理程序回调例程大约花费1.7ms (100Hz所需的Timer0中断处理程序周期为10ms)。
然而在Timer0初始化例程中有:
NVIC_SetPriority (SWTIM_IRQn 3);/* set TIM0 Interrupt的优先级为最低*/
因此,据我所知,而定时器具有最低的优先级,并且不应影响更高级别的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捕获输出,有很大的时间增量。在两次通知之间通常有~70ms的时间间隔。然后通常有1-2个通知,时间增量低于1ms,然后又是~70ms间隙。我附以PDF格式的帧速率图。Grafh显示主机的平均报告频率为30Hz,看起来像真的。
好。我在Timer0中断程序中从mems芯片中移除了收集数据。现在Timer0 ISR的执行时间非常短——4.5微秒。看起来平均包速率现在符合wireshark捕获统计数据的要求(现在我有80Hz的通知速率和wireshark统计数据显示我大约每秒80个包),但报告速率不稳定。
在这些软件修改后,每5-6个包之间有许多短时间间隔,不到1ms,并且有延迟~70ms的间隔。通知包应该每10毫秒到达一次。
DA14580应用程序中用于发送通知包的操作系统例程以所需的稳定频率执行。它可以在示波器上看到。在将gattc_send_evt_cmd发送到OS内核后,我放置了调试引脚切换例程。也许BLE栈中有一些同步例程我错过了?
用于测试目的,我试图删除所有传感器过滤。我现在只有Timer0,它会产生100Hz中断并更改全局标志。从钩子#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中没有使用睡眠动作。键盘参考项目连接间隔MIN和MAX为7.5ms(6*1.25)。
如何检查主机是否接受我的间隔?
好。一点更新。
您已指出检查主机的延迟参数接受。据我所知,设备发送它的优先连接参数,但主机可以彻底泄露它们并发送自己的连接参数。我启用了调试消息,现在我可以在UART终端中查看Linux主机:
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捕获中可以看到的延迟。
托管相应地恢复我的连接延迟参数是否真实了?
我找到了解决方案。
这是我的错误。我正在评论使用_pref_conn_params_on,而我正在搜索代码内存减少解决方案,并且没有允许它。所以设备甚至没有发送它自己的预处理参数。
我还有一个关于连接参数更新超时的问题。从连接到主机40秒后更新它们有什么原因吗?修改为5秒,因为Wireshark捕获延迟1秒显示连接后没有交换更新参数报文。
嗨me9atherion,
很高兴您找到了它,延迟连接参数的原因是为了确保主机已经完成发送他的参数,这是安全的。
由于MT_dialog