PB03F学习之蓝牙协议栈及从机源码分析

[复制链接]
查看706 | 回复4 | 2024-10-29 20:54:00 | 显示全部楼层 |阅读模式
本帖最后由 sujingliang 于 2024-10-30 12:36 编辑

本文大部分内容为搬砖,阅读SDK时都或多或少会遇到相关概念有助理解。


一、蓝牙协议栈

7633.1.jpg


1、PHY层
    1Mbps自适应跳频GFSK(高斯频移键控),运行在免证的2.4GHz。

2、LL层

    LL层为RF控制器,控制设备处于准备(standby)、广播、监听/扫描(scan)、初始化、连接,这五种状态中一种。五种状态切换描述为:未连接时,设备广播信息,另外一个设备一直监听或按需扫描,两个设备连接初始化,设备连接上了。发起聊天的设备为主设备,接受聊天的设备为从设备,同一次聊天只能有一个意见领袖,即主设备和从设备不能切换。

3、HCI层

    HCI层为接口层,向上为主机提供软件应用程序接口(API),对外为外部硬件控制接口,可以通过串口、SPI、USB来实现设备控制。

4、L2CAP层

    L2CAP层提供数据封装服务,允许逻辑上的点对点通讯。

5、SM层

    SM层提供配对和密匙分发,实现安全连接和数据交换。

6、ATT层

    ATT层负责数据检索,允许设备向另外一个设备展示一块特定的数据称之为属性,在ATT环境中,展示属性的设备称之为服务器,与它配对的设备称之为客户端。链路层的主机从机和这里的服务器、客服端是两种概念,主设备既可以是服务器,也可以是客户端。从设备毅然。

7、GATT层

    GATT层定义了使用 ATT 的服务框架和配置文件(profiles)的结构。BLE 中所有的数据通信都需要经过 GATT。GATT负责处理向上与应用打交道,其关键工作是把为检索工作提供合适的profile结构,而profile由检索关键词(characteristics)组成。

8、GAP层

    GAP直接与应用程序或配置文件(profiles)通信的接口,处理设备发现和连接相关服务。另外还处理安全特性的初始化。对上级,提供应用程序接口,对下级,管理各级职能部门,尤其是指示LL层控制室五种状态切换,指导保卫处做好机要工作。



二、从机源码分析,应该可以实现一个蓝牙点灯
从机源码位于phy6222_v313_0512\example\ble_peripheral\simpleBlePeripheral


顺藤摸瓜先抓个特征值characteristics)分析,理清SDK实现头绪,至于GATT层、GAP层一般变化不大,暂且放下吧。

1、特征值(characteristics)定义(sbpProfile_ota.h)
源码中定义了7个特征值
  1. // Profile Parameters
  2. #define SIMPLEPROFILE_CHAR1                   0  // RW uint8 - Profile Characteristic 1 value
  3. #define SIMPLEPROFILE_CHAR2                   1  // RW uint8 - Profile Characteristic 2 value
  4. #define SIMPLEPROFILE_CHAR3                   2  // RW uint8 - Profile Characteristic 3 value
  5. #define SIMPLEPROFILE_CHAR4                   3  // RW uint8 - Profile Characteristic 4 value
  6. #define SIMPLEPROFILE_CHAR5                   4  // RW uint8 - Profile Characteristic 4 value
  7. #define SIMPLEPROFILE_CHAR6                   5  // RW uint8 - Profile Characteristic 4 value
  8. #define SIMPLEPROFILE_CHAR7                   6  // RW uint8 - Profile Characteristic 4 value


  9. // Key Pressed UUID
  10. #define SIMPLEPROFILE_CHAR1_UUID            0xFFF1
  11. #define SIMPLEPROFILE_CHAR2_UUID            0xFFF2
  12. #define SIMPLEPROFILE_CHAR3_UUID            0xFFF3
  13. #define SIMPLEPROFILE_CHAR4_UUID            0xFFF4
  14. #define SIMPLEPROFILE_CHAR5_UUID            0xFFF5
  15. #define SIMPLEPROFILE_CHAR6_UUID            0xFFF6
  16. #define SIMPLEPROFILE_CHAR7_UUID            0xFFF7
复制代码
2、UUID的定义(sbpProfile_ota.c)
UUID转换一个形式:
  1. // Characteristic 4 UUID: 0xFFF4
  2. CONST uint8 simpleProfilechar4UUID[ATT_BT_UUID_SIZE] =
  3. {
  4.     LO_UINT16(SIMPLEPROFILE_CHAR4_UUID), HI_UINT16(SIMPLEPROFILE_CHAR4_UUID)
  5. };

  6. // Characteristic 5 UUID: 0xFFF5
  7. CONST uint8 simpleProfilechar5UUID[ATT_BT_UUID_SIZE] =
  8. {
  9.     LO_UINT16(SIMPLEPROFILE_CHAR5_UUID), HI_UINT16(SIMPLEPROFILE_CHAR5_UUID)
  10. };
复制代码
3、属性(sbpProfile_ota.c)
特征值的属性:可读、可写、值变量、说明......
  1. // Simple Profile Characteristic 4 Properties
  2. static uint8 simpleProfileChar4Props = GATT_PROP_READ | GATT_PROP_WRITE;

  3. // Characteristic 4 Value
  4. static uint8 simpleProfileChar4 = 0;

  5. // Simple Profile Characteristic 4 Configuration Each client has its own
  6. // instantiation of the Client Characteristic Configuration. Reads of the
  7. // Client Characteristic Configuration only shows the configuration for
  8. // that client and writes only affect the configuration of that client.
  9. static gattCharCfg_t simpleProfileChar4Config[GATT_MAX_NUM_CONN];

  10. // Simple Profile Characteristic 4 User Description
  11. static uint8 simpleProfileChar4UserDesp[] = "Power\0";
复制代码
4、属性表(sbpProfile_ota.c)
所有的特征值凑在一起,准备被初始化
  1. static gattAttribute_t simpleProfileAttrTbl[] =
  2. {
  3. ......
  4.   // Characteristic 4 Declaration
  5.     {
  6.         { ATT_BT_UUID_SIZE, characterUUID },
  7.         GATT_PERMIT_READ,
  8.         0,
  9.         &simpleProfileChar4Props
  10.     },

  11.     // Characteristic Value 4
  12.     {
  13.         { ATT_BT_UUID_SIZE, simpleProfilechar4UUID },
  14.         GATT_PERMIT_READ | GATT_PERMIT_WRITE,
  15.         0,
  16.         (uint8*)& simpleProfileChar4
  17.     },

  18.     // Characteristic 4 User Description
  19.     {
  20.         { ATT_BT_UUID_SIZE, charUserDescUUID },
  21.         GATT_PERMIT_READ,
  22.         0,
  23.         simpleProfileChar4UserDesp
  24.     },

  25. ......
  26. }
复制代码
5、属性设置操作(sbpProfile_ota.c)
本地设置特征值(characteristics)的value:simpleProfileChar4
  1. bStatus_t SimpleProfile_SetParameter( uint8 param, uint8 len, void* value )
  2. {
  3. ......
  4. case SIMPLEPROFILE_CHAR4:
  5.         if ( len == sizeof ( uint8 ) )
  6.         {
  7.             simpleProfileChar4 = *((uint8*)value);
  8.             // See if Notification has been enabled
  9.             //GATTServApp_ProcessCharCfg( simpleProfileChar4Config, &simpleProfileChar4, FALSE,
  10.             //                            simpleProfileAttrTbl, GATT_NUM_ATTRS( simpleProfileAttrTbl ),
  11.             //                            INVALID_TASK_ID );
  12.         }
  13.         else
  14.         {
  15.             ret = bleInvalidRange;
  16.         }

  17.         break;
  18. ......
  19. }
复制代码
6、属性获取操作(sbpProfile_ota.c)
  1. bStatus_t SimpleProfile_GetParameter( uint8 param, void* value )
  2. {
  3. ......
  4.     case SIMPLEPROFILE_CHAR4:
  5.         *((uint8*)value) = simpleProfileChar4;
  6.         //*((uint16*)value) = simpleProfileChar4;
  7.         break;
  8. .......
  9. }
复制代码
7、属性读操作(sbpProfile_ota.c)

  1. static uint8 simpleProfile_ReadAttrCB( uint16 connHandle, gattAttribute_t* pAttr,
  2.                                        uint8* pValue, uint16* pLen, uint16 offset, uint8 maxLen )
  3. {
  4. ......
  5. case SIMPLEPROFILE_CHAR4_UUID:
  6.             *pLen = 1;
  7.             pValue[0] = *pAttr->pValue;
  8.             break;
  9. ......
  10. }
复制代码



8、属性写操作(sbpProfile_ota.c)
  1. static bStatus_t simpleProfile_WriteAttrCB( uint16 connHandle, gattAttribute_t* pAttr,
  2.                                             uint8* pValue, uint16 len, uint16 offset )
  3. {
  4. .......
  5. case SIMPLEPROFILE_CHAR4_UUID:

  6.             //Validate the value
  7.             // Make sure it's not a blob oper
  8.             if ( offset == 0 )
  9.             {
  10.                 if ( len != 1 )
  11.                 {
  12.                     status = ATT_ERR_INVALID_VALUE_SIZE;
  13.                 }
  14.             }
  15.             else
  16.             {
  17.                 status = ATT_ERR_ATTR_NOT_LONG;
  18.             }

  19.             //Write the value
  20.             if ( status == SUCCESS )
  21.             {
  22.                 uint8* pCurValue = (uint8*)pAttr->pValue;
  23.                 *pCurValue = pValue[0];

  24.                 if( uuid == SIMPLEPROFILE_CHAR4_UUID )
  25.                 {
  26.                     notifyApp = SIMPLEPROFILE_CHAR4;
  27.                 }
  28.             }

  29.             break;

  30. .......
  31. }
复制代码

9、simpleBLEPeripheral.c
simpleProfileChangeCB()特征值改变时的回调函数,当主机给从机发送数据时,从机就会回调这个函数来告知应用层有数据送达。
static void simpleProfileChangeCB( uint8 paramID )函数的switch中关于CHAR4的判断
如果回调函数输入为SIMPLEPROFILE_CHAR4,通过SimpleProfile_GetParameter读取特征值,判断是否为0x01,如果为真,点亮LED_GPIO。
  1. static void simpleProfileChangeCB( uint8 paramID )
  2. {
  3. uint8 newValue[IBEACON_ATT_LONG_PKT];
  4. uint8 newValue1;
  5.     switch( paramID )
  6.     {
  7.     case SIMPLEPROFILE_CHAR4:
  8.         SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR4,&newValue1);
  9.         if(newValue1==0x01)
  10.         {
  11.                 hal_gpio_write(LED_GPIO, 0);
  12.         }
  13.         else{
  14.                 hal_gpio_write(LED_GPIO, 1);
  15.         }
  16.         break;
  17.    }
  18. }
复制代码
上面只有第9步需要手工加入点灯的步骤,其他都是源码自带的。
今天没有条件验证。应该可以是通过BLE蓝牙调试助手APP(主机)通过BLE连接PB03F(从机),主机发送0x01给SIMPLEPROFILE_CHAR4_UUID点亮LED。

补充一下:

1、用手机BLE调试助手发现目标:BUMBLE-FFFFFFFF,连接
1_1.jpg
2、连接成功后,发现3个服务,UNKNOWN SERVICE是自定义的服务,因为不是SIG标准服务,所以显示为UNKNOWN
2.jpg
3、向特征值FFF4,发送HEX格式的0x01。
3.jpg
4、蓝牙收到0x01后点亮LED
4.jpg

5、板子背面。设计粗糙,见笑了。
两个飞线是VCC、GND。因为PB03F没有RST引脚,将VCC、GND飞出来可以手动控制模块上电,便于烧录,重启。
5.jpg




回复

使用道具 举报

爱笑 | 2024-10-30 08:34:43 | 显示全部楼层
用心做好保姆工作
回复

使用道具 举报

小小鸟 | 2024-10-30 09:11:13 | 显示全部楼层
回复

使用道具 举报

lazy | 2024-10-30 11:11:51 | 显示全部楼层
厉害
回复

使用道具 举报

大猫的鱼 | 2024-10-30 21:11:51 | 显示全部楼层
不错不错
回复

使用道具 举报

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

本版积分规则