/** * @brief Send a CAN message * * @param frame Pointer to a CAN frame * * @return 0 on success, otherwise negative error code * * Environments: * * This service can be called from: * * - User-space task (non-RT, RT) * * Rescheduling: none. */ int CanPort::send(rtcan_frame_t* frame) { int ret; ret = rt_dev_send(fd, frame, sizeof(rtcan_frame_t), 0); if (ret != sizeof(rtcan_frame_t)) { return ret; } return 0; }
void CANDev::send(const uint32_t can_id, const uint8_t len, const uint8_t *data){ struct can_frame frame; frame.can_id = can_id; frame.can_dlc = len; memcpy(frame.data, data, len); #if !defined(HAVE_RTNET) write(dev, (void *)&frame, sizeof(frame)); #else rt_dev_send(dev, (void *)&frame, sizeof(frame), 0); #endif }
bool CANDev::send(const uint32_t can_id, const uint8_t len, const uint8_t *data) { struct can_frame frame; frame.can_id = can_id; frame.can_dlc = len; memcpy(frame.data, data, len); size_t ret = rt_dev_send(dev, reinterpret_cast<void*>(&frame), sizeof(frame), 0); if (ret == sizeof(frame)) { return true; } else { return false; } }
static void rt_task(void) { int i, j, ret; for (i = 0; i < loops; i++) { rt_task_sleep(rt_timer_ns2ticks(delay)); if (count) memcpy(&frame.data[0], &i, sizeof(i)); /* Note: sendto avoids the definiton of a receive filter list */ if (use_send) ret = rt_dev_send(s, (void *)&frame, sizeof(can_frame_t), 0); else ret = rt_dev_sendto(s, (void *)&frame, sizeof(can_frame_t), 0, (struct sockaddr *)&to_addr, sizeof(to_addr)); if (ret < 0) { switch (ret) { case -ETIMEDOUT: if (verbose) printf("rt_dev_send(to): timed out"); break; case -EBADF: if (verbose) printf("rt_dev_send(to): aborted because socket was closed"); break; default: fprintf(stderr, "rt_dev_send: %s\n", strerror(-ret)); break; } i = loops; /* abort */ break; } if (verbose && (i % print) == 0) { if (frame.can_id & CAN_EFF_FLAG) printf("<0x%08x>", frame.can_id & CAN_EFF_MASK); else printf("<0x%03x>", frame.can_id & CAN_SFF_MASK); printf(" [%d]", frame.can_dlc); for (j = 0; j < frame.can_dlc; j++) { printf(" %02x", frame.data[j]); } printf("\n"); } } }
int CANSocket::send(int busId, const unsigned char* data, size_t len) const { boost::unique_lock<thread::RealTimeMutex> ul(mutex); struct can_frame frame; frame.can_id = busId; frame.can_dlc = len; memcpy(frame.data, data, len); int ret = rt_dev_send(handle, (void *) &frame, sizeof(can_frame_t), 0); if (ret < 0) { ul.unlock(); switch (ret) { case -EAGAIN: // -EWOULDBLOCK logMessage("CANSocket::%s: " "rt_dev_send(): data would block during non-blocking send (output buffer full)") % __func__; return 1; break; case -ETIMEDOUT: logMessage("CANSocket::%s: " "rt_dev_send(): timed out") % __func__; return 2; break; case -EBADF: logMessage("CANSocket::%s: " "rt_dev_send(): aborted because socket was closed") % __func__; return 2; default: logMessage("CANSocket::%s: " "rt_dev_send(): (%d) %s") % __func__ % -ret % strerror(-ret); return 2; } } return 0; }
int main(int argc, char *argv[]) { RT_TASK *task; RTIME trp, max = 0, min = 1000000000, avrg = 0; int sockfd, ret, hard_timer_running, i; struct sockaddr_in local_addr, server_addr; struct { long long count; char msg[100]; } msg = { 0LL, "this message was sent using rtnet-rtai." }; signal(SIGTERM, sigh); signal(SIGINT, sigh); signal(SIGHUP, sigh); /* Set address structures to zero. */ memset(&local_addr, 0, sizeof(struct sockaddr_in)); memset(&server_addr, 0, sizeof(struct sockaddr_in)); /* Check arguments and set addresses. */ if (argc == 6) { local_addr.sin_family = AF_INET; local_addr.sin_addr.s_addr = INADDR_ANY; local_addr.sin_port = htons(atoi(argv[1])); server_addr.sin_family = AF_INET; inet_aton(argv[2], &server_addr.sin_addr); server_addr.sin_port = htons(atoi(argv[3])); NR_TRIPS = atoi(argv[4]); PERIOD = atoi(argv[5])*1000LL; } else { fprintf(stderr, "Usage: " "%s <local-port> " "<server-ip> <server-port> " "<number-of-trips> <sending-period-us>\n", argv[0]); return 1; } /* Create new socket. */ sockfd = rt_dev_socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { printf("Error opening socket: %d\n", sockfd); return 1; } /* Link the Linux process to RTAI. */ if (!(hard_timer_running = rt_is_hard_timer_running())) { start_rt_timer(0); } task = rt_thread_init(nam2num("SMPCLT"), 1, 0, SCHED_OTHER, 0xFF); if (task == NULL) { rt_dev_close(sockfd); printf("CANNOT LINK LINUX SIMPLECLIENT PROCESS TO RTAI\n"); return 1; } /* Lock allocated memory into RAM. */ printf("RTnet, simpleclient for RTAI (user space).\n"); mlockall(MCL_CURRENT|MCL_FUTURE); /* Switch over to hard realtime mode. */ rt_make_hard_real_time(); /* Bind socket to local address specified as parameter. */ ret = rt_dev_bind(sockfd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr_in)); /* Specify destination address for socket; needed for rt_socket_send(). */ rt_dev_connect(sockfd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)); /* Send messages */ for (i = 1; i <= NR_TRIPS && !end; i++) { rt_sleep(nano2count(PERIOD)); msg.count = i; trp = rt_get_time_ns(); rt_dev_send(sockfd, &msg, sizeof(long long) + strlen(msg.msg) + 1, 0); rt_dev_recv(sockfd, &msg, sizeof(msg), 0); trp = (msg.count - trp)/1000; if (trp < min) min = trp; if (i > 3 && trp > max) max = trp; avrg += trp; printf("Client received: trip time %lld (us), %s\n", trp, msg.msg); } msg.count = -1; rt_dev_send(sockfd, &msg, sizeof(long long) + strlen(msg.msg) + 1, 0); /* Switch over to soft realtime mode. */ rt_make_soft_real_time(); /* Close socket, must be in soft-mode because socket was created as non-rt. */ rt_dev_close(sockfd); /* Unlink the Linux process from RTAI. */ if (!hard_timer_running) { stop_rt_timer(); } rt_task_delete(task); printf("Min trip time %lld, Max trip time %lld, Average trip time %lld\n", min, max, avrg/i); return 0; }