CH58X/CH57X/V208 Observer(觀察者)例程討論講解

2022-11-11 18:03:15

使用的是沁恆的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)轉載。