STM32/STM8技术论坛
直播中

654524

12年用户 475经验值
擅长:嵌入式技术 模拟技术 控制/MCU
私信 关注
[经验]

CC254x-BLE协议栈添加服务与特征值

`CC254x-BLE协议栈添加服务与特征值


针对协议栈版本:CC254x-1.4.2.2
使用的工程文件:Texas InstrumentsBLE-CC254x-1.4.2.2ProjectsleSimpleBLEPeripheralCC2541DBSimpleBLEPeripheral.eww
实验过程:
1.修改profile
2.应用层处理
3.使用SensorTag测试结果
(后续有时间会写一篇ti协议栈OSAL任务调度的讲解)
一.增加服务,增加两个特征值 的宏定义
位置:simpleGATTprofile.h


// Profile Parameters

#define SIMPLEPROFILE_CHAR1                   0  // RW uint8 - Profile Characteristic 1 value

#define SIMPLEPROFILE_CHAR2                   1  // RW uint8 - Profile Characteristic 2 value

#define SIMPLEPROFILE_CHAR3                   2  // RW uint8 - Profile Characteristic 3 value

#define SIMPLEPROFILE_CHAR4                   3  // RW uint8 - Profile Characteristic 4 value

#define SIMPLEPROFILE_CHAR5                   4  // RW uint8 - Profile Characteristic 5 value

#define SIMPLEPROFILE_CHAR6                   5  // RW uint8 - Profile Characteristic 6 value

#define SIMPLEPROFILE_CHAR7                   6  // RW uint8 - Profile Characteristic 7 value



  

// Simple Profile Service UUID

#define SIMPLEPROFILE_SERV_UUID               0xFFF0

#define SIMPLEPROFILE_TEST_UUID               0xFFE0

   

// Key Pressed UUID

#define SIMPLEPROFILE_CHAR1_UUID            0xFFF1

#define SIMPLEPROFILE_CHAR2_UUID            0xFFF2

#define SIMPLEPROFILE_CHAR3_UUID            0xFFF3

#define SIMPLEPROFILE_CHAR4_UUID            0xFFF4

#define SIMPLEPROFILE_CHAR5_UUID            0xFFF5

#define SIMPLEPROFILE_CHAR6_UUID            0xFFE1

#define SIMPLEPROFILE_CHAR7_UUID            0xFFE2



1.png

二.增加服务,增加两个特征值的UUID
位置:simpleGATTprofile.c
// Simple GATT Profile Test UUID: 0xFFE0

CONST uint8 simpleProfileTestUUID[ATT_BT_UUID_SIZE] =

{

  LO_UINT16(SIMPLEPROFILE_TEST_UUID), HI_UINT16(SIMPLEPROFILE_TEST_UUID)

};



// Characteristic 6 UUID: 0xFFE1

CONST uint8 simpleProfilechar6UUID[ATT_BT_UUID_SIZE] =

{

  LO_UINT16(SIMPLEPROFILE_CHAR6_UUID), HI_UINT16(SIMPLEPROFILE_CHAR6_UUID)

};



// Characteristic 7 UUID: 0xFFE2

CONST uint8 simpleProfilechar7UUID[ATT_BT_UUID_SIZE] =

{

  LO_UINT16(SIMPLEPROFILE_CHAR7_UUID), HI_UINT16(SIMPLEPROFILE_CHAR7_UUID)

};


2.png


3.png

三.增加服务和特征值的属性
位置:simpleGATTprofile.c


// Simple Profile Service attribute

static CONST gattAttrType_t simpleProfileService = { ATT_BT_UUID_SIZE, simpleProfileServUUID };



// Simple Profile Test attribute

static CONST gattAttrType_t simpleProfileTest = { ATT_BT_UUID_SIZE, simpleProfileTestUUID };


4.png
增加特征值6,属性为可读可写
增加特征值7,属性为Notify(通知)
// Simple Profile Characteristic 6 Properties

static uint8 simpleProfileChar6Props = GATT_PROP_READ | GATT_PROP_WRITE;



// Characteristic 6 Value

static uint8 simpleProfileChar6 = 0;



// Simple Profile Characteristic 6 User Description

static uint8 simpleProfileChar6UserDesp[17] = "Characteristic 6";





// Simple Profile Characteristic 7 Properties

static uint8 simpleProfileChar7Props = GATT_PROP_NOTIFY;



// Characteristic 7 Value

static uint8 simpleProfileChar7 = 0;



// Simple Profile Characteristic 7 Configuration Each client has its own

// instantiation of the Client Characteristic Configuration. Reads of the

// Client Characteristic Configuration only shows the configuration for

// that client and writes only affect the configuration of that client.

static gattCharCfg_t *simpleProfileChar7Config;

                                       

// Simple Profile Characteristic 7 User Description

static uint8 simpleProfileChar7UserDesp[17] = "Characteristic 7";


5.png
四.增加注册服务列表
位置:simpleGATTprofile.c
static gattAttribute_t testProfileAttrTbl[8] =

{

  // Simple Profile Service

  {

    { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */

    GATT_PERMIT_READ,                         /* permissions */

    0,                                        /* handle */

    (uint8 *)&simpleProfileTest               /* pValue */

  },



    // Characteristic 6 Declaration

    {

      { ATT_BT_UUID_SIZE, characterUUID },

      GATT_PERMIT_READ,

      0,

      &simpleProfileChar6Props

    },



      // Characteristic Value 6

      {

        { ATT_BT_UUID_SIZE, simpleProfilechar6UUID },

        GATT_PERMIT_READ | GATT_PERMIT_WRITE,

        0,

        &simpleProfileChar6

      },



      // Characteristic 6 User Description

      {

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ,

        0,

        simpleProfileChar6UserDesp

      },



    // Characteristic 7 Declaration

    {

      { ATT_BT_UUID_SIZE, characterUUID },

      GATT_PERMIT_READ,

      0,

      &simpleProfileChar7Props

    },



      // Characteristic Value 7

      {

        { ATT_BT_UUID_SIZE, simpleProfilechar7UUID },

        0,

        0,

        &simpleProfileChar7

      },



      // Characteristic 7 configuration

      {

        { ATT_BT_UUID_SIZE, clientCharCfgUUID },

        GATT_PERMIT_READ | GATT_PERMIT_WRITE,

        0,

        (uint8 *)&simpleProfileChar7Config

      },

      

      // Characteristic 7 User Description

      {

        { ATT_BT_UUID_SIZE, charUserDescUUID },

        GATT_PERMIT_READ,

        0,

        simpleProfileChar7UserDesp

      },

};


6.png

五.注册新的服务
位置:SimpleProfile_AddService
simpleProfileChar4Config = (gattCharCfg_t *)osal_mem_alloc( sizeof(gattCharCfg_t) *

                                                              linkDBNumConns );

  simpleProfileChar7Config = (gattCharCfg_t *)osal_mem_alloc( sizeof(gattCharCfg_t) *

                                                              linkDBNumConns );

  if ( simpleProfileChar4Config == NULL || simpleProfileChar7Config == NULL)

  {     

    return ( bleMemAllocError );

  }

  

  // Initialize Client Characteristic Configuration attributes

  GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar4Config );

  GATTServApp_InitCharCfg( INVALID_CONNHANDLE, simpleProfileChar7Config );

  

  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 );

   

    status = GATTServApp_RegisterService( testProfileAttrTbl,

                                          GATT_NUM_ATTRS( testProfileAttrTbl ),

                                          GATT_MAX_ENCRYPT_KEY_SIZE,

                                          &simpleProfileCBs );



7.png
六.增加特征值设置处理
位置:SimpleProfile_SetParameter
case SIMPLEPROFILE_CHAR6:

      if ( len == sizeof ( uint8 ) )

      {

        simpleProfileChar6 = *((uint8*)value);

      }

      else

      {

        ret = bleInvalidRange;

      }

      break;



    case SIMPLEPROFILE_CHAR7:

      if ( len == sizeof ( uint8 ) )

      {

        simpleProfileChar7 = *((uint8*)value);

        

        // See if Notification has been enabled

        GATTServApp_ProcessCharCfg( simpleProfileChar7Config, &simpleProfileChar7, FALSE,

                                    testProfileAttrTbl, GATT_NUM_ATTRS( testProfileAttrTbl ),

                                    INVALID_TASK_ID, simpleProfile_ReadAttrCB );

      }


8.png

七.增加特征值获取处理
位置:SimpleProfile_GetParameter


case SIMPLEPROFILE_CHAR6:

      *((uint8*)value) = simpleProfileChar6;

      break;  







    case SIMPLEPROFILE_CHAR7:

      *((uint8*)value) = simpleProfileChar7;


9.png
八.增加特征值读取处理
位置:simpleProfile_ReadAttrCB


10.png
九.增加特征值写入处理
位置:simpleProfile_WriteAttrCB
case SIMPLEPROFILE_CHAR1_UUID:

      case SIMPLEPROFILE_CHAR3_UUID:

      case SIMPLEPROFILE_CHAR6_UUID:



        //Validate the value

        // Make sure it's not a blob oper

        if ( offset == 0 )

        {

          if ( len != 1 )

          {

            status = ATT_ERR_INVALID_VALUE_SIZE;

          }

        }

        else

        {

          status = ATT_ERR_ATTR_NOT_LONG;

        }

        

        //Write the value

        if ( status == SUCCESS )

        {

          uint8 *pCurValue = (uint8 *)pAttr->pValue;        

          *pCurValue = pValue[0];



          if( pAttr->pValue == &simpleProfileChar1 )

          {

            notifyApp = SIMPLEPROFILE_CHAR1;        

          }

          else if( pAttr->pValue == &simpleProfileChar3 )

          {

            notifyApp = SIMPLEPROFILE_CHAR3;           

          }

          else

          {

            notifyApp = SIMPLEPROFILE_CHAR6;           

          }

        }

            

        break;


11.png
到此为止!!!Profile就修改完了。下面开始应用层的处理。
十. 增加广播数据
位置:simpleBLEPeripheral.c
0x03,   // length of this data

  GAP_ADTYPE_16BIT_MORE,      // some of the UUID's, but not all

  LO_UINT16( SIMPLEPROFILE_TEST_UUID ),

  HI_UINT16( SIMPLEPROFILE_TEST_UUID ),



十一.初始化特征值
位置:SimpleBLEPeripheral_Init
uint8 charValue1 = 1;

    uint8 charValue2 = 2;

    uint8 charValue3 = 3;

    uint8 charValue4 = 4;

    uint8 charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };

    uint8 charValue6 = 6;

    uint8 charValue7 = 7;

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR1, sizeof ( uint8 ), &charValue1 );

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR2, sizeof ( uint8 ), &charValue2 );

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, sizeof ( uint8 ), &charValue3 );

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof ( uint8 ), &charValue4 );

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5 );

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR6, sizeof ( uint8 ), &charValue6 );

    SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR7, sizeof ( uint8 ), &charValue7 );


13.png


十二.增加特征值处理应用
位置:SimpleBLEPeripheral_ProcessEvent

时间处理函数中,在启动事件中创建周期性事件


15.png


周期性事件中调用处理函数performPeriodicTask


16.png


处理函数中读取char6的值,并写入char7
这样当char7改变时,会自动通知serve端


17.png

测试结果:
下载并运行程序,打开SensorTag这款TI官方APP。可以看到设备名。
1.jpg
点击设备并选择Service Explorer,可以看到我们添加的UUID为0xffe0的服务

2.jpg

3.jpg


点进去可以看到UUID为0xffe1的特征值其属性是读写,0xffe2属性为N(Notify)


4.jpg
点选0xffe2特征值,选择打开Notify开关on。


5.jpg
稍微等待,可以接收到设备notify过来的值06。


6.jpg

然后返回到UUID为0xffe1的特征值,修改其值为9


7.jpg

8.jpg
返回0xffe2可以看到设备主动notify过来的值是9

9.jpg

实验到此结束,你可以在开发板手机之间传输 PWM等任何数据了。
其过程只针对TI协议栈CC254x-1.4.2.2这个版本。
后面有时间,开贴讲解协议栈中负责各层任务调度的OSAL系统。

` 12.png

更多回帖

发帖
×
20
完善资料,
赚取积分