嗨,每年,
我使用了App_easy定时器进行LED闪烁功能。但是,在将代码闪烁到SPI Flash后,设备重新启动持续。我调试代码,并查看Porram进入闪烁函数和调用的app_easy_timer函数。
该程序永远不会前进到代码(req-> delay = delay; req-> timer_id = timer_id; ke_msg_send(req);)
after it excute the code (struct create_new_timer_struct *req = KE_MSG_ALLOC(APP_CREATE_NEW_TIMER, TASK_APP, TASK_APP, create_new_timer_struct);
这是否意味着内存Alloc错误,并且通过这个原因reboot是reboot?我以前从未遇到过这种现象
Device:
你好,
Do you try running the "prox_reporter" reference software with the app_easy_timer feature in SDK5 ? Your described observation cannot conclude the issue is due to "app_easy_timer" function. More information is required such as how you run your test, on what software, ....
问候,
嗨,wl_dialog,
I know that the app_easy_timer is the issue , because before I add the code of led blink part to the dsps-host project which I also have a process that use a app-easy-timer, it works fine.
what I want to know is that I just use a app-easy-timer to toggle the led pin, why I have block at the code
struct create_new_timer_struct *req = KE_MSG_ALLOC(APP_CREATE_NEW_TIMER, TASK_APP, TASK_APP,create_new_timer_struct);
Follow is the source code of the led.c
#include“LED.H”
#include“app_easy_timer.h”
/ *LED control structure */
typedef struct {
uint8_t todo; /* Blink cycles left */
uint8_t%;/ *循环百分比* /
uint16_t期间;/ *开/关循环时间(msec)* /
uint32_t next; /* Time for next change */
LEDCONTROL_T;
/ ***************************************************************************************************
*全局变量
*************************************************************************************************** /
static LedControl_t ledCtrl __attribute__((section("retention_mem_area0"),zero_init));
/ ***************************************************************************************************
*本地功能
*************************************************************************************************** /
静电voidedupdate(空白);
/ ***************************************************************************************************
*函数 - API
*************************************************************************************************** /
/ ***************************************************************************************************
* @fn ledinit.
*
* @brief初始化服务
*
* @param init - pointer to void that contains the initialized value
*
* @return none
*************************************************************************************************** /
void LedInit(空白)
{
LED_INIT();
}
/ ***************************************************************************************************
* @fn ledblink.
*
* @brief Blink the leds
*
* @param LED - 要闪烁的LED的位屏蔽值
* numBlinks - number of blinks
* percent - the percentage in each period where the led
*将在
* period - length of each cycle in milliseconds
*
* @return none
*************************************************************************************************** /
void LedBlink (uint8_t numBlinks, uint8_t percent, uint16_t period)
{
LEDCTRL.TODO = 2 * NUMBLINKS-1;
ledCtrl.percent = percent;
LEDCTRL.PERIOD =期间;
LED_OFF();
if( percent && period )
{
if( percent < 100 )
{
app_easy_timer(1,Ledupdate);
}
别的
{
LED_ON ();
}
}
别的
{
//关
LED_OFF();
}
}
/ ***************************************************************************************************
* @fn LedUpdate
*
* @brief更新LED使用眨眼
*
* @param none
*
* @return none
*************************************************************************************************** /
static void LedUpdate (void)
{
LED_TOGGLE();
Ledctrl.todo--;
if( ledCtrl.todo /*|| LED_STATE()*/)
{
if(led_state())
{
LEDCTRL.NEXT = LEDCTRL.PERIOD *(100-LEDCTRL.percent);
}
别的
{
ledCtrl.next = ledCtrl.period*ledCtrl.percent;
}
app_easy_timer(LEDCTRL.NEXT/10 lexpdate);
}
}
你能帮我检查代码的一些错误,我真的找不到原因。
其他更多,我刚刚使用LEDINIT来启动LED端口和LEDBLINK(20,35,1000)来在System_init()中进行测试。
更多,我发现了is i invoke LedBlink() in the system_init, I will get continuous reboot after I flash the code to the flash. But if I invoke the LedBlink() in the main_func() after system_init(), this phenomenon will not happen, but I never can get the LedUpdate() invoked. also I have start a timer when a button is pressed, and I can get the callback of this timer invoked when the timer expired. This really confused me, any suggestion will be much appreciated!
你好,
您的问题与您将“LEDBLINK(20,35,1000)”声明的妥善相关。它是因为app_easy_timer和malloc()需要内核计时器和堆服务。只有在内核初始化并激活后,才能调用您的函数。建议在System_Init()之后放入您的语句,并使您的LEDBLink函数闪烁永远以缓解您的调试。
int main_func(void)
{
sleep_mode_t sleep_mode;
//global initialise
system_init();
LedBlink(20,35,1000);
/ *
************************************************************************************
* Platform initialization
************************************************************************************
* /
而(1)
{
.....
}
}
问候,
I already done as you suggested, but I still can't get led blink. now I have invoke LedBlink on the device connection event, and led blinks right. So is it because the ble is sleep so that we can't start a timer?
你好,
Before going into sleep mode, it is supposed no more activity is alive including LED blinking. No matter in extended or deep sleep mode, all I/O blocks will be turned off including the timer service. So, the LED blink timer service is disabled.
To ease the debugging of new driver or function, the simple way is to add one statement as follows to disable going into sleep mode but idle mode to give the minimal impact on software behaviour.
// get the allowed sleep mode
//从rwip_power_down()到wfi()的时间必须尽可能短!!
sleep_mode = rwip_power_down();
/ *语句添加* / sleep_mode = mode_idle;
然后你应该连续看到你的LED眨眼。
问候,
你好,
修复了错误,如下所示:
// get the allowed sleep mode
//从rwip_power_down()到wfi()的时间必须尽可能短!!
sleep_mode = rwip_power_down();
/ *statement added */
if((sleep_mode == mode_ext_sleep)||(sleep_mode == mode_deep_sleep)))
{
sleep_mode = mode_idle;
}
问候,
困惑我是:
我在system_init()之后调用LeDblink(),当时kernal已上升时。在LeDBlink()中,我已经设置了一个将唤醒ble的计时器,因此为什么我的计时器回调仍然无法触发?如果我第一次在LeDBlink()中创建计时器时,如果这是真的,如果这是真的?我想我可以在第一次创建计时器之前强制唤醒。我已经尝试了api arch_ble_force_wakeup(),arch_ble_ext_wakeup_on()等。但仍然不能闪烁。这些API可以真正强制设备唤醒?
你好,
The technique to verify your LedBlink() function and its behavior can be done by simply forcing the sleep_mode not going into mode_ext_sleep or mode_deep_sleep. To integrate the LED blinking function and let it behaves in what you intended, you need to understand how the software is structured.
在实际应用中,有两个(2)个线程独立运行,BLE堆栈和用户应用程序运行。内核仅提供服务和用户应用程序需要管理和监督所有资源使用情况并监视所有活动以确定设备可以进入睡眠模式。
int main_func(void)
{
sleep_mode_t sleep_mode;
//global initialise
system_init();
/ *
************************************************************************************
* Platform initialization
************************************************************************************
* /
而(1)
{
do {
// schedule all pending events
schedule_while_ble_on();
}
while (app_asynch_proc() != GOTO_SLEEP); //grant control to the application, try to go to power down
//if the application returns GOTO_SLEEP
.....
}
}
App_Asynch_Proc()函数是用户应用程序的检查,无论是否发生任何活动,都会阻止设备进入睡眠模式,而BLE堆栈线程已准备好进入睡眠状态。
typedef枚举{
goto_sleep = 0,
keep_powered.
} arch_main_loop_callback_ret_t;
在您的情况下,只要LED闪烁不允许设备睡眠即可,就可以返回“KEEP_POWERED”。
静态内联void schedule_whle_ble_on(void)
{
// BLE clock is enabled
while (ble_is_powered())
{
// BLE event end is set. conditional RF calibration can run.
uint8_t ble_evt_end_set = ke_event_get(KE_EVENT_BLE_EVT_END);
//执行消息和事件
Rwip_schedule();
if(ble_evt_end_set)
{
uint32_t sleep_duration = 0;
rcx20_read_freq();
//如果您有足够的时间运行收音机的温度校准
if(lld_sleep_check(&sleep_duration,4))// 6插槽 - > 3.750 ms
//检查时间和温度以运行无线电校准。
条件_run_radio_cals();
}
//grant control to the application, try to go to sleep
//if the application returns GOTO_SLEEP
if(app_asynch_trm()!= goto_sleep)
{
continue; // so that rwip_schedule() is called again
}
别的
{
ARCH_PRINTF_PROCESS();
break;
}
}
}
app_asynch_trm()函数在运行ble堆栈时处理用户应用程序。RWIP_Schedule()将处理队列中的所有消息,直到完成,并且控件将传递给App_Asynch_trm()函数,并基于返回的值“Keep_Powered”或“Goto_Sleep”来决定保持活动或相应地睡眠。
Please notice that there is no function to keep track any software timer is running or not. It is the responsibility of the owner of the soft timer is to keep track its activity.
要在SDK5中开发您的应用程序,建议研究以下结构,并了解它是如何运行的,因为它是SDK5结构的关键。
struct arch_main_loop_callbacks {
void (*app_on_init)(void);
ARCH_MAIN_LOOP_CALLBACK_RET_T(* APP_ON_BLE_POWERED)(void);
ARCH_MAIN_LOOP_CALLBACK_RET_T(* APP_ON_SYSTEM_POWERED)(VOID);
void(* app_before_sleep)(void);
sleep_mode_t (*app_validate_sleep)(sleep_mode_t sleep_mode);
void(* app_gen_to_sleep)(sleep_mode_t sleep_mode);
void(* app_resume_from_sleep)(void);
};
static const struct arch_main_loop_callbacks user_app_main_loop_callbacks = {
.app_on_init = default_app_on_init,
//默认情况下,系统唤醒时重新加载并恢复监视程序。
//用户必须考虑看门狗定时器处理(请保持运行,
//冻结它,重新加载,恢复IT等),当App_On_ble_Powered()正在呈现时
//调用并可能可能影响主循环。
.app_on_ble_powered = null,
//默认情况下,系统唤醒时重新加载并恢复监视程序。
//用户必须考虑看门狗定时器处理(请保持运行,
//冻结它,重新加载,恢复IT等),当app_on_system_powered()是
//调用并可能可能影响主循环。
.app_on_system_powered = null,
.app_before_sleep = null,
.app_validate_sleep = NULL,
.app_going_to_sleep = NULL,
.app_resume_from_sleep = NULL,
};
问候,
非常感谢,有用的建议