Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | /* * Copyright (c) 2018 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include <logging/log.h> LOG_MODULE_REGISTER(net_socket_can_sample, LOG_LEVEL_DBG); #include <zephyr.h> #include <net/socket.h> #include <net/socket_can.h> #define PRIORITY 7 #define STACKSIZE 750 #define SLEEP_PERIOD K_SECONDS(1) static k_tid_t tx_tid; static K_THREAD_STACK_DEFINE(tx_stack, STACKSIZE); static struct k_thread tx_data; static void tx(int *can_fd) { int fd = POINTER_TO_INT(can_fd); struct zcan_frame msg = {0}; struct can_frame frame = {0}; int ret, i; msg.dlc = 8U; msg.id_type = CAN_STANDARD_IDENTIFIER; msg.std_id = 0x1; msg.rtr = CAN_DATAFRAME; for (i = 0; i < msg.dlc; i++) { msg.data[i] = 0xF0 | i; } can_copy_zframe_to_frame(&msg, &frame); LOG_DBG("Sending CAN data..."); while (1) { ret = send(fd, &frame, sizeof(frame), K_FOREVER); if (ret < 0) { LOG_ERR("Cannot send CAN message (%d)", -errno); } k_sleep(SLEEP_PERIOD); } } static void rx(int fd) { struct sockaddr_can can_addr; socklen_t addr_len; struct zcan_frame msg; struct can_frame frame; int ret; LOG_DBG("Waiting CAN data..."); while (1) { u8_t *data; memset(&frame, 0, sizeof(frame)); addr_len = sizeof(can_addr); ret = recvfrom(fd, &frame, sizeof(struct can_frame), 0, (struct sockaddr *)&can_addr, &addr_len); if (ret < 0) { LOG_ERR("Cannot receive CAN message (%d)", ret); continue; } can_copy_frame_to_zframe(&frame, &msg); LOG_INF("CAN msg: type 0x%x RTR 0x%x EID 0x%x DLC 0x%x", msg.id_type, msg.rtr, msg.std_id, msg.dlc); if (!msg.rtr) { if (msg.dlc > 8) { data = (u8_t *)msg.data_32; } else { data = msg.data; } LOG_HEXDUMP_INF(data, msg.dlc, "Data"); } else { LOG_INF("EXT Remote message received"); } } } static int setup_socket(void) { const struct zcan_filter zfilter = { .id_type = CAN_STANDARD_IDENTIFIER, .rtr = CAN_DATAFRAME, .std_id = 0x1, .rtr_mask = 1, .std_id_mask = CAN_STD_ID_MASK }; struct can_filter filter; struct sockaddr_can can_addr; struct net_if *iface; int fd; int ret; can_copy_zfilter_to_filter(&zfilter, &filter); iface = net_if_get_first_by_type(&NET_L2_GET_NAME(CANBUS)); if (!iface) { LOG_ERR("No CANBUS network interface found!"); return -ENOENT; } fd = socket(AF_CAN, SOCK_RAW, CAN_RAW); if (fd < 0) { ret = -errno; LOG_ERR("Cannot create CAN socket (%d)", ret); return ret; } can_addr.can_ifindex = net_if_get_by_iface(iface); can_addr.can_family = PF_CAN; ret = bind(fd, (struct sockaddr *)&can_addr, sizeof(can_addr)); if (ret < 0) { ret = -errno; LOG_ERR("Cannot bind CAN socket (%d)", ret); goto cleanup; } ret = setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)); if (ret < 0) { ret = -errno; LOG_ERR("Cannot set CAN sockopt (%d)", ret); goto cleanup; } /* Delay TX startup so that RX is ready to receive */ tx_tid = k_thread_create(&tx_data, tx_stack, K_THREAD_STACK_SIZEOF(tx_stack), (k_thread_entry_t)tx, INT_TO_POINTER(fd), NULL, NULL, PRIORITY, 0, K_SECONDS(1)); if (!tx_tid) { ret = -ENOENT; errno = -ret; LOG_ERR("Cannot create TX thread!"); goto cleanup; } LOG_DBG("Started socket CAN TX thread"); return fd; cleanup: (void)close(fd); return ret; } void main(void) { int fd; fd = setup_socket(); if (fd < 0) { LOG_ERR("Cannot start CAN application (%d)", fd); return; } rx(fd); } |