TI BLE STACK - OSAL
TI 的OSAL做的很不错,不过看起来也挺费劲可能自己水平太差吧,网上买的谷雨的开发板觉得确实挺不错的。
做点学习笔记,首先是记录OSAL里执行的顺序流程,主要是task ,event,message
1,
APP_Main.c:
/* Initialize the operating system */
osal_init_system();
其中初始化了
// Initialize the system tasks.
osalInitTasks();
- /*********************************************************************
- * @fn osalInitTasks
- *
- * @brief This function invokes the initialization function for each task.
- *
- * @param void
- *
- * @return none
- */
- void osalInitTasks( void )
- {
- uint8 taskID = ;
- tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
- osal_memset( tasksEvents, , (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 );
- }
osalInitTasks
这个很关键,这个函数在OSAL_APP.c,初始化了所有的task以及tasksEvents,用来存储每个task中的事件表。
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
2,task存放:
- // The order in this table must be identical to the task initialization calls below in osalInitTask.
- 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
- };
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
这里进入无限循环:
- void osal_start_system( void )
- {
- #if !defined ( ZBIT ) && !defined ( UBIT )
- for(;;) // Forever Loop
- #endif
- {
- osal_run_system();
- }
- }
osal_start_system
主要调用每个task判断在其中的osal_run_system
- /*********************************************************************
- * @fn osal_run_system
- *
- * @brief
- *
- * This function will make one pass through the OSAL taskEvents table
- * and call the task_event_processor() function for the first task that
- * is found with at least one event pending. If there are no pending
- * events (all tasks), this function puts the processor into Sleep.
- *
- * @param void
- *
- * @return none
- */
- void osal_run_system( void )
- {
- uint8 idx = ;
- #ifndef HAL_BOARD_CC2538
- osalTimeUpdate();
- #endif
- Hal_ProcessPoll();
- do {
- if (tasksEvents[idx]) // Task is highest priority that is ready.
- {
- break;
- }
- } while (++idx < tasksCnt);
- if (idx < tasksCnt)
- {
- uint16 events;
- halIntState_t intState;
- HAL_ENTER_CRITICAL_SECTION(intState);
- events = tasksEvents[idx];
- tasksEvents[idx] = ; // Clear the Events for this task.
- HAL_EXIT_CRITICAL_SECTION(intState);
- activeTaskID = idx;
- events = (tasksArr[idx])( idx, events );
- activeTaskID = TASK_NO_TASK;
- HAL_ENTER_CRITICAL_SECTION(intState);
- tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
- HAL_EXIT_CRITICAL_SECTION(intState);
- }
- #if defined( POWER_SAVING )
- else // Complete pass through all task events with no activity?
- {
- osal_pwrmgr_powerconserve(); // Put the processor/system into sleep
- }
- #endif
- /* Yield in case cooperative scheduling is being used. */
- #if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
- {
- osal_task_yield();
- }
- #endif
- }
osal_run_system
先按task id判断优先级在前的task跳出来,然后根据event来执行程序。所谓根据event来执行是在task的主函数中通过if来判断:
比如我现在看的SimpleBLEPeripheral_ProcessEvent()也就是我们的application task
- /*********************************************************************
- * @fn SimpleBLEPeripheral_ProcessEvent
- *
- * @brief Simple BLE Peripheral Application Task event processor. This function
- * is called to process all events for the task. Events
- * include timers, messages and any other user defined events.
- *
- * @param task_id - The OSAL assigned task ID.
- * @param events - events to process. This is a bit map and can
- * contain more than one event.
- *
- * @return events not processed
- */
- uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
- {
- VOID task_id; // OSAL required parameter that isn't used in this function
- if ( events & SYS_EVENT_MSG )
- {
- 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 );
- }
- // return unprocessed events
- return (events ^ SYS_EVENT_MSG);
- }
- if ( events & SBP_START_DEVICE_EVT )
- {
- // Start the Device
- VOID GAPRole_StartDevice( &simpleBLEPeripheral_PeripheralCBs );
- // Start Bond Manager
- VOID GAPBondMgr_Register( &simpleBLEPeripheral_BondMgrCBs );
- // Set timer for first periodic event
- osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
- return ( events ^ SBP_START_DEVICE_EVT );
- }
- if ( events & SBP_PERIODIC_EVT )
- {
- // Restart timer
- if ( SBP_PERIODIC_EVT_PERIOD )
- {
- osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD );
- }
- // Perform periodic application task
- performPeriodicTask();
- return (events ^ SBP_PERIODIC_EVT);
- }
- #if defined ( PLUS_BROADCASTER )
- if ( events & SBP_ADV_IN_CONNECTION_EVT )
- {
- uint8 turnOnAdv = TRUE;
- // Turn on advertising while in a connection
- GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &turnOnAdv );
- return (events ^ SBP_ADV_IN_CONNECTION_EVT);
- }
- #endif // PLUS_BROADCASTER
- // Discard unknown events
- return ;
- }
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 )
- /*********************************************************************
- * @fn SimpleBLEPeripheral_Init
- *
- * @brief Initialization function for the Simple BLE Peripheral App Task.
- * This is called during initialization and should contain
- * any application specific initialization (ie. hardware
- * initialization/setup, table initialization, power up
- * notificaiton ... ).
- *
- * @param task_id - the ID assigned by OSAL. This ID should be
- * used to send messages and set timers.
- *
- * @return none
- */
- void SimpleBLEPeripheral_Init( uint8 task_id )
- {
- simpleBLEPeripheral_TaskID = task_id;
- // Setup the GAP
- VOID GAP_SetParamValue( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL );
- // Setup the GAP Peripheral Role Profile
- {
- #if defined( CC2540_MINIDK )
- // For the CC2540DK-MINI keyfob, device doesn't start advertising until button is pressed
- uint8 initial_advertising_enable = FALSE;
- #else
- // For other hardware platforms, device starts advertising upon initialization
- uint8 initial_advertising_enable = TRUE;
- #endif
- // By setting this to zero, the device will go into the waiting state after
- // being discoverable for 30.72 second, and will not being advertising again
- // until the enabler is set back to TRUE
- uint16 gapRole_AdvertOffTime = ;
- uint8 enable_update_request = DEFAULT_ENABLE_UPDATE_REQUEST;
- uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
- uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
- uint16 desired_slave_latency = DEFAULT_DESIRED_SLAVE_LATENCY;
- uint16 desired_conn_timeout = DEFAULT_DESIRED_CONN_TIMEOUT;
- // Set the GAP Role Parameters
- GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );
- GAPRole_SetParameter( GAPROLE_ADVERT_OFF_TIME, sizeof( uint16 ), &gapRole_AdvertOffTime );
- GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );
- GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );
- GAPRole_SetParameter( GAPROLE_PARAM_UPDATE_ENABLE, sizeof( uint8 ), &enable_update_request );
- GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );
- GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );
- GAPRole_SetParameter( GAPROLE_SLAVE_LATENCY, sizeof( uint16 ), &desired_slave_latency );
- GAPRole_SetParameter( GAPROLE_TIMEOUT_MULTIPLIER, sizeof( uint16 ), &desired_conn_timeout );
- }
- // Set the GAP Characteristics
- GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );
- // Set advertising interval
- {
- uint16 advInt = DEFAULT_ADVERTISING_INTERVAL;
- GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MIN, advInt );
- GAP_SetParamValue( TGAP_LIM_DISC_ADV_INT_MAX, advInt );
- GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, advInt );
- GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, advInt );
- }
- // Setup the GAP Bond Manager
- {
- uint32 passkey = ; // passkey "000000"
- uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
- uint8 mitm = TRUE;
- uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
- uint8 bonding = TRUE;
- GAPBondMgr_SetParameter( GAPBOND_DEFAULT_PASSCODE, sizeof ( uint32 ), &passkey );
- GAPBondMgr_SetParameter( GAPBOND_PAIRING_MODE, sizeof ( uint8 ), &pairMode );
- GAPBondMgr_SetParameter( GAPBOND_MITM_PROTECTION, sizeof ( uint8 ), &mitm );
- GAPBondMgr_SetParameter( GAPBOND_IO_CAPABILITIES, sizeof ( uint8 ), &ioCap );
- GAPBondMgr_SetParameter( GAPBOND_BONDING_ENABLED, sizeof ( uint8 ), &bonding );
- }
- // Initialize GATT attributes
- GGS_AddService( GATT_ALL_SERVICES ); // GAP
- GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
- DevInfo_AddService(); // Device Information Service
- SimpleProfile_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile
- #if defined FEATURE_OAD
- VOID OADTarget_AddService(); // OAD Profile
- #endif
- // Setup the SimpleProfile Characteristic Values
- {
- uint8 charValue1 = ;
- uint8 charValue2 = ;
- uint8 charValue3 = ;
- uint8 charValue4 = ;
- uint8 charValue5[SIMPLEPROFILE_CHAR5_LEN] = { , , , , };
- SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR1, sizeof ( uint8 ), &charValue1 );
- SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR2, sizeof ( uint8 ), &charValue2 );
- SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR3, sizeof ( uint8 ), &charValue3 );
- SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof ( uint8 ), &charValue4 );
- SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5 );
- }
- #if defined( CC2540_MINIDK )
- SK_AddService( GATT_ALL_SERVICES ); // Simple Keys Profile
- // Register for all key events - This app will handle all key events
- RegisterForKeys( simpleBLEPeripheral_TaskID );
- // makes sure LEDs are off
- HalLedSet( (HAL_LED_1 | HAL_LED_2), HAL_LED_MODE_OFF );
- // For keyfob board set GPIO pins into a power-optimized state
- // Note that there is still some leakage current from the buzzer,
- // accelerometer, LEDs, and buttons on the PCB.
- P0SEL = ; // Configure Port 0 as GPIO
- P1SEL = ; // Configure Port 1 as GPIO
- P2SEL = ; // Configure Port 2 as GPIO
- P0DIR = 0xFC; // Port 0 pins P0.0 and P0.1 as input (buttons),
- // all others (P0.2-P0.7) as output
- P1DIR = 0xFF; // All port 1 pins (P1.0-P1.7) as output
- P2DIR = 0x1F; // All port 1 pins (P2.0-P2.4) as output
- P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
- P1 = ; // All pins on port 1 to low
- P2 = ; // All pins on port 2 to low
- #endif // #if defined( CC2540_MINIDK )
- #if (defined HAL_LCD) && (HAL_LCD == TRUE)
- #if defined FEATURE_OAD
- #if defined (HAL_IMAGE_A)
- HalLcdWriteStringValue( "BLE Peri-A", OAD_VER_NUM( _imgHdr.ver ), , HAL_LCD_LINE_1 );
- #else
- HalLcdWriteStringValue( "BLE Peri-B", OAD_VER_NUM( _imgHdr.ver ), , HAL_LCD_LINE_1 );
- #endif // HAL_IMAGE_A
- #else
- HalLcdWriteString( "BLE Peripheral", HAL_LCD_LINE_1 );
- #endif // FEATURE_OAD
- #endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
- // Register callback with SimpleGATTprofile
- VOID SimpleProfile_RegisterAppCBs( &simpleBLEPeripheral_SimpleProfileCBs );
- // Enable clock divide on halt
- // This reduces active current while radio is active and CC254x MCU
- // is halted
- HCI_EXT_ClkDivOnHaltCmd( HCI_EXT_ENABLE_CLK_DIVIDE_ON_HALT );
- #if defined ( DC_DC_P0_7 )
- // Enable stack to toggle bypass control on TPS62730 (DC/DC converter)
- HCI_EXT_MapPmIoPortCmd( HCI_EXT_PM_IO_PORT_P0, HCI_EXT_PM_IO_PORT_PIN7 );
- #endif // defined ( DC_DC_P0_7 )
- // Setup a delayed profile startup
- osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
- }
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_key.c中void halProcessKeyInterrupt (void)
- /**************************************************************************************************
- * @fn halProcessKeyInterrupt
- *
- * @brief Checks to see if it's a valid key interrupt, saves interrupt driven key states for
- * processing by HalKeyRead(), and debounces keys by scheduling HalKeyRead() 25ms later.
- *
- * @param
- *
- * @return
- **************************************************************************************************/
- void halProcessKeyInterrupt (void)
- {
- bool valid=FALSE;
- #if defined ( CC2540_MINIDK )
- if( HAL_KEY_SW_1_PXIFG & HAL_KEY_SW_1_BIT) /* Interrupt Flag has been set by SW1 */
- {
- HAL_KEY_SW_1_PXIFG = ~(HAL_KEY_SW_1_BIT); /* Clear Interrupt Flag */
- valid = TRUE;
- }
- if (HAL_KEY_SW_2_PXIFG & HAL_KEY_SW_2_BIT) /* Interrupt Flag has been set by SW2 */
- {
- HAL_KEY_SW_2_PXIFG = ~(HAL_KEY_SW_2_BIT); /* Clear Interrupt Flag */
- valid = TRUE;
- }
- #else
- if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT) /* Interrupt Flag has been set */
- {
- HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /* Clear Interrupt Flag */
- valid = TRUE;
- }
- if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT) /* Interrupt Flag has been set */
- {
- HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT); /* Clear Interrupt Flag */
- valid = TRUE;
- }
- #endif
- if (valid)
- {
- osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);
- }
- }
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()
- /**************************************************************************************************
- * @fn HalKeyPoll
- *
- * @brief Called by hal_driver to poll the keys
- *
- * @param None
- *
- * @return None
- **************************************************************************************************/
- void HalKeyPoll (void)
- {
- uint8 keys = ;
- uint8 notify = ;
- #if defined (CC2540_MINIDK)
- if (!(HAL_KEY_SW_1_PORT & HAL_KEY_SW_1_BIT)) /* Key is active low */
- {
- keys |= HAL_KEY_SW_1;
- }
- if (!(HAL_KEY_SW_2_PORT & HAL_KEY_SW_2_BIT)) /* Key is active low */
- {
- keys |= HAL_KEY_SW_2;
- }
- #else
- if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT)) /* Key is active low */
- {
- keys |= HAL_KEY_SW_6;
- }
- if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT)) /* Key is active HIGH */
- {
- keys = halGetJoyKeyInput();
- }
- #endif
- /* If interrupts are not enabled, previous key status and current key status
- * are compared to find out if a key has changed status.
- */
- if (!Hal_KeyIntEnable)
- {
- if (keys == halKeySavedKeys)
- {
- /* Exit - since no keys have changed */
- return;
- }
- else
- {
- notify = ;
- }
- }
- else
- {
- /* Key interrupt handled here */
- if (keys)
- {
- notify = ;
- }
- }
- /* Store the current keys for comparation next time */
- halKeySavedKeys = keys;
- /* Invoke Callback if new keys were depressed */
- if (notify && (pHalKeyProcessFunction))
- {
- (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
- }
- }
HalKeyPoll()
前面是判断哪个被按下,最后一句很关键:
/* Invoke Callback if new keys were depressed */
if (notify && (pHalKeyProcessFunction))
{
(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
}
回调函数这时候启动OnBoard_KeyCallback这在之前的初始化时候和pHalKeyProcessFunction挂钩
5,
- /*********************************************************************
- * @fn OnBoard_KeyCallback
- *
- * @brief Callback service for keys
- *
- * @param keys - keys that were pressed
- * state - shifted
- *
- * @return void
- *********************************************************************/
- void OnBoard_KeyCallback ( uint8 keys, uint8 state )
- {
- uint8 shift;
- (void)state;
- // shift key (S1) is used to generate key interrupt
- // applications should not use S1 when key interrupt is enabled
- shift = (OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE) ? false : ((keys & HAL_KEY_SW_6) ? true : false);
- if ( OnBoard_SendKeys( keys, shift ) != SUCCESS )
- {
- // Process SW1 here
- if ( keys & HAL_KEY_SW_1 ) // Switch 1
- {
- }
- // Process SW2 here
- if ( keys & HAL_KEY_SW_2 ) // Switch 2
- {
- }
- // Process SW3 here
- if ( keys & HAL_KEY_SW_3 ) // Switch 3
- {
- }
- // Process SW4 here
- if ( keys & HAL_KEY_SW_4 ) // Switch 4
- {
- }
- // Process SW5 here
- if ( keys & HAL_KEY_SW_5 ) // Switch 5
- {
- }
- // Process SW6 here
- if ( keys & HAL_KEY_SW_6 ) // Switch 6
- {
- }
- }
- /* If any key is currently pressed down and interrupt
- is still enabled, disable interrupt and switch to polling */
- if( keys != )
- {
- if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )
- {
- OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
- HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
- }
- }
- /* If no key is currently pressed down and interrupt
- is disabled, enable interrupt and turn off polling */
- else
- {
- if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )
- {
- OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
- HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
- }
- }
- }
OnBoard_KeyCallback
在on_board.c中
主要的一句:OnBoard_SendKeys( keys, shift )这里发送给了前台task
- *********************************************************************
- * @fn OnBoard_SendKeys
- *
- * @brief Send "Key Pressed" message to application.
- *
- * @param keys - keys that were pressed
- * state - shifted
- *
- * @return status
- *********************************************************************/
- uint8 OnBoard_SendKeys( uint8 keys, uint8 state )
- {
- keyChange_t *msgPtr;
- if ( registeredKeysTaskID != NO_TASK_ID )
- {
- // Send the address to the task
- msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
- if ( msgPtr )
- {
- msgPtr->hdr.event = KEY_CHANGE;
- msgPtr->state = state;
- msgPtr->keys = keys;
- osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
- }
- return ( SUCCESS );
- }
- else
- return ( FAILURE );
- }
OnBoard_SendKeys
osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
registeredKeysTaskID之前初始化注册ID我们的apptask,并且这个函数osal_msg_send会触发一个SYS_EVENT_MSG这样就到了前台
6,msg的各种结构:
- static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
- {
- switch ( pMsg->event )
- {
- #if defined( CC2540_MINIDK )
- case KEY_CHANGE:
- simpleBLEPeripheral_HandleKeys( ((keyChange_t *)pMsg)->state, ((keyChange_t *)pMsg)->keys );
- break;
- #endif // #if defined( CC2540_MINIDK )
- default:
- // do nothing
- break;
- }
- }
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
以及整个工程的流程了,花了两三天时间看完的,感谢谷雨资料
TI BLE STACK - OSAL的更多相关文章
- TI BLE协议栈软件框架分析
看源代码的时候,一般都是从整个代码的入口处开始,TI BLE 协议栈源码也不例外.它的入口main()函数就是整个程序的入口,由系统上电时自动调用. 它主要做了以下几件事情: (一)底层硬件初始化配 ...
- TI BLE: Advertisement
#define GAPROLE_ADVERT_ENABLED 0x305 //!< Enable/Disable Advertising. Read/Write. Size is uint8. ...
- TI BLE CC2541的SPI主模式
SPI就是用4条线来串行传输数据, 2541只能用模拟的方式用GPIO来做. //*********************************************************** ...
- TI BLE:SCAN
主机会运行SCAN来搜寻广播中的设备 运行函数: GAPCentralRole_StartDiscovery( DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_AC ...
- TI BLE CC2541的通讯协议.
包类型: 01命令/02数据/03应答消息 开始标志FF/本数据包长度(注意是16进制)/校验码/包ID/包类型01: 表示是命令/01表示下面要开始传输/03字符串编号/字符串长度/结束位FEFF ...
- TI BLE CC2541的I2C主模式
由于要写TM1680, 写命令跟写数据, 所以需要使用CC2541的I2C, 2541是有硬件I2C的. tm1680.c: #include "tm1680.h" //TM168 ...
- TI BLE:读本机地址
uint8 ownAddress[B_ADDR_LEN]; //B_ADDR_LEN=6GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress); #def ...
- TI BLE : GAP Bond Manager
// Setup the GAP Bond Manager { uint32 passkey = 0; // passkey "000000" uint8 pairMode = G ...
- 让BLE设备的名称包含MAC地址
对于研发和测试BLE来说,经常看到同名的设备,是极为不方便的,一大堆设备同时上电会让同事不知道哪一个设备才是自己真正想操作的目标.再说一下小米手环,家中有三支小米手环,打开设备搜索全是“MI”,都不知 ...
随机推荐
- Anaconda基本用法
Anaconda基本用法 conda info --envs/(-e) // 查看当前的环境变量 conda create -n py36(环境的名称,随意) python=3.6(指定版本) // ...
- python flask获取微信用户信息流程
需要了解的几个url 用户第一次访问时的url,包含以下几个参数 https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID& ...
- Directory获取方式
1) FSDirectory.open FSDirectory.open()会以最合适的方式来获取一个Directory对象. 2) RAMDirectory 可以将磁盘中的索引加载到内存中,访问速度 ...
- 自动生成 serialVersionUID 的设置
1 把鼠标放在类名上,会出现小灯泡的形状 点击 Add ‘serialVersionUID’ field... 即可生成 如果鼠标放在类名上没有出现 Add ‘serialVersionUID’ fi ...
- python接口测试之Http请求(三)
python的强大之处在于提供了很多的标准库,这些标准库可以直接调用,本节部分,重点学习和总结在 接口测试中Python的Http请求的库的学习. 首先来看httplib,官方的解释为:本模块定义了类 ...
- Linux find常用命令
今天研究一下find的一些常用的命令. find格式:find filepath [-option] [-print|-exec|-ok...] 其中常用的option主要有 -type d|f|s| ...
- 18.9.22 noip模拟赛
此题为找规律.期望100 实际100 #include<cstdio> #include<cstring> #include<iostream> #include& ...
- Servlet实现国际化
以下内容引用自http://wiki.jikexueyuan.com/project/servlet/internationalization.html: 三个重要术语: 国际化(i18n):这意味着 ...
- 谈论javascript闭包
闭包看似很简单,其实牵扯了很多东西,例如:上下文作用域(事件处理程序).内存占用.局部以及全局变量.回调函数以及编程模式等 首先我们谈论一个问题,为什么需要闭包? 1.var全局定义(全局污染)- 指 ...
- android 加密手机完毕后待机两分钟出现有频率的杂音
这个音效是code里面主动加的,是为了提醒end user输入PIN的一个提示音,也标志着加密手机动作的完毕. 详细位置是在alps\packages\apps\Settings\src\com\an ...