Search code examples
pointersembeddedvoiduartblackfin

Return value of (void*) 57600 in C


I am reading the source code of a UART peripheral and there is a function as below:

eResult = adi_stdio_ControlDevice (hSTDIOUART,
    ADI_STDIO_COMMAND_SET_UART_BAUD_RATE, (void *)57600);

This function is used to connect UART and number 57600 is the baudrate. What I do not understand is the meaning of (void*)57600.

I think this maybe a pointer to const and the return value of (void*)57600 is 57600. When we use (void*)57600, does it mean we are creating a pointer that points to the 57600 value?

And why we must use (void*)57600?


Solution

  • Not quite. The "return value" (quoted because it's not actually being returned from a function, instead it's the result of a cast) of (void *)57600 is simply the value 57600 being treated as (or, in other words, cast to) a void pointer.

    And, while you are actually converting 57600 to a void pointer, it's almost certainly not being used as a pointer. More likely is that the prototype for adi_stdio_ControlDevice has a generic argument (one that can be used for many things).

    Device control functions are particularly apt to do that since they are meant to be generic across a large variety of devices, so you may have to give a wide variety of types to the calls.

    You'll probably find that, for the command to set the baud rate, it simply gets cast back to an integral value at the other end before being used, something like:

    static int localSpeed;
    static char *localString;
    static double localPi;
    static struct rational { int numerator; int denominator } localStruct;
    
    bool adi_stdio_ControlDevice (HANDLE hndl, COMMAND cmd, void *generic) {
        switch (cmd) {
            case ADI_STDIO_COMMAND_SET_UART_BAUD_RATE: {
                localSpeed = (int)generic;
                break;
            }
            case ADI_COMMAND_WITH_STRING_ARG: {
                if (localString) free(localString);
                localString = strdup((char*)generic);
                break;
            }
            case ADI_COMMAND_WITH_DOUBLE_PTR_ARG: {
                localPi = *((double*)generic));
                break;
            }
            case ADI_COMMAND_WITH_STRUCT_PTR: {
                memcpy(localStruct, generic, sizeof(localStruct));
                break;
            }
        }
    }
    

    Other commands (such as the fake ones I've added) would be able to use the generic argument in a variety of ways, as integers or other pointer types for example.


    This is actually supported by the documentation (VisualDSP++ 5.0 Device Drivers and System Services Manual for Blackfin® Processors) for that call, which states:

     ADI_STDIO_RESULT adi_stdio_ControlDevice (
       ADI_STDIO_DEVICE_HANDLE hStdioDevice,
       uint32_t nCommandID,
       void *const pValue
     );
     : : :
    pValue: Argument required for executing the command. Depending upon the command, different types of arguments are required.