一、实现自定义服务

在 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 的
函数,如下:
   case (TASK_ID_CUSTOM):{// Call the custom Modulesmsg_pol = appm_get_handler(&app_custom_table_handler, msgid, param, src_id);} break;
5. 在 app.c 文件中的服务列表中添加自定义服务,如下:
/// List of service to add in the database
enum appm_svc_list
{APPM_SVC_CUSTOM,APPM_SVC_DIS,APPM_SVC_BATT,APPM_SVC_OADS,APPM_SVC_LIST_STOP ,
};
6. 在 app.c 文件中的函数列表中增加往 db 添加自定义服务的函数,如下:

/// List of functions used to create the database
static const appm_add_svc_func_t appm_add_svc_func_list[APPM_SVC_LIST_STOP] =
{(appm_add_svc_func_t)app_custom_add_custom,(appm_add_svc_func_t)app_dis_add_dis,(appm_add_svc_func_t)app_batt_add_bas,(appm_add_svc_func_t)app_oad_add_oads,
};
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
例如:

//send data api
void app_fff1_send_lvl(uint8_t* buf, uint8_t len)
{if(app_fff0_env.send_status==0){app_fff0_env.send_status=1;// Allocate the messagestruct fff0s_fff1_level_upd_req * req = KE_MSG_ALLOC(FFF0S_FFF1_LEVEL_UPD_REQ,prf_get_task_from_id(TASK_ID_FFF0S),TASK_APP,fff0s_fff1_level_upd_req);// Fill in the parameter structure  req->length = len;memcpy(req->fff1_level, buf, len);// Send the messageke_msg_send(req);}
}

3. 数据接收回调
例如:
//数据接收回调函数
static int fff2_writer_req_handler(ke_msg_id_t const msgid,struct fff0s_fff2_writer_ind *param,ke_task_id_t const dest_id,ke_task_id_t const src_id)
{// Drop the messageUART_PRINTF("FFF2 param->value = 0x ");for(uint8_t i = 0;i < param->length;i++){UART_PRINTF("%02x ",param->fff2_value[i]);}UART_PRINTF("\r\n");return (KE_MSG_CONSUMED);
}
4. 数据发送状态回复
static int fff1_level_upd_handler(ke_msg_id_t const msgid,struct fff0s_fff1_level_upd_rsp const *param,ke_task_id_t const dest_id,ke_task_id_t const src_id)
{if(param->status == GAP_ERR_NO_ERROR){//uint8_t buf[128];//memset(buf, 0xcc, 128);//app_fff1_send_lvl(buf, 128);app_fff0_env.send_status=0;}return (KE_MSG_CONSUMED);
}

5. Notify 成功使能回调

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

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

  1. 蓝牙芯片----BK3431开发笔记------快速入门(2)

    应该是512K,flash. 1.准备工具 BK3431Q开发板.通用联机下载器 2.软件工具 keil arm,版本V5.12以上 通用联机下载器上位机软件Beken_ProgramVer4 二.编 ...

  2. 蓝牙芯片----BK3431开发笔记------注意事项(1)

    1.烧录器与芯片引脚的对应关系 烧录器接口 芯片引脚 HOLD p02 WP P03 VDD VCC VPP RSTN GND GDN SCK P06 SS P07 SI P04 OS P05 2.进 ...

  3. C#开发笔记之22-C#中的int、long、float、double等类型都占多少个字节的内存。

    本文由 比特飞 原创发布,欢迎大家踊跃转载. 转载请注明本文地址:C#开发笔记之22-C#中的int.long.float.double等类型都占多少个字节的内存. | .Net中文网. C#开发笔记 ...

  4. 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩:纹理映射技术(二)...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 作者:毛星云(浅墨)    邮箱: happylifemxy@163.com 本篇文章里,我们首先对Direct3D之中固定功能流水线中的 ...

  5. 【Visual C++】游戏开发笔记四十三 浅墨DirectX教程十一 为三维世界添彩 纹理映射技术 二

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  6. 微信小程序实例——天气预报开发笔记(进行中...)

    ★ 背景 [提示]:正在补充更新中- 首先,附上一张效果图. 之前就有关注过小程序的发展,感觉可以抽一点的时间来学习一下,通过官方文档以及提供的示例 Demo,发现兴趣挺高,不失为一个可以扩展自身技能 ...

  7. 【Visual C++】游戏开发笔记四十一 浅墨DirectX教程之九 为三维世界添彩:纹理映射技术(一)...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhmxy555/article/details/8523341 作者:毛星云(浅墨 ...

  8. 【Visual C++】游戏开发笔记四十 浅墨DirectX教程之八 绘制真实质感的三维世界:光照与材质专场...

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 作者:毛星云(浅墨)    邮箱: happylifemxy@163.com 本篇文章里,我们对Direct3D之中固定功能流水线中的3D ...

  9. 【Visual C++】游戏开发笔记四十七 浅墨DirectX教程十五 翱翔于三维世界 摄像机的实现

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow 本系列文章由zhm ...

最新文章

  1. Shell脚本中的并发
  2. 七牛云 直播 java_七牛云直播SDK之推流解析
  3. java jsp 文件上传_用JSP编写文件上传
  4. HashMap 与 Hashtable 的区别
  5. 再不自动化就晚啦!优云教你4步打造基于CentOS的产品镜像
  6. 【Python CheckiO 题解】Popular Words
  7. spring整合hibernate的applicationContext.xml文件配置以及web.xml
  8. oracle大作业_最累人7大专业
  9. 微课--Python生成器函数定义与使用(19分钟)
  10. Java_Spring MVC_Servlet
  11. 德州扑克AI--Programming Poker AI(译)
  12. 轻量级网络模型之EfficientNet
  13. php什么是同源策略,javascript - 绕过同源策略的方法
  14. linux安装红警教程,红警2任务安装教程_红色警戒2任务安装方法一览
  15. 100 年前科幻小说的概念,创造了今天千亿美元的市场
  16. 【Visual C++】游戏开发五十 浅墨DirectX教程十八 雪花飞扬:实现唯美的粒子系统
  17. 华为超级技术大牛的十年经验总结
  18. FFE均衡技术的原理、作用及特点
  19. python 91 32 默认参数
  20. 浅析有限元法中的沙漏现象

热门文章

  1. h5 c3 特效网站
  2. python按enter退出_【cmd按任意键退出 python】
  3. ES pinyin 插件 拼音搜索 原理 match_phase
  4. vb.net 生成随机数
  5. html怎么改变网页整体的大小,html设置浏览器大小
  6. Spring容器是什么?为什么要使用Spring容器?
  7. c++构造函数的定义
  8. LinkedIn领英人脉显示1度、2度、3度、领英会员的意思和区别是什么?
  9. 解决VMware中虚拟机(centos7)无法上网的一种方法
  10. w7电脑蓝屏怎么解决_电脑突然蓝屏,教您电脑突然蓝屏怎么解决