zoukankan      html  css  js  c++  java
  • 【BLE】CC2541之加入自己定义任务

    本篇博文最后改动时间:2017年01月06日,11:06。


    一、简单介绍

    本文介绍怎样在SimpleBLEPeripheralproject中。加入一个香瓜任务。

    (香瓜任务与project原有任务相互独立。互不影响)


    二、实验平台

    协议栈版本号:BLE-CC254x-1.4.0

    编译软件:IAR 8.20.2

    硬件平台:Smart RF(主芯片CC2541)


    版权声明

    博主:甜甜的大香瓜

    声明:喝水不忘挖井人,转载请注明出处。

    原文地址:http://blog.csdn.NET/feilusia

    联系方式:897503845@qq.com

    香瓜BLE之CC2541群:127442605

    香瓜BLE之CC2640群:557278427

    香瓜BLE之Android群:541462902

    香瓜单片机之STM8/STM32群:164311667
    甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?

    spm=2013.1.1000126.d21.hd2o8i


    四、实验前提
    1、在进行本文步骤前。请先阅读下面博文:
    暂无

    2、在进行本文步骤前,请先实现下面博文:
    暂无


    五、基础知识

    1、任务、事件、消息的差别是什么?

    答:

    1)简述

    1台设备中有多个任务,1个任务有16个事件,消息用于不同任务之间的传递。


    2)详述

    任务:SimpleBLEPeripheralproject中从底层的LL层到应用的Application层。一共分为有12个任务,每一个任务会分配一个事件管理的变量,变量统一存在:

    uint16 *tasksEvents;
    当中,越底层的优先级越高。应用层的优先级是最低的,也就是此层中的事件是最后才会处理。


    事件:1个任务中有16个事件,也就是上面tasksEvents的16位每一位都相应一个事件。0x0001意味着第0位的事件须要被运行。

    注意,每一个任务的第15位事件(0x8000)是用于不同任务之间的消息传递的,此事件不可被我们编程使用!

    !!!


    消息:用于不同任务之间的传递。

    比方,当按键按下时,HAL层检測到了按键。osal会将按键的信息打包,通过消息的形式发往应用层,终于在应用层做按键的处理。


    以下举个样例。加强理解。

    比如,tasksEvents[11] = 0x0002。那么就意味着,第11个任务的第1位事件须要被运行。

    首先,在OSAL_SimpleBLEPeripheral.c中,能够看到第11个任务是应用层。

    const pTaskEventHandlerFn tasksArr[] =
    {
      LL_ProcessEvent,                                                  // task 0
      Hal_ProcessEvent,                                                 // task 1
      HCI_ProcessEvent,                                                 // task 2
    #if defined ( OSAL_CBTIMER_NUM_TASKS )
      OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ),           // task 3
    #endif
      L2CAP_ProcessEvent,                                               // task 4
      GAP_ProcessEvent,                                                 // task 5
      GATT_ProcessEvent,                                                // task 6
      SM_ProcessEvent,                                                  // task 7
      GAPRole_ProcessEvent,                                             // task 8
      GAPBondMgr_ProcessEvent,                                          // task 9
      GATTServApp_ProcessEvent,                                         // task 10
      SimpleBLEPeripheral_ProcessEvent                                  // task 11
    };

    其次,在应用层的SimpleBLEPeripheral.h文件里。发现0x0002事件是周期事件

    // Simple BLE Peripheral Task Events
    #define SBP_START_DEVICE_EVT                              0x0001
    #define SBP_PERIODIC_EVT                                  0x0002

    最后。当osal层运行到应用层时,就会去运行应用层中的事件处理函数SimpleBLEPeripheral_ProcessEvent中的SBP_PERIODIC_EVT事件了。


    2、是否一定须要加入自己的任务、事件、消息?

    答:SimpleBLEPeripheralproject中已经给每一个层分配了任务,而osal也把消息机制做好了。因此并不一定要加入自己的任务、消息。

    而应用层的事件往往是须要被修改的,比方加入按键事件、通信事件、定时事件、採集事件……

    当应用层的16个事件都被你使用完了,这时候才须要考虑新增一个任务,这样又多16个事件可使用。


    六、实验步骤

    1、加入香瓜任务的初始化调用

    1)调用香瓜任务的初始化函数OSAL_SimpleBLEPeripheral.c的osalInitTasks中

    void osalInitTasks( void )
    {
      uint8 taskID = 0;
    
      tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
      osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
    
      /* LL Task */
      LL_Init( taskID++ );
    
      /* Hal Task */
      Hal_Init( taskID++ );
    
      /* HCI Task */
      HCI_Init( taskID++ );
    
    #if defined ( OSAL_CBTIMER_NUM_TASKS )
      /* Callback Timer Tasks */
      osal_CbTimerInit( taskID );
      taskID += OSAL_CBTIMER_NUM_TASKS;
    #endif
    
      /* L2CAP Task */
      L2CAP_Init( taskID++ );
    
      /* GAP Task */
      GAP_Init( taskID++ );
    
      /* GATT Task */
      GATT_Init( taskID++ );
    
      /* SM Task */
      SM_Init( taskID++ );
    
      /* Profiles */
      GAPRole_Init( taskID++ );
      GAPBondMgr_Init( taskID++ );
    
      GATTServApp_Init( taskID++ );
    //香瓜
      /* Application */
      SimpleBLEPeripheral_Init( taskID++ );
    
      /* 香瓜应用 */
      GUA_Init( taskID );
    //香瓜
    }
    注意SimpleBLEPeripheral_Init任务的括号里。taskID须要添加。

    而香瓜任务为最后一个任务。不须要再添加。


    2)注冊香瓜任务的事件(OSAL_SimpleBLEPeripheral.c中)

    const pTaskEventHandlerFn tasksArr[] =
    {
      LL_ProcessEvent,                                                  // task 0
      Hal_ProcessEvent,                                                 // task 1
      HCI_ProcessEvent,                                                 // task 2
    #if defined ( OSAL_CBTIMER_NUM_TASKS )
      OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ),           // task 3
    #endif
      L2CAP_ProcessEvent,                                               // task 4
      GAP_ProcessEvent,                                                 // task 5
      GATT_ProcessEvent,                                                // task 6
      SM_ProcessEvent,                                                  // task 7
      GAPRole_ProcessEvent,                                             // task 8
      GAPBondMgr_ProcessEvent,                                          // task 9
      GATTServApp_ProcessEvent,                                         // task 10
      SimpleBLEPeripheral_ProcessEvent,                                 // task 11
    //香瓜
      GUA_ProcessEvent                                                  // task 12    
    //香瓜
    };
    将香瓜任务中的事件处理函数名称。写到tasksArr中,当osal轮询到有香瓜任务的事件须要运行时,就会运行GUA_ProcessEvent函数。


    3)加入香瓜任务的头文件(OSAL_SimpleBLEPeripheral.c中)

    //香瓜
    #include "GUA.h"
    //香瓜


    2、编写并加入香瓜任务

    1)写一个GUA.c(存放在“……BLE-CC254x-1.4.0ProjectsleSimpleBLEPeripheralSourceGUA”路径下)

    //******************************************************************************      
    //name:         GUA.c      
    //introduce:    香瓜任务  
    //author:       甜甜的大香瓜    
    //changetime:   2016.04.07  
    //email:        897503845@qq.com  
    //******************************************************************************
    
    /*********************头文件************************/ 
    #include "GUA.h"
    #include "OSAL.h"
    #include "ioCC2541.h"
    
    
    /*********************宏定义************************/ 
    #define VOID (void)
    #define GUA_LED_TEST_EVT_PERIOD                   1000
    
    
    /***************内部变量声明************************/ 
    static uint8 GUA_TaskID;   // Task ID for internal task/event processing
    
    
    /***************内部函数声明************************/ 
    static void GUA_ProcessOSALMsg( osal_event_hdr_t *pMsg );
    
    
    //******************************************************************************          
    //name:             GUA_Init          
    //introduce:        香瓜任务的初始化         
    //parameter:        task_id:任务的ID         
    //return:           none        
    //author:           甜甜的大香瓜   
    //email:            897503845@qq.com 
    //changetime:       2016.04.07       
    //******************************************************************************
    void GUA_Init( uint8 task_id )
    {
      GUA_TaskID = task_id;  
      
      //运行香瓜任务的启动事件
      osal_set_event( GUA_TaskID, GUA_START_DEVICE_EVT );
    }
    
    //******************************************************************************          
    //name:             GUA_ProcessEvent          
    //introduce:        香瓜任务的事件处理         
    //parameter:        task_id:任务的ID,       
    //                  events:事件
    //return:           返回运行后的事件状态        
    //author:           甜甜的大香瓜        
    //email:            897503845@qq.com 
    //changetime:       2016.04.07        
    //******************************************************************************
    uint16 GUA_ProcessEvent( uint8 task_id, uint16 events )
    {
      VOID task_id; 
    
      //系统事件
      if ( events & SYS_EVENT_MSG )
      {
        uint8 *pMsg;
    
        if ( (pMsg = osal_msg_receive( GUA_TaskID )) != NULL )
        {
          GUA_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
    
          VOID osal_msg_deallocate( pMsg );
        }
    
        return (events ^ SYS_EVENT_MSG);
      }
    
      //香瓜任务的启动事件
      if ( events & GUA_START_DEVICE_EVT )
      {
        osal_start_timerEx( GUA_TaskID, GUA_LED_TEST_EVT, GUA_LED_TEST_EVT_PERIOD );
    
        return ( events ^ GUA_START_DEVICE_EVT );
      }
      
      //香瓜任务的LED点灯事件
      if ( events & GUA_LED_TEST_EVT )
      {
        //test    
        P1_1 = ~P1_1;         //这里測试按一次长按键按键,就取反一次P1_1,方便观察P1_1相应的led      
        P1SEL &= ~(1 << 1);   //设置为IO口    
        P1DIR |= (1 << 1);    //设置为输出     
    
        osal_start_timerEx( GUA_TaskID, GUA_LED_TEST_EVT, GUA_LED_TEST_EVT_PERIOD );    
        //test
        
        return ( events ^ GUA_LED_TEST_EVT );
      }
      
      return 0;
    }
    
    //******************************************************************************          
    //name:             GUA_ProcessOSALMsg          
    //introduce:        香瓜任务的消息处理         
    //parameter:        pMsg:消息         
    //return:           none        
    //author:           甜甜的大香瓜        
    //email:            897503845@qq.com 
    //changetime:       2016.04.07        
    //******************************************************************************
    static void GUA_ProcessOSALMsg( osal_event_hdr_t *pMsg )
    {
      switch ( pMsg->event )
      {
        default:
          break;
      }
    }

    2)写一个头文件GUA.h(存放在“……BLE-CC254x-1.4.0ProjectsleSimpleBLEPeripheralSourceGUA”路径下)

    //******************************************************************************      
    //name:         GUA.c      
    //introduce:    香瓜任务头文件  
    //author:       甜甜的大香瓜    
    //changetime:   2016.04.07  
    //email:        897503845@qq.com  
    //******************************************************************************
    #ifndef GUA_H
    #define GUA_H
    
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    
    /*********************头文件************************/ 
    #include "bcomdef.h"
      
      
    /*********************宏定义************************/ 
    #define GUA_START_DEVICE_EVT                              0x0001
    #define GUA_LED_TEST_EVT                                  0x0002
      
      
    /*******************香瓜函数************************/ 
    extern void GUA_Init( uint8 task_id );
    extern uint16 GUA_ProcessEvent( uint8 task_id, uint16 events );
    
    
    #ifdef __cplusplus
    }
    #endif
    
    
    #endif

    3)project中加入GUA.c和GUA.h



    4)在IAR设置中加入香瓜任务的源文件路径

    $PROJ_DIR$....SimpleBLEPeripheralSourceGUA 


    七、注意事项

    手机可能缓存了之前的代码(在更新过CC2541的代码之后,都须要清除手机端的缓存!!!),因此要清除缓存。清除缓存的方法例如以下:

    方法一:关闭app、关闭蓝牙总开关、打开蓝牙总开关、打开app。
    方法二:手机重新启动。


    八、实验结果

    代码下进Smart RF之后。板子上P11引脚相应的LED2会一秒变换一次亮、灭状态。

    这个LED2亮灭的測试代码即在香瓜任务中实现的,所以香瓜任务加入成功。



  • 相关阅读:
    PTP 接线方式及通讯距离
    串口通信基本概念
    Modbus RTU 通信应用案例
    Modbus 指令
    Modbus RTU新版本指令介绍
    Integer自动装箱和拆箱
    重写hashCode方法,导致内存泄漏
    Dom4j入门
    Java设计模式(9)——观察者模式
    IntelliJ IDEA版本控制——过滤提交文件
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7354369.html
Copyright © 2011-2022 走看看