CC2541从main函数开始运行,main函数主要做的是相关初始化,最后一句为启动osal系统.
当main函数启动osal系统之后会跳到simpleBLEPeripheral.c中执行。
simpleBLEPeripheral.c中一开始是一些宏定义,参数、数组、函数声明。
// How often to perform periodic event
#define SBP_PERIODIC_EVT_PERIOD 5000 //执行定时事件的时间 5000ms
// What is the advertising interval when device is discoverable (units of 625us, 160=100ms)
#define DEFAULT_ADVERTISING_INTERVAL 160 //广播间隔 间隔越大 功耗越小
// Limited discoverable mode advertises for 30.72s, and then stops
// General discoverable mode advertises indefinitely
#if defined ( CC2540_MINIDK )
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_LIMITED
#else
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
#endif // defined ( CC2540_MINIDK )
// Minimum connection interval (units of 1.25ms, 80=100ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 80 //最小连接间隔
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 800 //最大连接间隔
// Slave latency to use if automatic parameter update request is enabled
#define DEFAULT_DESIRED_SLAVE_LATENCY 0 //从设备延迟 允许Slave(从设备)在没有数据要发的情况下,跳过一定数目的连接事件(Connection events),在这些连接事件(Connection events)中不必回复Master(主设备)的包,这样就能更加省电。
范围可以是0 ~ 499
// Supervision timeout value (units of 10ms, 1000=10s) if automatic parameter update request is enabled
#define DEFAULT_DESIRED_CONN_TIMEOUT 1000 //连接超时时间 如果两个设备超过这个时间没有交换链路层数据(空包 Empty PDU)来维持连接的话 会断开连接
// Whether to enable automatic parameter update request when a connection is formed
#define DEFAULT_ENABLE_UPDATE_REQUEST TRUE //是否使能参数更新请求
// Connection Pause Peripheral time value (in seconds)
#define DEFAULT_CONN_PAUSE_PERIPHERAL 6 //
// Company Identifier: Texas Instruments Inc. (13)
#define TI_COMPANY_ID 0x000D
#define INVALID_CONNHANDLE 0xFFFF
// Length of bd addr as a string
#define B_ADDR_STR_LEN 15
广播数组
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8 advertData[] =
{
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16( SIMPLEPROFILE_SERV_UUID ),
HI_UINT16( SIMPLEPROFILE_SERV_UUID ),
};
[1]广播发现模式:分为受限广播和正常广播 受限广播只会在上电之后广播30.72秒,正常广播则一直广播。
[2]service uuid:通知主机此从机中带了包括那些服务,可以是16bit uuid、32bit uuid、128bit uuid。
[3]另外包含了一个生产商id
扫描反馈数组
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8 scanRspData[] =
{
// complete name
0x14, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
0x53, // 'S'
0x69, // 'i'
0x6d, // 'm'
0x70, // 'p'
0x6c, // 'l'
0x65, // 'e'
0x42, // 'B'
0x4c, // 'L'
0x45, // 'E'
0x50, // 'P'
0x65, // 'e'
0x72, // 'r'
0x69, // 'i'
0x70, // 'p'
0x68, // 'h'
0x65, // 'e'
0x72, // 'r'
0x61, // 'a'
0x6c, // 'l'
// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), // 100ms
HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), // 1s
HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
// Tx power level
0x02, // length of this data
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm
};
[1]设备名 :可以选择是短的名字、完整的名字
[2]最大最小连接间隔:连接间隔决定了主设备与从设备的交互间隔;它是指两个连续的连接事件开始处的时间距离,可以是7.5ms ~ 4s内的任意值,但必须为 1.25ms 的整数倍。要确定从设备与主设备的实际交互间隔,需要用到从设备延迟这一参数,代表从设备在必须侦听之前可以忽略多少个连接事件。
[3]发射功率
注册回调函数
// GAP Role Callbacks
static gapRolesCBs_t simpleBLEPeripheral_PeripheralCBs =
{
peripheralStateNotificationCB, // Profile State Change Callbacks
NULL // When a valid RSSI is read from controller (not used by application)
};
// GAP Bond Manager Callbacks
static gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
{
NULL, // Passcode callback (not used by application)
NULL // Pairing / Bonding state Callback (not used by application)
};
// Simple GATT Profile Callbacks
static simpleProfileCBs_t simpleBLEPeripheral_SimpleProfileCBs =
{
simpleProfileChangeCB // Charactersitic value change callback
};
1、SimpleBLEPeripheral_Init()
函数原型为void SimpleBLEPeripheral_Init( uint8 task_id )
这个函数的功能是初始化Simple BLE 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 = 0;
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 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 = 0; // passkey "000000"
uint8 pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ; //这个宏是表示等待对方发起配对请求的模式,如果主从机都是这种模式,则双方都不会发起配对请求。
uint8 mitm = TRUE;
uint8 ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;//这个宏是只显示密码,将密码显示在LCD上给主机看,主机也就知道密码了。如果设备有按键可以输入密码,也可以选择GAPBOND_IO_CAP_KEYBOARD_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 );
}
初始化 GATT属性
// Initialize GATT attributes
GGS_AddService( GATT_ALL_SERVICES ); // GAP 添加GAP GATT服务
GATTServApp_AddService( GATT_ALL_SERVICES ); // GATT attributes 添加GATT服务
DevInfo_AddService(); // Device Information Service 通过注册GATT属性和GATT服务来初始化设备信息
SimpleProfile_AddService( GATT_ALL_SERVICES ); // Simple GATT Profile 通过注册GATT属性和GATT服务来初始化Simple Profile service
设置特征值初值
// Setup the SimpleProfile Characteristic Values
{
uint8 charValue1 = 1;
uint8 charValue2 = 2;
uint8 charValue3 = 3;
uint8 charValue4 = 4;
uint8 charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 };
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 );
}
最后执行
// Setup a delayed profile startup
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT ); //设置osal事件 启动一个任务
2、SimpleBLEPeripheral_ProcessEvent()
函数原型为uint16 SimpleBLEPeripheral_ProcessEvent( uint8 task_id, uint16 events )
初始化之后会执行
SimpleBLEPeripheral_ProcessEvent()函数,这个函数的主要功能是处理事件回调,事件包括定时器事件、消息和其他所有的用户定义事件。
根据传入的event参数决定事件处理函数 事件处理函数可以自定义 return返回事件已处理
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 );
}
事件id定义必须不能重复,不然会导致自定义任务执行出现问题
// Simple BLE Peripheral Task Events
#define SBP_START_DEVICE_EVT 0x0001
#define SBP_PERIODIC_EVT 0x0002
3、simpleBLEPeripheral_ProcessOSALMsg()
函数原型为static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *pMsg )
此函数的功能为处理将到来任务消息。
4、peripheralStateNotificationCB()
函数原型为static void peripheralStateNotificationCB( gaprole_States_t newState )
此函数为设备连接状态回调函数,当设备的连接状态发生改变时,会执行此回调函数。我们可以在此函数中得到当前设备的运行状态。
设备的几种状态
GAPROLE_STARTED :开始状态
GAPROLE_ADVERTISING:正在广播
GAPROLE_CONNECTED:连接上主机之后
GAPROLE_CONNECTED_ADV:连接上主机继续广播
GAPROLE_WAITING_AFTER_TIMEOUT:连接超时
GAPROLE_ERROR:其他错误
5、simpleProfileChangeCB()
函数原型为static void simpleProfileChangeCB( uint8 paramID )
此函数是特征值变化后的回调函数,当特征值被所连接的设备改变之后,会执行此回调函数。我们可以在这里接收特征值的值。比如说
比如说SIMPLEPROFILE_CHAR1改变,就在这个分支下接收。
case SIMPLEPROFILE_CHAR1: SimpleProfile_GetParameter( SIMPLEPROFILE_CHAR1, &newValue ); #if (defined HAL_LCD) && (HAL_LCD == TRUE) HalLcdWriteStringValue( "Char 1:", (uint16)(newValue), 10, HAL_LCD_LINE_3 ); #endif // (defined HAL_LCD) && (HAL_LCD == TRUE) break;
6、bdAddr2Str()
函数原型为char *bdAddr2Str( uint8 *pAddr )
此函数用于将设备MAC地址转换成字符串