蓝牙芯片----BK3431开发笔记------RW stack中添加自定义服务教程(4)

举报
心跳包 发表于 2021/11/12 23:20:41 2021/11/12
【摘要】 一、实现自定义服务 在 RW 协议栈协议栈中添加一个自定义服务需要实现 6 个文件,分别为: custom.c custom.h custom_task.c custom_task.h app_custom.c app_custom.h 在 sdk\ble_s...

一、实现自定义服务

在 RW 协议栈协议栈中添加一个自定义服务需要实现 6 个文件,分别为:
custom.c
custom.h
custom_task.c
custom_task.h
app_custom.c
app_custom.h
sdk\ble_stack\common\profiles\custom。将custom.h、custom_task.h文件放在api目录下,custom.c、custom_task.c两个文件放在src目录下。将app_custom.c与app_custom.h存放在projects\ble\ble_app_gatt\app\下。
本文档以 custom 服务为例介绍了如何添加一个服务到 RW 的详细步骤。
1. sdk\ble_stack\common\profiles\custom 目录如下:
2. projects\ble_app_gatt\app 目录如下:

 

二、添加 service 到工程中
1. 使用 keil 5.12 打开对应工程,在工程目录 profile 目录下添加指定 profile 相关源文
件,本例中是 custom.c 和 custom_task.c,如下图:
 

2. 在 keil C/C++选项卡下面添加对应 profile 的路径,如下:
 
3. 在工程目录 app 目录下添加指定自定义服务在应用层文件:
4. 在 app_task.c 文件中找到 appm_msg_handler 函数,在其中自定义服务获取 handler 的
函数,如下:

     
  1. case (TASK_ID_CUSTOM):
  2. {
  3. // Call the custom Modules
  4. msg_pol = appm_get_handler(&app_custom_table_handler, msgid, param, src_id);
  5. } break;
5. 在 app.c 文件中的服务列表中添加自定义服务,如下:

      
  1. /// List of service to add in the database
  2. enum appm_svc_list
  3. {
  4. APPM_SVC_CUSTOM,
  5. APPM_SVC_DIS,
  6. APPM_SVC_BATT,
  7. APPM_SVC_OADS,
  8. APPM_SVC_LIST_STOP ,
  9. };
6. 在 app.c 文件中的函数列表中增加往 db 添加自定义服务的函数,如下:

 


    
  1. /// List of functions used to create the database
  2. static const appm_add_svc_func_t appm_add_svc_func_list[APPM_SVC_LIST_STOP] =
  3. {
  4. (appm_add_svc_func_t)app_custom_add_custom,
  5. (appm_add_svc_func_t)app_dis_add_dis,
  6. (appm_add_svc_func_t)app_batt_add_bas,
  7. (appm_add_svc_func_t)app_oad_add_oads,
  8. };
7. 在 app.c 文件中找到 appm_init 函数,在其中添加 app_custom_init()函数,如下
8. 在 rwip_task.h 文件中增加自定义服务的 task_id,如下:
9. 在 prf.c 文件中添加 custom_prf_itf_get()的调用:
10. 在 prf.c 文件中添加 custom_prf_itf_get()的声明:
11. 在 rwprf_config.h 文件中增加如下定义:

 

BLE_CUSTOM_SERVER 这 个 宏 定 义 在 custom.c 、 custom.h 、 custom_task.c 、 custom_task.h 中都有用到,只有当这个宏被打开后,编译器在编译的时候才能把 自定义的服务编译进去。部分截图如下
 
以上步骤全部完成之后,整体编译 project,使用 lightblue 连接进行验证是否添 加成功。
三、app_custom.c 接口说明:
度 备注
1. custom 服务实现了两个特征,其 UUID 及相关属性如下表所示


 
UUID 
特征权限 可发送/接收数据长度 备注
0xAAB0     Service UUID
0xAAB1 Norify
20bytes
Tx
0xAAB2 Write without response
20bytes
Rx
2. 数据发送 API
例如:

             
  1. //send data api
  2. void app_fff1_send_lvl(uint8_t* buf, uint8_t len)
  3. {
  4. if(app_fff0_env.send_status==0)
  5. {
  6. app_fff0_env.send_status=1;
  7. // Allocate the message
  8. struct fff0s_fff1_level_upd_req * req = KE_MSG_ALLOC(FFF0S_FFF1_LEVEL_UPD_REQ,
  9. prf_get_task_from_id(TASK_ID_FFF0S),
  10. TASK_APP,
  11. fff0s_fff1_level_upd_req);
  12. // Fill in the parameter structure
  13. req->length = len;
  14. memcpy(req->fff1_level, buf, len);
  15. // Send the message
  16. ke_msg_send(req);
  17. }
  18. }

 

 
3. 数据接收回调
例如:

            
  1. //数据接收回调函数
  2. static int fff2_writer_req_handler(ke_msg_id_t const msgid,
  3. struct fff0s_fff2_writer_ind *param,
  4. ke_task_id_t const dest_id,
  5. ke_task_id_t const src_id)
  6. {
  7. // Drop the message
  8. UART_PRINTF("FFF2 param->value = 0x ");
  9. for(uint8_t i = 0;i < param->length;i++)
  10. {
  11. UART_PRINTF("%02x ",param->fff2_value[i]);
  12. }
  13. UART_PRINTF("\r\n");
  14. return (KE_MSG_CONSUMED);
  15. }
4. 数据发送状态回复

            
  1. static int fff1_level_upd_handler(ke_msg_id_t const msgid,
  2. struct fff0s_fff1_level_upd_rsp const *param,
  3. ke_task_id_t const dest_id,
  4. ke_task_id_t const src_id)
  5. {
  6. if(param->status == GAP_ERR_NO_ERROR)
  7. {
  8. //uint8_t buf[128];
  9. //memset(buf, 0xcc, 128);
  10. //app_fff1_send_lvl(buf, 128);
  11. app_fff0_env.send_status=0;
  12. }
  13. return (KE_MSG_CONSUMED);
  14. }

 5. Notify 成功使能回调


            
  1. static int fff0s_fff1_level_ntf_cfg_ind_handler(ke_msg_id_t const msgid,
  2. struct fff0s_fff1_level_ntf_cfg_ind const *param,
  3. ke_task_id_t const dest_id,
  4. ke_task_id_t const src_id)
  5. {
  6. UART_PRINTF("param->ntf_cfg = %x\r\n",param->ntf_cfg);
  7. if(param->ntf_cfg == PRF_CLI_STOP_NTFIND)
  8. {
  9. //ke_timer_clear(FFF0S_FFF1_LEVEL_PERIOD_NTF,dest_id);
  10. }else
  11. {
  12. //ke_timer_set(FFF0S_FFF1_LEVEL_PERIOD_NTF,dest_id , 1);
  13. }
  14. return (KE_MSG_CONSUMED);
  15. }
为了系统的稳定,应用层发送 notify 到手机端时需要在发送完成一包数据之后再 触发下一次的发送。
 

文章来源: xintiaobao.blog.csdn.net,作者:心跳包,版权归原作者所有,如需转载,请联系作者。

原文链接:xintiaobao.blog.csdn.net/article/details/107004641

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。