首页 > 其他分享 >CH58X/CH57X/V208 Observer(观察者)例程讨论讲解

CH58X/CH57X/V208 Observer(观察者)例程讨论讲解

时间:2022-11-11 15:25:41浏览次数:88  
标签:CH57X tmos Observer SCAN 例程 uint8 pEvent DEFAULT DISCOVERY

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

标签:CH57X,tmos,Observer,SCAN,例程,uint8,pEvent,DEFAULT,DISCOVERY
From: https://www.cnblogs.com/frontier/p/16860673.html

相关文章

  • 【Grpc(一)】Java 何如理解StreamObserver?
    刚开始接触Grpc时,桩代码里有许多StreamObserver类型,不太清楚是怎么用的,这里做一个记录。首先看下StreamObserver接口定义:publicinterfaceStreamObserver<V>{voidon......
  • Vue 数组中出现__ob__: Observer无法取值
    问题说明在开发项目中经常要从数据库中拿到数组然后复制给新的数组使用,但是会发现有时候会发现带有 __ob__:Observer 数组后缀的就是没有办法取到值,更可怕的是 consol......
  • 用于现代JavaScript的Observer API
    英文| https://dev.to/codyjasonbennett作者|CodyBennettObserverAPI(观察者API)释放了Web隐藏的超能力,以创建真正的响应式体验,从懒加载关键内容到非侵入式性能监控。在......
  • CH573F蓝牙从机(peripheral)例程讲解(服务修改篇)
    修改服务需要对蓝牙比较熟悉的工程师去完成,否则在例程功能满足自己需求时,不建议修改,很容易改错,下面就简单介绍下如何在别的char添加一个nofify属性。step1:给SimpleProfi......
  • mega板和openmv通信例程
    mega板和openmv通信例程openmvimporttimefrompybimportUARTuart=UART(3,9600)#注意波特率while(True):uart.write("123"+"\n")time.sleep_ms(......
  • CH58X/CH57X/V208的Broadcaster(广播者)例程讲解
    在对ble进行应用的时候,每个用户的需求可能不尽相同。这里着重介绍从机Broadcaster例程,只广播不连接。使用该例程时可以在手机使用APP上对Broadcaster进行调试。安卓端在......
  • js 对DOM观察大小改变的处理通知方法。ResizeObserver的应用。
    环境代码示例使用了VUE3的setup的语法糖。代码//这里使用弱引用//key是DOM实例//value是溢出的结果,true标识溢出,false标识没有溢出。constoverflowResultMap=......
  • 编译gRPC相关示例程序,undefined reference to `deflateInit2_'等相关错误解决
    编译gRPC相关示例程序时,出现如下链接错误:/home/suph/.local/lib/libgrpc.a(message_compress.cc.o):Infunction`zlib_compress(grpc_slice_buffer*,grpc_slice_buffer*......
  • 用IntersectionObserver来处理已读未读
    *参考地址:IntersectionObserver-WebAPI接口参考|MDN(mozilla.org)一、IntersectionObserver的使用场景主要用来监听目标元素和指定的根元素之间,在滚动界面的时......
  • CH573/579/582 ADC例程介绍
    在adc的例程中共有六种AD测量,1、温度测量,2、单通道测量,3、DMA单通道测量,4、差分通道测量,5、触摸按键测量,6、中断方式单通道测量,接下来我们逐一描述。一、温度测量首先调......