socan 1.2.1
Linux SocketCAN higher level library
|
c source code file for socan object layer library. More...
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdbool.h>
#include <errno.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <time.h>
#include <semaphore.h>
#include <pthread.h>
#include <mqueue.h>
#include <linux/net_tstamp.h>
#include <linux/sockios.h>
#include <linux/can.h>
#include <linux/can/raw.h>
#include <socan.h>
Go to the source code of this file.
Data Structures | |
struct | sq_elm |
type of a single element in the 'squeue' queue More... | |
struct | squeue |
queue for CAN objects. More... | |
struct | socan_obj_s |
struct | cob_dict |
struct | socan_hdl_s |
struct | can_port |
Macros | |
#define | __USE_GNU |
#define | READER_DEFAULT_PRIO 97 |
absolute default priority of reader task | |
#define | WRITER_DEFAULT_PRIO 97 |
absolute default priority of writer task | |
#define | MAX_WQ_MESSAGES 32 |
max. number of CAN objects in writer queue | |
#define | MAX_QR_MESSAGES 32 |
max. number of CAN objects in reader queue | |
#define | ERRPRINT(lv, ...) |
#define | ERRPRINT_FUNC(lv, FUNC, ...) |
#define | ERRPRINT_ERRNO(syscall) |
#define | ERRPRINT_RC(syscall, rc) |
#define | ERRPRINT_RC_FUNC(FUNC, syscall, rc) |
#define | CCODE(x) |
#define | THREAD_NAMELEN 16 |
#define | PTHREAD_STACK_MIN 16384 |
#define | MUTEX_LOCK(mutex) |
#define | MUTEX_UNLOCK(mutex) |
#define | TASK "reader" |
#define | TASK "writer" |
Typedefs | |
typedef struct sq_elm | sq_elm |
type of a single element in the 'squeue' queue | |
Enumerations | |
enum | socan_module_state { UNINITIALIZED = 0 , ERROR = 1 , INITIALIZED = 2 } |
state of the socan module More... | |
Functions | |
int | socan_errprintlevel (int level) |
int | socan_tracelevel (int level) |
char * | socan_str_rc (socan_rc rc) |
bool | socan_rc_is_error (socan_rc rc) |
socan_rc | socan_port_bitrate (unsigned char port, unsigned int *bitrate) |
socan_hdl | socan_open (void) |
bool | socan_close (socan_hdl h) |
socan_rc | socan_port_device (unsigned char port, char **dev) |
cob_dict * | cob_dict_new (void) |
void | cob_dict_delete (cob_dict *dict) |
int | socan_add_port (const char *devicename) |
socan_rc | socan_add_obj (socan_hdl hdl, unsigned char port, unsigned short cob, unsigned char length, unsigned int tmo_ms, socan_obj_type type) |
socan_rc | socan_del_obj (unsigned char port, unsigned short cob) |
socan_rc | socan_obj_info (socan_hdl hdl, unsigned char port, unsigned short cob, unsigned char *length, unsigned int *tmo_ms, socan_obj_type *type) |
socan_rc | socan_obj_ts (unsigned char port, unsigned short cob, unsigned long *ts) |
socan_rc | socan_ts_to_str (unsigned long ts, char *buf, int buflen) |
socan_rc | socan_set_inhibit (unsigned char port, unsigned short cob, unsigned long inhibit_time) |
socan_rc | socan_use_queue (unsigned char port, unsigned short cob) |
socan_rc | socan_new_user_area (unsigned char port, unsigned short cob, unsigned int size, void **area) |
socan_rc | socan_user_area (unsigned char port, unsigned short cob, void **area) |
socan_rc | socan_set_user_area (unsigned char port, unsigned short cob, void *ptr) |
socan_rc | socan_free_user_area (unsigned char port, unsigned short cob) |
socan_rc | socan_readnow (socan_hdl hdl, unsigned char port, unsigned short cob, void *data) |
socan_rc | socan_read (socan_hdl hdl, unsigned char port, unsigned short cob, void *data) |
socan_rc | socan_queue_read (socan_hdl hdl, unsigned char *port, unsigned short *cob, void *data) |
socan_rc | socan_write (socan_hdl hdl, unsigned char port, unsigned short cob, const void *data) |
socan_rc | socan_writelater (socan_hdl hdl, unsigned char port, unsigned short cob, const void *data) |
socan_rc | socan_write_inhibit (socan_hdl hdl, unsigned char port, unsigned short cob, const void *data, unsigned long *inhibit_time) |
bool | socan_realtime_setup (bool use_rt_priority, bool require_rt_priority, int reader_priority, int writer_priority) |
bool | socan_init (void) |
c source code file for socan object layer library.
socan - SocketCAN higher level library
Copyright 2025 Helmholtz-Zentrum Berlin für Materialien und Energie GmbH https://www.helmholtz-berlin.de
Author: Goetz Pfeiffer Goetz.nosp@m..Pfe.nosp@m.iffer.nosp@m.@hel.nosp@m.mholt.nosp@m.z-be.nosp@m.rlin..nosp@m.de
socan is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
socan is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with socan. If not, see https://www.gnu.org/licenses/.
This file, socan.c, contains the implementation of the socan object layer library.
Definition in file socan.c.
#define ERRPRINT | ( | lv, | |
... ) |
#define ERRPRINT_ERRNO | ( | syscall | ) |
#define ERRPRINT_FUNC | ( | lv, | |
FUNC, | |||
... ) |
#define ERRPRINT_RC | ( | syscall, | |
rc ) |
#define ERRPRINT_RC_FUNC | ( | FUNC, | |
syscall, | |||
rc ) |
#define MAX_QR_MESSAGES 32 |
#define MAX_WQ_MESSAGES 32 |
#define MUTEX_LOCK | ( | mutex | ) |
#define MUTEX_UNLOCK | ( | mutex | ) |
#define READER_DEFAULT_PRIO 97 |
#define WRITER_DEFAULT_PRIO 97 |
enum socan_module_state |
socan_rc socan_add_obj | ( | socan_hdl | hdl, |
unsigned char | port, | ||
unsigned short | cob, | ||
unsigned char | length, | ||
unsigned int | tmo_ms, | ||
socan_obj_type | type ) |
Define a CAN object.
Before reading from or writing to a CAN object, it has to be defined with this function.
[in] | hdl | The handle obtained by socan_open(). |
[in] | port | The number of the CAN port |
[in] | cob | The CAN object ID. |
[in] | length | The length of the CAN object in bytes. The minimum value is 0, the maximum value is SOCAN_FRAME_LENGTH. |
[in] | tmo_ms | The timeout in milliseconds. |
[in] | type | The type of the CAN object |
int socan_add_port | ( | const char * | devicename | ) |
Add a SocketCAN device as a new CAN port.
socan used CAN ports to distinguish physical CAN interfaces. This functions associates a new CAN port number with the given interface name.
[in] | devicename | The name of the CAN device. You can see can devices with the command 'ip link'. |
bool socan_close | ( | socan_hdl | h | ) |
socan_rc socan_del_obj | ( | unsigned char | port, |
unsigned short | cob ) |
Delete a CAN object and free it's resources.
This deletes a CAN object that was previously defined with socan_add_obj(). Note that it is not an error, when the CAN object wasn't defined in the first place. In this case, the function does nothing and returns SOCAN_OK.
[in] | port | The port number. |
[in] | cob | The CAN object id |
int socan_errprintlevel | ( | int | level | ) |
Get and/or set the socan error print level.
The error print level determines if and when messages are printed to the console in case of errors. These are the currently known error print levels:
[in] | level | The error print level. If >=0, set this as new error print level. If <0, do not change the error print level, only read it. |
socan_rc socan_free_user_area | ( | unsigned char | port, |
unsigned short | cob ) |
Free a memory memory block associated with a CAN object.
This function calls free() on the memory block that was associated with a CAN object by calling socan_new_user_area() or socan_set_user_area(). If there is no associated memory block the function simply returns SOCAN_OK.
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
bool socan_init | ( | void | ) |
Initialize the socan library.
This starts the internal data structures and starts the library threads. You should have added CAN bus ports with socan_add_port() before.
socan_rc socan_new_user_area | ( | unsigned char | port, |
unsigned short | cob, | ||
unsigned int | size, | ||
void ** | area ) |
Create a memory block associated with a CAN object.
A memory block of arbitrary size is created with this function. This memory block is associated with the CAN object and can later be retrieved with function socan_user_area(). This can be used for the application to store additional data with a CAN object. Note that this function allocates new memory. If there was already a memory block associated, this block is freed first. When the CAN object is later deleted with socan_del_obj(), the memory block is freed, too.
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
socan_rc socan_obj_info | ( | socan_hdl | hdl, |
unsigned char | port, | ||
unsigned short | cob, | ||
unsigned char * | length, | ||
unsigned int * | tmo_ms, | ||
socan_obj_type * | type ) |
Return information for a CAN object.
This returns properties of the CAN object.
[in] | hdl | The handle obtained by socan_open(). |
[in] | port | The port number. |
[in] | cob | The CAN object id |
[out] | length | This length is returned in this parameter |
[out] | tmo_ms | This timeout is returned in this parameter |
[out] | type | The type of the CAN object is returned in this parameter |
socan_rc socan_obj_ts | ( | unsigned char | port, |
unsigned short | cob, | ||
unsigned long * | ts ) |
Return the time stamp of the CAN object.
For read objects, this is the time when data arrived for this object. For write objects this is the time when data was written to the CAN bus for this object. The time stamp is measured in microseconds. The absolute value of the time stamp is compatible with the function gettimeofday as provided by libc. You would get a compatible time stamp like this:
[in] | port | The number of the CAN port |
[in] | cob | The CAN object ID. |
[out] | ts | The time stamp is returned here. |
socan_hdl socan_open | ( | void | ) |
socan_rc socan_port_bitrate | ( | unsigned char | port, |
unsigned int * | bitrate ) |
socan_rc socan_port_device | ( | unsigned char | port, |
char ** | dev ) |
Return the device name associated with a port.
This is the same device name that was given to socan_add_port() to associate the device name with a port previously.
[in] | port | The port number. |
[out] | dev | A pointer to a pointer of char. When the function returns, '*dev' will point to the device name. |
socan_rc socan_queue_read | ( | socan_hdl | hdl, |
unsigned char * | port, | ||
unsigned short * | cob, | ||
void * | data ) |
Blocking read any of the queue-read CAN objects.
Queue-read CAN objects are CAN objects of type SOCAN_READ or SOCAN_READ_RTR which were configured with function socan_use_queue(). The function waits until new data is available on any of the queue read objects. Note that there is no timeout here, if no new data arrives, the function will wait indefinitely. For SOCAN_READ_RTR objects new data will only be received when you create an RTR-read request first. This is done by calling socan_write(), socan_writelater() or socan_write_inhibit() on the SOCAN_READ_RTR object.
[in] | hdl | The handle obtained by socan_open(). |
[out] | port | The port number of the CAN object that was read. |
[cob] | cob The CAN object ID. of the CAN object that was read. | |
[out] | data | A pointer to the data. |
bool socan_rc_is_error | ( | socan_rc | rc | ) |
Blocking read of a SOCAN_READ or SOCAN_READ_RTR object.
This function reads from a CAN object and waits until new data arrives. For remote read (SOCAN_READ_RTR) objects, the function sends an RTR frame and waits for the reply.
[in] | hdl | The handle obtained by socan_open(). |
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
[out] | data | A pointer to the data. |
Read buffer from a SOCAN_READ or SOCAN_READ_RTR object and return immediately.
This function reads the local data buffer of the CAN object. Note that for remote read (SOCAN_READ_RTR) objects, the function does not issue a RTR frame, no data is sent to the CAN bus. The function always returns immediately.
[in] | hdl | The handle obtained by socan_open(). |
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
[out] | data | A pointer to the data. |
bool socan_realtime_setup | ( | bool | use_rt_priority, |
bool | require_rt_priority, | ||
int | reader_priority, | ||
int | writer_priority ) |
Set up real time scheduling and priorities.
This function can be called before socan_init() is called. It is used to change the defaults for the real time priorities of the library. These are the defaults, if socan_realtime_setup is not called:
[in] | use_rt_priority | If true, the library uses real time priorities for it's internal threads and SCHED_FIFO scheduling polity. If false, it uses SCHED_OTHER scheduling policy and default priorities. The reader_priority and writer_priority parameters are ignored in this case. |
[in] | require_rt_priority | If true and if use_rt_priority is true, real time priorities are considered mandatory. If the application has no sufficient rights to use SCHED_FIFO scheduling policy and real time priorities, socan_init() will fail. If require_rt_priority is false, real time priorities are considered optional, insufficient rights do not cause socan_init() to fail, it only prints a warning and uses normal SCHED_OTHER policy and default priorities. |
[in] | reader_priority | This is the priority of the internal reader task when real time priorities are used (see also use_rt_priority and require_rt_priority). |
[in] | writer_priority | This is the priority of the internal writer task when real time priorities are used (see also use_rt_priority and require_rt_priority). |
socan_rc socan_set_inhibit | ( | unsigned char | port, |
unsigned short | cob, | ||
unsigned long | inhibit_time ) |
Sets the inhibit time of a CAN object.
The inhibit time is the minimum time that between two write operations on the same CAN object. This is intended to avoid congestion (data loss) on the receiver. The inhibit time is observed by some of the write functions, see also the documentation of these functions.
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
[in] | inhibit_time | The inhibit time in microseconds |
socan_rc socan_set_user_area | ( | unsigned char | port, |
unsigned short | cob, | ||
void * | ptr ) |
Associate an allocated memory block with a CAN object.
A memory block that was created with malloc() or calloc() is associated with a CAN object with this function. Note that is is imperative that the memory was allocated as described above since socan will call free() on this block when the CAN object is deleted or socan_new_user_area() is called. Note too, that a previously associated memory block is not freed automatically, the application must ensure that there is no memory leak and free the old memory block itself.
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
[in] | ptr | A pointer to the memory block. |
char * socan_str_rc | ( | socan_rc | rc | ) |
int socan_tracelevel | ( | int | level | ) |
Get and/or set the socan trace level.
The trace level determines if and when messages are printed to the console during normal operation. These are the currently known trace print levels:
[in] | level | The trace level. If >=0, set this as new trace level. If <0, do not change the trace level, only read it. |
socan_rc socan_ts_to_str | ( | unsigned long | ts, |
char * | buf, | ||
int | buflen ) |
Convert a time stamp to a string.
This function converts the time stamp returned by socan_obj_ts() to a human readable string. The string is stored in the buffer provided as parameter to this function.
[in] | ts | The time stamp |
[in] | buf | The address of the string buffer |
[in] | buflen | The length of the string buffer |
socan_rc socan_use_queue | ( | unsigned char | port, |
unsigned short | cob ) |
Prepare a CAN object for using socan_queue_read()
The functions socan_readnow() and socan_read() only allow to read from a single CAN object. socan_queue_read() however, waits for incoming data on a number of CAN objects. These CAN objects are not given to socan_queue_read() as a parameter, instead the CAN objects are set up to be used by socan_queue_read() with this function.
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
socan_rc socan_user_area | ( | unsigned char | port, |
unsigned short | cob, | ||
void ** | area ) |
Return memory block associated with a CAN object.
This returns a pointer to the memory block that was previously created with socan_new_user_area(). If there was never a memory created, the function returns a NULL pointer.
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
[out] | area | A pointer to the memory block is returned here. |
Write a SOCAN_WRITE or SOCAN_WRITE_RTR object synchronously.
In case of a SOCAN_WRITE object, the function triggers the writing and waits until the write is finished or a timeout occurs. In case of a SOCAN_WRITE_RTR object, the function simply writes to the internal buffer of the CAN object and returns immediately.
[in] | hdl | The handle obtained by socan_open(). |
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
[in] | data | A pointer to the data. |
socan_rc socan_write_inhibit | ( | socan_hdl | hdl, |
unsigned char | port, | ||
unsigned short | cob, | ||
const void * | data, | ||
unsigned long * | inhibit_time ) |
Write a SOCAN_WRITE or SOCAN_WRITE_RTR object asynchronously with inhibit time.
In case of a SOCAN_WRITE object, the function triggers the writing and returns immediately if the time passed since the last write is bigger than the inhibit time. If this is not the case, the function returns SOCAN_WAIT and the write is aborted. In case of a SOCAN_WRITE_RTR object, the function simply writes to the internal buffer of the CAN object and returns immediately.
[in] | hdl | The handle obtained by socan_open(). |
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
[in] | data | A pointer to the data. |
[out] | inhibit_time | Time the user task has to wait in microseconds. |
socan_rc socan_writelater | ( | socan_hdl | hdl, |
unsigned char | port, | ||
unsigned short | cob, | ||
const void * | data ) |
Write a SOCAN_WRITE or SOCAN_WRITE_RTR object asynchronously.
In case of a SOCAN_WRITE object, the function triggers the writing and returns immediately. In case of a SOCAN_WRITE_RTR object, the function simply writes to the internal buffer of the CAN object and returns immediately.
[in] | hdl | The handle obtained by socan_open(). |
[in] | port | The port number. |
[in] | cob | The CAN object ID. |
[in] | data | A pointer to the data. |