• TI BLE STACK


    TI 的OSAL做的很不错,不过看起来也挺费劲可能自己水平太差吧,网上买的谷雨的开发板觉得确实挺不错的。

    做点学习笔记,首先是记录OSAL里执行的顺序流程,主要是task ,event,message

    1,

    APP_Main.c:

    /* Initialize the operating system */
    osal_init_system();

    其中初始化了

    // Initialize the system tasks.
    osalInitTasks();

     1 /*********************************************************************
     2  * @fn      osalInitTasks
     3  *
     4  * @brief   This function invokes the initialization function for each task.
     5  *
     6  * @param   void
     7  *
     8  * @return  none
     9  */
    10 void osalInitTasks( void )
    11 {
    12   uint8 taskID = 0;
    13 
    14   tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
    15   osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
    16 
    17   /* LL Task */
    18   LL_Init( taskID++ );
    19 
    20   /* Hal Task */
    21   Hal_Init( taskID++ );
    22 
    23   /* HCI Task */
    24   HCI_Init( taskID++ );
    25 
    26 #if defined ( OSAL_CBTIMER_NUM_TASKS )
    27   /* Callback Timer Tasks */
    28   osal_CbTimerInit( taskID );
    29   taskID += OSAL_CBTIMER_NUM_TASKS;
    30 #endif
    31 
    32   /* L2CAP Task */
    33   L2CAP_Init( taskID++ );
    34 
    35   /* GAP Task */
    36   GAP_Init( taskID++ );
    37 
    38   /* GATT Task */
    39   GATT_Init( taskID++ );
    40 
    41   /* SM Task */
    42   SM_Init( taskID++ );
    43 
    44   /* Profiles */
    45   GAPRole_Init( taskID++ );
    46   GAPBondMgr_Init( taskID++ );
    47 
    48   GATTServApp_Init( taskID++ );
    49 
    50   /* Application */
    51   SimpleBLEPeripheral_Init( taskID );
    52 }
    osalInitTasks

    这个很关键,这个函数在OSAL_APP.c,初始化了所有的task以及tasksEvents,用来存储每个task中的事件表。

    tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
    osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

    2,task存放:

     1 // The order in this table must be identical to the task initialization calls below in osalInitTask.
     2 const pTaskEventHandlerFn tasksArr[] =
     3 {
     4   LL_ProcessEvent,                                                  // task 0
     5   Hal_ProcessEvent,                                                 // task 1
     6   HCI_ProcessEvent,                                                 // task 2
     7 #if defined ( OSAL_CBTIMER_NUM_TASKS )
     8   OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ),           // task 3
     9 #endif
    10   L2CAP_ProcessEvent,                                               // task 4
    11   GAP_ProcessEvent,                                                 // task 5
    12   GATT_ProcessEvent,                                                // task 6
    13   SM_ProcessEvent,                                                  // task 7
    14   GAPRole_ProcessEvent,                                             // task 8
    15   GAPBondMgr_ProcessEvent,                                          // task 9
    16   GATTServApp_ProcessEvent,                                         // task 10
    17   SimpleBLEPeripheral_ProcessEvent                                  // task 11
    18 };
    tasksArr[]

    OSAL_APP.c 之后程序的各任务函数都在这里。

    typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );

    3,task,os启动

    APP_Main.c:  

    /* Start OSAL */
    osal_start_system(); // No Return from here

    这里进入无限循环:

    1 void osal_start_system( void )
    2 {
    3 #if !defined ( ZBIT ) && !defined ( UBIT )
    4   for(;;)  // Forever Loop
    5 #endif
    6   {
    7     osal_run_system();
    8   }
    9 }
    osal_start_system

    主要调用每个task判断在其中的osal_run_system

     1 /*********************************************************************
     2  * @fn      osal_run_system
     3  *
     4  * @brief
     5  *
     6  *   This function will make one pass through the OSAL taskEvents table
     7  *   and call the task_event_processor() function for the first task that
     8  *   is found with at least one event pending. If there are no pending
     9  *   events (all tasks), this function puts the processor into Sleep.
    10  *
    11  * @param   void
    12  *
    13  * @return  none
    14  */
    15 void osal_run_system( void )
    16 {
    17   uint8 idx = 0;
    18 
    19 #ifndef HAL_BOARD_CC2538
    20   osalTimeUpdate();
    21 #endif
    22   
    23   Hal_ProcessPoll();
    24 
    25   do {
    26     if (tasksEvents[idx])  // Task is highest priority that is ready.
    27     {
    28       break;
    29     }
    30   } while (++idx < tasksCnt);
    31 
    32   if (idx < tasksCnt)
    33   {
    34     uint16 events;
    35     halIntState_t intState;
    36 
    37     HAL_ENTER_CRITICAL_SECTION(intState);
    38     events = tasksEvents[idx];
    39     tasksEvents[idx] = 0;  // Clear the Events for this task.
    40     HAL_EXIT_CRITICAL_SECTION(intState);
    41 
    42     activeTaskID = idx;
    43     events = (tasksArr[idx])( idx, events );
    44     activeTaskID = TASK_NO_TASK;
    45 
    46     HAL_ENTER_CRITICAL_SECTION(intState);
    47     tasksEvents[idx] |= events;  // Add back unprocessed events to the current task.
    48     HAL_EXIT_CRITICAL_SECTION(intState);
    49   }
    50 #if defined( POWER_SAVING )
    51   else  // Complete pass through all task events with no activity?
    52   {
    53     osal_pwrmgr_powerconserve();  // Put the processor/system into sleep
    54   }
    55 #endif
    56 
    57   /* Yield in case cooperative scheduling is being used. */
    58 #if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
    59   {
    60     osal_task_yield();
    61   }
    62 #endif
    63 }
    osal_run_system

    先按task id判断优先级在前的task跳出来,然后根据event来执行程序。所谓根据event来执行是在task的主函数中通过if来判断:

    比如我现在看的SimpleBLEPeripheral_ProcessEvent()也就是我们的application task

     1 /*********************************************************************
     2  * @fn      SimpleBLEPeripheral_ProcessEvent
     3  *
     4  * @brief   Simple BLE Peripheral Application Task event processor.  This function
     5  *          is called to process all events for the task.  Events
     6  *          include timers, messages and any other user defined events.
     7  *
     8  * @param   task_id  - The OSAL assigned task ID.
     9  * @param   events - events to process.  This is a bit map and can
    10  *                   contain more than one event.
    11  *
    12  * @return  events not processed
    13  */
    14 uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
    15 {
    16 
    17   VOID task_id; // OSAL required parameter that isn't used in this function
    18 
    19   if ( events & SYS_EVENT_MSG )
    20   {
    21     uint8 *pMsg;
    22 
    23     if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL )
    24     {
    25       simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );
    26 
    27       // Release the OSAL message
    28       VOID osal_msg_deallocate( pMsg );
    29     }
    30 
    31     // return unprocessed events
    32     return (events ^ SYS_EVENT_MSG);
    33   }
    34 
    35   if ( events & SBP_START_DEVICE_EVT )
    36   {
    37     // Start the Device
    38     VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );
    39 
    40     // Start Bond Manager
    41     VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
    42 
    43     // Set timer for first periodic event
    44     osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
    45 
    46     return ( events ^ SBP_START_DEVICE_EVT );
    47   }
    48 
    49   if ( events & SBP_PERIODIC_EVT )
    50   {
    51     // Restart timer
    52     if ( SBP_PERIODIC_EVT_PERIOD )
    53     {
    54       osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
    55     }
    56 
    57     // Perform periodic application task
    58     performPeriodicTask();
    59 
    60     return (events ^ SBP_PERIODIC_EVT);
    61   }
    62 
    63 #if defined ( PLUS_BROADCASTER )
    64   if ( events & SBP_ADV_IN_CONNECTION_EVT )
    65   {
    66     uint8 turnOnAdv = TRUE;
    67     // Turn on advertising while in a connection
    68     GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &turnOnAdv );
    69 
    70     return (events ^ SBP_ADV_IN_CONNECTION_EVT);
    71   }
    72 #endif // PLUS_BROADCASTER
    73 
    74   // Discard unknown events
    75   return 0;
    76 }
    SimpleBLEPeripheral_ProcessEvent

    看到先执行:SYS_EVENT_MSG然后是SBP_START_DEVICE_EVT

    每个EVENT执行完就return保证不过多占用CPU,

    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);

    return之后又会回到osal_run_system循环

    4,event插入:

    先不说SYS_EVENT_MSG,

    刚才的SBP_START_DEVICE_EVT是在初始化时候就插入的

    osalInitTasks();中的void SimpleBLEPeripheral_Init( uint8 task_id )

      1 /*********************************************************************
      2  * @fn      SimpleBLEPeripheral_Init
      3  *
      4  * @brief   Initialization function for the Simple BLE Peripheral App Task.
      5  *          This is called during initialization and should contain
      6  *          any application specific initialization (ie. hardware
      7  *          initialization/setup, table initialization, power up
      8  *          notificaiton ... ).
      9  *
     10  * @param   task_id - the ID assigned by OSAL.  This ID should be
     11  *                    used to send messages and set timers.
     12  *
     13  * @return  none
     14  */
     15 void SimpleBLEPeripheral_Init( uint8 task_id )
     16 {
     17   simpleBLEPeripheral_TaskID = task_id;
     18 
     19   // Setup the GAP
     20   VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );
     21   
     22   // Setup the GAP Peripheral Role Profile
     23   {
     24     #if defined( CC2540_MINIDK )
     25       // For the CC2540DK-MINI keyfob, device doesn't start advertising until button is pressed
     26       uint8 initial_advertising_enable = FALSE;
     27     #else
     28       // For other hardware platforms, device starts advertising upon initialization
     29       uint8 initial_advertising_enable = TRUE;
     30     #endif
     31 
     32     // By setting this to zero, the device will go into the waiting state after
     33     // being discoverable for 30.72 second, and will not being advertising again
     34     // until the enabler is set back to TRUE
     35     uint16 gapRole_AdvertOffTime = 0;
     36 
     37     uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST;
     38     uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
     39     uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
     40     uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY;
     41     uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT;
     42 
     43     // Set the GAP Role Parameters
     44     GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
     45     GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );
     46 
     47     GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
     48     GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
     49 
     50     GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request );
     51     GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );
     52     GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );
     53     GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency );
     54     GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout );
     55   }
     56 
     57   // Set the GAP Characteristics
     58   GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );
     59 
     60   // Set advertising interval
     61   {
     62     uint16 advInt = DEFAULT_ADVERTISING_INTERVAL;
     63 
     64     GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );
     65     GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt );
     66     GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );
     67     GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt );
     68   }
     69 
     70   // Setup the GAP Bond Manager
     71   {
     72     uint32 passkey = 0; // passkey "000000"
     73     uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
     74     uint8 mitm = TRUE;
     75     uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
     76     uint8 bonding = TRUE;
     77     GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey );
     78     GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );
     79     GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );
     80     GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );
     81     GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );
     82   }
     83 
     84   // Initialize GATT attributes
     85   GGS_AddService( GATT_ALL_SERVICES );            // GAP
     86   GATTServApp_AddService( GATT_ALL_SERVICES );    // GATT attributes
     87   DevInfo_AddService();                           // Device Information Service
     88   SimpleProfile_AddService( GATT_ALL_SERVICES );  // Simple GATT Profile
     89 #if defined FEATURE_OAD
     90   VOID OADTarget_AddService();                    // OAD Profile
     91 #endif
     92 
     93   // Setup the SimpleProfile Characteristic Values
     94   {
     95     uint8 charValue1 = 1;
     96     uint8 charValue2 = 2;
     97     uint8 charValue3 = 3;
     98     uint8 charValue4 = 4;
     99     uint8 charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
    100     SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR1, sizeof ( uint8 ), &charValue1 );
    101     SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR2, sizeof ( uint8 ), &charValue2 );
    102     SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, sizeof ( uint8 ), &charValue3 );
    103     SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof ( uint8 ), &charValue4 );
    104     SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5 );
    105   }
    106 
    107 
    108 #if defined( CC2540_MINIDK )
    109 
    110   SK_AddService( GATT_ALL_SERVICES ); // Simple Keys Profile
    111 
    112   // Register for all key events - This app will handle all key events
    113   RegisterForKeys( simpleBLEPeripheral_TaskID );
    114 
    115   // makes sure LEDs are off
    116   HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
    117 
    118   // For keyfob board set GPIO pins into a power-optimized state
    119   // Note that there is still some leakage current from the buzzer,
    120   // accelerometer, LEDs, and buttons on the PCB.
    121 
    122   P0SEL = 0; // Configure Port 0 as GPIO
    123   P1SEL = 0; // Configure Port 1 as GPIO
    124   P2SEL = 0; // Configure Port 2 as GPIO
    125 
    126   P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons),
    127                 // all others (P0.2-P0.7) as output
    128   P1DIR = 0xFF; // All port 1 pins (P1.0-P1.7) as output
    129   P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output
    130 
    131   P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
    132   P1 = 0;   // All pins on port 1 to low
    133   P2 = 0;   // All pins on port 2 to low
    134 
    135 #endif // #if defined( CC2540_MINIDK )
    136 
    137 #if (defined HAL_LCD) && (HAL_LCD == TRUE)
    138 
    139 #if defined FEATURE_OAD
    140   #if defined (HAL_IMAGE_A)
    141     HalLcdWriteStringValue( "BLE Peri-A", OAD_VER_NUM( _imgHdr.ver ), 16, HAL_LCD_LINE_1 );
    142   #else
    143     HalLcdWriteStringValue( "BLE Peri-B", OAD_VER_NUM( _imgHdr.ver ), 16, HAL_LCD_LINE_1 );
    144   #endif // HAL_IMAGE_A
    145 #else
    146   HalLcdWriteString( "BLE Peripheral", HAL_LCD_LINE_1 );
    147 #endif // FEATURE_OAD
    148 
    149 #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
    150 
    151   // Register callback with SimpleGATTprofile
    152   VOID SimpleProfile_RegisterAppCBs( &simpleBLEPeripheral_SimpleProfileCBs );
    153 
    154   // Enable clock divide on halt
    155   // This reduces active current while radio is active and CC254x MCU
    156   // is halted
    157   HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT );
    158 
    159 #if defined ( DC_DC_P0_7 )
    160 
    161   // Enable stack to toggle bypass control on TPS62730 (DC/DC converter)
    162   HCI_EXT_MapPmIoPortCmd( HCI_EXT_PM_IO_PORT_P0, HCI_EXT_PM_IO_PORT_PIN7 );
    163 
    164 #endif // defined ( DC_DC_P0_7 )
    165 
    166   // Setup a delayed profile startup
    167   osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
    168 
    169 }
    SimpleBLEPeripheral_Init

    最后一句:

    // Setup a delayed profile startup
    osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );

    5,message:

    只能简单做个笔记不细说它的功能作用,我们在SimpleBLEPeripheral_ProcessEvent的SYS_EVENT_MSG中看到的,一般message在这发送的是key事件,传回key的值这样可以带一些自己的data,不像event只是标志。

    至于这个key的来源:

    1,之前已经初始化过hal_key,在前面可以找到,

    /* Initialize Key stuff */
    OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
    //OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
    HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

    SimpleBLEPeripheral_Init中注册,把key和task联系起来,也就是key按了之后通知哪个task

    // Register for all key events - This app will handle all key events
    RegisterForKeys( simpleBLEPeripheral_TaskID );

    2,执行顺序首先是按键引起中断:

    一旦有中断发生,中断函数首先跳转到
    HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
    {
      halProcessKeyInterrupt();
     
    ………
    }

    hal_key.c中void halProcessKeyInterrupt (void)

     1 /**************************************************************************************************
     2  * @fn      halProcessKeyInterrupt
     3  *
     4  * @brief   Checks to see if it's a valid key interrupt, saves interrupt driven key states for
     5  *          processing by HalKeyRead(), and debounces keys by scheduling HalKeyRead() 25ms later.
     6  *
     7  * @param
     8  *
     9  * @return
    10  **************************************************************************************************/
    11 void halProcessKeyInterrupt (void)
    12 {
    13   bool valid=FALSE;
    14 
    15 #if defined ( CC2540_MINIDK )
    16   if( HAL_KEY_SW_1_PXIFG & HAL_KEY_SW_1_BIT) /* Interrupt Flag has been set by SW1 */
    17   {
    18     HAL_KEY_SW_1_PXIFG = ~(HAL_KEY_SW_1_BIT); /* Clear Interrupt Flag */
    19     valid = TRUE;
    20   }
    21 
    22   if (HAL_KEY_SW_2_PXIFG & HAL_KEY_SW_2_BIT)  /* Interrupt Flag has been set by SW2 */
    23   {
    24     HAL_KEY_SW_2_PXIFG = ~(HAL_KEY_SW_2_BIT); /* Clear Interrupt Flag */
    25     valid = TRUE;
    26   }
    27 #else
    28   if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)  /* Interrupt Flag has been set */
    29   {
    30     HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /* Clear Interrupt Flag */
    31     valid = TRUE;
    32   }
    33 
    34   if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT)  /* Interrupt Flag has been set */
    35   {
    36     HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT); /* Clear Interrupt Flag */
    37     valid = TRUE;
    38   }
    39 #endif
    40   if (valid)
    41   {
    42     osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);
    43   }
    44 }
    void halProcessKeyInterrupt (void)

    判断是否中断,中断清楚标志,最后osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);

    这是告诉Hal_TaskID 的task,发生了HAL_KEY_EVENT,延时HAL_KEY_DEBOUNCE_VALUE之后执行,这里延时个人认为是去抖动

    3,

    Hal_TaskID 的task在hal_drive.c中

    uint16 Hal_ProcessEvent( uint8 task_id, uint16 events )

    if (events & HAL_KEY_EVENT)
    {
    #if (defined HAL_KEY) && (HAL_KEY == TRUE)
    /* Check for keys */
    HalKeyPoll();

    /* if interrupt disabled, do next polling */
    if (!Hal_KeyIntEnable)
    {
    osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);
    }
    #endif
    return events ^ HAL_KEY_EVENT;
    }

    执行了HalKeyPoll();函数,注意后面if如果没有中断则100ms后再启动这个event,没有中断就是在这轮询

    4,HalKeyPoll()

     1 /**************************************************************************************************
     2  * @fn      HalKeyPoll
     3  *
     4  * @brief   Called by hal_driver to poll the keys
     5  *
     6  * @param   None
     7  *
     8  * @return  None
     9  **************************************************************************************************/
    10 void HalKeyPoll (void)
    11 {
    12   uint8 keys = 0;
    13   uint8 notify = 0;
    14 #if defined (CC2540_MINIDK)
    15   if (!(HAL_KEY_SW_1_PORT & HAL_KEY_SW_1_BIT))    /* Key is active low */
    16   {
    17     keys |= HAL_KEY_SW_1;
    18   }
    19   if (!(HAL_KEY_SW_2_PORT & HAL_KEY_SW_2_BIT))    /* Key is active low */
    20   {
    21     keys |= HAL_KEY_SW_2;
    22   }
    23 #else
    24   if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT))    /* Key is active low */
    25   {
    26     keys |= HAL_KEY_SW_6;
    27   }
    28 
    29   if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT))  /* Key is active HIGH */
    30   {
    31     keys = halGetJoyKeyInput();
    32   }
    33 #endif
    34 
    35   /* If interrupts are not enabled, previous key status and current key status
    36    * are compared to find out if a key has changed status.
    37    */
    38   if (!Hal_KeyIntEnable)
    39   {
    40     if (keys == halKeySavedKeys)
    41     {
    42       /* Exit - since no keys have changed */
    43       return;
    44     }
    45     else
    46     {
    47       notify = 1;
    48     }
    49   }
    50   else
    51   {
    52     /* Key interrupt handled here */
    53     if (keys)
    54     {
    55       notify = 1;
    56     }
    57   }
    58 
    59   /* Store the current keys for comparation next time */
    60   halKeySavedKeys = keys;
    61 
    62   /* Invoke Callback if new keys were depressed */
    63   if (notify && (pHalKeyProcessFunction))
    64   {
    65     (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
    66 
    67   }
    68 }
    HalKeyPoll()

    前面是判断哪个被按下,最后一句很关键:

    /* Invoke Callback if new keys were depressed */
    if (notify && (pHalKeyProcessFunction))
    {
    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);

    }

    回调函数这时候启动OnBoard_KeyCallback这在之前的初始化时候和pHalKeyProcessFunction挂钩

    5,

     1 /*********************************************************************
     2  * @fn      OnBoard_KeyCallback
     3  *
     4  * @brief   Callback service for keys
     5  *
     6  * @param   keys  - keys that were pressed
     7  *          state - shifted
     8  *
     9  * @return  void
    10  *********************************************************************/
    11 void OnBoard_KeyCallback ( uint8 keys, uint8 state )
    12 {
    13   uint8 shift;
    14   (void)state;
    15 
    16   // shift key (S1) is used to generate key interrupt
    17   // applications should not use S1 when key interrupt is enabled
    18   shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false);
    19 
    20   if ( OnBoard_SendKeys( keys, shift ) != SUCCESS )
    21   {
    22     // Process SW1 here
    23     if ( keys & HAL_KEY_SW_1 )  // Switch 1
    24     {
    25     }
    26     // Process SW2 here
    27     if ( keys & HAL_KEY_SW_2 )  // Switch 2
    28     {
    29     }
    30     // Process SW3 here
    31     if ( keys & HAL_KEY_SW_3 )  // Switch 3
    32     {
    33     }
    34     // Process SW4 here
    35     if ( keys & HAL_KEY_SW_4 )  // Switch 4
    36     {
    37     }
    38     // Process SW5 here
    39     if ( keys & HAL_KEY_SW_5 )  // Switch 5
    40     {
    41     }
    42     // Process SW6 here
    43     if ( keys & HAL_KEY_SW_6 )  // Switch 6
    44     {
    45     }
    46   }
    47 
    48   /* If any key is currently pressed down and interrupt
    49      is still enabled, disable interrupt and switch to polling */
    50   if( keys != 0 )
    51   {
    52     if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )
    53     {
    54       OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
    55       HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
    56     }
    57   }
    58   /* If no key is currently pressed down and interrupt
    59      is disabled, enable interrupt and turn off polling */
    60   else
    61   {
    62     if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )
    63     {
    64       OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
    65       HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
    66     }
    67   }
    68 }
    OnBoard_KeyCallback

    在on_board.c中

    主要的一句:OnBoard_SendKeys( keys, shift )这里发送给了前台task

     1 *********************************************************************
     2  * @fn      OnBoard_SendKeys
     3  *
     4  * @brief   Send "Key Pressed" message to application.
     5  *
     6  * @param   keys  - keys that were pressed
     7  *          state - shifted
     8  *
     9  * @return  status
    10  *********************************************************************/
    11 uint8 OnBoard_SendKeys( uint8 keys, uint8 state )
    12 {
    13   keyChange_t *msgPtr;
    14 
    15   if ( registeredKeysTaskID != NO_TASK_ID )
    16   {
    17     // Send the address to the task
    18     msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
    19     if ( msgPtr )
    20     {
    21       msgPtr->hdr.event = KEY_CHANGE;
    22       msgPtr->state = state;
    23       msgPtr->keys = keys;
    24 
    25       osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
    26     }
    27     return ( SUCCESS );
    28   }
    29   else
    30     return ( FAILURE );
    31 }
    OnBoard_SendKeys

    osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );

    registeredKeysTaskID之前初始化注册ID我们的apptask,并且这个函数osal_msg_send会触发一个SYS_EVENT_MSG这样就到了前台

    6,msg的各种结构:

     1 static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
     2 {
     3 switch ( pMsg->event )
     4 {
     5 #if defined( CC2540_MINIDK )
     6 case KEY_CHANGE:
     7 simpleBLEPeripheral_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
     8 break;
     9 #endif // #if defined( CC2540_MINIDK )
    10 
    11 default:
    12 // do nothing
    13 break;
    14 }
    15 }
    simpleBLEPeripheral_ProcessOSALMsg

    typedef struct
    {
    uint8 event;
    uint8 status;
    } osal_event_hdr_t;

    到了key:

    typedef struct
    {
    osal_event_hdr_t hdr;
    uint8 state; // shift
    uint8 keys; // keys
    } keyChange_t;

    最开始时候:

    uint8 *pMsg;

    if ( (pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )) != NULL )
    {
    simpleBLEPeripheral_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );

    // Release the OSAL message
    VOID osal_msg_deallocate( pMsg );
    }

    注意osal_msg_deallocate释放这样就算走完了一遍key

    以及整个工程的流程了,花了两三天时间看完的,感谢谷雨资料

  • 相关阅读:
    IIT(ISM) Virtual Farewell E Dictator's plan for Valentine's day! 二分
    HDU
    LightOJ
    HDU 4407 Sum 容斥原理
    HDU 4686 Arc of Dream 矩阵快速幂
    uoj418
    Gym101237C The Palindrome Extraction Manacher
    Codeforces 100032 K
    codechef Suffix Palindromes
    Codeforces 932G Palindrome Partition
  • 原文地址:https://www.cnblogs.com/wwjdwy/p/3625733.html
Copyright © 2020-2023  润新知