NMI发生在代码开始执行之后。代码崩溃,甚至当看门狗禁用(//#define CFG_WDOG),因为外设没有开始广告,所以我猜它崩溃了。
我怎么知道代码在哪里卡住了?它是通过PC寄存器值吗?你能解释一下这是怎么做的吗?看门狗超时后,PC值为0x200005F0。
谢谢你!
嗨费尔南多,
当fw崩溃并进入Hardfault或NMI_Handler时,当这种情况发生时,fw将ARM寄存器的值存储在两个特定的基址0x81800和0x81850。因此,您可以从内存窗口检查PC计数器的值,以及应用程序崩溃的确切位置。事实上,你注释掉NMI和你的代码崩溃并不意味着fw击中了NMI_Handler(最有可能它没有,因为你没有定义看门狗)。程序计数器,当监管机构已经发生的值,直接指向当前执行的命令,所以你不能够使用,如果你的弗兰克-威廉姆斯打敝中断或Hardfault,因为电脑会点敝中断或Hardfault处理程序。
由于MT_dialog
如果我禁用watchdog (//#define CFG_WDOG),并通过放置断点,我可以验证代码永远不会到达wdg_reload(WATCHDOG_DEFAULT_PERIOD);但它确实到达了GLOBAL_INT_START();这意味着它正在进入睡眠模式,即使我设置了app_default_sleep_mode = ARCH_SLEEP_OFF;这是为什么呢?
我所做的一切都是遵循“软件开发人员指南”中的“使用空项目模板”,在那之后,我已经将葡萄糖浓度传感器包含到项目中。然后我做了以下更改,以使它工作:Obs:我包含了所有需要的。h文件,项目编译时没有任何错误。如果我不将GLPS包含到项目中,代码也可以正常工作。
----------------------------------------------------------------------------------------------------------------user_config.h
Static const struct prf_func_callbacks user_prf_funcs[] ={{TASK_GLPS, app_glps_create_db app_glps_enable},{task_none, null, null}, //不移动。一定要在最后};-----------------------------------------------------------------------------------------------------------------user_profiles_config.h
# include“diss.h”# include“glps.h”------------------------------------------------------------------------------------------------------------------user_glucose_application.c
空白app_glps_create_db(空白){struct glps_create_db_req *req = KE_MSG_ALLOC(glps_create_db_req,TASK_GLPS TASK_APP,glps_create_db_req);申请- > start_hdl = 0;申请- > meas_ctx_supported = 0;/ /请求- > meas_ctx_supported = GLPS_MEAS_CTX_SUPPORTED;
ke_msg_send(要求的);}
空白app_glps_enable (uint16_t conhdl){结构glps_enable_req *req = KE_MSG_ALLOC(glps_enable_req,TASK_GLPS TASK_APP,glps_enable_req);申请- > conhdl = conhdl;/ /请求- > = feGLP_FET_LOW_BAT_DET_DUR_MEAS_SUPP特性;/ /请求- > sec_lvl = get_user_prf_srv_perm (TASK_DISS);/ /请求- > con_type = PRF_CON_DISCOVERY;
ke_msg_send(要求的);}-------------------------------------------------------------------------------------------------------------------user_glucosensor_application.h
空白app_glps_enable (uint16_t conhdl);空白app_glps_create_db(无效);--------------------------------------------------------------------------------------------------------------------user_modules_config.h
#定义EXCLUDE_DLG_GAP (0)#定义EXCLUDE_DLG_TIMER (0)#定义EXCLUDE_DLG_MSG (0)#定义EXCLUDE_DLG_SEC (0)#定义EXCLUDE_DLG_DISS (0)#定义EXCLUDE_DLG_PROXR (1)#定义EXCLUDE_DLG_BASS (1)#定义EXCLUDE_DLG_FINDL (1)#定义EXCLUDE_DLG_FINDT (1)#定义EXCLUDE_DLG_SPOTAR (1)#定义EXCLUDE_DLG_CUSTS1 (1)#定义EXCLUDE_DLG_CUSTS2 (1)--------------------------------------------------------------------------------------------------------------------我真的不明白一个人应该如何处理才能找出在FW中代码卡住的地方。所以你的意思是我应该检查地址0x81800和0x81850,从这些地址,我必须寻找PC值,将指向它卡住的部分代码?我该怎么做?我发了一张我在调试时收到的照片。
如果你禁用看门狗,fw没有理由重新加载看门狗,因为你没有使用它。如果您定义了看门狗,那么重新加载的代码将进入执行。也因为你没有睡眠,事实上代码通过GLOBAL_INT_START()多恩不是说设备是睡觉,为了让设备睡眠必须输入()条件,检查如果睡在mode_ext或mode_deep_sleep为了权力的权力领域。试着检查模板项目,我不能看到任何NMI执行而没有看门狗定义,所以即使你有未定义CFG_WDOG定义在你的代码的某处,你是启用它。总之,除非你有看门狗功能,否则我不可能想到NMI_Handler发生。
关于调试和如何找出你的代码停滞的地方,例如在模板项目上,我已经定义了看门狗并放置了一个while(1);在user_on_connection()函数中,这意味着当我连接到一个设备时,代码将在while(1)循环中卡住,看门狗将引导我到NMI_Handler()。所以为了检查我的代码是否卡住了,我看到Handler是NMI,所以ARM寄存器被转储的BASE_ADDRESS是0x81850,所以我从keil打开一个内存窗口并输入这个基地地址。根据寄存器是如何保存的,我检查第7位的基地地址的值,以检查我的程序计数器(设置您的内存窗口显示在unsigned长)。我看到第7位的值是0x200050FA,所以我去到程序集窗口并跟踪这个地址,程序集最终将指向用户连接中的while(1)循环,在那里代码卡住了。
非常感谢,我设法找出了代码卡住的地方,它在GLOBAL_INT_START ();为什么会这样,有什么线索吗?我附上一张照片。
就像我说的,如果看门狗被启用了,只有这样NMI将发生,关于得到它的原因,我猜你已经增加了广告间隔超过看门狗超时(2.6秒),所以设备卡在WFI()等待一个从未到来的中断,因为BLE事件是远远在时间。
谢谢你的快速回放。
就像我说的,除了上面提到的,我什么都没做。但为了确保广告间隔是正常的,我甚至将其设置为110 (68.7 ms),但仍然没有任何效果。
obs:如果下面的代码行(插入了"create"和"enable"函数)有注释,则FW不进入NMI处理程序。
Static const struct prf_func_callbacks user_prf_funcs[] ={/ / {TASK_GLPS, app_glps_create_db app_glps_enable},{task_none, null, null}, //不移动。一定要在最后};
如果是这种情况,那么一旦发送消息,数据库的创建就不会得到确认,在创建数据库时检查消息流,消息是否触发了适当的处理程序?我假设default_app_on_db_init_complete回调函数永远不会触发,并且您实现它的数据库永远不会创建。当数据库完成时,fw是否处理确认,是否发送APP_MODULE_INIT_CMP_EVT消息?检查接近报告程序,并检查其他概要文件如何处理数据库创建。
你是对的,我没有为了发送“APP_MODULE_INIT_CMP_EVT”消息而处理“GLPS_CREATE_DB_CFM”消息。
查看接口规范。pdf,它说“GLPS_CREATE_DB_CFM”有“目的地:TASK_API”。它们的意思是“目的地:TASK_APP”吗?
我设法使它工作在最后,使用“user_catch_rest_hndl”。
有没有一种方法可以实现这个消息处理使用代替catch rest cb,使用下面的app_task和profle_task使用?
Static const struct ke_msg_handler app_glps_process_handlers[] ={(ke_msg_func_t) glps_create_db_cfm_handler}, {GLPS_CREATE_DB_CFM};
我试过用这种方法做,但没有成功。我希望这样做,因为它感觉更紧凑,因为我将处理的所有消息都被限制在一个地方。
概要文件有为其消息分配的独立任务,例如,接近报告程序,因为接近概要文件有TASK_PROXR任务,所以它取决于您希望如何实现葡萄糖概要文件,因此葡萄糖传感器有TASK_GLPS任务作为它的专用任务。例如,如果您查看邻近概要文件你会发现创建数据库(app_proxr_create_db)任务的目的地TASK_PROXR和确认proxr_create_db_req_handler()函数提供了发送到TASK_APP(通知概要文件创建)的主要任务。是的,确认的目的地必须被发送到TASK_APP,以知道这个配置文件的数据库已经完成,以便进入下一个。
是的你可以做像你提到的,但为了工作你需要创建一个app_glps_process_handler()函数(就像app_proxr_process_handler app_proxr_task.c文件中())来处理事件,有的从这个概要文件和调用适当的处理程序,这个处理器函数应该放在app_entry_point.c文件中的app_process_handlers[]数组中。
嗨费尔南多,
当fw崩溃并进入Hardfault或NMI_Handler时,当这种情况发生时,fw将ARM寄存器的值存储在两个特定的基址0x81800和0x81850。因此,您可以从内存窗口检查PC计数器的值,以及应用程序崩溃的确切位置。事实上,你注释掉NMI和你的代码崩溃并不意味着fw击中了NMI_Handler(最有可能它没有,因为你没有定义看门狗)。程序计数器,当监管机构已经发生的值,直接指向当前执行的命令,所以你不能够使用,如果你的弗兰克-威廉姆斯打敝中断或Hardfault,因为电脑会点敝中断或Hardfault处理程序。
由于MT_dialog
如果我禁用watchdog (//#define CFG_WDOG),并通过放置断点,我可以验证代码永远不会到达wdg_reload(WATCHDOG_DEFAULT_PERIOD);但它确实到达了GLOBAL_INT_START();这意味着它正在进入睡眠模式,即使我设置了app_default_sleep_mode = ARCH_SLEEP_OFF;这是为什么呢?
我所做的一切都是遵循“软件开发人员指南”中的“使用空项目模板”,在那之后,我已经将葡萄糖浓度传感器包含到项目中。
然后我做了以下更改,以使它工作:
Obs:我包含了所有需要的。h文件,项目编译时没有任何错误。如果我不将GLPS包含到项目中,代码也可以正常工作。
----------------------------------------------------------------------------------------------------------------
user_config.h
Static const struct prf_func_callbacks user_prf_funcs[] =
{
{TASK_GLPS, app_glps_create_db app_glps_enable},
{task_none, null, null}, //不移动。一定要在最后
};
-----------------------------------------------------------------------------------------------------------------
user_profiles_config.h
# include“diss.h”
# include“glps.h”
------------------------------------------------------------------------------------------------------------------
user_glucose_application.c
空白app_glps_create_db(空白)
{
struct glps_create_db_req *req = KE_MSG_ALLOC(glps_create_db_req,
TASK_GLPS TASK_APP,
glps_create_db_req);
申请- > start_hdl = 0;
申请- > meas_ctx_supported = 0;
/ /请求- > meas_ctx_supported = GLPS_MEAS_CTX_SUPPORTED;
ke_msg_send(要求的);
}
空白app_glps_enable (uint16_t conhdl)
{
结构glps_enable_req *req = KE_MSG_ALLOC(glps_enable_req,
TASK_GLPS TASK_APP,
glps_enable_req);
申请- > conhdl = conhdl;
/ /请求- > = feGLP_FET_LOW_BAT_DET_DUR_MEAS_SUPP特性;
/ /请求- > sec_lvl = get_user_prf_srv_perm (TASK_DISS);
/ /请求- > con_type = PRF_CON_DISCOVERY;
ke_msg_send(要求的);
}
-------------------------------------------------------------------------------------------------------------------
user_glucosensor_application.h
空白app_glps_enable (uint16_t conhdl);
空白app_glps_create_db(无效);
--------------------------------------------------------------------------------------------------------------------
user_modules_config.h
#定义EXCLUDE_DLG_GAP (0)
#定义EXCLUDE_DLG_TIMER (0)
#定义EXCLUDE_DLG_MSG (0)
#定义EXCLUDE_DLG_SEC (0)
#定义EXCLUDE_DLG_DISS (0)
#定义EXCLUDE_DLG_PROXR (1)
#定义EXCLUDE_DLG_BASS (1)
#定义EXCLUDE_DLG_FINDL (1)
#定义EXCLUDE_DLG_FINDT (1)
#定义EXCLUDE_DLG_SPOTAR (1)
#定义EXCLUDE_DLG_CUSTS1 (1)
#定义EXCLUDE_DLG_CUSTS2 (1)
--------------------------------------------------------------------------------------------------------------------
我真的不明白一个人应该如何处理才能找出在FW中代码卡住的地方。
所以你的意思是我应该检查地址0x81800和0x81850,从这些地址,我必须寻找PC值,将指向它卡住的部分代码?
我该怎么做?
我发了一张我在调试时收到的照片。
嗨费尔南多,
如果你禁用看门狗,fw没有理由重新加载看门狗,因为你没有使用它。如果您定义了看门狗,那么重新加载的代码将进入执行。也因为你没有睡眠,事实上代码通过GLOBAL_INT_START()多恩不是说设备是睡觉,为了让设备睡眠必须输入()条件,检查如果睡在mode_ext或mode_deep_sleep为了权力的权力领域。试着检查模板项目,我不能看到任何NMI执行而没有看门狗定义,所以即使你有未定义CFG_WDOG定义在你的代码的某处,你是启用它。总之,除非你有看门狗功能,否则我不可能想到NMI_Handler发生。
关于调试和如何找出你的代码停滞的地方,例如在模板项目上,我已经定义了看门狗并放置了一个while(1);在user_on_connection()函数中,这意味着当我连接到一个设备时,代码将在while(1)循环中卡住,看门狗将引导我到NMI_Handler()。所以为了检查我的代码是否卡住了,我看到Handler是NMI,所以ARM寄存器被转储的BASE_ADDRESS是0x81850,所以我从keil打开一个内存窗口并输入这个基地地址。根据寄存器是如何保存的,我检查第7位的基地地址的值,以检查我的程序计数器(设置您的内存窗口显示在unsigned长)。我看到第7位的值是0x200050FA,所以我去到程序集窗口并跟踪这个地址,程序集最终将指向用户连接中的while(1)循环,在那里代码卡住了。
由于MT_dialog
非常感谢,我设法找出了代码卡住的地方,它在GLOBAL_INT_START ();
为什么会这样,有什么线索吗?
我附上一张照片。
嗨费尔南多,
就像我说的,如果看门狗被启用了,只有这样NMI将发生,关于得到它的原因,我猜你已经增加了广告间隔超过看门狗超时(2.6秒),所以设备卡在WFI()等待一个从未到来的中断,因为BLE事件是远远在时间。
由于MT_dialog
谢谢你的快速回放。
就像我说的,除了上面提到的,我什么都没做。但为了确保广告间隔是正常的,我甚至将其设置为110 (68.7 ms),但仍然没有任何效果。
obs:如果下面的代码行(插入了"create"和"enable"函数)有注释,则FW不进入NMI处理程序。
Static const struct prf_func_callbacks user_prf_funcs[] =
{
/ / {TASK_GLPS, app_glps_create_db app_glps_enable},
{task_none, null, null}, //不移动。一定要在最后
};
嗨费尔南多,
如果是这种情况,那么一旦发送消息,数据库的创建就不会得到确认,在创建数据库时检查消息流,消息是否触发了适当的处理程序?我假设default_app_on_db_init_complete回调函数永远不会触发,并且您实现它的数据库永远不会创建。当数据库完成时,fw是否处理确认,是否发送APP_MODULE_INIT_CMP_EVT消息?检查接近报告程序,并检查其他概要文件如何处理数据库创建。
由于MT_dialog
你是对的,我没有为了发送“APP_MODULE_INIT_CMP_EVT”消息而处理“GLPS_CREATE_DB_CFM”消息。
查看接口规范。pdf,它说“GLPS_CREATE_DB_CFM”有“目的地:TASK_API”。它们的意思是“目的地:TASK_APP”吗?
我设法使它工作在最后,使用“user_catch_rest_hndl”。
有没有一种方法可以实现这个消息处理使用代替catch rest cb,使用下面的app_task和profle_task使用?
Static const struct ke_msg_handler app_glps_process_handlers[] =
{
(ke_msg_func_t) glps_create_db_cfm_handler}, {GLPS_CREATE_DB_CFM
};
我试过用这种方法做,但没有成功。我希望这样做,因为它感觉更紧凑,因为我将处理的所有消息都被限制在一个地方。
嗨费尔南多,
概要文件有为其消息分配的独立任务,例如,接近报告程序,因为接近概要文件有TASK_PROXR任务,所以它取决于您希望如何实现葡萄糖概要文件,因此葡萄糖传感器有TASK_GLPS任务作为它的专用任务。例如,如果您查看邻近概要文件你会发现创建数据库(app_proxr_create_db)任务的目的地TASK_PROXR和确认proxr_create_db_req_handler()函数提供了发送到TASK_APP(通知概要文件创建)的主要任务。是的,确认的目的地必须被发送到TASK_APP,以知道这个配置文件的数据库已经完成,以便进入下一个。
是的你可以做像你提到的,但为了工作你需要创建一个app_glps_process_handler()函数(就像app_proxr_process_handler app_proxr_task.c文件中())来处理事件,有的从这个概要文件和调用适当的处理程序,这个处理器函数应该放在app_entry_point.c文件中的app_process_handlers[]数组中。
由于MT_dialog