int can_init(uint32_t id, uint32_t mask, can_tx_callback_t atxcb, can_rx_callback_t arxcb, struct csp_can_config *conf) { struct ifreq ifr; struct sockaddr_can addr; pthread_t rx_thread; csp_assert(conf && conf->ifc); txcb = atxcb; rxcb = arxcb; /* Create socket */ if ((can_socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { csp_log_error("socket: %s\r\n", strerror(errno)); return -1; } /* Locate interface */ strncpy(ifr.ifr_name, conf->ifc, IFNAMSIZ - 1); if (ioctl(can_socket, SIOCGIFINDEX, &ifr) < 0) { csp_log_error("ioctl: %s\r\n", strerror(errno)); return -1; } /* Bind the socket to CAN interface */ addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; if (bind(can_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { csp_log_error("bind: %s\r\n", strerror(errno)); return -1; } /* Set promiscuous mode */ if (mask) { struct can_filter filter; filter.can_id = id; filter.can_mask = mask; if (setsockopt(can_socket, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) < 0) { csp_log_error("setsockopt: %s\r\n", strerror(errno)); return -1; } } /* Create receive thread */ if (pthread_create(&rx_thread, NULL, mbox_rx_thread, NULL) != 0) { csp_log_error("setsockopt: %s\r\n", strerror(errno)); return -1; } /* Create mailbox pool */ if (can_mbox_init() != 0) { csp_log_error("Failed to create tx thread pool\n"); return -1; } return 0; }
int can_init(uint32_t id, uint32_t mask, can_tx_callback_t atxcb, can_rx_callback_t arxcb, struct csp_can_config *conf) { csp_assert(conf && conf->bitrate && conf->clock_speed); /* Set id and mask */ can_id = id; can_mask = mask; /* Set callbacks */ txcb = atxcb; rxcb = arxcb; /* Set fcpu and bps */ clock_speed = conf->clock_speed; bitrate = conf->bitrate; return can_reset(clock_speed, bitrate); }
int can_init(csp_iface_t *csp_if_can, uint32_t id, uint32_t mask, can_tx_callback_t atxcb, can_rx_callback_t arxcb, struct csp_can_config *conf) { struct ifreq ifr; struct sockaddr_can addr; csp_thread_handle_t rx_thread; int *can_socket; can_iface_ctx_t *iface_ctx; iface_ctx = get_available_interface_ctx(); if (iface_ctx == NULL) { return -1; } csp_if_can->driver = (void *)iface_ctx; iface_ctx->csp_can_socket.csp_if_can = csp_if_can; can_socket = &iface_ctx->csp_can_socket.can_socket; csp_assert(conf && conf->ifc); txcb = atxcb; rxcb = arxcb; /* Create socket */ if ((*can_socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { csp_log_error("socket: %s", strerror(errno)); return -1; } /* Locate interface */ strncpy(ifr.ifr_name, conf->ifc, IFNAMSIZ - 1); if (ioctl(*can_socket, SIOCGIFINDEX, &ifr) < 0) { csp_log_error("ioctl: %s", strerror(errno)); return -1; } /* Bind the socket to CAN interface */ addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; if (bind(*can_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) { csp_log_error("bind: %s", strerror(errno)); return -1; } /* Set promiscuous mode */ if (mask) { struct can_filter filter; filter.can_id = id; filter.can_mask = mask; if (setsockopt(*can_socket, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) < 0) { csp_log_error("setsockopt: %s", strerror(errno)); return -1; } } /* Set read timeout */ { struct timeval tv = { .tv_sec = 0, .tv_usec = 1000, }; if (setsockopt(*can_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) { csp_log_error("setsockopt: %s", strerror(errno)); return -1; } } /* Create receive thread */ if(csp_thread_create(mbox_rx_thread, (signed char *)"mbox_rx", 1024, (void *)&iface_ctx->csp_can_socket, 3, &rx_thread) != CSP_ERR_NONE) { //TODO: Adjust priority csp_log_error("thread creation"); return -1; } /* Create mailbox pool */ if (can_mbox_init(iface_ctx) != 0) { csp_log_error("Failed to create tx thread pool"); return -1; } return 0; }