arch_ble_ext_wakeup_on的目的是什么?

7个帖子/ 0个新
最后发表
奥伦
离线
最后看到:1年10个月前
专家
加入:2014-06-28 22:03
arch_ble_ext_wakeup_on的目的是什么?

你好,
我们正在使用SDK 5.0.4,我正在查看user_sleepmode示例。
看起来该程序在两种情况下监听点击按钮的中断。

第一种情况是在连接期间。要开始倾听,user_app_set_button_event被调用并执行:

wkupct_register_callback (user_app_button_press_cb);
wkupct_enable_irq (WKUPCT_PIN_SELECT (GPIO_BUTTON_PORT GPIO_BUTTON_PIN),
WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, next_event), //极性
1、// 1个事件
10);

倾听被打断了user_app_disable_button这电话wkupct_disable_irq ();
监听回调函数(user_app_button_press_cb)也叫user_app_set_button_event保持侦听按钮点击(实际上它侦听按钮模式下的开关,通过选择正确的“next_event”)。

第二种情况是当节目停止广告时(10秒后)。当user_app_adv_undirect_complete以状态为GAP_ERR_CANCELED(也就是说,这是一个故意的副词)它调用:

arch_ble_ext_wakeup_on ();
//配置唤醒按钮
app_button_enable ();

的目的arch_ble_ext_wakeup_on是:使BLE核心永久休眠。只有外部事件才能唤醒它。”。它只是将一个内部标志设置为true。
然后,app_button_enable电话:

app_easy_wakeup_set (app_wakeup_cb);
wkupct_register_callback (app_button_press_cb);
wkupct_enable_irq(WKUPCT_PIN_SELECT(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN), //选择pin (GPIO_BUTTON_PORT, GPIO_BUTTON_PIN)
WKUPCT_PIN_POLARITY(GPIO_BUTTON_PORT, GPIO_BUTTON_PIN, WKUPCT_PIN_POLARITY_LOW), //极性低
1、// 1个事件
40);

也就是说,它节省了app_wakeup_cb在一旁等待将来的召唤app_easy_wakeup,并运行与第一种情况类似的代码,以便开始侦听按钮中断。
当中断发生时,app_button_press_cb被调用并执行:

if (GetBits16(SYS_STAT_REG, PER_IS_DOWN))
{
periph_init ();
}


如果我理解正确的话,这个代码必须在深度睡眠的外部唤醒中调用(在长时间睡眠时调用它有害吗?)
然后,app_button_press_cb继续调用:

如果(arch_ble_ext_wakeup_get ())
{
arch_set_sleep_mode (app_default_sleep_mode);
arch_ble_force_wakeup ();
arch_ble_ext_wakeup_off ();
app_easy_wakeup ();
}

也就是说,它检查外部唤醒标志是否开启,初始化睡眠模式(app_default_sleep_mode为深度睡眠),唤醒BLE,关闭外部唤醒标志(即计时器和BLE事件现在也可以唤醒)和调用app_easy_wakeup ()(电话app_wakeup_cb正如我之前解释的那样)。

在第二种情况下,这种机制的优点是什么?我们可以避免打电话arch_ble_ext_wakeup_on ()这样我们就不用重新配置睡眠模式和重新唤醒BLE了。打电话有什么用arch_ble_ext_wakeup_on ()如果程序没有任何定时器,也没有发布(即定时器和BLE事件不能唤醒程序)不管怎样-所以只有外部唤醒可以)。

如果我们使用,程序会在深度睡眠时消耗更少的能量吗arch_ble_ext_wakeup_on

为什么第二个案子从不打电话来wkupct_disable_irq ()?之后要睡觉吗arch_ble_ext_wakeup_on也就是说你不用打电话了wkupct_disable_irq ()在你醒来之后?

谢谢,
奥伦佐莫

设备:
LC_Dialog
离线
最后看到:2个月6天前
工作人员
加入:2016-09-19 23:20
你好,奥伦,

你好,奥伦,

我很抱歉没有及时回答你的问题。

关于第一个问题,
不。你也可以用它来延长睡眠时间。用户只能设置默认的唤醒选项。SDK负责如何唤醒所有模块的其余过程。
对于第二组问题,
即使系统处于深度睡眠状态,系统堆栈也会定期唤醒(在CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS中定义)。这是为了轮询UART(这是在SDK的GTL接口上操作的副作用)以检查任何现有数据。user_app_undirect_complete()中的arch_ble_ext_wakeup_on()将在这些间隔期间抑制此唤醒过程以节省电量。
注意:您可以通过禁用此功能在智能片段中注意到这一点
第三个问题,
对于中断,在第一种情况下,用户将按钮设置为侦听按钮按下,然后禁用它。但是,第二种情况下的睡眠是由sdk处理的,并且需要中断处于活动状态,以便在每次系统保持睡眠状态时唤醒系统。
注意:有关睡眠和唤醒模式的更多信息,请参阅以下文档。
感谢您与我们联系。如果您还有任何问题,请告诉我们。我们很乐意帮忙!
LC_Dialog
奥伦
离线
最后看到:1年10个月前
专家
加入:2014-06-28 22:03
你好,信用证,

你好,信用证,
感谢您提供的信息丰富的回复。
我们现在注意到CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS参数rwip_sleep ()功能很复杂,但我们理解你的解释。
我们希望太空舱能尽可能长时间地保持深度睡眠状态,而不是每隔10秒就醒来一次。我们不关心轮询UART—在我们的用例中,一旦模块被烧录,它将永远不会连接到UART。
是否可以增加CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS参数?如果是,最大值是多少?
我想我们应该用arch_ble_ext_wakeup_on当我们想要深度睡眠直到外部唤醒。然而,在某些情况下,我们只是想要长时间的深度睡眠(几个小时,几天)——我们通过创建一个周期定时器来实现KE_TIMER_DELAY_MAX-1还有一个计数器。我们可以每300秒醒来一次,但不想每10秒醒来一次……

问候,
奥伦佐莫

注:
我们不太关心不精确的时间——如果我们设置一个1小时的计时器,我们不关心它是在50分钟还是70分钟后醒来。20%的准确度对于我们的用例来说已经足够好了。

LC_Dialog
离线
最后看到:2个月6天前
工作人员
加入:2016-09-19 23:20
你好,奥伦,

你好,奥伦,

的值可以修改CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS从1秒到23.3小时(以秒为单位的值)。当arch_ble_ext_wakeup_on调用时,它将抑制此值以使BLE进入永久睡眠状态,这对于睡眠持续时间的任何值都是相同的。然而,如果arch_ble_ext_wakeup_off则sleep_duration的值将生效。

对于您的第二个需求,我还没有完全理解用例。你能详细描述一下这个场景吗?

但是,您可以通过更改上述定义来延长睡眠时间。它将控制BLE的唤醒周期。但是,可以通过调用arch_ble_ext_wake_on ()为了在外部事件(或)上唤醒,您也可以使用计时器作为唤醒机制而不是外部事件。

注意:BLE事件的休眠过程(假设为10s)由智能算法管理,该算法将决定是否将BLE置于休眠状态。当我们在某个随机时间唤醒BLE时,该算法将检查是否有效地回到睡眠状态或保持清醒以等待下一个正常事件(例如广告),并且基于该决定,这可能会消耗比我们预期更多的能量。请在调度唤醒时考虑这一点

问候,

信用证

奥伦
离线
最后看到:1年10个月前
专家
加入:2014-06-28 22:03
你好,信用证,

你好,信用证,
第二个需求是,例如,当我们有一个传感器(按钮),我们想要深度睡眠,直到外部事件发生或直到1小时过去(因为我们开始睡觉)。

我们不能呼唤arch_ble_ext_wakeup_on在这种情况下,因为我们需要一个计时器在1小时后唤醒,如果没有外部事件发生……

app_easy_timer不应该用上面的值调用吗KE_TIMER_DELAY_MAX-1(5分钟)所以我们使用定时器KE_TIMER_DELAY_MAX-1还有一个初始化为12的倒计时计数器。
当timer回调函数被调用时,我们将计数器减少1,然后:
-如果计数器高于0,我们重新创建定时器(延迟为KE_TIMER_DELAY_MAX-1(即5分钟)。
—如果计数器为0,我们知道12*5min = 1小时过去了。
如果中间发生了外部事件,我们取消计时器。

实际上,我认为这个技巧应该是内置功能app_easy_timer在使用大延迟的情况下(在v5.0.4中)app_easy_timer调用ASSERT_ERROR(delay < KE_TIMER_DELAY_MAX)(即不允许出现大的延迟)。

你知道默认的10秒唤醒(由于?CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS)也发生在以前的SDK版本?具体来说,我想知道版本3.0.4和3.0.8。我们将把这个值增加到23.3小时,但我们已经有很多模块已经被以前的sdk烧毁了。

问候,
奥伦佐莫

奥伦
离线
最后看到:1年10个月前
专家
加入:2014-06-28 22:03
你好,信用证,

你好,信用证,
23小时等于82800000毫秒。
MAX_SLEEP_DURATION_EXTERNAL_WAKEUP定义为MS_TO_SLOTS_CONVERT (CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS)MS_TO_SLOTS_CONVERT (x)宏给((int)((1000 * x) / 625))
乘以1000会产生一个编译警告:“整数操作结果超出范围”警告(尽管在除以625后的最终值在范围内)。
一个快速的解决办法是将宏更改为:(int)((1000 * (long long)x) / 625))

只是想让你知道…

问候,
奥伦佐莫

LC_Dialog
离线
最后看到:2个月6天前
工作人员
加入:2016-09-19 23:20
你好,奥伦,

你好,奥伦,

到目前为止,我们的建议是使用计时器并重新开始计时,直到你达到你想要的时间。因为这将是最好的方法,也有助于您的调试。

的值不建议修改MAX_SLEEP_DURATION_EXTERNAL_WAKEUP因为它有效地改变了SDK实现。在之前的3.0.4和3.0.8版本中也是如此。

我们会考虑你的建议,把它作为默认选项app_easy_timer。但是,到目前为止,它还不是一个默认功能。

另外,感谢您对更改宏的建议。我将检查并升级以进行更正。

问候,

Leepeng