static const struct ke_msg_handler app_proxr_process_handlers[] =
{
{APP_PROXR_TIMER, (ke_msg_func_t)app_proxr_timer_handler},
{PROXR_ALERT_IND, (ke_msg_func_t)proxr_alert_ind_handler},
};
这个怎么使用的?
/// Element of a message handler table.
struct ke_msg_handler
{
/// Id of the handled message.
ke_msg_id_t id; -----这个ID已经和TASK有关系 比如 enum proxr_msg_id{PROXR_ALERT_IND = KE_FIRST_MSG(TASK_ID_PROXR),};
/// Pointer to the handler function for the msgid above.
ke_msg_func_t func;
};
它是统一送给APP用
enum process_event_response app_proxr_process_handler(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id,
enum ke_msg_status_tag *msg_ret)
return app_std_process_event(msgid, param, src_id, dest_id, msg_ret,
app_proxr_process_handlers,
sizeof(app_proxr_process_handlers) / sizeof(struct ke_msg_handler));
在里面找函数执行
static ke_msg_func_t handler_search(ke_msg_id_t const msg_id,
const struct ke_msg_handler *handlers,
const int handler_num)
{
for (int i = (handler_num-1); 0 <= i; i--)
{
if ((handlers[i].id == msg_id) || (handlers[i].id == KE_MSG_DEFAULT_HANDLER))
{
// If handler is NULL, message should not have been received in this state
ASSERT_ERR(handlers[i].func);
return handlers[i].func;
}
}
return NULL;
}
enum process_event_response app_std_process_event(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const src_id,
ke_task_id_t const dest_id,
enum ke_msg_status_tag *msg_ret,
const struct ke_msg_handler *handlers,
const int handler_num)
{
ke_msg_func_t func = NULL;
func = handler_search(msgid, handlers, handler_num);
if (func != NULL)
{
*msg_ret = (enum ke_msg_status_tag) func(msgid, param, dest_id, src_id);
return PR_EVENT_HANDLED;
}
else
{
return PR_EVENT_UNHANDLED;
}
}
那么谁调用 app_proxr_process_handler
它是一个TASK的接口 它放在一个数组
const process_event_func_t app_process_handlers[] = {
#if (!EXCLUDE_DLG_GAP)
(process_event_func_t) app_gap_process_handler,
#endif
#if ((BLE_PROX_REPORTER) && (!EXCLUDE_DLG_PROXR))
(process_event_func_t) app_proxr_process_handler,
#endif
等别人轮询 数组 app_process_handlers
int app_entry_point_handler(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
int i = 0;
enum ke_msg_status_tag process_msg_handling_result;
while (i < (sizeof(app_process_handlers) / sizeof(process_event_func_t)))
{
ASSERT_ERR(app_process_handlers[i]);//每一个函数都会跑进去执行
if (app_process_handlers[i](msgid, param, dest_id, src_id, &process_msg_handling_result) == PR_EVENT_HANDLED)
{
return (process_msg_handling_result);//任何一个执行了 那就结束了
}
i++;
}
//user cannot do anything else than consume the message
if (app_process_catch_rest_cb != NULL)
{
app_process_catch_rest_cb(msgid,param, dest_id, src_id);
}
return (KE_MSG_CONSUMED);
};
const struct ke_msg_handler app_default_state[] =
{
{KE_MSG_DEFAULT_HANDLER, (ke_msg_func_t)app_entry_point_handler},
};
const struct ke_state_handler app_default_handler = KE_STATE_HANDLER(app_default_state);
static const struct ke_task_desc TASK_DESC_APP = {NULL,
&app_default_handler,
ke_task_create(TASK_APP, &TASK_DESC_APP);
+++++++++++++++++++++在读一遍++++++++++++++++++
D:\git\dialog\6.0.10.511\projects\target_apps\ble_examples\prox_reporter\Keil_5
1----服务device information 每一个都是只读的
2---在link loss OX1803
IMMEDIATE ALERT 0X1802
都是点击什么发送什么手机APP就显示什么
区别是 IMMEDIATE ALERT
发送hight 板子LED快闪
发送mid 板子LED慢闪
发送no 板子LEDOFF
app_button_press_cb --SW3
user-app user_proxr
这个是官方SDK应用 这个写的很少 就是流程中的
sdk-app
app_proxr + app_proxr_task
app_proxr_task 三段式代码
1---
static int app_proxr_timer_handler(ke_msg_id_t const msgid,
static int proxr_alert_ind_handler(ke_msg_id_t const msgid,
2---
static const struct ke_msg_handler app_proxr_process_handlers[] =
{
{APP_PROXR_TIMER, (ke_msg_func_t)app_proxr_timer_handler},
{PROXR_ALERT_IND, (ke_msg_func_t)proxr_alert_ind_handler},
};
3---
enum process_event_response app_proxr_process_handler(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id,
enum ke_msg_status_tag *msg_ret)
{
return app_std_process_event(msgid, param, src_id, dest_id, msg_ret,
app_proxr_process_handlers,
sizeof(app_proxr_process_handlers) / sizeof(struct ke_msg_handler));
}
app_proxr_process_handler
app_process_handlers
app_entry_point_handler
这既是流程!它是SDK自己的 不是用户自己的 所以比较简单
那么消息触发在哪里呢
static const struct ke_msg_handler app_proxr_process_handlers[] =
{
{APP_PROXR_TIMER, (ke_msg_func_t)app_proxr_timer_handler},--这个函数是LED定时翻转的
{PROXR_ALERT_IND, (ke_msg_func_t)proxr_alert_ind_handler},--这个函数 default_proxr_alert_ind_handler 是开关
};
测试
link loss 发消息 2和函数都不会执行
IMMEDIATE ALERT 发消息hight 是先 proxr_alert_ind_handler 打开了 然后循环周期执行 app_proxr_timer_handler
也就是IMMEDIATE ALERT消息 先 proxr_alert_ind_handler-打开定时器 然后周期 ke_timer_set(APP_PROXR_TIMER, TASK_APP, alert_state.blink_timeout);
继续王国前看 PROXR_ALERT_IND
在91行
《这里和前面一样 手机APP写消息都是这里就开始的 gattc_write_req_ind_handler https://blog.csdn.net/weixin_42381351/article/details/114585846?spm=1001.2014.3001.5501》
static int gattc_write_req_ind_handler(ke_msg_id_t const msgid,
struct gattc_write_req_ind const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
if(param->value[0] <= PROXR_ALERT_HIGH)
{
// Allocate the alert value change indication
struct proxr_alert_ind *ind = KE_MSG_ALLOC(PROXR_ALERT_IND,
prf_dst_task_get(&(proxr_env->prf_env), conidx),
dest_id, proxr_alert_ind);
这里的处理是在profil中的
if(param->value[0] <= PROXR_ALERT_HIGH)
{
alert_lvl = param->value[0];
// Store alert level on the environment
这里是link loss 发消息 是保持数据
if(param->handle == (proxr_env->lls_start_hdl + LLS_IDX_ALERT_LVL_VAL))
{
proxr_env->lls_alert_lvl[conidx] = alert_lvl;
cfm->status = GAP_ERR_NO_ERROR;
}
else if(param->handle == (proxr_env->ias_start_hdl + IAS_IDX_ALERT_LVL_VAL))
{
// Allocate the alert value change indication
struct proxr_alert_ind *ind = KE_MSG_ALLOC(PROXR_ALERT_IND,
prf_dst_task_get(&(proxr_env->prf_env), conidx),
dest_id, proxr_alert_ind);
// Fill in the parameter structure
ind->alert_lvl = alert_lvl;
ind->char_code = PROXR_IAS_CHAR;
ind->conidx = conidx;
// Send the message
ke_msg_send(ind);
cfm->status = GAP_ERR_NO_ERROR;
}
else
{
cfm->status = ATT_ERR_REQUEST_NOT_SUPPORTED;
}
}
也就是2中不同的处理 是 param->handle
if(param->handle == (proxr_env->lls_start_hdl + LLS_IDX_ALERT_LVL_VAL))
else if(param->handle == (proxr_env->ias_start_hdl + IAS_IDX_ALERT_LVL_VAL))
关注 LLS_IDX_ALERT_LVL_VAL IAS_IDX_ALERT_LVL_VAL
const struct attm_desc proxr_ias_att_db[IAS_IDX_NB] =
{
// Immediate Alert Service Declaration
[IAS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE),0},
// Alert Level Characteristic Declaration
[IAS_IDX_ALERT_LVL_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), IAS_IDX_ALERT_LVL_VAL},
// Alert Level Characteristic Value
[IAS_IDX_ALERT_LVL_VAL] = {ATT_CHAR_ALERT_LEVEL, PERM(WR, ENABLE)|PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE) | sizeof(uint8_t)},
};
const struct attm_desc proxr_lls_att_db[LLS_IDX_NB] =
{
// Link Loss Service Declaration
[LLS_IDX_SVC] = {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), 0},
// Alert Level Characteristic Declaration
[LLS_IDX_ALERT_LVL_CHAR] = {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), LLS_IDX_ALERT_LVL_VAL},
// Alert Level Characteristic Value
[LLS_IDX_ALERT_LVL_VAL] = {ATT_CHAR_ALERT_LEVEL, PERM(RD, ENABLE) | PERM(WR, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE) | sizeof(uint8_t)},
};
// LLS Handles offsets
enum
{
LLS_IDX_SVC,
LLS_IDX_ALERT_LVL_CHAR,
LLS_IDX_ALERT_LVL_VAL,
LLS_IDX_NB,
};
/// IAS Handles offsets
enum
{
IAS_IDX_SVC,
IAS_IDX_ALERT_LVL_CHAR,
IAS_IDX_ALERT_LVL_VAL,
IAS_IDX_NB,
};
数组怎么用的 proxr_ias_att_db proxr_lls_att_db proxr_init
status = attm_svc_create_db(start_hdl, ATT_SVC_LINK_LOSS, (uint8_t *)&cfg_flag,
LLS_IDX_NB, NULL, env->task, &proxr_lls_att_db[0],
cfg_flag = PROXR_IAS_MANDATORY_MASK;
status = attm_svc_create_db(start_hdl, ATT_SVC_IMMEDIATE_ALERT, (uint8_t *)&cfg_flag,
IAS_IDX_NB, NULL, env->task, &proxr_ias_att_db[0],
status = attm_svc_create_db(start_hdl, ATT_SVC_TX_POWER, (uint8_t *)&cfg_flag,
TXPS_IDX_NB, NULL, env->task, &proxr_txps_att_db[0],
那就参见分析一下 APP点击 ATT_SVC_TX_POWER 的效果
proxr_txps_att_db
TXPS_IDX_TX_POWER_LVL_VAL
可以看到 最开始是这里 !!! 读写啊 !!!
gattc_read_req_ind_handler
后面是
gapm_dev_adv_tx_power_ind_handler
小结:手机APP写---gattc_write_req_ind_handler
手机APP读--------gattc_read_req_ind_handler
继续
看最后的UUID APP测试点击TX POWttxpower gapm_dev_adv_tx_power_ind_handler
/// Advertising channel Tx power level indication event
struct gapm_dev_adv_tx_power_ind
{
/// Advertising channel Tx power level
int8_t power_lvl;
};
修改一下这个函数吧! 现在就是点击一些 下面的数据就++
static int gapm_dev_adv_tx_power_ind_handler(ke_msg_id_t const msgid,
struct gapm_dev_adv_tx_power_ind const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
// Get the address of the environment
struct proxr_env_tag *proxr_env = PRF_ENV_GET(PROXR, proxr);
static int cont=8;
if( ke_state_get(dest_id) == PROXR_BUSY )
{
// Send data to peer device
struct gattc_read_cfm* cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, KE_BUILD_ID(TASK_GATTC, proxr_env->conidx_saved), dest_id,
gattc_read_cfm, sizeof(uint8_t));
cfm->length = sizeof(uint8_t);
cfm->value[0] = cont++;//param->power_lvl;
cfm->handle = proxr_env->txp_start_hdl + TXPS_IDX_TX_POWER_LVL_VAL;
cfm->status = GAP_ERR_NO_ERROR;
这个函数是怎么触发的 未解之谜啊 GAPM_DEV_ADV_TX_POWER_IND 没有人发
bass_init --电池0X180F
proxr_init--防止丢失 OX1804
增加:————————————————————————————————
UM-B-079 DA14585 & DA14586 Software Platform Reference (SDK 6.0.8)UM-B-079 DA14585 & DA14586 Software Platform Reference (SDK 6.0.8)
连接---https://www.dialog-semiconductor.com/search?keywords=RW-BT-KERNEL-SW-FS
在43页开始的 内核 任务 有描述
D:\A_CODE\6.0.10.511\sdk\platform\core_modules\ke\api
/// Element of a message handler table.
struct ke_msg_handler
{
/// Id of the handled message.
ke_msg_id_t id;
/// Pointer to the handler function for the msgid above.
ke_msg_func_t func;
};
/// Element of a state handler table.
struct ke_state_handler
{
/// Pointer to the message handler table of this state.
const struct ke_msg_handler *msg_table;
/// Number of messages handled in this state.
uint16_t msg_cnt;
};
#define KE_STATE_HANDLER(hdl) {hdl, sizeof(hdl)/sizeof(struct ke_msg_handler)}
/// Helps writing empty states.
#define KE_STATE_HANDLER_NONE {NULL, 0}
/// Task descriptor grouping all information required by the kernel for the scheduling.
struct ke_task_desc
{
/// Pointer to the state handler table (one element for each state).
const struct ke_state_handler* state_handler;----全部是空
/// Pointer to the default state handler (element parsed after the current state).
const struct ke_state_handler* default_handler;---有函数池子
/// Pointer to the state table (one element for each instance).
ke_state_t* state;
/// Maximum number of states in the task.
uint16_t state_max;
/// Maximum index of supported instances of the task.
uint16_t idx_max;
};
env->desc.default_handler = &custs1_default_handler;