Você está na página 1de 23

API IO Library

Datum

31.03.2004

Version

2.0.3

Seite 1/23

API IO Library
1 History
Version

Date

Author

Comments

1.5

25.11.2002

CS

Created from IO Library UsersGuide

Duda

Proposal for IO Library 2.0

2.0 (Draft) 16.12.2002

new channel inface and types/constants added

error hook added

feedback from DC

06.02.2003

CS

Changes of HIS discussion (DC, VW), cleanup

15.02.2003

CS

Remarks of 12feb03 HIS meeting

25.02.2003

CS

Cleanup (wording)

27.02.2003

Kraneis

Types IO_ValueType and IO_ChannelType instead of IO_U16

2.0

27.02.2003

CS

Cleanup (wording)

2.0.1

02.09.2003

CS

Minor corrections and clarifications


Allow getting version information for IOLibrary itself

2.0.2

15.12.2003

Spohr

Minor corrections and clarifications. Replace straight C types with


typedefs because of MISRA

2.0.3

31.03.2004

Spohr

Added comment about parallel service requests to IO drivers. Moved


error codes IO_E_INVALID_SIZE and IO_E_INVALID_POSITION
from IO driver document to IO library document. Clarified that size '0'
is invalid size. Cleanup.

Page 2/23

API IO Library
2 Contents
1

History..........................................................................................................................................................2

Contents.......................................................................................................................................................3

Introduction .................................................................................................................................................5

IO library API interface ...............................................................................................................................7


4.1

Constants ..........................................................................................................................................7

4.2

Types..................................................................................................................................................7

4.3

Synchronous API ..............................................................................................................................8

4.4

4.3.1

Interfaces available for all device types..................................................................................8

4.3.2

Interfaces for standard devices ..............................................................................................8

4.3.3

Interfaces for random devices ................................................................................................9

4.3.4

Interfaces for channel devices................................................................................................9

Asynchronous API..........................................................................................................................10
4.4.1

Interfaces available for all device types................................................................................10

4.4.2

Interfaces for standard devices ............................................................................................11

4.4.3

Interfaces for random devices ..............................................................................................11

4.4.4

Interfaces for channel devices..............................................................................................11

4.5

General API supported by all sorts of drivers .............................................................................12

4.6

Error Hook .......................................................................................................................................12

Driver implementation ..............................................................................................................................14


5.1

Overview ..........................................................................................................................................14

5.2

Driver API.........................................................................................................................................14
5.2.1

Synchronous driver interface................................................................................................14

5.2.2

Asynchronous driver interface..............................................................................................15

5.3

Error hook........................................................................................................................................18

5.4

Driver configuration........................................................................................................................19

5.5

Linked drivers .................................................................................................................................20

I/O Library Configurator ...........................................................................................................................21


6.1

6.2

Code generation..............................................................................................................................21
6.1.1

Code generation for synchronous drivers ............................................................................21

6.1.2

Code generation for asynchronous drivers ..........................................................................21

6.1.3

Code generation for linked drivers .......................................................................................21

DIL Format .......................................................................................................................................21


6.2.1

Overview...............................................................................................................................21

6.2.2

DIL format specification for driver files .................................................................................21

6.2.3

DIL format specification for saved configurations ................................................................23


Page 3/23

API IO Library

Page 4/23

API IO Library
3 Introduction
This document describes an interface for drivers in deeply embedded systems. Typically these systems only
have a few resources and overhead has to be omitted. Nevertheless a standardized interface between the
application and hardware drivers is useful e.g. to force modularisation and portability of application software. The
tools and concepts described herein provide one way of implementing such an interface. The interface is referred
to as the IO library.
The main goal is to offer a standardized interface to access low-level drivers, which may be accessed in the
following two ways: Either in a synchronous way where the caller blocks until the service is finished or in an
asynchronous way where a caller is informed from the driver once the work has been done. A driver which uses
the asynchronous model can also be used in conjunction with a buffer. This buffer contains the latest work for the
driver and the buffer services provides new work for the driver once it is ready again. The handling of the buffer is
done by the IO library and is independent of a specific asynchronous driver. The described interface supports the
synchronous and asynchronous models as well as buffered asynchronous methods. Since the IO library itself
1
also needs resources and some management, it uses an OSEK/VDX operating system.
The following picture shows the different interfaces of the IO library which are also described in this document.

application
synchronous

API

asynchronous

notification

asynchronous (with buffering)

IO library
asynchronous

asynchronous

asynchronous

synchronous

synchronous

synchronous

driver 1

driver 2

.....

driver N

Since hardware is sometimes very different, the IO library supports also different types of drivers. Depending on
the type of the driver specific services are available. Driver types can be either Standard, Random or Channel
drivers. Each of these driver types has its own set of services. (There are also services which are general
available for each driver. These are called common services.)
Drivers need not support the synchroneous interface and the asynchroneous interface in parallel. Also, drivers
need only be able to cope with one service at a time. Either the caller has to to make sure that only one service
request is issued at a time, or asynchroneous mode with sufficient buffering has to be used. The only exception
to this rule is the service to get the software version (IO_GetVersionOfDriver), which may always be called. The
IO driver specification can define more driver specific exceptions to this rule, for example a call to preliminary
terminate a running service request.
The IO library and the drivers have to be configured by the user before they can be used. With this approach the
drivers and the IO library can be tailored to the needs of the application and can be implemented in an optimised
1

OSEK/VDX is a trademark of Siemens


Page 5/23

API IO Library
way. Typically the configuration information has to be saved in order to reuse it later. The language used for this
purpose is called DIL (device implementation language). DIL is used for saving user configurations and to specify
driver information by people writing drivers for the IO library.

Page 6/23

API IO Library
4 IO library API interface
This chapter describes the API of the IO library which can be used by the application programmer. The API is
provided as a C language interface.

4.1

Constants

For the IO_ErrorType the following constants are defined:


IO_E_OK = 0
IO_E_BUSY = 1
IO_E_UNKNOWN_MODE = 2
IO_E_INVALID_SIZE = 20
IO_E_INVALID_POSITION = 21
For the IO_DeviceStateType the following constants are defined:
IO_STATE_IDLE
IO_STATE_ACTIVE
For the IO_FunctionNrType the following constants are defined:
(services of the common API)
IO_FUNC_Init
IO_FUNC_DeInit
IO_FUNC_Ioctl
(services of the standard API)
IO_FUNC_Read
IO_FUNC_Write
(services of the random API)
IO_FUNC_RRead
IO_FUNC_RWrite
IO_FUNC_RErase
(services of the channel API)
IO_FUNC_Get
IO_FUNC_Set

4.2

Types

The following types are defined by the IO library:


IO_ErrorType

(Recommended type: 16 bit unsigned value. Numbers from 0 to 15 are


reserved for the IOLibrary itself, numbers between 16 and 63 are defined
in the HIS IO Driver document. Error codes from 64 to 127 are for driver
specific error codes not defined in the HIS IO Driver document and
numbers starting from 128 are reserved for future use.)

IO_SymbolicName

(This is not a real type, just a name (e.g. a #define))

IO_DeviceType

(Type for driver numbers, recommended: 16 bit unsigned value)


Page 7/23

API IO Library

4.3

IO_FunctionNrType

(Type for function numbers, recommended: 16 bit unsigned value)

IO_DeviceStateType

(Recommended type: 16 bit unsigned value)

IO_SizeType

(Type to hold info about the size of an object)

IO_MemPtrType

(Type to hold the address to a memory location, recommended: pointer to


unsigned character)

IO_PositionType

(Type to a specific position within the managed device)

IO_ValueType

(Type for values of channel devices, fix type: 16 bit unsigned value)

IO_ChannelType

(Type to specify a channel from a channel devices, fix type: 16 bit


unsigned value)

IO_ModeType

(Type to specify the requested mode to the control functionality,


recommended: standard integer)

IO_U32

(32 bit unsigned value)

Synchronous API

The following services are provided by the IO library to access a synchronous driver. In synchronous mode the
API call returns after the work is done. This means that the call can block for some time (e.g. while programming
a flash EEPROM).
4.3.1

Interfaces available for all device types


IO_ErrorType IO_InitSync(IO_SymbolicName device, void * address)
This service initialises the driver device. The argument address may contain more parameters for the
initialisation of the driver or should be set to NULL if not needed. The service returns IO_E_OK or, if there
was an error, a driver specific error code.
IO_ErrorType IO_DeInitSync(IO_SymbolicName device, void * address)
This service is the counterpart of the above function and deinitialises the driver device. The argument
address may contain more parameters for the deinitialisation (e.g. save state settings, etc.) or should be
set to NULL if not needed. The service returns IO_E_OK or a driver specific error code.
IO_ErrorType IO_IoctlSync(IO_SymbolicName device, IO_ModeType mode, void *
address)
This service implements the control functionality of the driver device. The argument mode is used as a
command e.g. setting internal parameters or modes of the device. The argument address can be used
to supply additional arguments to the functions which may be needed by the command. The service
returns either IO_E_OK or a driver specific code.

4.3.2

Interfaces for standard devices


IO_ErrorType IO_ReadSync(IO_SymbolicName device, IO_MemPtrType address,
IO_SizeType size)
Page 8/23

API IO Library
This service implements the read functionality of the driver device. The argument address is a pointer to
the destination of the data to be read. After size units has been read, the service returns. It returns either
IO_E_OK, IO_E_INVALID_SIZE (size is '0') or a driver specific code.
IO_ErrorType IO_WriteSync(IO_SymbolicName device, const IO_MemPtrType
address, IO_SizeType size)
This service implements the write functionality of the driver device. The argument address is a pointer to
the destination of the data to be written. After writing size units, the service returns. It returns either
IO_E_OK, IO_E_INVALID_SIZE (size is '0') or a driver specific code.

4.3.3

Interfaces for random devices


IO_ErrorType IO_RReadSync(IO_SymbolicName device, IO_MemPtrType address,
IO_SizeType size, IO_PositionType location)
This service implements the random read functionality of the driver device. The argument address is a
pointer to the destination of the data to be read. The data is read from offset location. After size units has
been read, the service returns. It returns either IO_E_OK, IO_E_INVALID_POSITION (location is not
accessible), IO_E_INVALID_SIZE (size is '0' or too large) or a driver specific code.
IO_ErrorType IO_RWriteSync(IO_SymbolicName device, const IO_MemPtrType
address, IO_SizeType size, IO_PositionType location)
This service implements the random write functionality of the driver device. The argument address is a
pointer to the source of the data to be written. The data is written to offset location. After writing size
units, the service returns. It returns either IO_E_OK, IO_E_INVALID_POSITION (location is not
accessible), IO_E_INVALID_SIZE (size is '0' or too large) or a driver specific code.
IO_ErrorType IO_REraseSync(IO_SymbolicName device, IO_SizeType size,
IO_PositionType location)
This service implements the random erase functionality of the driver device. After erasing size units, the
service returns. It returns either IO_E_OK, IO_E_INVALID_POSITION (location is not accessible),
IO_E_INVALID_SIZE (size is '0' or too large) or a driver specific code.

4.3.4

Interfaces for channel devices


IO_ValueType IO_GetSync(IO_SymbolicName device, IO_ChannelType channel)
This service implements the channel based get functionality of the driver device. The argument channel
identifies the channel of the driver. The function returns the value of that specific channel. Errors are
reported using the error hook.
void IO_SetSync(IO_SymbolicName device, IO_ChannelType channel, IO_ValueType
value)
This service implements the channel based set functionality of the driver device. The argument channel
identifies the channel where to set the new value. Errors will be reported using the error hook.

Page 9/23

API IO Library
4.4

Asynchronous API

Accessing a driver using an asynchronous API causes an immediate return to the caller. The driver will inform the
caller via a function call after the work is finished. This function call is given to the driver as an argument during
the initial call. The function itself is called a callback. The callback always takes the following three arguments:

IO_DeviceType : This contains a number of the device. The number is generated from the
configuration tool and is named <device>_number.

IO_FunctionNrType: This argument contains the type of call. Possible values are IO_FUNC_Read,
IO_FUNC_Write, etc.

IO_ErrorType: This contains the return value of the call. A value of E_IO_OK indicates that the
service finished successfully. IO_E_INVALID_SIZE informs the user that an invalid size ('0' or too
large) has been passed as parameter. For random devices, , IO_E_INVALID_POSITION yields a
location which is not accessible. Other values indicate device specific problems.

Instead of supplying a callback function the user can also use the null pointer (NULL) as a argument. In this case
no function is called.
Depending on the configuration, calls to a asynchronous driver are buffered by the IOLibrary. This option can be
enabled during the configuration stage and is transparent to the user. Buffered requests are handed to the driver
in the order they arrive. Currently no checks are implemented to handle buffer overflow of these buffers.
Since the address of the callback is stored within the IO library, a successive service call can only be made if
either there is a free buffer, or after finishing the currently running service call via the callback function. Violating
this rule may cause undefined behaviour in the whole system!
The currently running service is only finished after the callback has returned. A successive service call within a
callback is therefor only possible if there is a free buffer. It should also be noted that calling a service in a callback
will add to the required stack space of the calling driver. Device drivers should have all work done before calling
the callback to be able to cope with the situation of back-to-back calls.
The following services are provided by the IO library to access an asynchronous driver.
4.4.1

Interfaces available for all device types


void IO_InitAsync(IO_SymbolicName device, void * address, void (*
completion)(IO_DeviceType, IO_FunctionNrType, IO_ErrorType))
This service initialises the driver device. The argument address may contain more parameters for the
initialisation of the driver or should be NULL if not needed. The result of the service is returned via the
supplied callback function.
void IO_DeInitAsync(IO_SymbolicName device, void * address, void (*
completion)(IO_DeviceType, IO_FunctionNrType, IO_ErrorType))
This service deinitialises the driver device. The argument address may contain more parameters for the
deinitialisation of the driver or should be NULL if not needed. The result of the service is returned via the
supplied callback function.
void IO_IoctlAsync(IO_SymbolicName device, IO_ModeType mode, void * address,
void (* completion)(IO_DeviceType, IO_FunctionNrType, IO_ErrorType))
This service implements the control functionality of the driver device. The argument mode is used as a
command e.g. setting internal parameter or modes of the device. The argument address can be used
to supply additional arguments to the functions which may be needed by the command. The service uses
the callback function to notify the user of the result of the action.
IO_DeviceStateType IO_CheckAsync(IO_SymbolicName device)
Page 10/23

API IO Library
This service can be used to check the state of the driver device. It does not use any callback functions,
but returns the current state to the user. Possible state values are: IO_STATE_IDLE or
IO_STATE_ACTIVE or other driver specific values.

4.4.2

Interfaces for standard devices


void IO_ReadAsync(IO_SymbolicName device, IO_MemPtrType address, IO_SizeType
size, void (* completion)(IO_DeviceType, IO_FunctionNrType, IO_ErrorType))
This service implements the read functionality of the driver device. The argument address is a pointer to
where the data to be read is stored. After size units being read, the service calls the supplied callback
function.
void IO_WriteAsync(IO_SymbolicName device, const IO_MemPtrType address,
IO_SizeType size, void (* completion)(IO_DeviceType, IO_FunctionNrType,
IO_ErrorType))
This service implements the write functionality of the driver device. The argument address is a pointer to
where the data which is to be written will be stored. After writing size units, the service calls the supplied
callback function.

4.4.3

Interfaces for random devices


void IO_RReadAsync(IO_SymbolicName device, IO_MemPtrType address, IO_SizeType
size, IO_PositionType location, void (* completion)(IO_DeviceType,
IO_FunctionNrType, IO_ErrorType))
This service implements the random read functionality of the driver device. The argument address is a
pointer to the destination of the data to be read. The data is read from offset location. After size units
being read, the service calls the supplied callback function.
void IO_RWriteAsync(IO_SymbolicName device, const IO_MemPtrType address,
IO_SizeType size, IO_PositionType location, void (*
completion)(IO_DeviceType, IO_FunctionNrType, IO_ErrorType))
This service implements the random write functionality of the driver device. The argument address is a
pointer to the source of the data to be written. The data is written to offset location. After writing size
units, the service calls the supplied callback function.
void IO_REraseAsync(IO_SymbolicName device, IO_SizeType size, IO_PositionType
location, void (* completion)(IO_DeviceType, IO_FunctionNrType,
IO_ErrorType))
This service implements the random erase functionality of the driver device. After erasing size units, the
service calls the supplied callback function.

4.4.4

Interfaces for channel devices


void IO_GetAsync(IO_SymbolicName device, IO_ChannelType channel, IO_ValueType
* value, void (* completion)(IO_DeviceType, IO_FunctionNrType, IO_ErrorType))
This service implements the channel based get functionality of the driver device. The argument channel
identifies the channel of the driver. The argument value is a pointer to where the data to be get is stored.
After value being get, the service calls the supplied callback function.

Page 11/23

API IO Library
void IO_SetAsync(IO_SymbolicName device, IO_ChannelType channel, IO_ValueType
value, void (* completion)(IO_DeviceType, IO_FunctionNrType, IO_ErrorType))
This service implements the channel based set functionality of the driver device. The argument channel
identifies the channel where to set the new value. After writing value, the service calls the supplied
callback function.

4.5

General API supported by all sorts of drivers

The following services are supported by all sorts of drivers:


IO_U32 IO_GetVersionOfDriver(IO_SymbolicName device)
This service returns the version information for the given driver. The service is typically implemented as a
macro and returns immediately to the caller. The information within the version information (which is
returned) is divided into the following fields (bit 0 = least significant bit):
Bit 0 to 7: revision number of the driver
Bit 8 to 15: version number of the driver
Bit 16 to 23: version of the IOLibrary to which the driver is compliant. The version info of the IOLibrary is
build from the version number (major and minor part, e.g. x.y) multiplied by 10. E.g. version 1.3 of the
IOLibrary will be 13.
Bit 24 to 31: reserved for vendor number, to be set to 0 if no vendor number is assigned by HIS.
This function can also be used to get version information about the IOLibrary itself, by using IOLibrary
as the name of the device:
version = IO_GetVersionOfDriver(IOLibrary);
The result contains in:
Bit 0 to 7: revision number of the IOLibrary itself
Bit 8 to 15: version number of the IOLibrary itself
Bit 16 to 23: The version of the API which is implemented by this IOLibrary. The version number
corresponds to the major and minor number of the API IOLibrary document multiplied by 10. E.g. if this
field contains the value 20 the API conforms to the V2.0.x of the API IOLibrary document.
Bit 24 to 31: for vendor number, to be set to 0 if no vendor number is assigned by HIS..

4.6

Error Hook

The IO Library supports a central error logging mechanism called error hook. The error hook is a global function
provided by the user. For each driver the user can enable the error hook by setting the IO_ERRORHOOK variable
of the driver to TRUE. The context where the hook will be called is not specified (it can be the user or driver
2
context) . This means that no other calls to drivers are allowed within the hook function.
The prototype of the error hook is:
void IO_ErrorHook (IO_DeviceType device, IO_ErrorType error);
The parameter device identifies the calling driver. The second parameter holds information about the
occurred problem.

The hook may also be called with an interrupt context or within a task if an OSEK OS is used.
Page 12/23

API IO Library
Note: it is the responsibility of the entity which encounters the error (library or driver) to call IO_ErrorHook.

Page 13/23

API IO Library
5 Driver implementation
5.1

Overview

This chapter explains how to implement a driver in a way that it can be used by the IO library.
5.2

Driver API

The driver must conform to a given application interface in order to be recognized by the IO library. These
interfaces depends on the type of driver. It must correspond to either the synchronous or asynchronous interface,
or alternatively may support both types. When buffering is used, the asynchronous interface will be used by the
IO library.
5.2.1
5.2.1.1

Synchronous driver interface


Services available for all device types (common services)
IO_ErrorType <Drivername>_InitSync(void *)
This function carries out the initialisation of the driver. The argument can be used as a pointer to an init
structure which holds additional parameters for the service. The function returns IO_E_OK or a driver
specific return code.
IO_ErrorType <Drivername>_DeInitSync(void *)
This function does the deinitialisation of the driver. The argument can be used as a pointer to an deinit
structure which holds additional parameters for the service. The function returns IO_E_OK or a driver
specific return code.
IO_ErrorType <Drivername>_IoctlSync(IO_ModeType,void *)
The Ioctl service offers the user a standardized interface to non-standard functions of the driver. It can be
used. for example, to set internal structures of the driver. Typically, the first argument defines some sort
of command and the second one holds additional parameters of the action to be performed. The service
returns IO_E_OK or a driver specific error code.
IO_U32 <DriverName>_GetVersionOfDriver()
This service returns a 32 bit value to the caller which contains version information of the driver. For the
format of the value see 4.5 General API supported by all sorts of drivers. The service can be easily
implemented as macro, which returns the version information.

5.2.1.2

Services available for standard devices


IO_ErrorType <Drivername>_ReadSync(IO_MemPtrType,IO_SizeType)
This service implements the read functionality. It reads data from the buffer pointed to by the first
argument. The second argument specifies the number of bytes to be read. The service returns
IO_E_OK, IO_E_INVALID_SIZE if the second parameter is '0' or a driver specific error code.
IO_ErrorType <Drivername>_WriteSync(const IO_MemPtrType,IO_SizeType)
This service implements the write functionality. It writes the data pointed to by the first argument to the
device. The second argument is the number of bytes to be written. The service returns IO_E_OK,
IO_E_INVALID_SIZE if the second parameter is '0' or a driver specific error code.

Page 14/23

API IO Library
5.2.1.3

Services available for random devices


IO_ErrorType <Drivername>_RReadSync(IO_MemPtrType,IO_SizeType,
IO_PositionType )
This service implements the random read functionality. It reads data from the buffer pointed to by the first
argument. The second argument specifies the number of bytes to be read. The third parameter specifies
the place where to read from. The service returns IO_E_OK, IO_E_INVALID_POSITION if the third
parameter points to a not accessible location, IO_E_INVALID_SIZE if the second parameter is '0' or
too large or a driver specific error code.
IO_ErrorType <Drivername>_RWriteSync(const IO_MemPtrType,IO_SizeType,
IO_PositionType )
This service implements the random write functionality. It writes the data pointed to by the first argument
to the device. The second argument is the number of bytes to be written. The last argument specifies the
place where the data is written. The service returns IO_E_OK, IO_E_INVALID_POSITION if the third
parameter points to a not accessible location, IO_E_INVALID_SIZE if the second parameter is '0' or
too large or a driver specific error code.
IO_ErrorType <Drivername>_REraseSync(IO_SizeType, IO_PositionType )
This service implements the random erase functionality. It erases the block starting at IO_PositionType
with the length IO_SizeType. The service returns IO_E_OK, IO_E_INVALID_POSITION if the second
parameter points to a not accessible location, IO_E_INVALID_SIZE if the first parameter is '0' or too
large or a driver specific error code.

5.2.1.4

Services available for channel devices


The channel device interface is designed to support fast access to low level periphery (e.g. Digital IO). It
uses 16 bit values and should not used in conjunction with runtime error sensible drivers. It is
recommended to use another interface (e.g random or standard) instead.
IO_ValueType <Drivername>_GetSync(IO_ChannelType channel)
This service implements the channel based get functionality. The argument channel identifies the
channel of the driver. The function returns the value of that specific channel. Errors will be reported using
the error hook.
void <Drivername>_SetSync(IO_ChannelType channel, IO_ValueType value)
This service implements the channel based set functionality. The argument channel identifies the
channel where to set the new value. Errors will be reported using the error hook.

Note: A driver must either implement the random, channel or the standard services. Drivers which are supporting
more than one service type are not supported.

5.2.2

Asynchronous driver interface

For the asynchronous interface, the following services have to be provided by the driver. The services return
immediately and inform the user once the actual call is finished via the callback routine.
The callback functionality works as follows: After the user calls a service of the IO library (e.g.
IO_ReadAsync()) the supplied callback function is stored in a global variable. The driver function is called and
returns immediately. After the actual work is done, the driver must call the callback function using the global
Page 15/23

API IO Library
variable. If the callback variable contains a value of NULL, the callback must not be used! The variable which
hold the callback value is generated and has a fixed name: <Drivername>_Callback. It should be used by the
driver like this:
If (<Drivername>_Callback != NULL)
(* <Drivername>_Callback)(devicename, functionname, errorcode);
where devicename is IO_DEVICENR_<Drivername> (supplied by the IO library), functionname is
IO_FUNC_<Functionnr> (also supplied by the IO library) and errorcode should contain a valid error code, or in
the case of no error IO_E_OK.
Note that it is the responsibility of the user to avoid additional calls to a driver whilst a service call is already busy.
The services are:

5.2.2.1

Services available for all device types


void <Drivername>_InitAsync(void *)
This function does the initialisation of the driver. The argument may be used as a pointer to an init
structure which depends on the driver itself. After the actual work is done, the user is informed via the
callback function. Using this method, the service will either return IO_E_OK or a driver specific code.
void <Drivername>_DeInitAsync(void *)
This function does the deinitialisation of the driver. The argument may be used as a pointer to an deinit
structure which depends on the driver itself. After the actual work is done, the user is informed via the
callback function. Using this method, the service will either return IO_E_OK or a driver specific code.
void <Drivername>_IoctlAsync(IO_ModeType ,void *)
The Ioctl service offers the user a standardized interface to non-standard functions of the driver. It can be
used, for example, to set internal structures of the driver. Typically the first argument defines some sort of
command and the second one holds additional parameters of the action to be performed. After the real
work the user is informed via the callback function, returning either IO_E_OK or a driver specific code.
IO_DeviceStateType <Drivername>_CheckAsync()
This service checks if the driver is currently active or not. It does not use the callback function and returns
the actual state immediately. Possible states of the returned variable are: IO_STATE_ACTIVE,
IO_STATE_IDLE, or a driver specific state.
IO_U32 <DriverName>_GetVersionOfDriver()
This service returns a 32 bit value to the caller which contains version information of the driver. For the
format of the value see 4.5 General API supported by all sorts of drivers. The service can be easily
implemented as macro, which returns the version information.

5.2.2.2

Services available for standard devices


void <Drivername>_ReadAsync(IO_MemPtrType,IO_SizeType)
This service implements the read functionality. It reads data from the buffer pointed to by the first
argument. The second argument gives the number of bytes to be read. After the actual work is done, the
user is informed via the callback function, returning either IO_E_OK, IO_E_INVALID_SIZE if the
second parameter is '0' or a driver specific code.
Page 16/23

API IO Library

void <Drivername>_WriteAsync(const IO_MemPtrType,IO_SizeType)


This service implements the write functionality. It writes the data pointed to by the first argument to the
device. The second argument states the number of bytes to be written. After the actual work is done, the
user is informed via the callback function, returning either IO_E_OK, IO_E_INVALID_SIZE if the
second parameter is '0' or a driver specific code.

5.2.2.3

Services available for random devices


void <Drivername>_RReadAsync(IO_MemPtrType,IO_SizeType, IO_PositionType )
This service implements the read functionality. It reads data from the buffer pointed to by the first
argument. The second argument gives the number of bytes to be read. The last parameter specifies the
place from where the data is read. After the actual work is done, the user is informed via the callback
function, returning either IO_E_OK, IO_E_INVALID_POSITION if the third parameter points to a not
accessible location, IO_E_INVALID_SIZE if the second parameter is '0' or too large or a driver
specific code.
void <Drivername>_RWriteAsync(const IO_MemPtrType,IO_SizeType,
IO_PositionType )
This service implements the random write functionality. It writes the data pointed to by the first argument
to the device. The second argument states the number of bytes to be written. The last parameter
specifies where the data is written. After the actual work is done, the user is informed via the callback
function, returning either IO_E_OK, IO_E_INVALID_POSITION if the third parameter points to a not
accessible location, IO_E_INVALID_SIZE if the second parameter is '0' or too large or a driver
specific code.
void <Drivername>_REraseAsync(IO_SizeType, IO_PositionType )
This service implements the random erase functionality. It erases the block starting at IO_PositionType
with the length IO_SizeType. After the actual work is done, the user is informed via the callback function,
returning either IO_E_OK, IO_E_INVALID_POSITION if the second parameter points to a not
accessible location, IO_E_INVALID_SIZE if the first parameter is '0' or too large or a driver specific
code.

5.2.2.4

Services available for channel devices


void <Drivername>_GetAsync(IO_ChannelType channel, IO_ValueType * value)
This service implements the channel based get functionality. The argument channel identifies the
channel of the driver. The argument value is a pointer to where the data to be get is stored. After the
actual work is done, the user is informed via the callback function, returning either IO_E_OK or a driver
specific code.
void <Drivername>_SetAsync(IO_ChannelType channel, IO_ValueType value)
This service implements the channel based set functionality. The argument channel identifies the
channel where to set the new value. After the actual work is done, the user is informed via the callback
function, returning either IO_E_OK or a driver specific code.

Note: A driver must either implement the random, the channel or the standard services. Drivers which are
supporting more than one service type are not supported.
Page 17/23

API IO Library
5.3

Error hook

If the user enables the error hook for a driver the driver must call the error hook if the return value of a service is
not IO_E_OK. For synchronous drivers the call to the hook function must be done before the service returns. For
asynchronous drivers the hook must be called before calling the user callback function.

Page 18/23

API IO Library

5.4

Driver configuration

The drivers configuration is stored in a configuration file. This file is parsed by a generator to get information
about the options which are needed by the driver. The format of the configuration file is described in the next
chapter. It contains definitions of driver specific parameters called variables. Most of these variables will belong to
driver specific features like register settings, driver modi etc. On the other hand there are some specific variables
which do not control the driver, but rather configure the IO library for the driver. These variables are:
-

IO_DRIVERMODUS : Contains the modus of the driver (as text) and must be either SYNCHRON,
ASYNCHRON or BOTH , depending on the supported modes. If the variable is missing the default is
SYNCHRON.

IO_NUMBEROFBUFFERS : Number of buffers (max. 255 per driver supported), if the drivers supports
asynchronous mode. The IO library can buffer up to IO_NUMBEROFBUFFERS requests, besides the
running request. If the variable is missing the default will be 0.

IO_DEVICETYPE : Specifies the type of the device. Depending on the type specific services of the driver
are available. Currently the following types are defined: STANDARD, CHANNEL or RANDOM. The variable
must be set to one value. If the variable is missing the default will be STANDARD.

IO_LINKEDDRIVER : Name of the real driver if this driver links to another. See 5.5 below for details. If
the variable is missing the device is not linked.

IO_ERRORHOOK : Specifies whether this driver must call the error hook function. Must be either TRUE
or FALSE. TRUE means that the driver must call the IO_ErrorHook function if a error occurs. If the
variable is missing, the default is FALSE.

IO_GENERATEDRIVER : allows to suppress generation of driver code. Values can be TRUE or FALSE.
The value should be set to FALSE if a configuration describes a driver which is not used. In this case no
buffers etc. are allocated for this driver and no driver files are copied during the generation process. If the
parameter is set to TRUE the code for the driver is generated. Default is TRUE.

The following code is a part of an configuration file for a driver:


#
# Driver description file for HC12D60 EEprom driver
#
NAME=EepromD60
# Should the driver call the IO_ErrorHook() ?
VAR.IO_ERRORHOOK.DISPLAY=CHECKBOX:TRUE,FALSE
VAR.IO_ERRORHOOK.COMMENT=ErrorHook_Used?
VAR.IO_ERRORHOOK.DEFAULT=TRUE
# size of (driver specific) buffer
VAR.BUFFSIZE.DISPLAY=TEXT
VAR.BUFFSIZE.COMMENT=Size_of_Buffer
VAR.BUFFSIZE.DEFAULT=50
# Variable for enabling the urgent write feature
VAR.UrgentWrite.DISPLAY=CHECKBOX:TRUE,FALSE
VAR.UrgentWrite.COMMENT=Include_urgent_write
VAR.UrgentWrite.DEFAULT=TRUE

Page 19/23

API IO Library
When implementing driver functions in C or assembly language, you can refer to variables of the configuration in
your source files. To refer a variable, you have to put two percent signs to the left and right of the variable name.
This sequence is recognized by the generator whilst copying the driver files to the user directory.
Example: Within your C files you may refer to a buffer whose size will be controlled via the configuration tool. To
do this, you should write the following in your source code:
unsigned char buffer[%%BUFFSIZE%%];
and after the configuration, the source will contain the actual user value of the buffer size instead of
%%BUFFSIZE%%. If the user selects a value of 50 for example, the variable name (with %% characters) is
replaced by the actual value:
unsigned char buffer[50];
5.5

Linked drivers

Sometimes it is necessary that drivers although they are defined independently must be handled by the IO library
as one device with respect to asynchronous IO. There are 2 cases which are handled by the IO library:
1. More than one driver share another IO library driver
nd

Example is a driver which does not use the hardware directly but uses another (2 ) driver for access.
This can happen, e.g if the real device is hidden across a bus system. In this case the user has to link the
nd
2 driver within the configuration to the original driver with the IO_LINKEDDRIVER variable.
nd

Since the 2 driver is typically also used by the application directly (or even by other drivers) the calls to
nd
the 2 driver are buffered by the IO library to avoid problems when user call services of these drivers
simultaneously. As a consequence the specified linked driver must be asynchronous, because only
asynchronous drivers can be buffered. Also the IO_GENERATEDRIVER variable must be set to TRUE
for the linked driver to avoid a linking to an unused driver.
2. More than one driver share another non IO library driver
Example is a bus system to which some external devices are connected. To access these devices the
access to the bus must be coordinated. Since the driver of the bus is not a real IO library driver, the
access must be serialized by the IO library itself. This is achieved by using one common buffer for all IO
devices which are using the same non IO driver. As a consequence the drivers must be configured to
use asynchronous mode, because only asynchronous drivers can be buffered. The IO_LINKEDDRIVER
variable must contain the name of the non IO library driver. All calls for IO library drivers which use the
same name are then queued using one buffer. The name of the non IO library driver must not match the
name of an existing IO library driver!

Page 20/23

API IO Library
6 I/O Library Configurator
6.1

Code generation

When using the IO library the user has to configure his/her application by selecting driver or IO library specific
variables. After the selection the IO library and the used drivers are generated into a user specific directory.
The generated files are:

IO_gen.h

IO_gen.c

IOLibrary.h

IOLibrary.c

Driver specific files: header, sources, assembly, OIL or any other files.

Depending on the configuration the generated IOLibrary.c and/or IO_gen.c may be empty.
The user must include the IOLibrary.h header file before he/she can use the services of the IO library.
6.1.1

Code generation for synchronous drivers

The code generated for synchronous drivers must make the transition from the user call to the driver function.
This is done by doing C preprocessor concatenation. In this way the call is made directly to the driver and no
additional code is needed.
6.1.2

Code generation for asynchronous drivers

The code generated for asynchronous drivers must also redirect the user call to the driver function, and have to
take care that calls are buffered if more users call the same driver. This is reached by using a buffer mechanism,
where the user have to supply the number of buffers. The buffer is realized as a FIFO buffer, so calls to the driver
are made according to the order they are arrived.
6.1.3

Code generation for linked drivers

Linked drivers are using other drivers and so buffering must be used if more users access the used driver. The
generation takes care of this behaviour and enables the buffing of calls depending on the configuration.
6.2

DIL Format

6.2.1

Overview

The format which is used to save configurations and to configure a driver is called DIL Device Implementation
Language. DIL is a plain ASCII format which is line oriented to allow easy understanding of the code and easy
programming of DIL readers and writers.
The general format of a DIL file consists of
1) lines of comments starting with a # are ignored
2) empty lines are also ignored
3) lines which have the form of NAME[.NAME]*=VALUE where NAME consists of alphanumeric characters
and VALUE consists of printable characters. The first NAME must be present, followed by other NAMEs
separated by dots (.). The depth of the NAME cascading is not limited, but should not be deeper than
10. The length of a single NAME is not limited. Between the last NAME element and the VALUE
element, there must be an equals sign (=). The VALUE part ends where the line ends. Note that the left
part of the equal sign is always case significant.
6.2.2

DIL format specification for driver files

Page 21/23

API IO Library
The following rules apply to driver config files. These files describe the possible parameters a driver offers
(including the IO specific variables from the last chapter). The filenames for these config files should end with
.cnf . The generator currently recognizes the following lines:
1) Lines starting with NAME have the form NAME=<VALUE> where the value is recognized as the driver
name. This driver name must be used if the user wants to call functions of the driver e.g.
IO_ReadSync(<drivername>,). The driver name is therefore case sensitive. Example:
NAME=Eeprom
Note that the driver name must be equal to the directory name where the driver files exists:
$OSEK_IOLIBRARY/src/drivers/<arch>/<drivername>
(<arch> = microprocessor architecture, see 6.2.3)
2) Lines starting with VAR define variables. The general form is VAR.<varname>.<field>=<value>. The
field value must be one of the following:
a. DISPLAY defines the type of input field for the variable. Possible values are: TEXT, LIST ,
RADIO or CHECKBOX. The values are case dependent.
i. TEXT defines that the variable will contain any sort of text, e.g. names, defines,
numbers, etc. Typically the user will get a text field as input within the configuration tool.
The value of a variable is the whole typed text. Example: VAR.MyVar.DISPLAY=TEXT
ii. LIST contains a list of different possibilities which are separated by colons. The value of
a variable is always one of the possible values which are specified. For example:
VAR.MyVar.DISPLAY=LIST:First Possibility,Second Possibility,Third Possibility
In this line the value of the variable MyVar is either First Possibility, Second
Possibility or Third Possibility.
iii. RADIO specifies the same as LIST with the exception that the visualization from a
configuration tool may differ from LIST.
Example: VAR.MyVar.DISPLAY=RADIO:First Possibility,Second Possibility,Third
Possibility
iv. The CHECKBOX is a special case of a LIST/RADIO field with exactly 2 options, mostly
used in conjunction with boolean cases (YES/NO or TRUE/FALSE). For example:
VAR.MyVar.DISPLAY=CHECKBOX:YES,NO
b. COMMENT defines a description of the field. The value contains the description.
c.

DEFAULT defines the default value for the variable.

The following example show a variable named Start which uses a text field as input and has a default
value of 0x100:
VAR.Start.DISPLAY=TEXT
VAR.Start.COMMENT=Start of EEPROM
VAR.Start.DEFAULT=0x100
3) Lines starting with GROUP are used for the GUI layout. The general form is GROUP.<groupname>=
<groupname>|<varname>,[<groupname>|<varname>]* where groupname is the name of another
group and varname is the name of a variable. The configurator tries to put the members of one group
together to visualise dependencies of the input fields.
4) Lines starting with TABS are used for the GUI layout. The general form is
TABS=<groupname>|<varname>,[<groupname>|<varname>]* , where groupname is the name of
another group and varname is the name of a variable. The configurator sets up a tabbed pane on top
level for every group or variable which is listed. The visible identifier for the specific tab is equal to the
corresponding group or variable name. Groups and variables which are not listed will be put in the top
level group. This improves clarity if a larger number of variables has to be configured.
Page 22/23

API IO Library
6.2.3

DIL format specification for saved configurations

The following rules apply to saved configuration files. Generally spoken these file contain the current values of a
specific application which uses some drivers managed by the IO Library. For files containing these data the
ending .dil should be used. These file consists of the following lines:
1) Lines starting with ARCH. The format is ARCH=<VALUE> where <VALUE> is a valid architecture
supported by the IO library. <VALUE> is used to find the right drivers for the generation and is placed in
the architecture section of the search path ($OSEK_IOLIBRARY/src/drivers/<ARCH>/driver). A
Example of such a line is:
ARCH=HC12
2) Lines in the form of DRIVER.<drivername>.VAR.<variablname>.VALUE=<VALUE>. These lines set the
driver specific variables to the specified values. Examples:
DRIVER.EEprom.VAR.Start.VALUE=1000
DRIVER.EEprom.VAR.UrgentWrite.VALUE=TRUE

Page 23/23

Você também pode gostar