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: Wed, 16 Aug 2023 19:01:26 +0200 [thread overview]
Message-ID: <789bd57b-75e6-8403-e01c-f6bda10a799d@hartkopp.net> (raw)
In-Reply-To: <20210618135127.250251-1-thwa1@web.de>
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-08-16 17:02 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 [this message]
2023-10-03 13:12 ` Oliver Hartkopp
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=789bd57b-75e6-8403-e01c-f6bda10a799d@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).