CH58X/CH57X/V208 Observer(观察者)例程讨论讲解
阅读原文时间:2023年07月08日阅读:2

使用的是沁恒的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)转载。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章