BLE-Stack 工程是如何作为App中TI-RTOS一个任务运行的
直接走读App代码,以下代码片段创建了协议栈任务。
//C:\ti\simplelink_cc2640r2_sdk_1_35_00_33\source\ti\ble5stack\icall\src\icall.c ICall_createRemoteTasks Line 519
void ICall_createRemoteTasks(void {
size_t i;
UInt keytask;
/* Cheap locking mechanism to lock tasks
* which may attempt to access the service call dispatcher
* till all services are registered.
*/
keytask = Task_disable();
for (i = 0; i < ICALL_REMOTE_THREAD_COUNT; i++) {
Task_Params params;
Task_Handle task;
ICall_CSState key;
//C:\ti\simplelink_cc2640r2_sdk_1_35_00_33\source\ti\ble5stack\icall\src\icall.c ICall_sendServiceMsg Line 2419
return (ICall_send(src, dstentity, format, msg));
最终ICall_send是直接将消息放入了目的Icall消息实体的消息队列中,并且触发事件,通知该任务唤醒解析处理消息。
//C:\ti\simplelink_cc2640r2_sdk_1_35_00_33\source\ti\ble5stack\icall\src\icall.c Icall_Send Line 2661
ICall_msgEnqueue(&ICall_entities[dest].task->queue, msg);
ICALL_SYNC_HANDLE_POST(ICall_entities[dest].task->syncHandle);
// Waits for an event to be posted associated with the calling thread.
// Note that an event associated with a thread is posted when a
// message is queued to the message receive queue of the thread
events = Event_pend(syncEvent, Event_Id_NONE, SBP_ALL_EVENTS,
ICALL_TIMEOUT_FOREVER);
当事件发生并被处理后,任务又等待事件标志并且保保持阻塞状态,直到有另一个事件发生。
// If TI-RTOS queue is not empty, process app message.
if (events & SBP_QUEUE_EVT)
{
while (!Queue_empty(appMsgQueue))
{
sbpEvt_t *pMsg = (sbpEvt_t *)Util_dequeueMsg(appMsgQueue);
if (pMsg)
{
// Process message.
SimpleBLEPeripheral_processAppMsg(pMsg);
// Free the space from the message.
ICall_free(pMsg);
}
}
}
// Application specific event ID for HCI Connection Event End Events
#define SBP_HCI_CONN_EVT_END_EVT 0x0001
static uint8_t SimpleBLEPeripheral_processGATTMsg(gattMsgEvent_t *pMsg)
{
// See if GATT server was unable to transmit an ATT response
if (pMsg->hdr.status == blePending)
{
// No HCI buffer was available. Let's try to retransmit the response
// on the next connection event.
if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity,
SBP_HCI_CONN_EVT_END_EVT) == SUCCESS)
{
// First free any pending response
SimpleBLEPeripheral_freeAttRsp(FAILURE);
// Hold on to the response message for retransmission
pAttRsp = pMsg;
// Application main loop
for (;;)
{
uint32_t events;
// Waits for an event to be posted associated with the calling thread.
// Note that an event associated with a thread is posted when a
// message is queued to the message receive queue of the thread
events = Event_pend(syncEvent, Event_Id_NONE, SBP_ALL_EVENTS,
ICALL_TIMEOUT_FOREVER);