0

我正在尝试在 STM32 板上制作 HID。但是我遇到了下一个问题:我不明白我的错误在哪里,我传递了一个指向包含报告函数数据的结构的指针,但是当我尝试编译代码时,我得到下一条消息:“keyboardHID *”类型的参数不兼容使用“uint8_t *”类型的参数,我以与此视频中的人相同的方式编写代码https://www.youtube.com/watch?v=tj1_hsQ5PR0。在他的情况下,这不是一个严重错误并且代码可以编译。

我的结构:

typedef struct
{
    uint8_t MODIFIER;
    uint8_t RESERVED;
    uint8_t KEYCODE1;
    uint8_t KEYCODE2;
    uint8_t KEYCODE3;
    uint8_t KEYCODE4;
    uint8_t KEYCODE5;
    uint8_t KEYCODE6;
} keyboardHID;

keyboardHID keyboardhid = {0,0,0,0,0,0,0,0}; // it should be like this, not differently

修改结构元素并向计算机发送报告的代码:

keyboardhid.MODIFIER = 0x02;  // left Shift
        keyboardhid.KEYCODE1 = 0x04;  // press 'a'
        keyboardhid.KEYCODE2 = 0x05;  // press 'b'
        USBD_HID_SendReport(&hUsbDeviceFS, &keyboardhid, sizeof (keyboardhid));
        HAL_Delay (50);
        
        keyboardhid.MODIFIER = 0x00;  // shift release
        keyboardhid.KEYCODE1 = 0x00;  // release key
        keyboardhid.KEYCODE2 = 0x00;  // release key
        USBD_HID_SendReport(&hUsbDeviceFS, &keyboardhid, sizeof (keyboardhid));
        HAL_Delay (1000);
4

1 回答 1

1

C 只允许隐式指针转换为void*. 类型不兼容,它们的指针也不兼容uint8_tkeyboardHID我认为uint8_t是,unsigned char但 C 标准不需要它。

通常,直接处理内存的函数应该使用void*like memcpy()ormemset()但它看起来USBD_HID_SendReport()不遵循这个约定。

你可以:

  1. 投射&keyboardhiduint8_t*. 这是安全的,因为字符类型的对齐要求最少。此外,字符是严格别名规则的明确例外。

  2. 使用&keyboardhid.MODIFIER. C 标准要求结构的地址与其第一个元素的地址相同。IMO,这是最晦涩难懂的方式。

  3. 使用工会。

union {
  keyboardHID keyboardhid;
  uint8_t bytes[sizeof(keyboardHID)];
} u;

并传递u.bytesUSBD_HID_SendReport().

我会选择选项 1,因为它是最简单和安全的。keyboardhid如果必须将选项 3 强制转换为字符类型以外void*的指针或指向字符类型(即uint32_t*)的指针,则选项 3 将是最好的。

于 2021-04-28T20:09:16.723 回答