diff --git a/boards/posix/native_posix/Kconfig.defconfig b/boards/posix/native_posix/Kconfig.defconfig index a226c26d60310..160ccad25b416 100644 --- a/boards/posix/native_posix/Kconfig.defconfig +++ b/boards/posix/native_posix/Kconfig.defconfig @@ -23,6 +23,9 @@ config NET_L2_ETHERNET config ETH_NATIVE_POSIX default y if NET_L2_ETHERNET +config CAN_NATIVE_POSIX + default y if NET_SOCKETS_CAN + endif # NETWORKING config FAKE_ENTROPY_NATIVE_POSIX diff --git a/boards/posix/native_posix/native_posix.dts b/boards/posix/native_posix/native_posix.dts index 5e52d3cbca163..28995c8ffaf01 100644 --- a/boards/posix/native_posix/native_posix.dts +++ b/boards/posix/native_posix/native_posix.dts @@ -141,6 +141,26 @@ current-speed = <0>; }; + can1: can_1 { + status = "okay"; + compatible = "zephyr,native-posix-can"; + label = "CAN_1"; + /* Dummy bus-speed entry to comply with can + * DTS binding + */ + bus-speed = <500000>; + }; + + can2: can_2 { + status = "okay"; + compatible = "zephyr,native-posix-can"; + label = "CAN_2"; + /* Dummy bus-speed entry to comply with can + * DTS binding + */ + bus-speed = <500000>; + }; + rng: rng { status = "okay"; compatible = "zephyr,native-posix-rng"; diff --git a/drivers/can/CMakeLists.txt b/drivers/can/CMakeLists.txt index 8276094bd737e..cbd130e5b1761 100644 --- a/drivers/can/CMakeLists.txt +++ b/drivers/can/CMakeLists.txt @@ -12,3 +12,15 @@ zephyr_sources_ifdef(CONFIG_CAN_RCAR can_rcar.c) zephyr_sources_ifdef(CONFIG_USERSPACE can_handlers.c) zephyr_sources_ifdef(CONFIG_CAN_SHELL can_shell.c) zephyr_sources_ifdef(CONFIG_CAN_NET can_net.c) + +if(CONFIG_CAN_NATIVE_POSIX) + zephyr_library() + zephyr_library_include_directories(${ZEPHYR_BASE}/subsys/net/l2) + zephyr_library_compile_definitions(NO_POSIX_CHEATS) + zephyr_library_compile_definitions(_BSD_SOURCE) + zephyr_library_compile_definitions(_DEFAULT_SOURCE) + zephyr_library_sources( + can_native_posix.c + can_native_posix_adapt.c + ) +endif() diff --git a/drivers/can/Kconfig b/drivers/can/Kconfig index ba975e9640bdf..219282694d314 100644 --- a/drivers/can/Kconfig +++ b/drivers/can/Kconfig @@ -94,5 +94,6 @@ source "drivers/can/Kconfig.mcan" source "drivers/can/Kconfig.rcar" source "drivers/can/Kconfig.loopback" source "drivers/can/Kconfig.net" +source "drivers/can/Kconfig.native_posix" endif # CAN diff --git a/drivers/can/Kconfig.native_posix b/drivers/can/Kconfig.native_posix new file mode 100644 index 0000000000000..5b8ae430c19a9 --- /dev/null +++ b/drivers/can/Kconfig.native_posix @@ -0,0 +1,71 @@ +# Native posix CAN configuration options + +# Copyright (c) 2019 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +config CAN_NATIVE_POSIX + bool "native_posix CAN Driver" + depends on ARCH_POSIX && NETWORKING + help + Enable native_posix CAN driver + +if CAN_NATIVE_POSIX + +config CAN_MAX_FILTER + int "Maximum number of concurrent active filters" + depends on CAN_NATIVE_POSIX + default 32 + range 1 56 + help + Defines the array size of the callback/msgq pointers. + Must be at least the size of concurrent reads. + +## Interface 1 +config CAN_NATIVE_POSIX_INTERFACE_1_ENABLED + bool "CANBUS interface 1" + default y + depends on CAN_NATIVE_POSIX + help + This option enables the CANBUS network interface for Native POSIX board. + +config CAN_NATIVE_POSIX_INTERFACE_1_NAME + string "CANBUS interface 1 name on Linux side" + depends on CAN_NATIVE_POSIX_INTERFACE_1_ENABLED + default "vcan0" + help + This option sets the CANBUS network interface 1 name in host system. + +config CAN_NATIVE_POSIX_INTERFACE_1_SOCKETCAN_NAME + string "Network device name" + depends on CAN_NATIVE_POSIX_INTERFACE_1_ENABLED + default "SOCKET_CAN_1" + help + Name of the network device driver for SocketCAN. + +## Interface 2 +config CAN_NATIVE_POSIX_INTERFACE_2_ENABLED + bool "CANBUS interface 2" + default n + depends on CAN_NATIVE_POSIX + help + This option enables the CANBUS network interface for Native POSIX board. + +if CAN_NATIVE_POSIX_INTERFACE_2_ENABLED + +config CAN_NATIVE_POSIX_INTERFACE_2_NAME + string "CANBUS interface 2 name on Linux side" + depends on CAN_NATIVE_POSIX_INTERFACE_2_ENABLED + default "vcan1" + help + This option sets the CANBUS network interface 2 name in host system. + +config CAN_NATIVE_POSIX_INTERFACE_2_SOCKETCAN_NAME + string "Network device name" + depends on CAN_NATIVE_POSIX_INTERFACE_2_ENABLED + default "SOCKET_CAN_2" + help + Name of the network device driver for SocketCAN. + +endif #CAN_NATIVE_POSIX_INTERFACE_2_ENABLED + +endif #CAN_NATIVE_POSIX diff --git a/drivers/can/can_native_posix.c b/drivers/can/can_native_posix.c new file mode 100644 index 0000000000000..398abf8580d79 --- /dev/null +++ b/drivers/can/can_native_posix.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * CANBUS driver for native_posix board. This is meant to test CANBUS + * connectivity between host and Zephyr. + */ + +#define DT_DRV_COMPAT zephyr_native_posix_can + +#define LOG_MODULE_NAME canbus_posix +#define LOG_LEVEL CONFIG_CAN_LOG_LEVEL + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "can_native_posix_priv.h" +#include "socket_can_context.h" + +#define NET_BUF_TIMEOUT K_MSEC(100) + +static int read_data(struct socket_can_context *ctx, int fd) +{ + struct net_pkt *pkt; + int count; + + struct can_frame frame; + + count = canbus_np_read_data(fd, (void *)(&frame), sizeof(frame)); + + if (count <= 0) { + return 0; + } + + struct zcan_frame zframe; + + can_copy_frame_to_zframe(&frame, &zframe); + + pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, sizeof(zframe), AF_CAN, + 0, NET_BUF_TIMEOUT); + if (!pkt) { + return -ENOMEM; + } + + if (net_pkt_write(pkt, (void *)(&zframe), sizeof(zframe))) { + net_pkt_unref(pkt); + return -ENOBUFS; + } + + if (net_recv_data(ctx->iface, pkt) < 0) { + net_pkt_unref(pkt); + } + + return 0; +} + +static void canbus_np_rx(struct socket_can_context *ctx) +{ + LOG_DBG("Starting ZCAN RX thread"); + + while (1) { + if (ctx->iface && net_if_is_up(ctx->iface)) { + while (!canbus_np_wait_data(ctx->dev_fd)) { + read_data(ctx, ctx->dev_fd); + } + } + + k_sleep(K_MSEC(10)); + } +} + +static int canbus_np_send(const struct device *dev, + const struct zcan_frame *msg, k_timeout_t timeout, + can_tx_callback_t callback_isr, void *callback_arg) +{ + struct socket_can_context *ctx = dev->data; + int ret = -ENODEV; + + ARG_UNUSED(timeout); + ARG_UNUSED(callback_isr); + ARG_UNUSED(callback_arg); + + if (ctx->dev_fd > 0) { + struct can_frame frame; + + can_copy_zframe_to_frame(msg, &frame); + + ret = canbus_np_write_data(ctx->dev_fd, &frame, sizeof(frame)); + if (ret < 0) { + LOG_ERR("Cannot send CAN data len %d (%d)", + frame.can_dlc, -errno); + } + } + + return ret < 0 ? ret : 0; +} + +static int canbus_np_attach_isr(const struct device *dev, can_rx_callback_t isr, + void *callback_arg, + const struct zcan_filter *filter) +{ + ARG_UNUSED(dev); + ARG_UNUSED(isr); + ARG_UNUSED(callback_arg); + ARG_UNUSED(filter); + + return 0; +} + +static void canbus_np_detach(const struct device *dev, int filter_nr) +{ + ARG_UNUSED(dev); + ARG_UNUSED(filter_nr); +} + +enum can_state canbus_np_get_state(const struct device *dev, + struct can_bus_err_cnt *err_cnt) +{ + ARG_UNUSED(dev); + ARG_UNUSED(err_cnt); + return CAN_ERROR_ACTIVE; +} + +void canbus_np_register_state_change_isr(const struct device *dev, + can_state_change_isr_t isr) +{ + ARG_UNUSED(dev); + ARG_UNUSED(isr); +} + +static const struct can_driver_api can_api_funcs = { + .send = canbus_np_send, + .attach_isr = canbus_np_attach_isr, + .detach = canbus_np_detach, + .get_state = canbus_np_get_state, + .register_state_change_isr = canbus_np_register_state_change_isr +}; + +#ifdef CONFIG_CAN_NATIVE_POSIX_INTERFACE_1_ENABLED +K_KERNEL_STACK_DEFINE(canbus_rx_stack1, + CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE); +static struct k_thread rx_thread_data1; +static struct socket_can_context canbus_context_data1; + +static int canbus_np1_init(const struct device *dev) +{ + struct socket_can_context *ctx = dev->data; + + ctx->if_name = CONFIG_CAN_NATIVE_POSIX_INTERFACE_1_NAME; + + ctx->dev_fd = canbus_np_iface_open(ctx->if_name); + if (ctx->dev_fd < 0) { + LOG_ERR("Cannot open %s (%d)", ctx->if_name, ctx->dev_fd); + } else { + /* Create a thread that will handle incoming data from host */ + k_thread_create(&rx_thread_data1, canbus_rx_stack1, + K_THREAD_STACK_SIZEOF(canbus_rx_stack1), + (k_thread_entry_t)canbus_np_rx, ctx, NULL, NULL, + K_PRIO_PREEMPT(14), 0, K_NO_WAIT); + } + + return 0; +} + +DEVICE_DT_INST_DEFINE(0, &canbus_np1_init, NULL, + (void *)&canbus_context_data1, NULL, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &can_api_funcs); +#endif /* CONFIG_CAN_NATIVE_POSIX_INTERFACE_1_ENABLED */ + +#ifdef CONFIG_CAN_NATIVE_POSIX_INTERFACE_2_ENABLED +K_KERNEL_STACK_DEFINE(canbus_rx_stack2, + CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE); +static struct k_thread rx_thread_data2; +static struct socket_can_context canbus_context_data2; + +static int canbus_np2_init(const struct device *dev) +{ + struct socket_can_context *ctx = dev->data; + + ctx->if_name = CONFIG_CAN_NATIVE_POSIX_INTERFACE_2_NAME; + + ctx->dev_fd = canbus_np_iface_open(ctx->if_name); + if (ctx->dev_fd < 0) { + LOG_ERR("Cannot open %s (%d)", ctx->if_name, ctx->dev_fd); + } else { + /* Create a thread that will handle incoming data from host */ + k_thread_create(&rx_thread_data2, canbus_rx_stack2, + K_THREAD_STACK_SIZEOF(canbus_rx_stack2), + (k_thread_entry_t)canbus_np_rx, ctx, NULL, NULL, + K_PRIO_PREEMPT(14), 0, K_NO_WAIT); + } + + return 0; +} + +DEVICE_DT_INST_DEFINE(1, &canbus_np2_init, NULL, + (void *)&canbus_context_data2, NULL, + POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &can_api_funcs); +#endif /* CONFIG_CAN_NATIVE_POSIX_INTERFACE_2_ENABLED */ + +#if defined(CONFIG_CAN_NATIVE_POSIX_INTERFACE_1_ENABLED) || \ + defined(CONFIG_CAN_NATIVE_POSIX_INTERFACE_2_ENABLED) + +#if defined(CONFIG_NET_SOCKETS_CAN) + +#include "socket_can_generic.h" + +static int socket_can_np_setsockopt(const struct device *dev, void *obj, int level, + int optname, const void *optval, + socklen_t optlen) +{ + struct socket_can_context *socket_context = dev->data; + struct can_filter filter; + + if (level != SOL_CAN_RAW && optname != CAN_RAW_FILTER) { + errno = EINVAL; + return -1; + } + + /* Our userspace can send either zcan_filter or can_filter struct. + * They are different sizes so we need to convert them if needed. + */ + if (optlen != sizeof(struct can_filter) && + optlen != sizeof(struct zcan_filter)) { + errno = EINVAL; + return -1; + } + + if (optlen == sizeof(struct zcan_filter)) { + can_copy_zfilter_to_filter((struct zcan_filter *)optval, + &filter); + } else { + memcpy(&filter, optval, sizeof(filter)); + } + + return canbus_np_setsockopt(socket_context->dev_fd, level, optname, + &filter, sizeof(filter)); +} + +static struct canbus_api socket_can_np_api = { + .iface_api.init = socket_can_iface_init, + .send = socket_can_send, + .close = socket_can_close, + .setsockopt = socket_can_np_setsockopt, +}; + +#ifdef CONFIG_CAN_NATIVE_POSIX_INTERFACE_1_ENABLED + +static int socket_can_init_1(const struct device *dev) +{ + /* To avoid warning, use socket_can_api defined in socket_can_generic.h. + * For native posix, use socket_can_np_api instead. + */ + (void)socket_can_api; + + const struct device *can_dev = DEVICE_DT_INST_GET(0); + struct socket_can_context *socket_context = dev->data; + + LOG_DBG("Init socket CAN device %p (%s) for dev %p (%s)", dev, + dev->name, can_dev, can_dev->name); + + socket_context->can_dev = can_dev; + + return 0; +} + +NET_DEVICE_INIT_INSTANCE(socket_can_native_posix_1, + CONFIG_CAN_NATIVE_POSIX_INTERFACE_1_SOCKETCAN_NAME, 0, + socket_can_init_1, NULL, + &canbus_context_data1, NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &socket_can_np_api, + CANBUS_RAW_L2, NET_L2_GET_CTX_TYPE(CANBUS_RAW_L2), CAN_MTU); +#endif /* CONFIG_CAN_NATIVE_POSIX_INTERFACE_1_ENABLED */ + +#ifdef CONFIG_CAN_NATIVE_POSIX_INTERFACE_2_ENABLED + +static int socket_can_init_2(const struct device *dev) +{ + /* To avoid warning, use socket_can_api defined in socket_can_generic.h. + * For native posix, use socket_can_np_api instead. + */ + (void)socket_can_api; + + const struct device *can_dev = DEVICE_DT_INST_GET(1); + struct socket_can_context *socket_context = dev->data; + + LOG_DBG("Init socket CAN device %p (%s) for dev %p (%s)", dev, + dev->name, can_dev, can_dev->name); + + socket_context->can_dev = can_dev; + + return 0; +} + +NET_DEVICE_INIT_INSTANCE(socket_can_native_posix_2, + CONFIG_CAN_NATIVE_POSIX_INTERFACE_2_SOCKETCAN_NAME, 1, + socket_can_init_2, NULL, + &canbus_context_data2, NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &socket_can_np_api, + CANBUS_RAW_L2, NET_L2_GET_CTX_TYPE(CANBUS_RAW_L2), CAN_MTU); +#endif /* CONFIG_CAN_NATIVE_POSIX_INTERFACE_2_ENABLED */ + +#endif /* CONFIG_NET_SOCKETS_CAN */ + +#endif /* CAN_NATIVE_POSIX_INTERFACE_1_ENABLED || CAN_NATIVE_POSIX_INTERFACE_2_ENABLED */ diff --git a/drivers/can/can_native_posix_adapt.c b/drivers/can/can_native_posix_adapt.c new file mode 100644 index 0000000000000..b7bb51d84b85c --- /dev/null +++ b/drivers/can/can_native_posix_adapt.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * Routines setting up the host system. Those are placed in separate file + * because there is naming conflicts between host and zephyr network stacks. + */ + +/* Host include files */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "arch/posix/posix_trace.h" + +#ifdef __linux +#include +#endif + +/* Zephyr include files. Be very careful here and only include minimum + * things needed. + */ +#define LOG_MODULE_NAME canbus_posix_adapt +#define LOG_LEVEL CONFIG_CAN_LOG_LEVEL + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#include + +#include "can_native_posix_priv.h" + +int canbus_np_iface_open(const char *if_name) +{ + struct sockaddr_can addr; + struct ifreq ifr; + int fd, ret = -EINVAL; + + fd = socket(PF_CAN, SOCK_RAW, CAN_RAW); + if (fd < 0) { + return -errno; + } + + (void)memset(&ifr, 0, sizeof(ifr)); + (void)memset(&addr, 0, sizeof(addr)); + +#ifdef __linux + strncpy(ifr.ifr_name, if_name, IFNAMSIZ); + + ret = ioctl(fd, SIOCGIFINDEX, (void *)&ifr); + if (ret < 0) { + ret = -errno; + close(fd); + return ret; + } + + /* Setup address for bind */ + addr.can_ifindex = ifr.ifr_ifindex; + addr.can_family = PF_CAN; + + /* bind socket to the zcan interface */ + ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) { + ret = -errno; + close(fd); + return ret; + } +#endif + + return fd; +} + +int canbus_np_iface_remove(int fd) +{ + return close(fd); +} + +static int ssystem(const char *fmt, ...) + __attribute__((__format__(__printf__, 1, 2))); + +static int ssystem(const char *fmt, ...) +{ + char cmd[255]; + va_list ap; + int ret; + + va_start(ap, fmt); + vsnprintf(cmd, sizeof(cmd), fmt, ap); + va_end(ap); + + posix_print_trace("%s\n", cmd); + + ret = system(cmd); + + return -WEXITSTATUS(ret); +} + +int canbus_np_wait_data(int fd) +{ + struct timeval timeout; + fd_set rset; + int ret; + + FD_ZERO(&rset); + + FD_SET(fd, &rset); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + ret = select(fd + 1, &rset, NULL, NULL, &timeout); + if (ret < 0 && errno != EINTR) { + return -errno; + } else if (ret > 0) { + if (FD_ISSET(fd, &rset)) { + return 0; + } + } + + return -EAGAIN; +} + +ssize_t canbus_np_read_data(int fd, void *buf, size_t buf_len) +{ + return read(fd, buf, buf_len); +} + +ssize_t canbus_np_write_data(int fd, void *buf, size_t buf_len) +{ + return write(fd, buf, buf_len); +} + +int canbus_np_setsockopt(int fd, int level, int optname, + const void *optval, socklen_t optlen) +{ + return setsockopt(fd, level, optname, optval, optlen); +} + +int canbus_np_getsockopt(int fd, int level, int optname, + void *optval, socklen_t *optlen) +{ + return getsockopt(fd, level, optname, optval, optlen); +} + +#if defined(CONFIG_NET_PROMISCUOUS_MODE) +int canbus_np_promisc_mode(const char *if_name, bool enable) +{ + return ssystem("ip link set dev %s promisc %s", + if_name, enable ? "on" : "off"); +} +#endif /* CONFIG_NET_PROMISCUOUS_MODE */ + +/* If we have enabled manual setup, then interface cannot be + * taken up or down by the driver as we normally do not have + * enough permissions. + */ + +int canbus_np_if_up(const char *if_name) +{ + return ssystem("ip link set dev %s up", if_name); +} + +int canbus_np_if_down(const char *if_name) +{ + return ssystem("ip link set dev %s down", if_name); +} diff --git a/drivers/can/can_native_posix_priv.h b/drivers/can/can_native_posix_priv.h new file mode 100644 index 0000000000000..1a42c22fb5bc1 --- /dev/null +++ b/drivers/can/can_native_posix_priv.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Private functions for native posix canbus driver. + */ + +#ifndef ZEPHYR_DRIVERS_CAN_NATIVE_POSIX_PRIV_H_ +#define ZEPHYR_DRIVERS_CAN_NATIVE_POSIX_PRIV_H_ + +int canbus_np_iface_open(const char *if_name); +int canbus_np_iface_close(int fd); +int canbus_np_wait_data(int fd); +ssize_t canbus_np_read_data(int fd, void *buf, size_t buf_len); +ssize_t canbus_np_write_data(int fd, void *buf, size_t buf_len); +int canbus_np_setsockopt(int fd, int level, int optname, + const void *optval, socklen_t optlen); +int canbus_np_getsockopt(int fd, int level, int optname, + void *optval, socklen_t *optlen); + +#endif /* ZEPHYR_DRIVERS_CAN_NATIVE_POSIX_PRIV_H_ */ diff --git a/drivers/can/socket_can_context.h b/drivers/can/socket_can_context.h new file mode 100644 index 0000000000000..7388e3fc81fdc --- /dev/null +++ b/drivers/can/socket_can_context.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +/* CANBUS related functions that are generic in all the drivers. */ + +#include +#include + +#ifndef ZEPHYR_DRIVERS_CAN_SOCKET_CAN_CONTEXT_H_ +#define ZEPHYR_DRIVERS_CAN_SOCKET_CAN_CONTEXT_H_ + +struct socket_can_context { + const struct device *can_dev; + struct net_if *iface; + + /* for can on native posix */ + const char *if_name; + int dev_fd; + + /* for can on embedded board */ + struct k_msgq *msgq; + + /* TODO: remove the thread and push data to net directly from rx isr */ + k_tid_t rx_tid; + struct k_thread rx_thread_data; +}; + +#endif /* ZEPHYR_DRIVERS_CAN_SOCKET_CAN_CONTEXT_H_ */ diff --git a/drivers/can/socket_can_generic.h b/drivers/can/socket_can_generic.h index d6afbc0d4c97a..dce1b5199e999 100644 --- a/drivers/can/socket_can_generic.h +++ b/drivers/can/socket_can_generic.h @@ -13,6 +13,8 @@ #ifndef ZEPHYR_DRIVERS_CAN_SOCKET_CAN_GENERIC_H_ #define ZEPHYR_DRIVERS_CAN_SOCKET_CAN_GENERIC_H_ +#include "socket_can_context.h" + #define SOCKET_CAN_NAME_0 "SOCKET_CAN_0" #define SOCKET_CAN_NAME_1 "SOCKET_CAN_1" #define SOCKET_CAN_NAME_2 "SOCKET_CAN_2" @@ -25,16 +27,6 @@ CAN_DEFINE_MSGQ(socket_can_msgq, 5); K_KERNEL_STACK_DEFINE(rx_thread_stack, RX_THREAD_STACK_SIZE); -struct socket_can_context { - const struct device *can_dev; - struct net_if *iface; - struct k_msgq *msgq; - - /* TODO: remove the thread and push data to net directly from rx isr */ - k_tid_t rx_tid; - struct k_thread rx_thread_data; -}; - static inline void socket_can_iface_init(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); diff --git a/samples/net/sockets/can/boards/native_posix.conf b/samples/net/sockets/can/boards/native_posix.conf new file mode 100644 index 0000000000000..e3f7d0a941002 --- /dev/null +++ b/samples/net/sockets/can/boards/native_posix.conf @@ -0,0 +1,2 @@ +CONFIG_CAN_NATIVE_POSIX=y +CONFIG_ETH_NATIVE_POSIX=n