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”,都不知 ...
随机推荐
- 88-On Balance Volume 能量潮指标.(2015.7.4)
On Balance Volume 能量潮指标 ~计算方法: 如果当天的收盘价高于昨天的话,那么:OBV(i) = OBV(i-1)+VOLUME(i) 如果当天的收盘价低于昨天的话,那么:OBV(i ...
- mat 服务器分析大堆,本地打开
1:服务器执行nohup sh /usr/local/mat/ParseHeapDump.sh es9.bin org.eclipse.mat.api:suspects org.eclipse.mat ...
- Jmeter-接口测试实例讲解
一.测试需求描述 1. 本次测试的接口为http服务端接口 2. 接口的主要分成两类,一类提供给查询功能接口,一类提供保存数据功能接口,这里我们举例2个保存数据的接口,因为这两个接口有关联性,比较有代 ...
- Spring框架中 配置c3p0连接池
开发准备: 1.导入jar包: ioc基本jar jdbcTemplate基本jar c3p0基本jar 别忘了mysql数据库驱动jar 原始程序代码:不使用配置文件方式(IOC)生成访问数据库对象 ...
- Selenium IDE-自动化实战
1.输入测试 Base URL 2.打开录制按钮(默认是录制状态,点击一下就是停止,再次点击,又继续录制) 3.在浏览器界面进行相关操作(比如输入selenium,点击搜索按钮,查看搜索结果),之后点 ...
- Codeforces Round #354 (Div. 2)-C. Vasya and String,区间dp问题,好几次cf都有这种题,看来的好好学学;
C. Vasya and String time limit per test 1 second memory limit per test 256 megabytes input standard ...
- 使用mysql-proxy 快速实现mysql 集群 读写分离
目前较为常见的mysql读写分离分为两种: 1. 基于程序代码内部实现:在代码中对select操作分发到从库:其它操作由主库执行:这类方法也是目前生产环境应用最广泛,知名的如DISCUZ X2.优点是 ...
- HDU 1564 找规律博弈
题目大意是: 从n*n的方格角落的一个起点出发,每次移到上下左右一个未曾到达过的位置,谁不能走了谁就输了 想了好久都想不出,看了大神的题解 Orz了 果然博弈不是脑残的游戏啊... 这里从起点出发,将 ...
- Pagodas 等差数列
nn pagodas were standing erect in Hong Jue Si between the Niushou Mountain and the Yuntai Mountain, ...
- POJ 2240_Arbitrage
题意: 给定一系列货币汇率,求能否从一种货币,经过一系列转换,最终转化回更高价值的该种货币. 分析: 即为求最长路并判断是否存在"正"权值回路,这里用的bellmanford算法. ...