diff --git a/drivers/can/CMakeLists.txt b/drivers/can/CMakeLists.txt index 5160611bec4..ce0dddf4dcb 100644 --- a/drivers/can/CMakeLists.txt +++ b/drivers/can/CMakeLists.txt @@ -16,6 +16,5 @@ zephyr_library_sources_ifdef(CONFIG_CAN_RCAR can_rcar.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE can_handlers.c) zephyr_library_sources_ifdef(CONFIG_CAN_SHELL can_shell.c) -zephyr_library_sources_ifdef(CONFIG_NET_SOCKETS_CAN can_socketcan.c) add_subdirectory(transceiver) diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index e88e7cd321f..503717c46ce 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -66,18 +66,6 @@ config CANFD_MAX_DLC optimize memory consumption. endif # CAN_FD_MODE -config CAN_SOCKETCAN_INIT_PRIORITY - int "socketCAN net device init priority" - default 81 - depends on NET_SOCKETS_CAN - help - socketCAN net device initialization priority. - Do not mess with it unless you know what you are doing. - Note that the priority needs to be lower than the net stack - so that it can start before the networking sub-system, - and higher than the CAN driver so that it can use the underlaying - driver when starting. - config CAN_RX_TIMESTAMP bool "Receiving timestamps" depends on CAN_HAS_RX_TIMESTAMP diff --git a/drivers/net/CMakeLists.txt b/drivers/net/CMakeLists.txt index fc71fe866c8..0b431455a2a 100644 --- a/drivers/net/CMakeLists.txt +++ b/drivers/net/CMakeLists.txt @@ -3,6 +3,7 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_NET_LOOPBACK loopback.c) +zephyr_library_sources_ifdef(CONFIG_NET_CANBUS canbus.c) if(CONFIG_NET_NATIVE) zephyr_library_sources_ifdef(CONFIG_SLIP slip.c) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 9aa2087a503..a3ea0d199a4 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -193,4 +193,32 @@ source "subsys/net/Kconfig.template.log_config.net" endif +# +# CAN bus network driver options +# +menuconfig NET_CANBUS + bool "Controller Area Network (CAN) bus network driver" + help + Enable the CAN bus network driver. This driver provides a network interface on top of the + CAN controller driver API. + +if NET_CANBUS + +module = NET_CANBUS +module-dep = LOG +module-str = Log level for CAN bus network driver +module-help = Sets log level CAN bus network driver. +source "subsys/net/Kconfig.template.log_config.net" + +config NET_CANBUS_INIT_PRIORITY + int "CAN bus network device init priority" + default 81 + help + CAN bus network device initialization priority. + + The priority needs to be lower than the network stack and higher than the CAN controller + driver. + +endif # NET_CAN + endif # NET_DRIVERS diff --git a/drivers/can/can_socketcan.c b/drivers/net/canbus.c similarity index 54% rename from drivers/can/can_socketcan.c rename to drivers/net/canbus.c index 7e8644b1a78..cd039f66ebc 100644 --- a/drivers/can/can_socketcan.c +++ b/drivers/net/canbus.c @@ -1,33 +1,35 @@ /* - * Copyright (c) 2019 Intel Corporation. + * Copyright (c) 2022 Vestas Wind Systems A/S * Copyright (c) 2022 Alexander Wachter + * Copyright (c) 2019 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 * */ #include +#include #include #include #include #include #include -LOG_MODULE_REGISTER(can_socketcan, CONFIG_CAN_LOG_LEVEL); +LOG_MODULE_REGISTER(net_canbus, CONFIG_NET_CANBUS_LOG_LEVEL); #define SEND_TIMEOUT K_MSEC(100) -struct socketcan_context { +struct net_canbus_context { struct net_if *iface; }; -struct socketcan_config { +struct net_canbus_config { const struct device *can_dev; }; -static void socketcan_recv(const struct device *dev, struct zcan_frame *frame, void *arg) +static void net_canbus_recv(const struct device *dev, struct zcan_frame *frame, void *user_data) { - struct socketcan_context *ctx = (struct socketcan_context *)arg; + struct net_canbus_context *ctx = user_data; struct net_pkt *pkt; int ret; @@ -54,11 +56,11 @@ static void socketcan_recv(const struct device *dev, struct zcan_frame *frame, v } } -static int socketcan_setsockopt(const struct device *dev, void *obj, int level, +static int net_canbus_setsockopt(const struct device *dev, void *obj, int level, int optname, const void *optval, socklen_t optlen) { - const struct socketcan_config *cfg = dev->config; - struct socketcan_context *socket_context = dev->data; + const struct net_canbus_config *cfg = dev->config; + struct net_canbus_context *context = dev->data; struct net_context *ctx = obj; int ret; @@ -69,7 +71,7 @@ static int socketcan_setsockopt(const struct device *dev, void *obj, int level, __ASSERT_NO_MSG(optlen == sizeof(struct zcan_filter)); - ret = can_add_rx_filter(cfg->can_dev, socketcan_recv, socket_context, optval); + ret = can_add_rx_filter(cfg->can_dev, net_canbus_recv, context, optval); if (ret == -ENOSPC) { errno = ENOSPC; return -1; @@ -80,26 +82,26 @@ static int socketcan_setsockopt(const struct device *dev, void *obj, int level, return 0; } -static void socketcan_close(const struct device *dev, int filter_id) +static void net_canbus_close(const struct device *dev, int filter_id) { - const struct socketcan_config *cfg = dev->config; + const struct net_canbus_config *cfg = dev->config; can_remove_rx_filter(cfg->can_dev, filter_id); } -static void socketcan_send_tx_callback(const struct device *dev, int error, void *arg) +static void net_canbus_send_tx_callback(const struct device *dev, int error, void *user_data) { ARG_UNUSED(dev); - ARG_UNUSED(arg); + ARG_UNUSED(user_data); if (error != 0) { - LOG_DBG("socket CAN TX error [%d]", error); + LOG_DBG("CAN bus TX error [%d]", error); } } -static int socketcan_send(const struct device *dev, struct net_pkt *pkt) +static int net_canbus_send(const struct device *dev, struct net_pkt *pkt) { - const struct socketcan_config *cfg = dev->config; + const struct net_canbus_config *cfg = dev->config; int ret; if (net_pkt_family(pkt) != AF_CAN) { @@ -107,12 +109,12 @@ static int socketcan_send(const struct device *dev, struct net_pkt *pkt) } ret = can_send(cfg->can_dev, (struct zcan_frame *)pkt->frags->data, - SEND_TIMEOUT, socketcan_send_tx_callback, NULL); + SEND_TIMEOUT, net_canbus_send_tx_callback, NULL); if (ret == 0) { net_pkt_unref(pkt); } else { - LOG_DBG("Cannot send socket CAN msg (%d)", ret); + LOG_DBG("Cannot send CAN msg (%d)", ret); } /* If something went wrong, then we need to return negative value to @@ -121,19 +123,19 @@ static int socketcan_send(const struct device *dev, struct net_pkt *pkt) return ret; } -static void socketcan_iface_init(struct net_if *iface) +static void net_canbus_iface_init(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); - struct socketcan_context *socket_context = dev->data; + struct net_canbus_context *context = dev->data; - socket_context->iface = iface; + context->iface = iface; LOG_DBG("Init CAN interface %p dev %p", iface, dev); } -static int socketcan_init(const struct device *dev) +static int net_canbus_init(const struct device *dev) { - const struct socketcan_config *cfg = dev->config; + const struct net_canbus_config *cfg = dev->config; if (!device_is_ready(cfg->can_dev)) { LOG_ERR("CAN device not ready"); @@ -143,19 +145,19 @@ static int socketcan_init(const struct device *dev) return 0; } -static struct canbus_api socketcan_api = { - .iface_api.init = socketcan_iface_init, - .send = socketcan_send, - .close = socketcan_close, - .setsockopt = socketcan_setsockopt, +static struct canbus_api net_canbus_api = { + .iface_api.init = net_canbus_iface_init, + .send = net_canbus_send, + .close = net_canbus_close, + .setsockopt = net_canbus_setsockopt, }; -static struct socketcan_context socketcan_ctx; +static struct net_canbus_context net_canbus_ctx; -static const struct socketcan_config socketcan_cfg = { +static const struct net_canbus_config net_canbus_cfg = { .can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus)) }; -NET_DEVICE_INIT(socket_can, "SOCKET_CAN", socketcan_init, NULL, &socketcan_ctx, &socketcan_cfg, - CONFIG_CAN_SOCKETCAN_INIT_PRIORITY, &socketcan_api, CANBUS_RAW_L2, +NET_DEVICE_INIT(net_canbus, "NET_CANBUS", net_canbus_init, NULL, &net_canbus_ctx, &net_canbus_cfg, + CONFIG_NET_CANBUS_INIT_PRIORITY, &net_canbus_api, CANBUS_RAW_L2, NET_L2_GET_CTX_TYPE(CANBUS_RAW_L2), CAN_MTU); diff --git a/include/zephyr/net/canbus.h b/include/zephyr/net/canbus.h new file mode 100644 index 00000000000..da5b6a3e067 --- /dev/null +++ b/include/zephyr/net/canbus.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_CAN_H_ +#define ZEPHYR_INCLUDE_NET_CAN_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * CAN L2 network driver API. + */ +struct canbus_api { + /** + * The net_if_api must be placed in first position in this + * struct so that we are compatible with network interface API. + */ + struct net_if_api iface_api; + + /** Send a CAN packet by socket */ + int (*send)(const struct device *dev, struct net_pkt *pkt); + + /** Close the related CAN socket */ + void (*close)(const struct device *dev, int filter_id); + + /** Set socket CAN option */ + int (*setsockopt)(const struct device *dev, void *obj, int level, + int optname, + const void *optval, socklen_t optlen); + + /** Get socket CAN option */ + int (*getsockopt)(const struct device *dev, void *obj, int level, + int optname, + const void *optval, socklen_t *optlen); +}; + +/* Make sure that the network interface API is properly setup inside + * CANBUS API struct (it is the first one). + */ +BUILD_ASSERT(offsetof(struct canbus_api, iface_api) == 0); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_CAN_H_ */ diff --git a/include/zephyr/net/socket_can.h b/include/zephyr/net/socket_can.h index 5e4b851e185..71d6ecf9ccf 100644 --- a/include/zephyr/net/socket_can.h +++ b/include/zephyr/net/socket_can.h @@ -16,7 +16,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { @@ -52,38 +51,6 @@ struct sockaddr_can { int can_ifindex; }; -/** - * CAN L2 driver API. Used by socket CAN. - */ -struct canbus_api { - /** - * The net_if_api must be placed in first position in this - * struct so that we are compatible with network interface API. - */ - struct net_if_api iface_api; - - /** Send a CAN packet by socket */ - int (*send)(const struct device *dev, struct net_pkt *pkt); - - /** Close the related CAN socket */ - void (*close)(const struct device *dev, int filter_id); - - /** Set socket CAN option */ - int (*setsockopt)(const struct device *dev, void *obj, int level, - int optname, - const void *optval, socklen_t optlen); - - /** Get socket CAN option */ - int (*getsockopt)(const struct device *dev, void *obj, int level, - int optname, - const void *optval, socklen_t *optlen); -}; - -/* Make sure that the network interface API is properly setup inside - * CANBUS API struct (it is the first one). - */ -BUILD_ASSERT(offsetof(struct canbus_api, iface_api) == 0); - /** * @} */ diff --git a/samples/net/sockets/can/prj.conf b/samples/net/sockets/can/prj.conf index ed89e64f3ce..6f8f9689676 100644 --- a/samples/net/sockets/can/prj.conf +++ b/samples/net/sockets/can/prj.conf @@ -3,6 +3,8 @@ CONFIG_NET_L2_ETHERNET=n CONFIG_CAN_MAX_FILTER=5 CONFIG_NETWORKING=y +CONFIG_NET_DRIVERS=y +CONFIG_NET_CANBUS=y CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_CAN=y CONFIG_NET_SOCKETS_POSIX_NAMES=y diff --git a/subsys/net/l2/canbus/canbus_raw.c b/subsys/net/l2/canbus/canbus_raw.c index 4158e2fa9fc..2bd7d605b25 100644 --- a/subsys/net/l2/canbus/canbus_raw.c +++ b/subsys/net/l2/canbus/canbus_raw.c @@ -11,7 +11,7 @@ LOG_MODULE_REGISTER(net_l2_canbus, LOG_LEVEL_NONE); #include #include #include -#include +#include static inline enum net_verdict canbus_recv(struct net_if *iface, struct net_pkt *pkt) diff --git a/subsys/net/lib/sockets/sockets_can.c b/subsys/net/lib/sockets/sockets_can.c index 844d2e09f85..9a1747727c5 100644 --- a/subsys/net/lib/sockets/sockets_can.c +++ b/subsys/net/lib/sockets/sockets_can.c @@ -19,7 +19,9 @@ LOG_MODULE_REGISTER(net_sock_can, CONFIG_NET_SOCKETS_LOG_LEVEL); #include #include #include +#include #include +#include #include "sockets_internal.h"