linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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
>>

  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).