I'm trying to make HID on STM32 board. But i stuck with next problem: I don't understand where my mistake, i passing a pointer to struct which contains data for report function, but when i try to compile code i get next messsage: argument of type "keyboardHID *" is incompatible with parametr of type "uint8_t *" I write code in the same way like man from this video https://www.youtube.com/watch?v=tj1_hsQ5PR0. In his case, this is not a critical error and code compiles.
My struct:
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
Code that modifies structure elements and sends reports to the computer:
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 allows implicit pointer conversions only to
void*
. Typesuint8_t
andkeyboardHID
are not compatible, neither their pointer. I assume thatuint8_t
isunsigned char
but C standard does not require it.Usually, functions that process memory directly should use
void*
likememcpy()
ormemset()
but it looks thatUSBD_HID_SendReport()
is not following this convention.You can:
Cast
&keyboardhid
touint8_t*
. It's safe because character types have the least alignment requirements. Moreover, characters are an explicit exception to strict aliasing rules.Use
&keyboardhid.MODIFIER
. C standard requires the address of the structure to be the same as an address of its first element. IMO, it is the most obscure way.Use an union.
And pass
u.bytes
toUSBD_HID_SendReport()
.I would go for option 1 as it is the simplest and safe. Option 3 will be the best if
keyboardhid
had to be cast to something other thanvoid*
or a pointer to character type (i.e.uint32_t*
).