蓝牙Simple Peripheral工程学习

发布于:2024-04-07 ⋅ 阅读:(117) ⋅ 点赞:(0)

前言

TI BLE SDK提供了Simple Peripheral工程,初学者可以通过这个工程来学习基本的蓝牙知识,通过实操掌握蓝牙基本的理论与通信方式。

在介绍这个工程前,先为大家介绍蓝牙Peripheral与Central的区别。如下图GAP主要负责Ble设备的连接,GAP状态机描述了设备空闲、设备发现与连接三个阶段的状态转换,状态解释如下
image-20240401162237271

  • Standby 复位后设备处于初始空闲态
  • Advertiser 广播者广播指定格式数据使其他设备知道自己可连接,广播消息可包含设备地址和一些附加数据比如设备名称
  • Scanner 接收广播消息时,扫描设备发送一个扫描请求给广播者,广播者回应一个扫描响应。这个过程称作设备发现。
  • Initiator 发起者需要选择一个对端设备去连接,当广播者接收到匹配的连接地址时,发起者可以发送连接请求建立连接。
  • Peripheral/Central 连接建立后,广播者为Peripheral作为Slave设备,发起者为Central作为Master设备。

根据上面介绍,我们知道Peripheral为发送广播消息的设备,也就是说Simple Peripheral工程会把Ble设备作为广播者,在测试时我们可以用手机作为Central设备来进行扫描连接。

Simple Peripheral工程解析

一. 总流程

—> main()
—> 初始化硬件模块、系统任务及建立自定义app任务
—> 进入Simple_Peripheral_createTask()【自定义app任务】
—> 进入回调函数SimplePeripheral_taskFxn()
—> 初始化app任务SimplePeripheral_init()
—> 处理(消息)事件及定时任务

1.1 打开Simple_Peripheral例程

在SDK安装路径中,参考我的路径:…\simplelink_cc13xx_cc26xx_sdk_7_10_01_24\examples\rtos\CC26X2R1_LAUNCHXL\ble5stack\simple_peripheral

1.2 main.c

1.2.1 初始化PIN 与 ICall 模块
// 初始化硬件
    Board_initGeneral();
// 初始化ICall软件模块,用于app和stack之间的通信
    ICall_init();
1.2.2 建立任务并启动BIOS
 // 启动远程任务,对应的ICall的入口点,包含stack任务,优先级5
    ICall_createRemoteTasks();
 // 初始化app任务,以后用户要添加一个自定义任务,都要这样添加
    SimpleBLEPeripheral_createTask();
 // 启动Bios
     BIOS_start();
1.2.4 完整代码
int main()
{
   
  /* Register Application callback to trap asserts raised in the Stack */
  RegisterAssertCback(AssertHandler);

  Board_initGeneral();

  // Enable iCache prefetching
  VIMSConfigure(VIMS_BASE, TRUE, TRUE);
  // Enable cache
  VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);

  /* Update User Configuration of the stack */
  user0Cfg.appServiceInfo->timerTickPeriod = Clock_tickPeriod;
  user0Cfg.appServiceInfo->timerMaxMillisecond  = ICall_getMaxMSecs();

  /* Initialize ICall module */
  ICall_init();

  /* Start tasks of external images - Priority 5 */
  ICall_createRemoteTasks();

  SimplePeripheral_createTask();

  /* enable interrupts and start SYS/BIOS */
  BIOS_start();

  return 0;
}

接下来, 我们不看系统调度, 直接来看SimplePeripheral_createTask() 这个任务即可。

1.3 simple_Peripheral.c

app任务,以后用户要添加一个自定义任务,都要像这样模仿

1.3.1 SimplePeripheral_createTask
void SimplePeripheral_createTask(void)
{
   
  // 创建一个任务结构体
  Task_Params taskParams;

  // 配置任务
  Task_Params_init(&taskParams);
  taskParams.stack = spTaskStack;
  taskParams.stackSize = SP_TASK_STACK_SIZE; // 堆栈大小,在开发中需要适当增大
  taskParams.priority = SP_TASK_PRIORITY;    // 优先级,数值越小优先级越低

  // SimplePeripheral_taskFxn是任务回调函数,此函数不会返回
  Task_construct(&spTask, SimplePeripheral_taskFxn, &taskParams, NULL);
}
1.3.2 SimplePeripheral_taskFxn
static void SimplePeripheral_taskFxn(UArg a0, UArg a1)
{
   
  // app任务初始化函数
  SimplePeripheral_init();

  // 死循环运行app任务
  for (;;)
  {
   
   ....
  // 这里是处理收到(消息) 事件与定时器事件的地方
   	//处理协议栈GAT,GATT,HCI等消息通知  
    SimplePeripheral_processStackMsg(pMsg);
    //处理Profile的回调,包括广播,配对,周期事件,自定义特征等消息callback   
    SimplePeripheral_processAppMsg(pMsg);
   ....
  }
}

二. 处理(消息)事件流程

2.1 处理stack事件

在上述1.3.2死循环体中

  // 处理stack发送的消息
  if (ICall_fetchServiceMsg(&src, &dest,
                            (void **)&pMsg) == ICALL_ERRNO_SUCCESS)
  {
   
    uint8 safeToDealloc = TRUE;

    if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
    {
   
      ICall_Stack_Event *pEvt = 

网站公告

今日签到

点亮在社区的每一天
去签到