使用的是沁恆的CH582M的Observer例程與官方的demo板。
本例程的功能是主機掃描到從機的MAC地址並列印出來。
先對宏定義進行理解討論。
最大響應掃描數為8,在串列埠偵錯助手那裡可以看到列印出的8個MAC地址。
這裡的白名單是預設關閉的。
接下來對初始化進行討論。
void Observer_Init() { ObserverTaskId = TMOS_ProcessEventRegister(Observer_ProcessEvent); // Setup Observer Profile { uint8_t scanRes = DEFAULT_MAX_SCAN_RES; GAPRole_SetParameter(GAPROLE_MAX_SCAN_RES, sizeof(uint8_t), &scanRes); } // Setup GAP GAP_SetParamValue(TGAP_DISC_SCAN, DEFAULT_SCAN_DURATION); // Setup a delayed profile startup tmos_set_event(ObserverTaskId, START_DEVICE_EVT); }
這裡是初始化期間呼叫的功能,這裡的詳解可以參照CH58X/CH57X/V208的Broadcaster(廣播者)例程講解 - 小舟從此逝_1 - 部落格園 (cnblogs.com)這篇文章。
接下來是對任務的管理排程,這裡用的是TMOS事件管理。關於TMOS的理解具體可以參照WCH TMOS用法詳解 - debugdabiaoge - 部落格園 (cnblogs.com)
再次之前我們要了解一下TMOS任務的排程,在這裡TMOS任務可以定義16個其中有15個自定義,1個系統任務。
廣播者的例程裡共寫了兩個任務,首先看到第一個任務
if(events & SYS_EVENT_MSG) { uint8_t *pMsg; if((pMsg = tmos_msg_receive(ObserverTaskId)) != NULL) { Observer_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg); // Release the TMOS message tmos_msg_deallocate(pMsg); } // return unprocessed events return (events ^ SYS_EVENT_MSG); }
這個任務就是唯一的一個系統任務,這裡是在各層協定棧之間傳遞資料,這這裡是接收訊息。同時還有這幾個函數用於內部資料的傳遞。這部分可以參考CH579/CH57x 的TMOS系統使用 - iot-fan - 部落格園 (cnblogs.com)對這部分進行更詳盡的瞭解。
extern bStatus_t tmos_msg_send( tmosTaskID taskID, uint8_t *msg_ptr ); extern uint8_t *tmos_msg_receive( tmosTaskID taskID ); extern uint8_t *tmos_msg_allocate( uint16_t len ); extern bStatus_t tmos_msg_deallocate( uint8_t *msg_ptr );
第二個任務則是使用者自定義事件,本例程中只使用了這一個自定義事件;
if(events & START_DEVICE_EVT) { // Start the Device GAPRole_ObserverStartDevice((gapRoleObserverCB_t *)&ObserverRoleCB); return (events ^ START_DEVICE_EVT); } // Discard unknown events return 0; }
GAPRole_ObserverStartDevice((gapRoleObserverCB_t *)&ObserverRoleCB);此函數是觀察者角色啟動裝置,在系統啟動期間呼叫一次。
下面討論的是對自定義任務的回撥函數。
static void ObserverEventCB(gapRoleEvent_t *pEvent) { switch(pEvent->gap.opcode) {
//事件初始化完成之後傳送
case GAP_DEVICE_INIT_DONE_EVENT:
{
GAPRole_ObserverStartDiscovery(DEFAULT_DISCOVERY_MODE,
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST);
PRINT("Discovering...\n"); } break;
//將裝置新增到裝置發現結果列表 case GAP_DEVICE_INFO_EVENT: { ObserverAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType); } break; //裝置發現完成將裝置羅列出來 case GAP_DEVICE_DISCOVERY_EVENT: { PRINT("Discovery over...\n"); // Display discovery results if(pEvent->discCmpl.numDevs > 0) { int i, j; // Increment index of current result (with wraparound) for(j = 0; j < pEvent->discCmpl.numDevs; j++) { PRINT("Device %d : ", j); for(i = 0; i < 6; i++) { PRINT("%x ", pEvent->discCmpl.pDevList[j].addr[i]); } PRINT("\n"); } } GAPRole_ObserverStartDiscovery(DEFAULT_DISCOVERY_MODE, DEFAULT_DISCOVERY_ACTIVE_SCAN, DEFAULT_DISCOVERY_WHITE_LIST); PRINT("Discovering...\n "); } break; default: break; } }
上述程式中的
GAPRole_ObserverStartDiscovery(DEFAULT_DISCOVERY_MODE,
DEFAULT_DISCOVERY_ACTIVE_SCAN,
DEFAULT_DISCOVERY_WHITE_LIST); 我們可以看到可以看到本函數的定義
extern bStatus_t GAPRole_ObserverStartDiscovery( uint8_t mode, uint8_t activeScan, uint8_t whiteList );
uint8_t mode:發現模式 uint8_t activeScan:如果為TRUE執行主動掃描 uint8_t whiteList:僅掃描白名單中的裝置
這三個引數在本例程的定義分別是:
#define DEFAULT_DISCOVERY_MODE DEVDISC_MODE_ALL
#define DEFAULT_DISCOVERY_ACTIVE_SCAN TRUE
#define DEFAULT_DISCOVERY_WHITE_LIST FALSE
ObserverAddDeviceInfo(pEvent->deviceInfo.addr, pEvent->deviceInfo.addrType);呼叫的函數為
static void ObserverAddDeviceInfo(uint8_t *pAddr, uint8_t addrType) { uint8_t i; // If result count not at max if(ObserverScanRes < DEFAULT_MAX_SCAN_RES) //如果未達到最大掃描數量,掃描個數由自己設定(大約可掃描的數量是40左右) { // Check if device is already in scan results for(i = 0; i < ObserverScanRes; i++) { if(tmos_memcmp(pAddr, ObserverDevList[i].addr, B_ADDR_LEN)) { return; } } // Add addr to scan result list tmos_memcpy(ObserverDevList[ObserverScanRes].addr, pAddr, B_ADDR_LEN); ObserverDevList[ObserverScanRes].addrType = addrType; // Increment scan result count ObserverScanRes++; } }
這只是最基礎的討論,如有問題請指正!
如轉載請標明出處!文章可能被無良網站搬運。某些網站拿著別人的文章寫著「我的程式設計學習分享」。
禁止soolco-部落格、易學程式設計網 - 易學程式設計網 (yixuebiancheng.com)轉載。