⚠️
大家好. .感谢来到论坛。令人兴奋的消息!我们现在正在转移到新的论坛平台的过程中,它将提供更好的功能,并包含在主对话网站。所有的帖子和账号已经迁移。我们现在只接受新论坛的流量-请发布任何新的帖子在//www.xmece.com/support.我们会在接下来的几天修复bug /优化搜索和标记。
11个员额/ 0个新员额
最后发表
chris0409
离线
最后看到:3年10个月前
加入:2017-01-11 05:59
app_easy_timer错误

嗨,everyboady,
我已经使用app_easy定时器来做一个Led闪烁功能。但在我闪过spi flash的代码后,设备继续重新启动。我调试了代码,看到程序进入blink函数和被调用的app_easy_timer函数。
程序永远不会进入代码(req->delay=delay;申请- > timer_id = timer_id;ke_msg_send(要求的);
在它执行代码(struct create_new_timer_struct *req = KE_MSG_ALLOC(APP_CREATE_NEW_TIMER, TASK_APP, TASK_APP, create_new_timer_struct);

这是否意味着内存分配错误,是否因为这个原因导致重新启动?我以前从未遇到过这种现象

设备:
WI_Dialog
离线
最后看到:1天18小时前
工作人员
加入:2014-01-03十六21
你好,

你好,
您是否尝试在SDK5中运行带有app_easy_timer特性的“prox_reporter”参考软件?您所描述的观察结果不能得出这个问题是由“app_easy_timer”函数引起的。您需要更多的信息,例如如何运行您的测试,在什么软件上,....
问候,

chris0409
离线
最后看到:3年10个月前
加入:2017-01-11 05:59
嗨,Wl_Dialog,

嗨,Wl_Dialog,
我知道app_easy_timer是问题所在,因为在我将led blink部分的代码添加到dsps-host项目之前,我也有一个使用app-easy-timer的进程,它工作得很好。
我想知道的是,我只是使用一个app-easy-timer来切换led引脚,为什么我有块在代码
struct create_new_timer_struct *req = KE_MSG_ALLOC(APP_CREATE_NEW_TIMER, TASK_APP, TASK_APP,create_new_timer_struct);
下面是led的源代码

# include“led.h”
# include“app_easy_timer.h”

/* LED控制结构*/
typedef struct {
uint8_t待办事项;/*闪烁周期左*/
uint8_t百分比;/*周期百分比*/
uint16_t时期;/*打开/关闭周期时间(msec) */
uint32_t下;/*下一次修改的时间
} LedControl_t;

/***************************************************************************************************
*全局变量
***************************************************************************************************/

static LedControl_t leddctrl __attribute__((section("retention_mem_area0"),zero_init));

/***************************************************************************************************
*本地函数
***************************************************************************************************/
static void LedUpdate (void);

/***************************************************************************************************
*函数- API
***************************************************************************************************/

/***************************************************************************************************
* @fn LedInit

* @brief初始化LED服务

* @param init -指向void的指针,包含初始化的值

* @return没有
***************************************************************************************************/
空白LedInit(空白)

LED_INIT ();

/***************************************************************************************************
* @fn LedBlink

* @brief闪烁led灯

* @param leds - led闪烁的位掩码值
* numBlinks -闪烁次数
* percent -每段时间内领先的百分比
*将会开始
* period -每个周期的长度,单位为毫秒

* @return没有
***************************************************************************************************/
void LedBlink (uint8_t numBlinks, uint8_t percent, uint16_t period)

ledCtrl。todo = 2 * numBlinks-1;
ledCtrl。% = %;
ledCtrl。时间=时期;
LED_OFF ();
If (percent && period)

If (percent < 100)

LedUpdate app_easy_timer(1日);

其他的

LED_ON ();


其他的

/ /关闭
LED_OFF ();

/***************************************************************************************************
* @fn LedUpdate

* @brief更新led与blink工作

* @param没有

* @return没有
***************************************************************************************************/
static void LedUpdate (void)

LED_TOGGLE ();
ledCtrl.todo——;
如果(ledCtrl。todo / * | | LED_STATE () * /)

如果(LED_STATE ())

ledCtrl。下一个= ledCtrl.period * (100 - ledctrl.percent);

其他的

ledCtrl。下一个= ledCtrl.period * ledCtrl.percent;

app_easy_timer (LedUpdate ledCtrl.next / 10日);


你能帮我检查一下代码是否有错误吗,我真的找不到原因。
另外,我只是使用LedInit初始化LED端口和LedBlink(20,35,1000)在System_Init()中做测试。

chris0409
离线
最后看到:3年10个月前
加入:2017-01-11 05:59
再多一点,我发现了

再多一点,我发现我在system_init中调用LedBlink(),我将得到持续重启后,我的flash代码到flash。但是如果我在system_init()之后的main_func()中调用LedBlink(),这种现象不会发生,但我永远无法调用LedUpdate()。当按钮被按下时,我还启动了一个计时器,当计时器过期时,我可以得到这个计时器的回调。这真的让我很困惑,任何建议都将不胜感激!

WI_Dialog
离线
最后看到:1天18小时前
工作人员
加入:2014-01-03十六21
你好,

你好,
你的问题与你把“LedBlink(20,35,1000)”放在哪里有关。这是因为app_easy_timer和malloc()需要内核计时器和堆服务。只有在内核初始化和激活后才能调用函数。建议将语句放在system_init()之后,并让LedBlink函数永远闪烁,以简化调试。

int main_func(空白)

sleep_mode_t sleep_mode;

/ /全局初始化
system_init ();

LedBlink (20, 1000);

/*
************************************************************************************
*平台初始化
************************************************************************************
*/
而(1)

.....

问候,

chris0409
离线
最后看到:3年10个月前
加入:2017-01-11 05:59
我已经像你一样做了

我已经按照你的建议做了,但我还是看不出来。现在我在设备连接事件上调用了LedBlink, led右闪。所以是不是因为祝福让我们睡觉了所以我们不能启动计时器?

WI_Dialog
离线
最后看到:1天18小时前
工作人员
加入:2014-01-03十六21
你好,

你好,

在进入睡眠模式之前,应该没有任何活动,包括LED闪烁。无论在扩展或深度睡眠模式下,所有的I/O块都将被关闭,包括定时器服务。因此,LED blink定时器服务被禁用。

为了简化新驱动程序或函数的调试,最简单的方法是添加如下语句:禁用进入睡眠模式但进入空闲模式,以使对软件行为的影响降到最低。

//获取允许的睡眠模式
//从rwip_power_down()到WFI()的时间必须尽可能短!!
sleep_mode = rwip_power_down ();
/*语句添加*/ sleep_mode = mode_idle;

然后你应该看到你的LED连续闪烁。

问候,

WI_Dialog
离线
最后看到:1天18小时前
工作人员
加入:2014-01-03十六21
你好,

你好,

修正错误如下:
//获取允许的睡眠模式
//从rwip_power_down()到WFI()的时间必须尽可能短!!
sleep_mode = rwip_power_down ();
/* * * * * *
If ((sleep_mode == mode_ext_sleep) || (sleep_mode == mode_deep_sleep)) / /将睡眠模式设置为睡眠模式

sleep_mode = mode_idle;

问候,

chris0409
离线
最后看到:3年10个月前
加入:2017-01-11 05:59
让我困惑的是:

让我困惑的是:
我在system_init()之后调用LedBlink(),当计时器内核上升时。在LedBlink()中,我设置了一个定时器来唤醒BLE,那么为什么我的定时器回调仍然不能被触发?当我第一次在LedBlink()中创建定时器时,如果BLE是睡眠的,如果这是真的?我想在我第一次创造计时器之前我可以强迫ble醒来。我已经尝试了API arch_ble_force_wakeup(), arch_ble_ext_wakeup_on()等,但仍然不能闪烁。这些api真的能强制设备唤醒吗?

WI_Dialog
离线
最后看到:1天18小时前
工作人员
加入:2014-01-03十六21
你好,

你好,
验证LedBlink()函数及其行为的技术可以通过简单地强制sleep_mode不进入mode_ext_sleep或mode_deep_sleep来实现。为了集成LED闪烁功能,并让它按照您的预期运行,您需要了解软件是如何构造的。
在实际应用中,有两个独立运行的线程,BLE栈和User应用。内核只提供服务和用户应用程序需要管理和监督所有资源的使用和监控所有活动,以确定设备是否可以进入睡眠模式。

int main_func(空白)

sleep_mode_t sleep_mode;

/ /全局初始化
system_init ();

/*
************************************************************************************
*平台初始化
************************************************************************************
*/
而(1)

{做
//调度所有挂起的事件
schedule_while_ble_on ();

while (app_asynch_proc() != GOTO_SLEEP);//将控制权限授予应用程序,尝试关闭电源
//如果应用程序返回GOTO_SLEEP
.....

app_asynch_proc()函数是一个检查用户应用程序是否有任何活动正在进行,防止设备进入睡眠模式,而BLE堆栈线程准备进入睡眠。

typedef enum {
GOTO_SLEEP = 0,
KEEP_POWERED
} arch_main_loop_callback_ret_t;

在你的情况下,这个函数可以返回“KEEP_POWERED”,只要LED是闪烁的,不允许设备进入睡眠。

静态内联void schedule_while_ble_on(void)

//开启BLE时钟
而(ble_is_powered ())

//设置BLE事件结束。有条件的射频校准可以运行。
uint8_t ble_end_set = ke_event_get(KE_EVENT_BLE_EVT_END);

//执行消息和事件
rwip_schedule ();

如果(ble_evt_end_set)

Uint32_t sleep_duration = 0;
rcx20_read_freq ();

//如果你有足够的时间,对收音机进行温度校准
如果(lld_sleep_check(&sleep_duration, 4)) //6个槽-> 3.750 ms . If (lld_sleep_check(&sleep_duration, 4)
//检查时间和温度以进行无线电校准。
conditionally_run_radio_cals ();

//将控制权授予应用程序,尝试进入睡眠
//如果应用程序返回GOTO_SLEEP
if (app_asynch_trm() != GOTO_SLEEP)

继续;//再次调用rwip_schedule(

其他的

arch_printf_process ();
打破;


函数的作用是:在BLE堆栈运行时处理用户应用程序。rwip_schedule()将处理队列中的所有消息,直到完成,控制将传递给app_asynch_trm()函数,并根据返回值“KEEP_POWERED”或“GOTO_SLEEP”来决定保持活动或相应进入睡眠。

请注意,没有跟踪任何软件定时器是否运行的功能。软计时器的所有者的责任是跟踪它的活动。

要在SDK5中开发应用程序,建议学习以下结构并理解其工作原理,因为它是SDK5结构的关键。

struct arch_main_loop_callbacks {
空白(* app_on_init)(空白);
arch_main_loop_callback_ret_t (* app_on_ble_powered)(空白);
arch_main_loop_callback_ret_t (* app_on_system_powered)(空白);
空白(* app_before_sleep)(空白);
sleep_mode_t (* app_validate_sleep) (sleep_mode_t sleep_mode);
空白(* app_going_to_sleep) (sleep_mode_t sleep_mode);
空白(* app_resume_from_sleep)(空白);
};

Static const struct arch_main_loop_callbacks user_app_main_loop_callbacks = {
.app_on_init = default_app_on_init,

//默认情况下,看门狗定时器在系统唤醒时重新加载并恢复。
//用户必须考虑看门狗定时器的处理(保持它运行,
//冻结它,重新加载它,恢复它,等等),当app_on_ble_powered()正在
//调用,并可能潜在地影响主循环。
.app_on_ble_powered =零,

//默认情况下,看门狗定时器在系统唤醒时重新加载并恢复。
//用户必须考虑看门狗定时器的处理(保持它运行,
//冻结它,重新加载它,恢复它,等等),当app_on_system_powered()正在
//调用,并可能潜在地影响主循环。
.app_on_system_powered =零,

.app_before_sleep =零,
.app_validate_sleep =零,
.app_going_to_sleep =零,
.app_resume_from_sleep =零,
};

问候,

chris0409
离线
最后看到:3年10个月前
加入:2017-01-11 05:59
非常感谢,

非常感谢,非常有用的建议