int main( void )
{
#if (defined (HAL_SLEEP)) && (HAL_SLEEP == TRUE)
GPIOA_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU );
GPIOB_ModeCfg( GPIO_Pin_All, GPIO_ModeIN_PU );
#endif
#ifdef DEBUG
GPIOA_SetBits(bTXD1);
GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA);
UART1_DefInit( );
#endif
PRINT("%s\n",VER_LIB);
CH57X_BLEInit( );//协议栈相关初始化
HAL_Init( );//硬件初始化
GAPRole_PeripheralInit( );//GAP角色初始化,初始化为外围设备,协议栈API函数
Peripheral_Init( ); //外围设备,自定义参数初始化,自定义函数
while(1){
TMOS_SystemProcess( );//TMOS系统运行,协议栈API函数
}
}
其中函数 GAPRole_PeripheralInit( )
,用于GAP角色初始化,初始化为外围设备,属于协议栈提供的API。
void Peripheral_Init( )
{
Peripheral_TaskID = TMOS_ProcessEventRegister( Peripheral_ProcessEvent );
//注册事件回调函数,TMOS是基于时间回调的,一个任务下,最多可以有16个事件,1个用于系统,另外15个用于用户
// 设置GAP角色参数
{
uint8 initial_advertising_enable = TRUE;
uint16 desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
uint16 desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
// Set the GAP Role Parameters
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );//使能广播
GAPRole_SetParameter( GAPROLE_SCAN_RSP_DATA, sizeof ( scanRspData ), scanRspData );//扫描回复数据,数据格式要遵循广播数据格式
GAPRole_SetParameter( GAPROLE_ADVERT_DATA, sizeof( advertData ), advertData );//扫描回复数据,数据格式要遵循广播数据格式
GAPRole_SetParameter( GAPROLE_MIN_CONN_INTERVAL, sizeof( uint16 ), &desired_min_interval );//最小连接间隔
GAPRole_SetParameter( GAPROLE_MAX_CONN_INTERVAL, sizeof( uint16 ), &desired_max_interval );//最大连接间隔
}
// Set the GAP Characteristics
GGS_SetParameter( GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName );//GAP特征,设备名称
// Set advertising interval
{
uint16 advInt = DEFAULT_ADVERTISING_INTERVAL;
GAP_SetParamValue( TGAP_DISC_ADV_INT_MIN, advInt );//最小广播间隔
GAP_SetParamValue( TGAP_DISC_ADV_INT_MAX, advInt );//最大广播间隔
}
// Initialize GATT attributes
GGS_AddService( GATT_ALL_SERVICES ); // GAP
GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes
//GAP和GATT这两个服务是协议栈自带的,如上调用即可。
// Init Connection Item
peripheralInitConnItem( &peripheralConnList );//连接参数初始化
// Setup a delayed profile startup
tmos_set_event( Peripheral_TaskID, SBP_START_DEVICE_EVT );
//启动Peripheral_TaskID任务下的SBP_START_DEVICE_EVT事件,其中tmos_set_event函数用于立刻执行某个事件
}
注册了任务回调函数之后,通过函数tmos_set_event
或者tmos_start_task
启动某个事件,会回调到这个函数中,任务中有4个事件,其中SBP_READ_RSSI_EVT
是周期性执行的事件,其他事件在特定情况下才会执行。
uint16 Peripheral_ProcessEvent( uint8 task_id, uint16 events )
{
// VOID task_id; // TMOS required parameter that isn't used in this function
if ( events & SYS_EVENT_MSG ){//系统事件
uint8 *pMsg;
if ( (pMsg = tmos_msg_receive( Peripheral_TaskID )) != NULL ){
Peripheral_ProcessTMOSMsg( (tmos_event_hdr_t *)pMsg );
// Release the TMOS message
tmos_msg_deallocate( pMsg );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if ( events & SBP_START_DEVICE_EVT ){//GAP外围设备启动事假
// Start the Device
GAPRole_PeripheralStartDevice( Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs );
return ( events ^ SBP_START_DEVICE_EVT );
}
if ( events & SBP_PARAM_UPDATE_EVT )//连接参数更新事件
{
// Send connect param update request
GAPRole_PeripheralConnParamUpdateReq( peripheralConnList.connHandle,
DEFAULT_DESIRED_MIN_CONN_INTERVAL,
DEFAULT_DESIRED_MAX_CONN_INTERVAL,
DEFAULT_DESIRED_SLAVE_LATENCY,
DEFAULT_DESIRED_CONN_TIMEOUT,
Peripheral_TaskID);
return (events ^ SBP_PARAM_UPDATE_EVT);
}
if ( events & SBP_READ_RSSI_EVT )//读取RSSI事假
{
GAPRole_ReadRssiCmd(peripheralConnList.connHandle);
tmos_start_task( Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD );
return (events ^ SBP_READ_RSSI_EVT);
}
// Discard unknown events
return 0;
}
GAPRole_PeripheralStartDevice( uint8 taskid, gapBondCBs_t *pCB,gapRolesCBs_t *pAppCallbacks );
用于启动外围设备;
taskid
:任务ID;
pCB
:绑定回调函数;
pAppCallbacks
:Gap角色回调函数;
其中pAppCallbacks
本身是一个结构体,包含三个函数指针,如下
typedef struct
{
gapRolesStateNotify_t pfnStateChange; //!< Whenever the device changes state
//设备状态改变函数指针
gapRolesRssiRead_t pfnRssiRead; //!< When a valid RSSI is read from controller
//RSSI读取函数指针
gapRolesParamUpdateCB_t pfnParamUpdate; //!< When the connection parameteres are updated
//连接参数更新函数指针
} gapRolesCBs_t;
如果GAP层设备状态发生了变化,协议栈会回调到这个函数中,用于在这个函数里面处理各种状态。
static void peripheralStateNotificationCB( gapRole_States_t newState, gapRoleEvent_t * pEvent )
{
switch ( newState )
{
case GAPROLE_STARTED://启动
PRINT( "Initialized..\n" );
break;
case GAPROLE_ADVERTISING://广播
if( pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT )
{
Peripheral_LinkTerminated( pEvent );
PRINT( "Disconnected.. Reason:%x\n",pEvent->linkTerminate.reason );
}
PRINT( "Advertising..\n" );
break;
case GAPROLE_CONNECTED://连接
if( pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT )
{
Peripheral_LinkEstablished( pEvent );//在这个函数中启动读取rssi事件、更新连接参数事件
}
PRINT( "Connected..\n" );
break;
case GAPROLE_CONNECTED_ADV://连接+广播
PRINT( "Connected Advertising..\n" );
break;
case GAPROLE_WAITING://等待
if( pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT )//等待广播
{
PRINT( "Waiting for advertising..\n" );
}
else if( pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT )//连接断开
{
Peripheral_LinkTerminated( pEvent );//在这个函数在,重新启动广播,关闭读取rssi
PRINT( "Disconnected.. Reason:%x\n",pEvent->linkTerminate.reason );
}
else if( pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT )
{
if( pEvent->gap.hdr.status != SUCCESS )
{
PRINT( "Waiting for advertising..\n" );
}
else
{
PRINT( "Error..\n" );
}
}
else
{
PRINT( "Error..%x\n",pEvent->gap.opcode );
}
break;
case GAPROLE_ERROR:
PRINT( "Error..\n" );
break;
default:
break;
}
}
static void peripheralParamUpdateCB( uint16 connHandle, uint16 connInterval,
uint16 connSlaveLatency, uint16 connTimeout )
{
if( connHandle == peripheralConnList.connHandle )
{
peripheralConnList.connInterval = connInterval;
peripheralConnList.connSlaveLatency = connSlaveLatency;
peripheralConnList.connTimeout = connTimeout;
PRINT("Update %x - Int %x \n", connHandle, connInterval);
}
else
{
PRINT("ERR..\n");
}
}
static void peripheralRssiCB( uint16 connHandle, int8 rssi )
{
PRINT( "RSSI -%d dB Conn %x \n", -rssi, connHandle);
}
可以看到,通过以上代码就构成了最小外围设备。