【CC2640R2F蓝牙学习笔记(一)蓝牙运行流程】

一、总流程

1.main函数

int main()
{
  /* Register Application callback to trap asserts raised in the Stack */
  RegisterAssertCback(AssertHandler);
初始化硬件GPIO
  Board_initGeneral();
  // Enable iCache prefetching
  VIMSConfigure(VIMS_BASE, TRUE, TRUE);
  // Enable cache
  VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);
#if !defined( POWER_SAVING )
  /* Set constraints for Standby, powerdown and idle mode */
  // PowerCC26XX_SB_DISALLOW may be redundant
  Power_setConstraint(PowerCC26XX_SB_DISALLOW);
  Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
#endif // POWER_SAVING
  /* Update User Configuration of the stack */
  user0Cfg.appServiceInfo->timerTickPeriod = Clock_tickPeriod;
  user0Cfg.appServiceInfo->timerMaxMillisecond  = ICall_getMaxMSecs();

  /* Initialize ICall module */
 初始化ICall软件模块,用于app和stack之间的通信
  ICall_init();
  /* Start tasks of external images - Priority 5 */
启动远程任务,对应的ICall的入口点,包含stack任务,优先级5
  ICall_createRemoteTasks();
 初始化app任务,用户要添加一个自定义任务
  SimplePeripheral_createTask();
  /* enable interrupts and start SYS/BIOS */
开启操作系统,永不返回
  BIOS_start();
  return 0;
}

2.app任务创建

2.1创建流程

1.任务创建函数
void SimplePeripheral_createTask(void)
{
    // 创建一个任务结构体
  Task_Params taskParams;
  // Configure task
  // 配置任务
  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);
}
2.外设应用任务的入口函数
static void SimplePeripheral_taskFxn(UArg a0, UArg a1)
{
  // app任务初始化函数
  SimpleBLEPeripheral_init();
  // 死循环运行app任务
  for (;;)
  {
   ....
   这里是处理收到(消息) 事件与定时器事件的地方
   ....
  }
}
3.外设初始化函数,在此函数里写
SimplePeripheral_init(void)

2.2周期性事件创建流程

1. 定义时钟结构体
static Clock_Struct clkVeriSion;
2. 创建周期性事件ID和周期的时间(单位毫秒)
#define SP_VERISION_PERIODIC_EVT             11
#define SP_VERISION_PERIOD                   2000
3. 将周期性事件ID传递给时钟处理程序的内存
spClockEventData_t argVeriSion =
{ .event = SP_VERISION_PERIODIC_EVT };
4.我们的事件,都是用定时器触发,所以,定义定时器时间结构体和事件ID后,注册定时器,通过调用Util_constructClock函数,给事件赋值参数
 Util_constructClock(&clkVeriSion, SimplePeripheral_clockHandler,
                      SP_VERISION_PERIOD, 0, false, (UArg)&argVeriSion);
 Util_constructClock(Clock_Struct *pClock,
                                 Clock_FuncPtr clockCB,
                                 uint32_t clockDuration,
                                 uint32_t clockPeriod,
                                 uint8_t startFlag,
                                 UArg arg)
 * @param   pClock        - pointer to clock instance structure.时钟结构体
 * @param   clockCB       - callback function upon clock expiration.时钟到期时的回调函数
 * @param   clockDuration - longevity of clock timer in milliseconds,时钟的周期时间
 * @param   clockPeriod   - 如果设置为0以外的值,第一个到期时间由clockDuration决定。
 *                          所有后使用时钟周期值。
 * @param   startFlag     - TRUE to start immediately, FALSE to wait.
 * @param   arg           - argument passed to callback function.传递给回调函数的参数,
 *                         也就是序号3定义的变量,传递给定时时间到了后的回调函数
 *                         SimplePeripheral_clockHandler(UArg arg)*                         此函数会创建一条消息并将该消息放入RTOS队列

clockPeriod 参数说明:
设置为0的话是单次定时器,不为0的话是周期定时器的周期;其区别是单次定时器执行一次完成结束以后就挂了
周期性定时器只要开启一次,会一直执行,除非关掉它。并且当该参数为0时,定时器的时间分辨率按照
DEFAULT_DISCOVERY_DELAY的设定执行,若非0,则定时器第一次运行时的时间分辨率按照
DEFAULT_DISCOVERY_DELAY定时,之后的就按照配置的clockPeriod来执行定时。
再TI给的demo代码中不能显示单次和周期定时器的区别,因为每次循环中执行中断函数时都开启了一次定时器,
所以,看不出区别,只能从Clock的创建函数中的第五个参数区别。

5.消息入队
当定时器时间到了后,进入时钟超时的处理函数SimplePeripheral_clockHandler(UArg arg)
在此函数中,加入消息入队判断语句,当事件产生后,由函数SimplePeripheral_enqueueMsg入队
else if(pData->event == SP_VERISION_PERIODIC_EVT)
 {
     SimplePeripheral_enqueueMsg(SP_VERISION_PERIODIC_EVT, NULL);
 }
6. app任务循环,处理事件
static void SimplePeripheral_taskFxn(UArg a0, UArg a1)
{
  // app任务初始化函数
  SimpleBLEPeripheral_init();
  // 死循环运行app任务
  for (;;)
  {
   ....
   这里是处理收到(消息) 事件与定时器事件的地方
   ....
  }
}
在函数内部,判断事件
      // If RTOS queue is not empty, process app message.
      if (events & SP_QUEUE_EVT)
      {
        while (!Queue_empty(appMsgQueueHandle))
        {
          spEvt_t *pMsg = (spEvt_t *)Util_dequeueMsg(appMsgQueueHandle);
          if (pMsg)
          {
            // Process message.
            在此函数中添加消息处理函数
            SimplePeripheral_processAppMsg(pMsg);

            // Free the space from the message.
            ICall_free(pMsg);
          }
        }
      }
比如:
  case SP_LED_REVERSE_EVT:
        LedStatus = 1;
        SimplePeripheral_LedReverse_performPeriodicTask();
        break;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值