nrf52832添加hid服务

由于有添加hid touch服务给ios和Android手机的需求,了解了一下关于hid描述符的东西,添加hid服务可参考官方demo ble/keyboard。sdk16的hid服务跟sdk12的hid服务有一点区别,就是要算好最大使用的内存池。添加下面宏代码可以为一个hid服务添加一个内存池,这里以demo的键盘hid服务为例子:

BLE_HIDS_DEF(m_hids,                                                /**< Structure used to identify the HID service. */
             NRF_SDH_BLE_TOTAL_LINK_COUNT,
             INPUT_REPORT_KEYS_MAX_LEN,
             OUTPUT_REPORT_MAX_LEN,
             FEATURE_REPORT_MAX_LEN);

根据代码命名可以看出(nordic的sdk代码写的真的好,命名也是命的好基本什么接口看函数名就能猜到意思):m_hids是个初始化hid服务用的对象,NRF_SDH_BLE_TOTAL_LINK_COUNT是连接的个数这里值为1,后面3个参数分别是hid服务的input大小值为8、output大小值为1,feature大小值为2(都是byte),这三个大小都是根据hid的描述符来的,input是指主机例如手机的输入,也就是设备的输出,output指的是手机的输出,也就是设备的输入。下面是demo的keyboard描述符:

 static uint8_t                     report_map_data[] =
    {
        0x05, 0x01,       // Usage Page (Generic Desktop)
        0x09, 0x06,       // Usage (Keyboard)
        0xA1, 0x01,       // Collection (Application)
        0x05, 0x07,       // Usage Page (Key Codes)
        0x19, 0xe0,       // Usage Minimum (224)
        0x29, 0xe7,       // Usage Maximum (231)
        0x15, 0x00,       // Logical Minimum (0)
        0x25, 0x01,       // Logical Maximum (1)
        0x75, 0x01,       // Report Size (1)
        0x95, 0x08,       // Report Count (8) 输入1byte
        0x81, 0x02,       // Input (Data, Variable, Absolute)

        0x95, 0x01,       // Report Count (1)
        0x75, 0x08,       // Report Size (8) 输入1byte
        0x81, 0x01,       // Input (Constant) reserved byte(1)

        0x95, 0x05,       // Report Count (5)
        0x75, 0x01,       // Report Size (1)  输出5bit
        0x05, 0x08,       // Usage Page (Page# for LEDs)
        0x19, 0x01,       // Usage Minimum (1)
        0x29, 0x05,       // Usage Maximum (5) 
        0x91, 0x02,       // Output (Data, Variable, Absolute), Led report
        0x95, 0x01,       // Report Count (1)
        0x75, 0x03,       // Report Size (3) 输出3bit
        0x91, 0x01,       // Output (Data, Variable, Absolute), Led report padding

        0x95, 0x06,       // Report Count (6)
        0x75, 0x08,       // Report Size (8) 输入6byte
        0x15, 0x00,       // Logical Minimum (0)
        0x25, 0x65,       // Logical Maximum (101)
        0x05, 0x07,       // Usage Page (Key codes)
        0x19, 0x00,       // Usage Minimum (0)
        0x29, 0x65,       // Usage Maximum (101)
        0x81, 0x00,       // Input (Data, Array) Key array(6 bytes)

        0x09, 0x05,       // Usage (Vendor Defined)
        0x15, 0x00,       // Logical Minimum (0)
        0x26, 0xFF, 0x00, // Logical Maximum (255)
        0x75, 0x08,       // Report Size (8 bit)
        0x95, 0x02,       // Report Count (2) 特性 2byte
        0xB1, 0x02,       // Feature (Data, Variable, Absolute)

        0xC0              // End Collection (Application)
    };

这里不仔细讲hid描述符怎么看,感兴趣的可以查看hid官方文档。之前由于我的touch描述符上用了12个byte的input,可是我上面的宏分配的input是8,代码量少,全局变量少的时候没出啥问题,在我移植应用代码到这个框架一直的多的时候就经常出现报错,要么是hid发送报错,要么广播报错,要么配对报错,,由于改代码,调试的过程中现象不一样,导致我前面定位不到问题,经过调试发现这些错误都是一些const声明的东西在程序运行过程中被清0了,我开始觉得是内存泄漏引起的,打开keil编译后的map文件发现这几个出问题的变量的确在ram地址上挨的比较近,于是我就抓住一个报错看,先看hid发送哪里,逐步打调试信息出来,发现手机跟设备连接的时候ble_hid.c里connect事件里会有个根据m_hids这个全局变量的input长度对宏定义BLE_HIDS_DEF的内存池进行memset,由于内存池分配的空间小了,导致memset的时候越界把后面的内容给清0了才导致了这个跳来跳去的问题,然后我宏分配的内存池根据描述符的所需要的大小来定义内存池大小就解决了这个问题,这个问题本来很简单可是却后面让我加了2天班。哎使用sdk的接口的时候一定留意,细心不能放过任何不理解的东西。

如果你遇到了跟我一样的问题就给我点个赞呗^ ^

你可能感兴趣的:(nordic)