I was wondering if there was some reason why FreeRTOS’s handles aren’t type safe? Right now, every handle (TaskHandle_t, QueueHandle_t, EventGroupHandle_t, etc.) is just void*. That means that any pointer at all can be passed where such a handle is needed—you can pass a QueueHandle_t where a TaskHandle_t is needed, for example, or perhaps easier to do, you can pass &handle where handle is needed, because void** is implicitly convertible to void*.
This could all be avoided if the handles were typedefs of “struct <something> *”, where “struct <something>” is perhaps even the real struct behind the handles, but the struct itself is left incomplete (not fully defined) in the header files to prevent applications from poking at hidden data—thus the handles remain opaque, as desired. Then the compiler would give errors for conversion between incompatible pointer types.