From: Oliver Hartkopp <socketcan@hartkopp.net>
To: Thomas Wagner <thwa1@web.de>, mkl@pengutronix.de
Cc: linux-can@vger.kernel.org
Subject: Re: [PATCH] libsocketcan: Add new functions to get/set CAN FD bittimings
Date: Tue, 3 Oct 2023 15:12:36 +0200 [thread overview]
Message-ID: <93863dae-d2bf-60ec-976f-26e752cfe5ad@hartkopp.net> (raw)
In-Reply-To: <789bd57b-75e6-8403-e01c-f6bda10a799d@hartkopp.net>
Hello Marc,
was there also any feedback on this request?
Would it make sense to continue any libsocketcan development on GitHub?
Best regards,
Oliver
On 2023-08-16 19:01, Oliver Hartkopp wrote:
> What happened to this patch?
>
> I sometimes get requests via PM about CAN FD support for libsocketcan ...
>
> @mkl: Do you still maintain the git at
> https://git.pengutronix.de/cgit/tools/libsocketcan ??
>
> There's also a fork which added some more documentation:
> https://github.com/lalten/libsocketcan
>
> Best regards,
> Oliver
>
> On 18.06.21 15:51, Thomas Wagner wrote:
>> This patch adds new functions to get/set bittimings for both can fd
>> phases,
>> arbitration phase and data phase.
>>
>> It mimics the same behaviour as the ip link tool where can fd bitrates
>> always
>> have to be set by calling i.e.:
>>
>> ip link set can0 type can bitrate 500000 dbitrate 2000000 fd on
>>
>>
>> Signed-off-by: Thomas Wagner <thwa1@web.de>
>> Tested-by: Thomas Wagner <thwa1@web.de>
>> ---
>> include/libsocketcan.h | 5 +
>> src/libsocketcan.c | 235 ++++++++++++++++++++++++++++++++++++++++-
>> 2 files changed, 235 insertions(+), 5 deletions(-)
>>
>> diff --git a/include/libsocketcan.h b/include/libsocketcan.h
>> index 1603a7b..844104d 100644
>> --- a/include/libsocketcan.h
>> +++ b/include/libsocketcan.h
>> @@ -40,16 +40,21 @@ int can_do_start(const char *name);
>>
>> int can_set_restart_ms(const char *name, __u32 restart_ms);
>> int can_set_bittiming(const char *name, struct can_bittiming *bt);
>> +int can_set_fd_bittimings(const char *name, struct can_bittiming *bt,
>> struct can_bittiming *dbt);
>> int can_set_ctrlmode(const char *name, struct can_ctrlmode *cm);
>> int can_set_bitrate(const char *name, __u32 bitrate);
>> +int can_set_fd_bitrates(const char *name, __u32 bitrate, __u32
>> dbitrate);
>> int can_set_bitrate_samplepoint(const char *name, __u32 bitrate,
>> __u32 sample_point);
>> +int can_set_fd_bitrates_samplepoints(const char *name, __u32 bitrate,
>> __u32 sample_point, __u32 dbitrate, __u32 dsample_point);
>>
>> int can_get_restart_ms(const char *name, __u32 *restart_ms);
>> int can_get_bittiming(const char *name, struct can_bittiming *bt);
>> +int can_get_data_bittiming(const char *name, struct can_bittiming *bt);
>> int can_get_ctrlmode(const char *name, struct can_ctrlmode *cm);
>> int can_get_state(const char *name, int *state);
>> int can_get_clock(const char *name, struct can_clock *clock);
>> int can_get_bittiming_const(const char *name, struct
>> can_bittiming_const *btc);
>> +int can_get_data_bittiming_const(const char *name, struct
>> can_bittiming_const *btc);
>> int can_get_berr_counter(const char *name, struct can_berr_counter
>> *bc);
>> int can_get_device_stats(const char *name, struct can_device_stats
>> *cds);
>> int can_get_link_stats(const char *name, struct rtnl_link_stats64
>> *rls);
>> diff --git a/src/libsocketcan.c b/src/libsocketcan.c
>> index 60142cc..e7a334f 100644
>> --- a/src/libsocketcan.c
>> +++ b/src/libsocketcan.c
>> @@ -66,6 +66,8 @@
>> #define GET_BERR_COUNTER 7
>> #define GET_XSTATS 8
>> #define GET_LINK_STATS 9
>> +#define GET_DATA_BITTIMING 10
>> +#define GET_DATA_BITTIMING_CONST 11
>>
>> struct get_req {
>> struct nlmsghdr n;
>> @@ -84,6 +86,7 @@ struct req_info {
>> __u32 restart_ms;
>> struct can_ctrlmode *ctrlmode;
>> struct can_bittiming *bittiming;
>> + struct can_bittiming *dbittiming;
>> };
>>
>> /**
>> @@ -486,6 +489,16 @@ static int do_get_nl_link(int fd, __u8 acquire,
>> const char *name, void *res)
>> } else
>> fprintf(stderr, "no bittiming data found\n");
>>
>> + break;
>> + case GET_DATA_BITTIMING:
>> + if (can_attr[IFLA_CAN_DATA_BITTIMING]) {
>> + memcpy(res,
>> + RTA_DATA(can_attr[IFLA_CAN_DATA_BITTIMING]),
>> + sizeof(struct can_bittiming));
>> + ret = 0;
>> + } else
>> + fprintf(stderr, "no data bittiming data found\n");
>> +
>> break;
>> case GET_CTRLMODE:
>> if (can_attr[IFLA_CAN_CTRLMODE]) {
>> @@ -517,6 +530,16 @@ static int do_get_nl_link(int fd, __u8 acquire,
>> const char *name, void *res)
>> } else
>> fprintf(stderr, "no bittiming_const data found\n");
>>
>> + break;
>> + case GET_DATA_BITTIMING_CONST:
>> + if (can_attr[IFLA_CAN_DATA_BITTIMING_CONST]) {
>> + memcpy(res,
>> +
>> RTA_DATA(can_attr[IFLA_CAN_DATA_BITTIMING_CONST]),
>> + sizeof(struct can_bittiming_const));
>> + ret = 0;
>> + } else
>> + fprintf(stderr, "no data bittiming_const data
>> found\n");
>> +
>> break;
>> case GET_BERR_COUNTER:
>> if (can_attr[IFLA_CAN_BERR_COUNTER]) {
>> @@ -648,6 +671,12 @@ static int do_set_nl_link(int fd, __u8 if_state,
>> const char *name,
>> sizeof(struct can_bittiming));
>> }
>>
>> + if (req_info->dbittiming != NULL) {
>> + addattr_l(&req.n, 1024, IFLA_CAN_DATA_BITTIMING,
>> + req_info->dbittiming,
>> + sizeof(struct can_bittiming));
>> + }
>> +
>> if (req_info->ctrlmode != NULL) {
>> addattr_l(&req.n, 1024, IFLA_CAN_CTRLMODE,
>> req_info->ctrlmode,
>> @@ -878,7 +907,7 @@ int can_set_ctrlmode(const char *name, struct
>> can_ctrlmode *cm)
>> * line. e.g. "can0"
>> * @param bt pointer to a can_bittiming struct
>> *
>> - * This sets the bittiming of the can device. This is for advantage
>> usage. In
>> + * This sets the bittiming of the can device. This is for advanced
>> usage. In
>> * normal cases you should use can_set_bitrate to simply define the
>> bitrate and
>> * let the driver automatically calculate the bittiming. You will
>> only need this
>> * function if you wish to define the bittiming in expert mode with
>> fully
>> @@ -916,6 +945,64 @@ int can_set_bittiming(const char *name, struct
>> can_bittiming *bt)
>> return set_link(name, 0, &req_info);
>> }
>>
>> +/**
>> + * @ingroup extern
>> + * can_set_fd_bittimings - setup the bittimings for can fd.
>> + *
>> + * @param name name of the can fd device. This is the netdev name, as
>> ifconfig -a shows
>> + * in your system. usually it contains prefix "can" and the numer of
>> the can
>> + * line. e.g. "can0"
>> + * @param bt pointer to a can_bittiming struct used for arbitration
>> phase
>> + * @param dbt pointer to a can_bittiming struct used for data phase
>> + *
>> + * By calling this function can fd mode is automatically set.
>> + *
>> + * This sets the bittiming of the can fd device. This is for advanced
>> usage. In
>> + * normal cases you should use can_set_fd_bitrates to simply define
>> the bitrate and
>> + * let the driver automatically calculate the bittiming. You will
>> only need this
>> + * function if you wish to define the bittimings in expert mode with
>> fully
>> + * manually defined timing values.
>> + * You have to define the bittiming structs yourself. a can_bittiming
>> struct
>> + * consists of:
>> + *
>> + * @code
>> + * struct can_bittiming {
>> + * __u32 bitrate;
>> + * __u32 sample_point;
>> + * __u32 tq;
>> + * __u32 prop_seg;
>> + * __u32 phase_seg1;
>> + * __u32 phase_seg2;
>> + * __u32 sjw;
>> + * __u32 brp;
>> + * }
>> + * @endcode
>> + *
>> + * to define a customized bittiming, you have to define tq, prop_seq,
>> + * phase_seg1, phase_seg2 and sjw. See
>> http://www.can-cia.org/index.php?id=88
>> + * for more information about bittiming and synchronizations on can bus.
>> + *
>> + * @return 0 if success
>> + * @return -1 if failed
>> + */
>> +
>> +int can_set_fd_bittimings(const char *name, struct can_bittiming *bt,
>> struct can_bittiming *dbt)
>> +{
>> + struct can_ctrlmode cm;
>> + memset(&cm, 0, sizeof(cm));
>> + cm.mask = CAN_CTRLMODE_FD;
>> + cm.flags = CAN_CTRLMODE_FD;
>> +
>> + /* netlink expects both, timings and the fd flag, to always be
>> set simultaneously */
>> + struct req_info req_info = {
>> + .bittiming = bt,
>> + .dbittiming = dbt,
>> + .ctrlmode = &cm
>> + };
>> +
>> + return set_link(name, 0, &req_info);
>> +}
>> +
>> /**
>> * @ingroup extern
>> * can_set_bitrate - setup the bitrate.
>> @@ -924,7 +1011,7 @@ int can_set_bittiming(const char *name, struct
>> can_bittiming *bt)
>> * in your system. usually it contains prefix "can" and the numer of
>> the can
>> * line. e.g. "can0"
>> * @param bitrate bitrate of the can bus
>> - *
>> +
>> * This is the recommended way to setup the bus bit timing. You only
>> have to
>> * give a bitrate value here. The exact bit timing will be calculated
>> * automatically. To use this function, make sure that
>> CONFIG_CAN_CALC_BITTIMING
>> @@ -945,6 +1032,43 @@ int can_set_bitrate(const char *name, __u32
>> bitrate)
>> return can_set_bittiming(name, &bt);
>> }
>>
>> +/**
>> + * @ingroup extern
>> + * can_set_fd_bitrates - setup the bitrates for can fd.
>> + *
>> + * @param name name of the can fd device. This is the netdev name, as
>> ifconfig -a shows
>> + * in your system. usually it contains prefix "can" and the numer of
>> the can
>> + * line. e.g. "can0"
>> + * @param bitrate bitrate of the can fd bus during arbitration phase
>> + * @param dbitrate bitrate of the can fd bus during data phase
>> + *
>> + * By calling this function can fd mode is automatically set.
>> + *
>> + * This is the recommended way to setup the bus bit timings. You only
>> have to
>> + * give both bitrate values here. The exact bit timings will be
>> calculated
>> + * automatically. To use this function, make sure that
>> CONFIG_CAN_CALC_BITTIMING
>> + * is set to y in your kernel configuration. Bitrate can be a value
>> between
>> + * 1000(1kbit/s) and 1000000(1000kbit/s) for arbitration phase. For
>> data phase
>> + * bitrate can be a value between 1000(1kbit/s) and 14049876(1kbit/s).
>> + *
>> + * @return 0 if success
>> + * @return -1 if failed
>> + */
>> +
>> +int can_set_fd_bitrates(const char *name, __u32 bitrate, __u32 dbitrate)
>> +{
>> + struct can_bittiming bt;
>> + struct can_bittiming dbt;
>> +
>> + memset(&bt, 0, sizeof(bt));
>> + bt.bitrate = bitrate;
>> +
>> + memset(&dbt, 0, sizeof(dbt));
>> + dbt.bitrate = dbitrate;
>> +
>> + return can_set_fd_bittimings(name, &bt, &dbt);
>> +}
>> +
>> /**
>> * @ingroup extern
>> * can_set_bitrate_samplepoint - setup the bitrate.
>> @@ -974,6 +1098,44 @@ int can_set_bitrate_samplepoint(const char
>> *name, __u32 bitrate,
>> return can_set_bittiming(name, &bt);
>> }
>>
>> +/**
>> + * @ingroup extern
>> + * can_set_fd_bitrates_samplepoints - setup the bitrates.
>> + *
>> + * @param name name of the can fd device. This is the netdev name, as
>> ifconfig -a shows
>> + * in your system. usually it contains prefix "can" and the numer of
>> the can
>> + * line. e.g. "can0"
>> + * @param bitrate bitrate of the can fd bus during arbitration phase
>> + * @param sample_point sample point value of the can fd bus during
>> arbitration phase
>> + * @param dbitrate bitrate of the can fd bus during data phase
>> + * @param dsample_point sample point value of the can fd bus during
>> data phase
>> + *
>> + * By calling this function can fd mode is automatically set.
>> + *
>> + * This one is similar to can_set_fd_bitrates, only you can
>> additionally set up the
>> + * time points for sampling (sample point) customly instead of using the
>> + * CIA recommended value. sample_point can be a value between 0 and 999.
>> + *
>> + * @return 0 if success
>> + * @return -1 if failed
>> + */
>> +int can_set_fd_bitrates_samplepoints(const char *name, __u32 bitrate,
>> + __u32 sample_point, __u32 dbitrate, __u32 dsample_point)
>> +{
>> + struct can_bittiming bt;
>> + struct can_bittiming dbt;
>> +
>> + memset(&bt, 0, sizeof(bt));
>> + bt.bitrate = bitrate;
>> + bt.sample_point = sample_point;
>> +
>> + memset(&dbt, 0, sizeof(dbt));
>> + dbt.bitrate = dbitrate;
>> + dbt.sample_point = dsample_point;
>> +
>> + return can_set_fd_bittimings(name, &bt, &dbt);
>> +}
>> +
>> /**
>> * @ingroup extern
>> * can_get_state - get the current state of the device
>> @@ -1040,7 +1202,9 @@ int can_get_restart_ms(const char *name, __u32
>> *restart_ms)
>> * line. e.g. "can0"
>> * @param bt pointer to the bittiming struct.
>> *
>> - * This one stores the current bittiming configuration.
>> + * This one stores the current bittiming configuration. For can fd it
>> holds
>> + * the bittiming for the arbitration phase. To get the bittiming for
>> the data phase
>> + * use can_get_data_bittimings.
>> *
>> * Please see can_set_bittiming for more information about bit timing.
>> *
>> @@ -1052,6 +1216,28 @@ int can_get_bittiming(const char *name, struct
>> can_bittiming *bt)
>> return get_link(name, GET_BITTIMING, bt);
>> }
>>
>> +/**
>> + * @ingroup extern
>> + * can_get_data_bittimings - get the current data phase bittimnig
>> configuration.
>> + *
>> + * @param name name of the can fd device. This is the netdev name, as
>> ifconfig -a shows
>> + * in your system. usually it contains prefix "can" and the numer of
>> the can
>> + * line. e.g. "can0"
>> + * @param bt pointer to the bittiming struct.
>> + *
>> + * This one stores the current data phase bittiming configuration. To
>> get the bittiming
>> + * for the arbitration phase use can_get_bittiming.
>> + *
>> + * Please see can_set_fd_bittimings for more information about bit
>> timing.
>> + *
>> + * @return 0 if success
>> + * @return -1 if failed
>> + */
>> +int can_get_data_bittiming(const char *name, struct can_bittiming *bt)
>> +{
>> + return get_link(name, GET_DATA_BITTIMING, bt);
>> +}
>> +
>> /**
>> * @ingroup extern
>> * can_get_ctrlmode - get the current control mode.
>> @@ -1104,8 +1290,10 @@ int can_get_clock(const char *name, struct
>> can_clock *clock)
>> * line. e.g. "can0"
>> * @param btc pointer to the bittiming constant struct.
>> *
>> - * This one stores the hardware dependent bittiming constant. The
>> - * can_bittiming_const struct consists:
>> + * This one stores the hardware dependent bittiming constant. For can
>> fd it holds
>> + * the bittiming constant for the arbitration phase. To get the
>> bittiming constant
>> + * for the data phase use can_get_data_bittiming_const.The
>> can_bittiming_const
>> + * struct consists:
>> *
>> * @code
>> * struct can_bittiming_const {
>> @@ -1132,6 +1320,43 @@ int can_get_bittiming_const(const char *name,
>> struct can_bittiming_const *btc)
>> return get_link(name, GET_BITTIMING_CONST, btc);
>> }
>>
>> +/**
>> + * @ingroup extern
>> + * can_get_data_bittiming_const - get the current data phase
>> bittimnig configuration.
>> + *
>> + * @param name name of the can fd device. This is the netdev name, as
>> ifconfig -a shows
>> + * in your system. usually it contains prefix "can" and the numer of
>> the can
>> + * line. e.g. "can0"
>> + * @param btc pointer to the bittiming constant struct.
>> + *
>> + * This one stores the hardware dependent bittiming constant for the
>> data phase. To get
>> + * the bittiming constant for the arbitration phase use
>> can_get_bittiming.
>> + * The can_bittiming_const struct consists:
>> + *
>> + * @code
>> + * struct can_bittiming_const {
>> + * char name[16];
>> + * __u32 tseg1_min;
>> + * __u32 tseg1_max;
>> + * __u32 tseg2_min;
>> + * __u32 tseg2_max;
>> + * __u32 sjw_max;
>> + * __u32 brp_min;
>> + * __u32 brp_max;
>> + * __u32 brp_inc;
>> + * };
>> + * @endcode
>> + *
>> + * The information in this struct is used to calculate the bus bit
>> timing
>> + * automatically.
>> + *
>> + * @return 0 if success
>> + * @return -1 if failed
>> + */
>> +int can_get_data_bittiming_const(const char *name, struct
>> can_bittiming_const *btc)
>> +{
>> + return get_link(name, GET_DATA_BITTIMING_CONST, btc);
>> +}
>>
>> /**
>> * @ingroup extern
>> --
>> 2.25.1
>>
next prev parent reply other threads:[~2023-10-03 13:12 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-18 13:51 [PATCH] libsocketcan: Add new functions to get/set CAN FD bittimings Thomas Wagner
2023-08-16 17:01 ` Oliver Hartkopp
2023-10-03 13:12 ` Oliver Hartkopp [this message]
2023-10-10 13:44 ` Marc Kleine-Budde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=93863dae-d2bf-60ec-976f-26e752cfe5ad@hartkopp.net \
--to=socketcan@hartkopp.net \
--cc=linux-can@vger.kernel.org \
--cc=mkl@pengutronix.de \
--cc=thwa1@web.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).