Warning: main(/www/www/htdocs/style/globals.php) [function.main]: failed to open stream: No such file or directory in /www/www/docs/6.4.1/neutrino/lib_ref/d/devctl.html on line 1

Warning: main() [function.include]: Failed opening '/www/www/htdocs/style/globals.php' for inclusion (include_path='.:/www/www/common:/www/www/php/lib/php') in /www/www/docs/6.4.1/neutrino/lib_ref/d/devctl.html on line 1

Warning: main(/www/www/htdocs/style/header.php) [function.main]: failed to open stream: No such file or directory in /www/www/docs/6.4.1/neutrino/lib_ref/d/devctl.html on line 8

Warning: main() [function.include]: Failed opening '/www/www/htdocs/style/header.php' for inclusion (include_path='.:/www/www/common:/www/www/php/lib/php') in /www/www/docs/6.4.1/neutrino/lib_ref/d/devctl.html on line 8

devctl()

Control a device

Synopsis:

#include <sys/types.h>
#include <unistd.h>
#include <devctl.h>

int devctl( int filedes,
            int dcmd,
            void * dev_data_ptr,
            size_t n_bytes,
            int * dev_info_ptr );

Arguments:

filedes
A file descriptor that you obtained by opening the device.
dcmd
A device-specific command for the process managing the open device. The set of valid device-control commands, the associated data interpretation, the returned dev_info_ptr values, and the effect of the command on the device all depend on the device driver.
For: See:
General information Device-control commands,” below
Commands for manipulating processes Controlling processes via the /proc filesystem in the Processes chapter of the QNX Neutrino Programmer's Guide
Specific commands <sys/dcmd_*.h> header files
dev_data_ptr
Depending on the command, this argument is one of:
n_bytes
The size of the data to be sent to the driver, or the maximum size of the data to be received from the driver. MsgSend() is used to transfer the data.
dev_info_ptr
NULL, or a pointer to a location that the device to can use to return additional status information instead of just success or failure. The data returned via dev_info_ptr depends on the device driver.

Library:

libc

Use the -l c option to qcc to link against this library. This library is usually included automatically.

Description:

The devctl() function sends the device-specific command dcmd to the process managing the device opened as filedes. For example, you can send commands to specify properties for devices such as keyboards, sound cards or serial ports.

Device-control commands

Use these macros to set up the device-control commands:

__DIOF(class, cmd, data)
Get information from the device.
__DION(class, cmd)
A command with no associated data.
__DIOT(class, cmd, data)
Pass information to the device.
__DIOTF(class, cmd, data)
Pass some information to the device, and get some from it.

The arguments to these macros are:

class
The major category for the command. The device-control commands are divided into the following classes to make organization easier:
cmd
The specific command in the class.
data
The type of data to pass to and/or from the device. The dev_data_ptr argument to devctl() must be a pointer to this type of data, and n_bytes is usually the size of this type of data.

Note: The size of the structure that's passed as the last field to the __DIO* macros must be less than 2^14 == 16K. Anything larger than this interferes with the upper two directional bits.

Resource managers can use the following macros, which are defined in <devctl.h>, when handling commands:

get_device_command(cmd)
Extract the class and the specific device command from cmd (i.e. strip off the data type and the direction).
get_device_direction(cmd)
Get the direction of the command (DEVDIR_TO, DEVDIR_FROM, DEVDIR_TOFROM, or DEVDIR_NONE).

Returns:

EOK
Success.
EAGAIN
The devctl() command couldn't be completed because the device driver was in use by another process, or the driver was unable to carry out the request due to an outstanding command in progress.
EBADF
Invalid open file descriptor, filedes.
EINTR
The devctl() function was interrupted by a signal.
EINVAL
The device driver detected an error in dev_data_ptr or n_bytes.
EIO
The devctl() function couldn't complete because of a hardware error.
ENOSYS
The device doesn't support the dcmd command.
ENOTTY
The dcmd argument isn't a valid command for this device.
EPERM
The process doesn't have sufficient permission to carry out the requested command.

Examples:

Example 1: Setting RTS on a serial port

Here's a quick example of setting and unsetting RTS (Request to Send) on a serial port:

/* For "devctl()" */
#include <devctl.h>
#include <sys/dcmd_chr.h>

/* For "open()" */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* For Errors */
#include <stdlib.h>
#include <stdio.h>

int check_RTS(int fd);

int main(void)
{
    int data = 0, fd, error;

    if((fd = open ("/dev/ser2", O_RDONLY)) == -1)
    {
     fprintf(stderr, "Error with open() on /dev/ser2.  Make sure exists.\n");
     perror (NULL);
     exit(EXIT_FAILURE);
    }

    check_RTS(fd);

    /* Let's turn ON RTS now. */
    data = _CTL_RTS_CHG | _CTL_RTS;

    if (error = devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
    {
    fprintf(stderr, "Error setting RTS: %s\n",
        strerror ( error ));
        exit(EXIT_FAILURE);
    }
    /* RTS should now be ON. */

    check_RTS(fd);

    sleep (2);


    /* Now let's turn RTS OFF. */
    data = _CTL_RTS_CHG | 0;

    if (error = devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL))
    {
        fprintf(stderr, "Error setting RTS: %s\n",
            strerror ( error ));
        exit(EXIT_FAILURE);
    }
    /* RTS should now be OFF. */

    check_RTS(fd);

    close(fd);

    return (1);
}


int check_RTS(int fd)
{
    int data = 0, error;

    /*
     Let's see if RTS is set, tell devctl() we're requesting 
     line status information and devctl() then assigns data 
     the line status information for us. Too easy.
    */
    if (error = devctl (fd, DCMD_CHR_LINESTATUS, &data,
                        sizeof(data), NULL))
    {
       fprintf(stderr, "Error setting RTS: %s\n",
           strerror ( error ));
       exit(EXIT_FAILURE);
    }

    if (data & _LINESTATUS_SER_RTS)

        printf("RTS is SET!\n");

    else

        printf("RTS is NOT set\n");

    return(1);
}

The two main areas of interest are the setting of data and the devctl() call. The data variable is used for both sending and receiving data.

When setting RTS, data is assigned a value that's sent to the device via devctl().

If data equals: RTS is turned:
_CTL_RTS_CHG | _CTL_RTS ON
_CTL_RTS_CHG OFF

When checking to see if RTS is set, we call devctl() with dcmd set to the DCMD_CHR_LINESTATUS macro and data containing any value (zero is clean). The devctl() function returns with data containing the Line Status value. This then can be used to determine what lines are set on that device. In our example, we check against _LINESTATUS_SER_RTS.

To find out what values to use with different DCMD_* commands, look in the appropriate <sys/dcmd_*.h>header file. For example, you'll find macros for the following values under DCMD_CHR_LINESTATUS in <sys/dcmd_chr.h>:

The value that's in the header is a “bitwise &” with the value in data to see if the value is high for that line.

Example 2: Cycling through Caps Lock, Num Lock, and Scroll Lock

In the following example, we open the device /dev/kbd and we start applying changes to the Caps Lock, Scroll Lock, and Num Lock properties.

The key lines in this example are the same as in the last example; they focus around the data variable. This value is just a simple integer value that's passed into the devctl() function. The data variable is assigned its values by simply performing a bitwise OR to the predefined values in the </usr/include/sys/dcmd_chr.h> header. Note the values used in the bitwise OR:

If data equals: Num Lock is turned:
_CONCTL_NUM_CHG | _CONCTL_NUM ON
_CONCTL_NUM_CHG OFF

This also applies for the other either/or values in the <dcmd_chr.h> header.

/* For "devctl()" */
#include <devctl.h>
#include <sys/dcmd_chr.h>

/* For "open()" */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* For Errors */
#include <stdlib.h>
#include <stdio.h>


int main(void)
{
    int data, fd, toggle = 1, error;

    /* Open the device we wish to manipulate. */
    if((fd = open ("/dev/kbd", O_RDONLY)) == -1)
    {
     fprintf(stderr, "Error with open() on /dev/kbd.  Make sure exists.\n");
     perror (NULL);
     exit(EXIT_FAILURE);
    }

    while(1)
    {
    switch(toggle)
    {
        case 1:
        {
          /*
           Turn on Num Lock and make sure that 
           Caps and Scroll lock are turned off.
          */
          data = (_CONCTL_NUM_CHG | _CONCTL_NUM) | _CONCTL_CAPS_CHG |
                 _CONCTL_SCROLL_CHG;
          break;
        }
        case 2:
        {
          /*
           Turn off Num Lock and now turn on Caps Lock 
           (Scroll lock is already off).
          */
          data = _CONCTL_NUM_CHG | (_CONCTL_CAPS_CHG | _CONCTL_CAPS);
          break;
        }
        case 3:
        {
          /*
           Turn off Caps lock and turn on Scroll lock 
           (Num lock is already off).
          */
          data = _CONCTL_CAPS_CHG | (_CONCTL_SCROLL_CHG | _CONCTL_SCROLL);
          toggle = 0;
          break;
        }
    }

    /* Explanation below. */
    if (error = devctl (fd, DCMD_CHR_SERCTL, &data,
                        sizeof(data), NULL))
    {
        fprintf(stderr, "Error setting KBD: %s\n",
            strerror ( error ));
        exit(EXIT_FAILURE);
    }

    sleep(1);
    toggle++;
    }

    return (1);
}

Here's a quick explanation of the above devctl() call:

devctl (fd, DCMD_CHR_SERCTL, &data, sizeof(data), NULL)

The first parameter, fd, is the file descriptor of the device that's being changed. The second parameter is the device class that's being changed. In this case, it's a character device DCMD_CHR, with a “subclass” of _SERCTL. The third parameter is the data variable; this is the ORed value.

Example 3: Duration example

In this code, tcdropline(), which is used to disconnect a communications line, uses devctl() (this is the actual source code, tcdropline() is a standard library function):

#include <termios.h>
#include <devctl.h>
#include <errno.h>
#include <sys/dcmd_chr.h>

int tcdropline(int fd, int duration) {
    int error; 

    duration = ((duration ? duration : 300) << 16) |
      _SERCTL_DTR_CHG | 0;

    if(error = devctl(fd, DCMD_CHR_SERCTL, &duration, sizeof duration, 0) == -1) {
       if(error == ENOSYS) {
          errno = ENOTTY;
       }
       return -1;
    }
    return 0;
}

Classification:

QNX Neutrino

Safety:
Cancellation point Yes
Interrupt handler No
Signal handler Yes
Thread Yes

Caveats:

When devctl() fails, the effect of the failed command depends on the device driver. The corresponding data might be transferred, partially transferred, or not transferred at all.

The devctl() function was originally part of the POSIX 1003.1d draft standard; but it was deprecated in the IEEE Approved Draft 10 standard.

See also:

close(), ioctl(), open(), read(), write()

Controlling processes via the /proc filesystem in the Processes chapter of the QNX Neutrino Programmer's Guide


Warning: main(/www/www/htdocs/style/footer.php) [function.main]: failed to open stream: No such file or directory in /www/www/docs/6.4.1/neutrino/lib_ref/d/devctl.html on line 731

Warning: main() [function.include]: Failed opening '/www/www/htdocs/style/footer.php' for inclusion (include_path='.:/www/www/common:/www/www/php/lib/php') in /www/www/docs/6.4.1/neutrino/lib_ref/d/devctl.html on line 731