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

你好,

我目前正在使用BLE外设示例的一个修改版本来尝试用ADC采样信号。我基本上已经用从ADC而不是计数器读取值的代码替换了adc_adcval1_timer_cb_handler中的代码。我遇到的问题是调用adc处理器函数的时间。我需要采样我的信号在2000Hz或2000采样每秒。当我试图获得计时器在10毫秒或以下时,我得到断开连接和platform_reset_func函数在调用adc处理器几次后被调用。我已经尝试了应用程序简单定时器的例子已经使用,我也尝试了使用timer0回调方法。两者似乎都有同样的问题。我想知道是否有一些限制因素与代码或软件本身的时间,我没有意识到?还有什么类型的事情导致调用platform_reset func?

谢谢!

关键词:
设备:
CYibin
离线
最后一次露面:10个月3周前
工作人员
加入:2017-12-14 02:48
迈克尔,

迈克尔,

你能给我看一下你的源代码吗?

目前我可以确认的是,app_easy_timer API的时间单位是10ms,这在2Khz采样时是不合适的。

布尔

CYibin

Michael12344.
离线
最后一次露面:2年3个月前
加入:2019-01-29 23:17
我理解app_easy

我理解app_easy_timer不会让我到达2Khz采样。然而,即使当我使用app easy定时器的最低可能的时间单位10毫秒也不起作用。下面是使用app_easy_timer编辑的部分。当APP_PERIPHERAL_CTRL_TIMER_DELAY设置为2个时间单位时,它工作得很好,但在使用1后不久断开连接。

#define APP_PERIPHERAL_CTRL_TIMER_DELAY (1) void user_svc1_ctrl_wr_ind_handler(ke_msg_id_t const msgid, struct custs1_val_write_ind const *param, ke_task_id_t const dest_id, ke_task_id_t const src_id) {uint8_t val = 0;memcpy (val,参数[0]- >值,参数- >长度);if (val != CUSTS1_CP_ADC_VAL1_DISABLE) {adc_init(GP_ADC_SE, GP_ADC_SIGN, GP_ADC_ATTN3X);adc_usDelay (20);adc_enable_channel (ADC_CHANNEL_P00);timer_used = app_easy_timer (APP_PERIPHERAL_CTRL_TIMER_DELAY app_adcval1_timer_cb_handler);} else {adc_disable();if (timer_used != EASY_TIMER_INVALID_TIMER) {app_easy_timer_cancel(timer_used);timer_used = EASY_TIMER_INVALID_TIMER;}} void app_adcval1_timer_cb_handler() {struct custs1_val_ntf_ind_req *req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ, prf_get_task_from_id(TASK_ID_CUSTS1), TASK_APP, custs1_val_ntf_ind_req, DEF_SVC1_ADC_VAL_1_CHAR_LEN); // ADC value to be sampled static uint16_t sample __attribute__((section("retention_mem_area0"), zero_init)); sample = adc_get_sample(); //req->conhdl = app_env->conhdl; req->handle = SVC1_IDX_ADC_VAL_1_VAL; req->length = DEF_SVC1_ADC_VAL_1_CHAR_LEN; req->notification = true; memcpy(req->value, &sample, DEF_SVC1_ADC_VAL_1_CHAR_LEN); ke_msg_send(req); if (ke_state_get(TASK_APP) == APP_CONNECTED) { // Set it once again until Stop command is received in Control Characteristic timer_used = app_easy_timer(APP_PERIPHERAL_CTRL_TIMER_DELAY, app_adcval1_timer_cb_handler); } }

以下是使用Timer0而不是App_easy_Timer的编辑部分,该零件应该能够更快地采样2kHz。但是,当使用App_easy_Timer时,我可以获得相同的断开连接并呼叫platform_reset_func,当时计时器0或低于10ms间隔时。这里的时间间隔设置为20ms,它工作正常。但是,如果您要将重新加载到1000(5ms),例如它将断开连接和调用platform_reset_func。user_cust1_impl.c中的其余部分在这两个例子中都是相同的。

#define no_pwm 0x0 #define重新加载4000 void user_svc1_ctrl_wr_ind_handler(ke_msg_handler(ke_msg_hand_t const msgs,struct custs1_val_write_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id){uint8_t val = 0;memcpy (val,参数[0]- >值,参数- >长度);if (val != CUSTS1_CP_ADC_VAL1_DISABLE) {adc_init(GP_ADC_SE, GP_ADC_SIGN, GP_ADC_ATTN3X);adc_usDelay (20);adc_enable_channel (ADC_CHANNEL_P00);timer0_stop();timer0_register_callback(app_adcval1_timer_cb_handler);set_tmr_enable(clk_per_reg_tmr_enabled);set_tmr_div(clk_per_reg_tmr_div_8);timer0_set_pwm_high_counter(no_pwm); timer0_set_pwm_low_counter(NO_PWM); timer0_init(TIM0_CLK_FAST, PWM_MODE_ONE, TIM0_CLK_DIV_BY_10); timer0_set_pwm_on_counter(RELOAD); // Enable SWTIM_IRQn irq timer0_enable_irq(); // Start Timer0 timer0_start(); } else { set_tmr_enable(CLK_PER_REG_TMR_DISABLED); adc_disable(); } } void app_adcval1_timer_cb_handler() { struct custs1_val_ntf_ind_req *req = KE_MSG_ALLOC_DYN(CUSTS1_VAL_NTF_REQ, prf_get_task_from_id(TASK_ID_CUSTS1), TASK_APP, custs1_val_ntf_ind_req, DEF_SVC1_ADC_VAL_1_CHAR_LEN); // ADC value to be sampled static uint16_t sample __attribute__((section("retention_mem_area0"), zero_init)); sample = adc_get_sample(); //req->conhdl = app_env->conhdl; req->handle = SVC1_IDX_ADC_VAL_1_VAL; req->length = DEF_SVC1_ADC_VAL_1_CHAR_LEN; req->notification = true; memcpy(req->value, &sample, DEF_SVC1_ADC_VAL_1_CHAR_LEN); ke_msg_send(req); }

谢谢!

Michael12344.
离线
最后一次露面:2年3个月前
加入:2019-01-29 23:17
只是为了避免

只是为了避免误解,user_custs_impl文件之外的其余项目是SDK的外设蓝牙低电平示例。

CYibin
离线
最后一次露面:10个月3周前
工作人员
加入:2017-12-14 02:48
嗨michael12344,

嗨michael12344,

将断开连接的原因是发送给SDK配置文件的通知命令太过频繁。

您应该使用ADC采样生成的数据,然后以较低的频率发送它们。

布尔

CYibin

Michael12344.
离线
最后一次露面:2年3个月前
加入:2019-01-29 23:17
你好,

你好,

有没有办法来解决这个问题?如果数据可以连续地传出,则将是更理想的,而是将所有样本收集到发送数据。是否有另一种发送/接收数据的方法,这些方法会更好,或者可以像我想要的一样经常或近常进行?

谢谢

PM_DIALOG.
离线
最后一次露面:4天20小时前
工作人员
加入:2018-02-08 11:03
嗨michael12344,

嗨michael12344,

τheplatform_reset_func()由platform_reset()调用,是由ROM代码实现的函数。您获得此断言的最可能原因是由于内存不足,因为您可能会尝试分配您永远不会消耗的消息。例如,如果要分配通知消息,并且您有一个小的连接间隔,则邮件堆叠堆积,直到连接事件到达,但在连接事件到达之前,使用大的连接间隔耗尽内存。哪个是您使用的连接间隔?

谢谢,PM_DIALOG.

Michael12344.
离线
最后一次露面:2年3个月前
加入:2019-01-29 23:17
你好,

你好,

是外围设备或中央设备上的连接间隔吗?我在user_peripheral.c和user_config.c中找到了以下内容,它看起来将10ms的最小和最大连接间隔设置为10ms至20ms。

void user_app_connection(uint8_t connection_idx,struct gapc_connection_req_ind const * param){if(app_env [connection_idx] .conidx!= gap_invalid_conidx){app_connection_idx = connection_idx;//停止广告数据更新timer app_easy_timer_cancel(app_add_data_update_timer_used);//检查已建立连接的参数是否是首选的参数。//如果没有,则计划连接参数更新请求。if((param-> con_interval  con_interval> user_connection_param_conf.intv_max)||(param-> con_latency!= user_connection_param_conf.latency)||(param-> sup_to!= user_connection_param_conf.time_out)){//连接参数不是这些,我们希望app_param_update_request_timer_used = app_easy_timer(app_param_update_request_to,param_update_request_timer_cb);}否则{//没有建立连接,重新启动通告user_app_adv_start();} default_app_on_connection(connection_idx,param);}
static const struct connection_param_configuration user_connection_param_conf = {///连接间隔在BLE双插槽中测量的最小值(1.25ms)///使用宏MS_TO_DOUBLESLOTS从毫秒(MS)转换为双插槽.Intv_min = MS_TO_DOUBLESLOTS(10),///在BLE双插槽中测量的连接间隔(1.25ms)///使用宏MS_TO_DOUBLESLOTS从毫秒(MS)转换为双插槽.INTV_MAX = MS_TO_DOUBLESLOTS(20),///在CONNECKENCE事件中测量的延迟.LATINGY = 0,///在定时器单元中测量的监控超时(10 ms)///使用宏MS_TO_TIMERUNITS将从毫秒(MS)转换为定时器单元.Time_out = MS_TO_TIMERUNITS(1250),///在BLE双槽中测量的最小连接事件持续时间(1.25ms)///使用宏MS_To_DoublesLots将从毫秒(MS)转换为双插槽.CE_LEN_MIN = MS_TO_DOUBLESLOTS(0),///在BLE双槽(1.25ms)///使用中测量的最大连接事件持续时间宏观ms_to_double.转换为从毫秒(MS)转换为双插槽.ce_len_max = ms_to_doubleslots(0),};

PM_DIALOG.
离线
最后一次露面:4天20小时前
工作人员
加入:2018-02-08 11:03
嗨michael12344,

嗨michael12344,

请您将连接间隔(.intv_min和.intv_max)更改为更大的一个吗?

谢谢,PM_DIALOG.

Michael12344.
离线
最后一次露面:2年3个月前
加入:2019-01-29 23:17
你好,

你好,

我尝试将intv_min和intv_max改为更大的值30-45ms和100-160ms。然而,由于仍然调用platform_reset_func(),这个问题似乎仍然存在。还有什么方法可以提高数据吞吐量吗?

PM_DIALOG.
离线
最后一次露面:4天20小时前
工作人员
加入:2018-02-08 11:03
嗨michael12344,

嗨michael12344,

在您的应用程序中,可能会在每次连接后出现某种内存泄漏堆积。当wrap_platform_reset()发生时,请确保错误代码是RESET_MEM_ALLOC_FAIL,为了找到它,您必须调试它。此外,检查在ADC读取期间是否发送了任何挂起的消息,并确保正在使用在处理消息时获得的消息,或者正在分配应该释放它们的数据。例如,如果你取样ADC,你分配消息,以便在有一个连接时通过通知发送数据,设备最终将耗尽内存,如果设备耗尽内存,这将导致设备重置。尝试从da1458x_config_advanced定义并增加DB_HEAP_SZ,例如,您可以将值设置为2048。

谢谢,PM_DIALOG.