我正在尝试在STM32板上制作HID。但我遇到了下一个问题:我不明白我的错误在哪里,我传递了一个指向结构的指针,该结构包含报表函数的数据,但当我试图编译代码时,我得到了下一条消息:类型为"的参数;键盘HID*";与类型为"的参数不兼容;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);
C只允许隐式指针转换为void*
。类型uint8_t
和keyboardHID
不兼容,它们的指针也不兼容。我假设uint8_t
是unsigned char
,但C标准不要求它
通常,直接处理内存的函数应该像memcpy()
或memset()
一样使用void*
,但看起来USBD_HID_SendReport()
没有遵循这个约定。
您可以:
-
铸造
&keyboardhid
至uint8_t*
。这是安全的,因为字符类型的对齐要求最低。此外,字符是严格别名规则的一个显式例外。 -
使用
&keyboardhid.MODIFIER
。C标准要求结构的地址与其第一个元素的地址相同。IMO,这是最模糊的方式。 -
使用并集。
union {
keyboardHID keyboardhid;
uint8_t bytes[sizeof(keyboardHID)];
} u;
并将u.bytes
传递到USBD_HID_SendReport()
。
我会选择选项1,因为它是最简单和安全的。如果必须将keyboardhid
强制转换为void*
以外的内容或指向字符类型的指针(即uint32_t*
(,则选项3将是最好的。