The architecture of the ChorusOS 4.0.1 Simulator for the Solaris Operating Environment (SPARC Platform Edition) is similar to ChorusOS 4.0.1 running on a physical target, except that direct access to hardware is not possible. Hardware can only be accessed through UNIX APIs based on UNIX file descriptors.
A typical example of a device driver would be one to emulate serial communication by using the read() and write() UNIX functions.
The success or failure of I/O operations are not signalled by interrupts as they are on a conventional target, but by a single UNIX signal, SIGIO
. Instead of attaching an interrupt, drivers attach a file descriptor to the interrupt handler.
Here is the procedure for writing a device driver using file descriptors for I/O access:
Retrieve the structure containing the UNIX function addresses.
Attach a file descriptor to the interrupt handler by calling the intr_attach() function.
Handle the interrupts by calling the appropriate UNIX functions.
Please refer to the ChorusOS 4.0 Device Driver Framework Guide for details on writing a device driver.
The following sections follow the same format as "Writing Bus Drivers" in ChorusOS 4.0 Device Driver Framework Guide. Only the differences are described.
In addition to including the header files for the DKI and DDI APIs involved in your device driver's implementation, you must also include the appropriate header file to access UNIX function calls. See "Retrieving UNIX Function Addresses" for more details.
The simulator BSP is fully compliant with the standard BSP.
The simulator BSP is fully compliant with the standard BSP.
There are two differences that you need to be aware of when writing registry functions for your device driver.
When accessing the device using UNIX function calls, you must perform these additional tasks:
When attaching to the interrupt handler, which processes the SIGIO
signal, you must perform these additional tasks:
In the init() function, the UNIX function structure pointer must be retrieved from the device tree (see "Retrieving UNIX Function Addresses").
The specific part of the init() function of the UNIX function structure pointer is retrieved from the device tree as follows:
device->fd = unixFct->open("/dev/tty0", UNIX_O_RDWR, 0); if (device->fd == -1) { DKI_ERR(("%s: /dev/tty0 open failed (%d)\n", path, unixFct->geterrno())); return; } /* Open SIGIO Parent Class */ res = sigioOps->open((BusId)busId, myNode, eventHandler, NULL, device, &device->busDevId); if (res != K_OK) { DKI_ERR(("%s: parent bus open() failed (%d)\n", path, res)); return; } /* Connect Interrupt Handler based on file descriptor */ res = sigioOps->intr_attach(device->busDevId, (void *)device->fd, (BusIntrHandler)intrHandler, device, &device->busIntrOps, &device->busIntrId); if (res != K_OK) { DKI_ERR(("%s: intr_attach failed (%d)\n", path, res)); return; }
In the init() function, a device must be opened by calling the open() UNIX function.
The interrupt number parameter is replaced by the file descriptor when calling the intr_attach() function.
The simulator BSP is fully compliant with the standard BSP. However, the shutdown related events, specified by the common bus API, are not implemented:
SYS_SHUTDOWN
DEV_SHUTDOWN
DEV_REMOVAL