4886|16

274

帖子

8

TA的资源

纯净的硅(初级)

楼主
 

【沁恒RISC-V内核 CH582】 7- 使用CH582蓝牙的notify主动上传数据 [复制链接]

 
 

前面使用CH582作为GATT服务器,实现了read和write的操作,这两个操作都是客户端主动发起的。而服务器使用notify的方式则能主动的上传数据。本文介绍如何通过CH582作为服务器,如何通过notify上传数据。

具有notify权限的特征需要多一个属性:客户特征配置 。这个属性需要具有读写权限,其作用是:用于客户端配置服务器的这个特征是否notify的。因此具有notify权限的特征需要包含以下属性:

  1. 特征声明
  2. 特征值
  3. 客户特征配置
  4. 特征用户描述(可选)

本实例仍然是在"BLE-Peripheral"工程中修改代码。实现notify功能主要包括以下步骤:

  1. 在属性表中增加相关的特征
  2. 实现特征的客户配置文件初始化
  3. 实现notify发送函数,并加入到定时发送的函数中
1.在属性表中增加相关的特征
static uint8 simpleProfileChar8Props = GATT_PROP_NOTIFY;
static uint8 simpleProfileChar8[SIMPLEPROFILE_CHAR8_LEN] = { 0 }; /*存放特征值的缓存区*/
static gattCharCfg_t simpleProfileChar8Config[4];/*保存客户配置信息,用于客户特征配置属性*/
static uint8 simpleProfileChar8UserDesp[] = "Characteristic 8\0";
/*在属性表中添加*/
// Characteristic 8 Declaration
  {
    { ATT_BT_UUID_SIZE, characterUUID },
    GATT_PERMIT_READ,
    0,
    &simpleProfileChar8Props
  },
  // Characteristic Value 8
  {
    { ATT_BT_UUID_SIZE, simpleProfilechar8UUID },
    0,
    0,
    simpleProfileChar8
  },
  // Characteristic 8 configuration
  {
    { ATT_BT_UUID_SIZE, clientCharCfgUUID },
    GATT_PERMIT_READ | GATT_PERMIT_WRITE,
    0,
    (uint8 *)simpleProfileChar8Config
  },
  // Characteristic 8 User Description
  {
    { ATT_BT_UUID_SIZE, charUserDescUUID },
    GATT_PERMIT_READ,
    0,
    simpleProfileChar8UserDesp
  },
2.实现特征的客户配置文件初始化

bStatus_t SimpleProfile_AddService( uint32 services ) 函数中增加对“客户特征配置”属性中的值的初始化,GATTServApp_InitCharCfg(INVALID_CONNHANDLE,simpleProfileChar8Config);

同时,还要在连接断开的回调函数中增加上面的初始化函数。

完整的 bStatus_t SimpleProfile_AddService( uint32 services ) 如下:

bStatus_t SimpleProfile_AddService( uint32 services )
{
  uint8 status = SUCCESS;

  // Initialize Client Characteristic Configuration attributes
  GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config );
  GATTServApp_InitCharCfg(INVALID_CONNHANDLE,simpleProfileChar8Config);/*新增加的用于初始化“客户特征配置”属性中的值*/
  // Register with Link DB to receive link status change callback
  linkDB_Register( simpleProfile_HandleConnStatusCB );  
  
  if ( services & SIMPLEPROFILE_SERVICE )
  {
    // Register GATT attribute list and CBs with GATT Server App
    status = GATTServApp_RegisterService( simpleProfileAttrTbl, 
                                          GATT_NUM_ATTRS( simpleProfileAttrTbl ),
                                          GATT_MAX_ENCRYPT_KEY_SIZE,
                                          &simpleProfileCBs );
  }

  return ( status );
}

而连接断开的回调函数就是上面代码中的 simpleProfile_HandleConnStatusCB 。其完整代码如下:

static void simpleProfile_HandleConnStatusCB( uint16 connHandle, uint8 changeType )
{ 
  // Make sure this is not loopback connection
  if ( connHandle != LOOPBACK_CONNHANDLE )
  {
    // Reset Client Char Config if connection has dropped
    if ( ( changeType == LINKDB_STATUS_UPDATE_REMOVED )      ||
         ( ( changeType == LINKDB_STATUS_UPDATE_STATEFLAGS ) && 
           ( !linkDB_Up( connHandle ) ) ) )
    { 
      GATTServApp_InitCharCfg( connHandle, simpleProfileChar4Config );
      GATTServApp_InitCharCfg( connHandle, simpleProfileChar8Config );
    }
  }
}
3. 实现notify发送函数,并加入到定时发送的函数中
//function at peripheral.c
static void periphercalChar8Notify(uint8_t *pValue,uint16_t len)
{
  attHandleValueNoti_t noti;
  noti.len = len;
  noti.pValue = GATT_bm_alloc( peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0 );
  if( noti.pValue )
  {
    tmos_memcpy( noti.pValue, pValue, noti.len );
    if(get_simple_profile_notify_8(peripheralConnList.connHandle, ¬i)!= SUCCESS){
      GATT_bm_free( (gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI );
    }
  }
}
//function at gattprofile.c
bStatus_t get_simple_profile_notify_8(uint16 connHandle,attHandleValueNoti_t *pNoti)
{
  uint16 value = GATTServApp_ReadCharCfg( connHandle, simpleProfileChar8Config );
  bStatus_t status=0;
  if ( value & GATT_CLIENT_CFG_NOTIFY )
  {
    pNoti->handle = simpleProfileAttrTbl[22].handle;

    status = GATT_Notification( connHandle, pNoti, FALSE );
    PRINT("NOTIFY_8_1 0x%02Xn",status);
    return status;
  }
  return bleIncorrectMode;
}

注意上面的两个函数没有在一个文件中。函数 bStatus_t get_simple_profile_notify_8(uint16 connHandle,attHandleValueNoti_t *pNoti) 和属性表在同一个文件中,这个函数的主要作用是得到特征值的handle,然后调用 GATT_Notification( connHandle, pNoti, FALSE ); 将数据发送出去。

这里还要注意一下 GATT_Notification( connHandle, pNoti, FALSE );的第2个参数必须是通过函数 GATT_bm_alloc( peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0 ); 动态申请的内存才能正常工作,否则的话会导致连接一直断开的情况。

下一步就是将发送函数加入到定时发送的函数中,定时发送是用的TMOS。

static void performPeriodicTask( void )
{
  uint8 notiData[SIMPLEPROFILE_CHAR4_LEN] = { 0x88 };
  uint8_t n8_data[SIMPLEPROFILE_CHAR8_LEN] = {0x12,0x34};
  n8_data[0] = my_count;
  peripheralChar4Notify( notiData, SIMPLEPROFILE_CHAR4_LEN );
  periphercalChar8Notify(n8_data,SIMPLEPROFILE_CHAR8_LEN);
}
4. 效果

从下图中可以看出,当打卡notify后,开始主动上传数据。

最新回复

mark一下,抽空学习经验。   详情 回复 发表于 2022-4-10 22:31
点赞 关注(1)
 
 

回复
举报

6841

帖子

11

TA的资源

版主

沙发
 

感谢分享,我仔细拜读了你的经验,这里有两个疑问

 这个-i是不是&noti,然后我定义了

 烧写程序后,没能接收到CHAR8的数据。真心希望你能帮忙解答一下,char4的88我这里是可以接收到的。谢谢了。

 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

板凳
 
lugl4313820 发表于 2022-3-16 17:38 感谢分享,我仔细拜读了你的经验,这里有两个疑问 这个-i是不是&noti,然后我定义了  烧写 ...

第一个红框是&noti,不知道你那里为什么显示的是i。

你在TMOS里增加上传的函数了吗?就是这个函数: static void performPeriodicTask( void )

 
 
 

回复

6841

帖子

11

TA的资源

版主

4
 
manhuami2007 发表于 2022-3-16 20:18 第一个红框是&noti,不知道你那里为什么显示的是i。 你在TMOS里增加上传的函数了吗?就是这个函数: ...

善意的提醒一下,相信我,你有没有回头看下自己的帖子。

 
 
 

回复

6841

帖子

11

TA的资源

版主

5
 

其实我更建议你提把工程上传,这样大家收获更深。谢谢

 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

6
 
lugl4313820 发表于 2022-3-16 20:32 其实我更建议你提把工程上传,这样大家收获更深。谢谢

我在手机上看是没有问题的,不知道为什么网页上有问题了。

 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

7
 

Peripheral_my.rar (1.44 MB, 下载次数: 21)

 

这个是工程文件,我又做了一些更改,增加了OLED和I2C的功能,所以可能跟我帖子里的代码有点区别,但是不影响NOTIFY的使用。

 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

8
 
lugl4313820 发表于 2022-3-16 20:32 其实我更建议你提把工程上传,这样大家收获更深。谢谢

我把工程文件上传了,你可能需要在你那里的例程文件夹里打开,要不可能会找不到库文件。

 
 
 

回复

6841

帖子

11

TA的资源

版主

9
 
manhuami2007 发表于 2022-3-16 20:57   这个是工程文件,我又做了一些更改,增加了OLED和I2C的功能,所以可能跟我帖子里的代码有点 ...

非常感谢您的支持,希望EEWORLD越来越来越好,有你这样的支持,中国定能走向世界,引领未来!

 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

10
 
lugl4313820 发表于 2022-3-16 20:59 非常感谢您的支持,希望EEWORLD越来越来越好,有你这样的支持,中国定能走向世界,引领未来!

谢谢夸奖,惭愧惭愧。咱们一起学习,一起进步。

 
 
 

回复

7452

帖子

2

TA的资源

五彩晶圆(高级)

11
 

现在当个嵌入式工程师简直又要会点硬件又会点底层又要协议又要网页还要app。。。

个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

12
 
freebsder 发表于 2022-3-17 23:10 现在当个嵌入式工程师简直又要会点硬件又会点底层又要协议又要网页还要app。。。

是的,FPGA,linux,安卓,网页,python感觉都要学,硬件也要做的可靠稳定。需要学的太多了

 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

13
 
fly007008009 发表于 2022-3-17 22:26  已经自己搞定; 此人不可信,言而无信;不想发就直接说  【不想发送】 我都没有QQ邮箱,哪 ...

不知道你为啥这么说,咱们没有联系过啊

 
 
 

回复

6841

帖子

11

TA的资源

版主

14
 
manhuami2007 发表于 2022-3-16 20:18 第一个红框是&noti,不知道你那里为什么显示的是i。 你在TMOS里增加上传的函数了吗?就是这个函数: ...

static void performPeriodicTask(void)
{
    uint8_t notiData[SIMPLEPROFILE_CHAR4_LEN] = {0x88};
    uint8_t n8_data[SIMPLEPROFILE_CHAR8_LEN] = {0x12,0x34};
    n8_data[0] = 0x01;
    peripheralChar4Notify(notiData, SIMPLEPROFILE_CHAR4_LEN);

    periphercalChar8Notify(n8_data,SIMPLEPROFILE_CHAR8_LEN);
}

我是添加了这个任务函数的

 
 
 

回复

6841

帖子

11

TA的资源

版主

15
 
可把工程发给你,帮我看看是什么回事吗?
 
 
 

回复

274

帖子

8

TA的资源

纯净的硅(初级)

16
 
lugl4313820 发表于 2022-3-19 07:59 可把工程发给你,帮我看看是什么回事吗?

好的,我私信给你我的邮箱地址

 
 
 

回复

303

帖子

5

TA的资源

一粒金砂(高级)

17
 

mark一下,抽空学习经验。

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表