drivers: net: canbus: move CAN bus network driver to drivers/net
Move the CAN bus network driver from drivers/can to drivers/net as it implements a network driver, not a CAN controller driver. Use a separate Kconfig for enabling the CAN bus network driver instead of piggybacking on the SocketCAN Kconfig. This allows for other (e.g. out-of-tree) SocketCAN transports. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
4a09967517
commit
d22a9909a1
10 changed files with 124 additions and 80 deletions
|
@ -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_USERSPACE can_handlers.c)
|
||||||
zephyr_library_sources_ifdef(CONFIG_CAN_SHELL can_shell.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)
|
add_subdirectory(transceiver)
|
||||||
|
|
|
@ -66,18 +66,6 @@ config CANFD_MAX_DLC
|
||||||
optimize memory consumption.
|
optimize memory consumption.
|
||||||
endif # CAN_FD_MODE
|
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
|
config CAN_RX_TIMESTAMP
|
||||||
bool "Receiving timestamps"
|
bool "Receiving timestamps"
|
||||||
depends on CAN_HAS_RX_TIMESTAMP
|
depends on CAN_HAS_RX_TIMESTAMP
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
zephyr_library()
|
zephyr_library()
|
||||||
|
|
||||||
zephyr_library_sources_ifdef(CONFIG_NET_LOOPBACK loopback.c)
|
zephyr_library_sources_ifdef(CONFIG_NET_LOOPBACK loopback.c)
|
||||||
|
zephyr_library_sources_ifdef(CONFIG_NET_CANBUS canbus.c)
|
||||||
|
|
||||||
if(CONFIG_NET_NATIVE)
|
if(CONFIG_NET_NATIVE)
|
||||||
zephyr_library_sources_ifdef(CONFIG_SLIP slip.c)
|
zephyr_library_sources_ifdef(CONFIG_SLIP slip.c)
|
||||||
|
|
|
@ -193,4 +193,32 @@ source "subsys/net/Kconfig.template.log_config.net"
|
||||||
|
|
||||||
endif
|
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
|
endif # NET_DRIVERS
|
||||||
|
|
|
@ -1,33 +1,35 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Intel Corporation.
|
* Copyright (c) 2022 Vestas Wind Systems A/S
|
||||||
* Copyright (c) 2022 Alexander Wachter
|
* Copyright (c) 2022 Alexander Wachter
|
||||||
|
* Copyright (c) 2019 Intel Corporation.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <zephyr/net/net_pkt.h>
|
#include <zephyr/net/net_pkt.h>
|
||||||
|
#include <zephyr/net/canbus.h>
|
||||||
#include <zephyr/net/socket_can.h>
|
#include <zephyr/net/socket_can.h>
|
||||||
#include <zephyr/drivers/can.h>
|
#include <zephyr/drivers/can.h>
|
||||||
#include <zephyr/devicetree.h>
|
#include <zephyr/devicetree.h>
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
|
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
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)
|
#define SEND_TIMEOUT K_MSEC(100)
|
||||||
|
|
||||||
struct socketcan_context {
|
struct net_canbus_context {
|
||||||
struct net_if *iface;
|
struct net_if *iface;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct socketcan_config {
|
struct net_canbus_config {
|
||||||
const struct device *can_dev;
|
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;
|
struct net_pkt *pkt;
|
||||||
int ret;
|
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)
|
int optname, const void *optval, socklen_t optlen)
|
||||||
{
|
{
|
||||||
const struct socketcan_config *cfg = dev->config;
|
const struct net_canbus_config *cfg = dev->config;
|
||||||
struct socketcan_context *socket_context = dev->data;
|
struct net_canbus_context *context = dev->data;
|
||||||
struct net_context *ctx = obj;
|
struct net_context *ctx = obj;
|
||||||
int ret;
|
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));
|
__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) {
|
if (ret == -ENOSPC) {
|
||||||
errno = ENOSPC;
|
errno = ENOSPC;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -80,26 +82,26 @@ static int socketcan_setsockopt(const struct device *dev, void *obj, int level,
|
||||||
return 0;
|
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);
|
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(dev);
|
||||||
ARG_UNUSED(arg);
|
ARG_UNUSED(user_data);
|
||||||
|
|
||||||
if (error != 0) {
|
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;
|
int ret;
|
||||||
|
|
||||||
if (net_pkt_family(pkt) != AF_CAN) {
|
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,
|
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) {
|
if (ret == 0) {
|
||||||
net_pkt_unref(pkt);
|
net_pkt_unref(pkt);
|
||||||
} else {
|
} 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
|
/* 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;
|
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);
|
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);
|
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)) {
|
if (!device_is_ready(cfg->can_dev)) {
|
||||||
LOG_ERR("CAN device not ready");
|
LOG_ERR("CAN device not ready");
|
||||||
|
@ -143,19 +145,19 @@ static int socketcan_init(const struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct canbus_api socketcan_api = {
|
static struct canbus_api net_canbus_api = {
|
||||||
.iface_api.init = socketcan_iface_init,
|
.iface_api.init = net_canbus_iface_init,
|
||||||
.send = socketcan_send,
|
.send = net_canbus_send,
|
||||||
.close = socketcan_close,
|
.close = net_canbus_close,
|
||||||
.setsockopt = socketcan_setsockopt,
|
.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))
|
.can_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_canbus))
|
||||||
};
|
};
|
||||||
|
|
||||||
NET_DEVICE_INIT(socket_can, "SOCKET_CAN", socketcan_init, NULL, &socketcan_ctx, &socketcan_cfg,
|
NET_DEVICE_INIT(net_canbus, "NET_CANBUS", net_canbus_init, NULL, &net_canbus_ctx, &net_canbus_cfg,
|
||||||
CONFIG_CAN_SOCKETCAN_INIT_PRIORITY, &socketcan_api, CANBUS_RAW_L2,
|
CONFIG_NET_CANBUS_INIT_PRIORITY, &net_canbus_api, CANBUS_RAW_L2,
|
||||||
NET_L2_GET_CTX_TYPE(CANBUS_RAW_L2), CAN_MTU);
|
NET_L2_GET_CTX_TYPE(CANBUS_RAW_L2), CAN_MTU);
|
55
include/zephyr/net/canbus.h
Normal file
55
include/zephyr/net/canbus.h
Normal file
|
@ -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 <zephyr/types.h>
|
||||||
|
#include <zephyr/net/net_ip.h>
|
||||||
|
#include <zephyr/net/net_if.h>
|
||||||
|
#include <zephyr/drivers/can.h>
|
||||||
|
|
||||||
|
#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_ */
|
|
@ -16,7 +16,6 @@
|
||||||
#include <zephyr/types.h>
|
#include <zephyr/types.h>
|
||||||
#include <zephyr/net/net_ip.h>
|
#include <zephyr/net/net_ip.h>
|
||||||
#include <zephyr/net/net_if.h>
|
#include <zephyr/net/net_if.h>
|
||||||
#include <zephyr/drivers/can.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -52,38 +51,6 @@ struct sockaddr_can {
|
||||||
int can_ifindex;
|
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);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,6 +3,8 @@ CONFIG_NET_L2_ETHERNET=n
|
||||||
CONFIG_CAN_MAX_FILTER=5
|
CONFIG_CAN_MAX_FILTER=5
|
||||||
|
|
||||||
CONFIG_NETWORKING=y
|
CONFIG_NETWORKING=y
|
||||||
|
CONFIG_NET_DRIVERS=y
|
||||||
|
CONFIG_NET_CANBUS=y
|
||||||
CONFIG_NET_SOCKETS=y
|
CONFIG_NET_SOCKETS=y
|
||||||
CONFIG_NET_SOCKETS_CAN=y
|
CONFIG_NET_SOCKETS_CAN=y
|
||||||
CONFIG_NET_SOCKETS_POSIX_NAMES=y
|
CONFIG_NET_SOCKETS_POSIX_NAMES=y
|
||||||
|
|
|
@ -11,7 +11,7 @@ LOG_MODULE_REGISTER(net_l2_canbus, LOG_LEVEL_NONE);
|
||||||
#include <zephyr/net/net_l2.h>
|
#include <zephyr/net/net_l2.h>
|
||||||
#include <zephyr/net/net_if.h>
|
#include <zephyr/net/net_if.h>
|
||||||
#include <zephyr/net/net_pkt.h>
|
#include <zephyr/net/net_pkt.h>
|
||||||
#include <zephyr/net/socket_can.h>
|
#include <zephyr/net/canbus.h>
|
||||||
|
|
||||||
static inline enum net_verdict canbus_recv(struct net_if *iface,
|
static inline enum net_verdict canbus_recv(struct net_if *iface,
|
||||||
struct net_pkt *pkt)
|
struct net_pkt *pkt)
|
||||||
|
|
|
@ -19,7 +19,9 @@ LOG_MODULE_REGISTER(net_sock_can, CONFIG_NET_SOCKETS_LOG_LEVEL);
|
||||||
#include <zephyr/net/socket.h>
|
#include <zephyr/net/socket.h>
|
||||||
#include <zephyr/syscall_handler.h>
|
#include <zephyr/syscall_handler.h>
|
||||||
#include <zephyr/sys/fdtable.h>
|
#include <zephyr/sys/fdtable.h>
|
||||||
|
#include <zephyr/net/canbus.h>
|
||||||
#include <zephyr/net/socket_can.h>
|
#include <zephyr/net/socket_can.h>
|
||||||
|
#include <zephyr/drivers/can.h>
|
||||||
|
|
||||||
#include "sockets_internal.h"
|
#include "sockets_internal.h"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue