问题描述
我正在尝试在 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}; // 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,sizeof (keyboardhid));
HAL_Delay (1000);
解决方法
C 只允许隐式指针转换为 void*
。
类型 uint8_t
和 keyboardHID
不兼容,它们的指针也不兼容。
我假设 uint8_t
是 unsigned char
但 C 标准不需要它。
通常,直接处理内存的函数应该使用 void*
之类的 memcpy()
或 memset()
,但看起来 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 将是最佳选择。