你好,
We are using SDK 5.0.4 and I was looking at the user_sleepmode example.
它看起来像程序侦听到两个案例中的按钮单击中断。
第一种情况是在连接期间。开始听,user_app_set_button_event.
is called and executes:
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 event
10);
并且倾听是停止的user_app_disable_button
which callswkupct_disable_irq();
。
聆听回调(user_app_button_press_cb.
) also callsuser_app_set_button_event.
要保持按钮单击按钮(实际上它侦听在按钮模式下切换,通过选择右“Next_Event”)。
The second case is when the program stops advertising (after 10 seconds). Whenuser_app_add_undirect_complete.
被称为状态GAP_ERR_CANCELED.
(i.e. it's a deliberate adv-stop) it calls:
arch_ble_ext_wakeup_on();
//配置唤醒按钮
app_button_enable();
的目的arch_ble_ext_wakeup_on
is:"Puts the BLE core to permanent sleep. Only an external event can wake it up."。它只是将内部标志设置为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), // polarity low
1, // 1 event
40);
即它拯救了app_wakeup_cb
除了将来召唤app_easy_wakeup.
,并对第一种情况运行类似的代码,以便开始侦听按钮中断。
When the interrupt occurs,app_button_press_cb.
is called and executes:
if(getBits16(sys_stat_reg,per_is_down))
{
periph_init();
}
。。。
如果我理解正确,在深度睡眠期间必须在外部唤醒中调用此代码(在使用延长睡眠时调用它是有害的吗?)。
然后,App_Button_Press_CB继续调用:
if (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();
}
i.e. it checks that the external-wakeup-flag is on, initializes the sleep-mode (app_default_sleep_mode is deep-sleep), wakes up the BLE, turn off the external-wakeup flag (i.e. timers and BLE events can now wake up too) and callsapp_easy_wakeup()
(呼叫app_wakeup_cb
正如我之前解释的那样)。
第二种情况下机制有哪些优点?我们可以避免呼唤arch_ble_ext_wakeup_on()
and then we won't have to re-configure the sleep mode and re-wake the BLE. What's the point of callingarch_ble_ext_wakeup_on()
如果程序没有任何定时器并且不通告(即,定时器和BLE事件无法唤醒该程序anyways- so only an external-wakeup can).
如果我们使用,该计划会在深睡眠期间消耗更少的电力arch_ble_ext_wakeup_on
?
How comes the second case never callswkupct_disable_irq()
? Does going to sleep afterarch_ble_ext_wakeup_on
means that you don't have to callwkupct_disable_irq()
after you wake up?
Thanks,
Oren Zomer
Hello Oren,
I apologize for the delay in answering your questions...
Hi LC,
Thank you for the informative response.
我们现在注意到CFG_MAX_SLEEP_DOURATION_EXTERNAL_WAKEUP_MS参数 - 该
rwip_sleep()
功能非常复杂,但我们理解你的解释。We want the module to stay in deep sleep as long as possible and not wake up every 10 seconds. We don't care about polling the UART - in our use-case, once the module is burned, it will never be connected to a UART.
Is it possible to increase the CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS parameter? If so, what is the maximal value?
I suppose we should use
arch_ble_ext_wakeup_on
when we want to deep-sleep until external wakeup. However, in some cases we just want to deep-sleep for long periods of time (hours, days) - we do it by creating a periodic-timer ofKE_TIMER_DELAY_MAX-1
and a counter. We are OK with waking up every 300 seconds, but don't want to wake up every 10 seconds...问候,
Oren Zomer
P.S.
We don't care much about imprecise timings - if we set a timer for 1 hour we don't care if it will wake up after 50 minutes or 70 minutes. 20% accuracy is good enough for our use-case.
Hello Oren,
是的,您可以修改值CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MSfrom 1sec upto a maximum of 23.3Hrs (value to be assinged in seconds). When thearch_ble_ext_wakeup_on调用它将抑制此值将BLE放入永久睡眠中,这对于睡眠持续时间的任何值相同。但是,如果arch_ble_ext_wakeup_off被调用,那么Sleep_Duration的值将生效。
为您的第二个要求,我还没有完全理解用例。你能详细说明这种情况吗?
However, you can extend the sleep duration by changing the above mentioned define. which will control the wakeup period for the BLE. However, this can be supressed by invoking theARCH_BLE_EXT_WAKE_ON()to wake up on an external event (Or) you can also use a timer as a wakeup mechanism instead of an external event.
Note: The sleep process for BLE events (assuming 10s) is managed by an intelligent algorithm that will decide to put the BLE to sleep or not. When we wakeup the BLE at some random time, this algorithm will check to see if it is efficient to go back to sleep or stay awake for the next normal event (say advertising) and based on the decision, this may consume more energy than we expect. Please consider this when scheduling the wakeup
问候,
LC.
你好LC,
例如,当我们有传感器(按钮)并且我们想要深度睡眠,直到外部事件发生或直到1小时过去(自从我们开始睡觉),那么第二个要求是。
We must not call
arch_ble_ext_wakeup_on
in this case because we need to have a timer to wake up after 1-hour if no external event happens...app_easy_timer
should not be called with values aboveKE_TIMER_DELAY_MAX-1
(5 minutes) so we use a timer ofKE_TIMER_DELAY_MAX-1
和初始化为12的倒计时计数器。When the timer-callback is called we reduce the counter by 1 and then:
- If the counter is above 0 we recreate the timer (with a delay of
KE_TIMER_DELAY_MAX-1
, i.e. 5 minutes).- If the counter is 0, we know that 12*5min = 1hour has passed.
If an external event happened in between, we cancel the timer.
I actually think this trick should be a built-in feature in
app_easy_timer
如果使用大延迟(在V5.0.4中实施)app_easy_timer
callsassert_error(delay,即不允许延迟大延迟)。
Do you know if the default 10-seconds wakeup (due to
CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS
)也发生在以前的SDK版本中?具体而言,我想了解3.0.4和3.0.8版本。我们将增加值到23.3小时,但我们已经有很多模块已经与以前的SDK燃烧。问候,
Oren Zomer
Hi LC,
23小时为82800000毫秒。
MAX_SLEEP_DURATION_EXTERNAL_WAKEUP
被定义为MS_TO_SLOTS_CONVERT(CFG_MAX_SLEEP_DURATION_EXTERNAL_WAKEUP_MS)
and thems_to_slots_convert(x)
macro gives((int)((1000 * x) / 625))
。The multiplication by 1000 creates a compilation warning: "integer operation result is out of range" warning (although the final value, after dividing by 625, is in the range).
A quick fix could be to change the macro to:
((int)((1000 *(很久)x) / 625))
。Just wanted to let you know...
问候,
Oren Zomer
Hello Oren,
截至目前,我们建议的是使用计时器并重新启动时间,直到您达到所需的时间。因为这是最好的方法,也有助于您的调试。
注意:我们不建议更改值MAX_SLEEP_DURATION_EXTERNAL_WAKEUP因为它有效地改变了SDK实现。它在以前的3.0.4和3.0.8中也是如此。
We would consider your suggestion for making it a default option in theapp_easy_timer.但是,截至目前它不可用作默认功能。
此外,感谢您建议更改宏。我会检查出来并升级以进行更正。
问候,
Leepeng