Data Types¶
This part describes the data-types that are defined in the simple CAN- interface.
sci_Object_Type¶
typedef enum sci_Object_Type
{ SCI_READ, SCI_WRITE, SCI_REMOTE_READ, SCI_REMOTE_WRITE
} sci_Object_Type;
This is the data type of a CAN-object. Explanation of each data type:
- SCI_READ
This is the data type of a read-object, data is read from the CAN-bus with an object of this type. IO-functions for an object of this type are sci_read(), sci_read_now(), sci_read_new() and sci_queue_read().
- SCI_WRITE
This is the data type of a write-object, data is written to the CAN-bus with an object of this type. The only IO-function for an object of this type is sci_write().
- SCI_REMOTE_READ
This is the data type for remote-read objects. These objects use the remote-transmission mechanism, that is defined in the CAN-specification. A remote-read object reads data by sending a CAN remote-request and waiting for a reply from another CAN device. This reply contains the data that is read from the other device. Although a remote-request sent, from a higher point of view, data is read from the CAN bus and from the other CAN device. IO-functions for an object of this type are sci_read(), sci_read_now(), sci_read_new, sci_write() and sci_queue_read(). sci_read() performs a complete request-cycle by sending the remote-request and waiting for the answer, while the other functions are used for so called divided remote reads. In this case, a remote-request is sent by the use of sci_write(). This function, however, does not wait for the reply to that request. The data can be read later by sci_read_now(), sci_read_new or sci_queue_read(). The later function has a special function, do also have a look at the description of sci_queue_read() in this documentation.
- SCI_REMOTE_WRITE
This is the data type for remote-write objects. These objects use the remote-transmission mechanism, that is defined in the CAN-specification. The data is not actually written to the CAN bus but only stored in the used CAN-interface card. The card will, without notifying the user-program, send that data when a remote-request to that object arrives (see above, SCI_REMOTE_READ).
sci_Return_Constants¶
enum sci_Return_Constants
{ SCI_NOTHING=0, SCI_OLD_DATA=1, SCI_LOST=2,
SCI_TMOUT=4, SCI_RESETTED=8, SCI_INCONSISTENT=16,
SCI_EXISTS=32,
SCI_WAIT=64,
SCI_ERROR=INT_MIN
};
This is a enumeration type that defines several flags. The returned value of any function of this library can be tested against these flags. A function can return more than one flag condition. For this reason, the returned value of a function should be tested against a flag with the ‘&’-construct.
Here is an example (be ret the return-code):
(ret & SCI_TMOUT)
This is 1 (TRUE) when a timeout occurred.
Explanation of the flags:
- SCI_NOTHING
This is the return-value of functions when no special flags are returned.
- SCI_OLD_DATA
This flag signals that old data, data that has already been read, was returned. This flag can only be returned by ordinary read-functions, all functions that are named sci_read…().
- SCI_LOST
This flag indicates that data was lost. There is only a buffer of up to 8 bytes available for each CAN object. Each CAN object can store one CAN data-frame, the next arriving frame will always overwrite the data from the previous frame. The flag indicates, that data was overwritten, without having been read by the user program. This flag can only be returned by read-functions, all functions that are named sci_read…() and sci_queue_read().
- SCI_TMOUT
This flag indicates that a timeout occurred. Timeouts for ordinary read objects (not remote-read objects) are not treated as errors, but the timeout is just indicated via this flag. The read-functions will return valid data from the object, namely the data that is still stored in the buffer of the CAN interface, the flag indicates that within the specified timeout, no new data did arrive. This flag can only be returned by ordinary read-functions, all functions that are named sci_read…().
- SCI_RESETTED
This flag indicates that the CAN interface has been resetted (probably by another process that uses sci). It is no longer guaranteed that the CAN-objects that were previously defined, can still be used. When this flag is detected, a user program should define all it’s needed CAN objects again before using any other sci-function.
- SCI_INCONSISTENT
This flag indicates inconsistent data. It was, probably due to slow program execution or too many CAN transmissions, impossible to get data from the CAN bus that is guaranteed to be valid and error-free. When this flag is detected, the user program cannot assume that the function has returned any valid or usable data. This flag can only be returned by read-functions, all functions that are named sci_read…() and sci_queue_read().
- SCI_EXISTS
This flag indicates, that a CAN object that was defined with sci_init_object was already defined. In this case, if the data of the object like length, object type, CAN id and port match, the existing object is duplicated. See also the description of sci_dup_object(). This flag can only be returned by sci_init_object.
- SCI_WAIT
This flag can only be returned by sci_write_inhibit(). It indicates, that the writing to the CAN object did not take place because the time passed since the last writing is smaller than the inhibit-time, defined for that object. See also the descriptions of sci_write_inhibit and sci_set_inhibit().
- SCI_ERROR
This flag indicates that an error occurred. Any function that returned this flag cannot be expected to have performed it’s function correctly. The error-code should be requested from sci by the call of sci_get_errcode(). If any other sci-function is called between the return of the SCI_ERROR flag by an function and the call of sci_get_errcode() the error-code may be lost.
sci_Return¶
typedef int sci_Return;
This is the type of the data, every function of this library returns. A variable of this type can be tested against flag-conditions, see also sci_Return_Constants.
sci_Bitrate¶
typedef enum sci_Bitrate_Constants
{ SCI_1000KB, /* bitrate of 1000KBPS */
SCI_500KB, /* bitrate of 500KBPS */
SCI_250KB, /* bitrate of 250KBPS */
SCI_125KB, /* bitrate of 125KBPS */
SCI_100KB, /* bitrate of 100KBPS */
SCI_66KB, /* bitrate of 66KBPS */
SCI_50KB, /* bitrate of 50KBPS */
SCI_20KB /* bitrate of 20KBPS */
} sci_Bitrate;
These constants are used to specify the bitrate for the sci_init- function. A bitrate can be defined for each available port. The names of the constants are self-describing, SCI_nnnnKB stands for a bitrate of nnnn KBit per second.
sci_Errcode¶
typedef enum sci_Errcode_Constants
{ SCI_NO_ERR, /* no error */
SCI_PORT_ERR, /* wrong port-parameter */
SCI_ID_ERR, /* wrong can-object-id */
SCI_TYPE_ERR, /* unknown object-type */
SCI_BITRATE_ERR, /* wrong bitrate chosen */
SCI_SET_CALLB_ERR, /* callback was already defined */
SCI_MODE_ERR, /* operation on object that has the wrong
mode (e.g. reading of a write-object
etc.) */
SCI_LENGTH_ERR, /* object read or written with wrong
length */
SCI_ACCESS_ERR, /* tried to access an already owned object*/
SCI_TIMEOUT_ERR, /* timeout has occurred */
SCI_TIMEOUT_VAL_ERR,/* timeout value out of range */
SCI_OFF_BUS_ERR, /* controller off-bus */
SCI_BUS_ERR, /* CAN bus error */
SCI_AUTHORIZE_ERR, /* only the first process that accesses the
port is allowed to initialize it */
/* new error-codes: */
SCI_DVR_OPEN_ERR, /* CAN-driver couldn't be opened */
SCI_DVR_ACCESS_ERR, /* driver couldn't be accessed, a kind of an
internal error */
SCI_HW_INIT_ERR, /* general HW initialization error */
SCI_RESET_ERR, /* hardware reset failed */
SCI_CHIP_CONF_ERR, /* wrong placement of CAN chip (only
for certain implementations of sci) */
SCI_ENV_ERR, /* missing environment variable (only for
certain implementations of sci) */
#if SCI_VER>=230
SCI_PLUGPORT_ERR, /* A plug-port number must be between
SCI_PLUGPORT_START and
SCI_PLUGPORT_START+SCI_MAX_PLUGPORTS-1 */
SCI_PLUG_DEF_ERR, /* the plug-port was already defined or
should have been defined but wasn't */
#endif
SCI_ERR_GENERAL /* general error */
} sci_Errcode;
This is the type that describes various errors. When an error occured, the error-code can be requested with the sci_get_errcode-function. The library can store a single error-code for each thread (threads are distinguished by the sci_Struc-parameter of all functions.
Explanation of the error-codes:
- SCI_NO_ERR
No error has been detected
- SCI_PORT_ERR
An invalid port-parameter was given to a function
- SCI_ID_ERR
An invalid CAN-id parameter was given to a function. Valid numbers range from 0 to 2047.
- SCI_TYPE_ERR
An invalid object-type parameter was given to a function. Valid object-types are defined in the enumeration sci_Object_Type.
- SCI_BITRATE_ERR
An invalid bitrate parameter was given to a function. Valid bitrates are defined in the enumeration sci_Bitrate.
- SCI_SET_CALLB_ERR
An attempt was made to set an object to the event-mode (with sci_set_callback), although the object was already set to the event-mode. This error can also occur on duplicated objects, for these special objects (see also the description of sci_dup_object()) only one (per CAN id) can be set to the event-mode. This one is then returned via the sci_Object pointer when an event was detected. See also the description of sci_set_callback) for the concept of event objects.
- SCI_MODE_ERR
A function was performed on an object whose type is not compatible with that function, e.g. sci_write() was performed on an ordinary read-object, or sci_read() was performed on a write object. Note that applying one of the read-functions sci_read, sci_read_now, sci_read_new or sci_readmany on an event-object also causes this error.
- SCI_LENGTH_ERR
Either a wrong length parameter was given to a function, valid lengths vary from 0 to 8 or an object has received a wrong number of bytes from the CAN bus. Since sci_init_object() defines a length for each object, an error occurs when data arrives for that object, that has a different number of bytes. The data-buffer on the CAN interface may be overwritten with that new data, but the read functions sci_read…() and sci_queue_read() will not copy that data to the user program.
- SCI_ACCESS_ERR
An attempt was made to perform an operation on an object that is already in use by another thread. This error can only be raised in multitasking-implementations of sci.
- SCI_TIMEOUT_ERR
A timeout-error occured. This error can only occur when the sci_write() is used. Concerning timeouts in read-functions, see also the description of the SCI_TMOUT flag that is part of the sci_Return_Constants enumeration type.
- SCI_TIMEOUT_VAL_ERR
A wrong timeout-value parameter was given to a function. Valid timeouts range from 0 to 32767.
- SCI_OFF_BUS_ERR
The CAN interface is in the OFF-BUS state. This error can only be caused by a hardware error in the CAN interface or at it’s CAN connection cable.
- SCI_BUS_ERR
A serious CAN bus error was detected, this can only be caused by faulty hardware in the CAN interface, the CAN connection cable or within another connected CAN device.
- SCI_AUTHORIZE_ERR
A thread that was not authorized to reset ports or change bitrates tried to do so. This error can only occur in multitasking- implementations of sci. Only the first thread that opened the SCI-library is allowed to reset ports or change bitrates. If this first thread closed the SCI-library and another thread opens the library with the same name as the first thread, it is also allowed to reset ports and change bitrates (see also the description of sci_open().
- SCI_DVR_OPEN_ERR
The driver for the CAN interface couldn’t be opened. This error can only be returned when sci_open() is called. Note that only some implementations of sci that are based on a driver, so this error can occur on some implementations of sci.
- SCI_DVR_ACCESS_ERR
The driver for the CAN interface couldn’t be accessed. This is an error that is similar in it’s meaning to SCI_DVR_OPEN_ERR, but it indicates an internal sci-error that shouldn’t happen under normal circumstances.
- SCI_HW_INIT_ERR
The CAN interface hardware couldn’t be initialized. This error can occur on implementations of sci that are not based on a driver and access the CAN interface directly.
- SCI_RESET_ERR
The reset of the CAN interface failed, this error can occur when the sci_reset() function is called. It indicates a problem with the CAN hardware.
- SCI_CHIP_CONF_ERR
A CAN chip was wrongly placed on the CAN card. This error can only occur on certain CAN interfaces, that allow the placement of one or more CAN chips on the interface card.
- SCI_ENV_ERR
An important environment variable is missing. Certain implementations of sci need environment variables to be set that characterize the hardware addresses of the CAN interface. Please consult the documentation of your CAN interface or your local sci implementation if this error happens.
- SCI_PLUGPORT_ERR
This error-code can be returned by sci_def_plug_in. A plug-port must be in the range of SCI_PLUGPORT_START and SCI_PLUGPORT_START+SCI_MAX_PLUGPORTS-1. If a given plug-port is not within this range, SCI_PLUGPORT_ERR is returned.
- SCI_PLUG_DEF_ERR
This error-code can be returned by sci_def_plug_in and sci_init_object. It is returned when it is either tried to defined a certain plug-port for a second time or when a plug-port is used that has not yet been defined.
- SCI_ERR_GENERAL
A general error occured. This unspecified sci error can happen at all sci functions. When an error is detected by your implementation of sci whose cause does not fall into one of the categories described above, SCI_ERR_GENERAL is returned. Either the error is an obvious parameter-error (wrong parameters were specified) for the function or it is a kind of internal error. In the later case, you should consult the author of your sci-implementation.
sci_Callback_Func¶
typedef void (*sci_Callback_Func)(sci_Object *obj, sci_Return ret,
char data[8]);
This is the legacy definition of a callback function type. This is no longer used. The corresponding parameter of function sci_set_callback mist alway be NULL.
sci_Plug_Func¶
typedef void (*sci_Plug_Func)(int l_len, char *l_data,
int h_len, char *h_data);
This is the prototype of a plug-in data-conversion function. 2 functions of that type are part of a plug-in. They perform data-conversion between the low-level format (raw-data from the CAN bus) and the high-level format (data that is passed to or from the application). Each data-conversion function gets a pointer to the low-level data, l_data, the length of the low-level data, l_len, a pointer to the high-level data, h_data, and a the length of the high-level data, h_len. The first conversion function, usually called h2l, should convert high-level to low-level data, the second function, usually called l2h, should convert low-level to high-level data.
sci_Plug_Lencalc¶
typedef int (*sci_Plug_Lencalc)(int h_len, int *l_len);
This is the type of a the plug-in length-conversion function. A plug-in has just one function of this type. It gets the length of the high-level data, h_len, calculates the resulting length of the low-level data and stores it to l_len. By this, the length of the low-level (raw CAN-bus-) data can be different from the length of the high-level (sci-application-) data. Note that the length can not vary while the application is running. This is due to the fact that CAN-objects always have a fixed length as long as they are defined. This function should return 1 (at least not zero) when a certain length conversion is supported by the plug-in, 0 in all other cases.
sci_Object¶
typedef struct sci_Object sci_Object;
This is the abstract type of a CAN-object. It contains a user part, that can be used to store user-defined pointer. The structure also contains internal data, but that data cannot be read or written to. Due to this unspecified internal data, whose size is unknown to the user, memory for sci-objects is only allocated by the library. A user program should only use pointers to sci-objects but should never create variables of the type sci_Object itself. The data type sci_Object is in it’s function similar to the FILE - structure that is used in C to handle files.
sci-objects are created with the sci_init_object() function; CAN-id, port, length and object-type are specified when the object is created. These properties cannot be modified later, if the CAN-id on that port shall have new properties, the existing sci-object has to be deleted with the sci_delete_object() function and created again with sci_init_object().
sci_Struc¶
typedef struct sci_Struc sci_Struc;
This is the abstract type of the CAN resources. A pointer to a variable of this type is returned, when sci_open is called. This pointer must be given for all other functions of this library. Different processes or threads must use different sci_Struc- parameters in their calls to the SCI-library. For this reason, the library can be called by different threads at a time an is by this, thread safe.
Note that the above definition does not represent the real structure of the sci-structure. All internal data, that this structure contains, is hidden from the user.