Пример #1
0
CANDev::CANDev(std::string dev_name, uint32_t can_id, uint32_t can_mask) {
  struct sockaddr_can addr;
  struct ifreq ifr;
  
  if((dev = rt_dev_socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    std::cout<< "Error while opening socket" << std::endl;
    dev = -1;
    return;
  }

  strcpy(ifr.ifr_name, dev_name.c_str());
  rt_dev_ioctl(dev, SIOCGIFINDEX, &ifr);
  
  addr.can_family  = AF_CAN;
  addr.can_ifindex = ifr.ifr_ifindex; 

  struct can_filter rfilter[1];
  rfilter[0].can_id   = can_id;
  rfilter[0].can_mask = can_mask;

  if (rt_dev_setsockopt(dev, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
                                        sizeof(struct can_filter)) < 0)
  {
    std::cout << "Error: filter" << std::endl;
    rt_dev_close(dev);
    dev = -1;
    return;
  }
  
  if(rt_dev_bind(dev, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    std::cout << "Error in socket bind" << std::endl;
    rt_dev_close(dev);
    dev = -1;
  }
}
Пример #2
0
int main(int argc, char *argv[])
{
    int sockfd = 0;
    struct ifreq ifr[MAX_RT_DEVICES];
    short flags[MAX_RT_DEVICES];
    int devices = 0;
    struct ifconf ifc;
    struct ifreq flags_ifr;
    int i, ret;

    printf("RTnet, interface lister for RTAI/fusion\n");

    /* Create new socket. */
    sockfd = rt_dev_socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {

        printf("Error opening socket: %d\n", sockfd);
        return 1;
    }

    ifc.ifc_len = sizeof(ifr);
    ifc.ifc_req = ifr;

    ret = rt_dev_ioctl(sockfd, SIOCGIFCONF, &ifc);
    if (ret < 0) {
        rt_dev_close(sockfd);

        printf("Error retrieving device list: %d\n", ret);
        return 1;
    }

    while (ifc.ifc_len >= (int)sizeof(struct ifreq)) {
        memcpy(flags_ifr.ifr_name, ifc.ifc_req[devices].ifr_name, IFNAMSIZ);
        ret = rt_dev_ioctl(sockfd, SIOCGIFFLAGS, &flags_ifr);
        if (ret < 0) {
            rt_dev_close(sockfd);

            printf("Error retrieving flags for device %s: %d\n",
                   flags_ifr.ifr_name, ret);
            return 1;
        }
        flags[devices] = flags_ifr.ifr_flags;

        ifc.ifc_len -= sizeof(struct ifreq);
        devices++;
    }

    rt_dev_close(sockfd);

    for (i = 0; i < devices; i++)
        printf("Device %s: IP %d.%d.%d.%d, flags 0x%08X\n", ifr[i].ifr_name,
               ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr.s_addr & 0xFF,
               ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr.s_addr >> 8 & 0xFF,
               ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr.s_addr >> 16 & 0xFF,
               ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr.s_addr >> 24,
               flags[i]);

    return 0;
}
Пример #3
0
/**
 * @brief Open a CAN device
 *
 * This function opens a new socket, gets the interface index and
 * binds the socket to the CAN IDs defined in the struct @a sockaddr_can.
 *
 * @param dev Number of the CAN device (e.g. 2 if you will open rtcan2)
 * @param scan Pointer to struct sockaddr_can
 * @param scan_size Size @a scan
 * @param module Pointer the RACK module. This pointer is needed to access
 *               the global timestamp.
 *
 * @return 0 on success, otherwise negative error code
 *
 * Environments:
 *
 * This service can be called from:
 *
 * - User-space task (non-RT)
 *
 * Rescheduling: possible.
 */
int CanPort::open(int dev, sockaddr_can* scan, int scan_size, RackModule *module)
{
    int             ret;
    struct ifreq    ifr;

    if (fd != -1) // file is open
    {
        return -EBUSY;
    }

    // Prepare CAN socket and controller
    fd = rt_dev_socket(PF_CAN, SOCK_RAW, 0);
    if (fd < 0)
    {
        return fd;
    }

    // get interface index
    sprintf(ifr.ifr_name, "rtcan%d", dev);
    ret = rt_dev_ioctl(fd, RTCAN_RTIOC_GET_IFINDEX, &ifr);
    if (ret)
    {
        goto exit_error;
    }

    // Bind socket to default CAN IDs
    scan->can_family  = AF_CAN;
    scan->can_ifindex = ifr.ifr_ifindex;

    ret = rt_dev_bind(fd, (struct sockaddr *)scan, scan_size);
    if (ret)
    {
        goto exit_error;
    }

    this->module = module;
    return 0;

exit_error:
    if (fd != -1)
        close();

    return ret;
}
Пример #4
0
			void InitRT(int port)
			{
#ifdef UNIX
				if ((FD_RT = rt_dev_socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_XDDP)) < 0)
				{
					throw std::runtime_error(std::string("RT data communication failed! Port:") + std::to_string(port));
				}

				struct timeval tv;
				tv.tv_sec = 1;  /* 30 Secs Timeout */
				tv.tv_usec = 0;  // Not Init'ing this can cause strange errors
				if (rt_dev_setsockopt(FD_RT, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval)))
				{
					throw std::runtime_error(std::string("RT data communication failed! Port:") + std::to_string(port));
				}

				/*
				* Set a local 16k pool for the RT endpoint. Memory needed to
				* convey datagrams will be pulled from this pool, instead of
				* Xenomai's system pool.
				*/
				const std::size_t poolsz = 16384; /* bytes */
				if (rt_dev_setsockopt(FD_RT, SOL_XDDP, XDDP_POOLSZ, &poolsz, sizeof(poolsz)))
				{
					throw std::runtime_error(std::string("RT data communication failed! Port:") + std::to_string(port));
				}

				/*
				* Bind the socket to the port, to setup a proxy to channel
				* traffic to/from the Linux domain.
				*
				* saddr.sipc_port specifies the port number to use.
				*/
				struct sockaddr_ipc saddr;
				memset(&saddr, 0, sizeof(saddr));
				saddr.sipc_family = AF_RTIPC;
				saddr.sipc_port = port;
				if (rt_dev_bind(FD_RT, (struct sockaddr *)&saddr, sizeof(saddr)))
				{
					throw std::runtime_error(std::string("RT pipe Init failed! Port:") + std::to_string(port));
				}
#endif
			}
Пример #5
0
int tims_socket(void)
{
    return rt_dev_socket(PF_TIMS, SOCK_RAW, 0);
}
Пример #6
0
int main(int argc, char **argv)
{
    int opt, ret;
    u_int32_t id, mask;
    u_int32_t err_mask = 0;
    struct ifreq ifr;
    char *ptr;
    char name[32];

    struct option long_options[] = {
        { "help", no_argument, 0, 'h' },
        { "verbose", no_argument, 0, 'v'},
        { "filter", required_argument, 0, 'f'},
        { "error", required_argument, 0, 'e'},
        { "timeout", required_argument, 0, 't'},
        { "timestamp", no_argument, 0, 'T'},
        { "timestamp-rel", no_argument, 0, 'R'},
        { 0, 0, 0, 0},
    };

    mlockall(MCL_CURRENT | MCL_FUTURE);

    signal(SIGTERM, cleanup_and_exit);
    signal(SIGINT, cleanup_and_exit);

    while ((opt = getopt_long(argc, argv, "hve:f:t:p:RT",
                              long_options, NULL)) != -1) {
        switch (opt) {
        case 'h':
            print_usage(argv[0]);
            exit(0);

        case 'p':
            print = strtoul(optarg, NULL, 0);
            break;

        case 'v':
            verbose = 1;
            break;

        case 'e':
            err_mask = strtoul(optarg, NULL, 0);
            break;

        case 'f':
            ptr = optarg;
            while (1) {
                id = strtoul(ptr, NULL, 0);
                ptr = strchr(ptr, ':');
                if (!ptr) {
                    fprintf(stderr, "filter must be applied in the form id:mask[:id:mask]...\n");
                    exit(1);
                }
                ptr++;
                mask = strtoul(ptr, NULL, 0);
                ptr = strchr(ptr, ':');
                add_filter(id, mask);
                if (!ptr)
                    break;
                ptr++;
            }
            break;

        case 't':
            timeout = (nanosecs_rel_t)strtoul(optarg, NULL, 0) * 1000000;
            break;

        case 'R':
            timestamp_rel = 1;
        case 'T':
            with_timestamp = 1;
            break;

        default:
            fprintf(stderr, "Unknown option %c\n", opt);
            break;
        }
    }

    ret = rt_dev_socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (ret < 0) {
        fprintf(stderr, "rt_dev_socket: %s\n", strerror(-ret));
        return -1;
    }
    s = ret;

    if (argv[optind] == NULL) {
        if (verbose)
            printf("interface all\n");

        ifr.ifr_ifindex = 0;
    } else {
        if (verbose)
            printf("interface %s\n", argv[optind]);

        strncpy(ifr.ifr_name, argv[optind], IFNAMSIZ);
        if (verbose)
            printf("s=%d, ifr_name=%s\n", s, ifr.ifr_name);

        ret = rt_dev_ioctl(s, SIOCGIFINDEX, &ifr);
        if (ret < 0) {
            fprintf(stderr, "rt_dev_ioctl GET_IFINDEX: %s\n", strerror(-ret));
            goto failure;
        }
    }

    if (err_mask) {
        ret = rt_dev_setsockopt(s, SOL_CAN_RAW, CAN_RAW_ERR_FILTER,
                                &err_mask, sizeof(err_mask));
        if (ret < 0) {
            fprintf(stderr, "rt_dev_setsockopt: %s\n", strerror(-ret));
            goto failure;
        }
        if (verbose)
            printf("Using err_mask=%#x\n", err_mask);
    }

    if (filter_count) {
        ret = rt_dev_setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER,
                                &recv_filter, filter_count *
                                sizeof(struct can_filter));
        if (ret < 0) {
            fprintf(stderr, "rt_dev_setsockopt: %s\n", strerror(-ret));
            goto failure;
        }
    }

    recv_addr.can_family = AF_CAN;
    recv_addr.can_ifindex = ifr.ifr_ifindex;
    ret = rt_dev_bind(s, (struct sockaddr *)&recv_addr,
                      sizeof(struct sockaddr_can));
    if (ret < 0) {
        fprintf(stderr, "rt_dev_bind: %s\n", strerror(-ret));
        goto failure;
    }

    if (timeout) {
        if (verbose)
            printf("Timeout: %lld ns\n", (long long)timeout);
        ret = rt_dev_ioctl(s, RTCAN_RTIOC_RCV_TIMEOUT, &timeout);
        if (ret) {
            fprintf(stderr, "rt_dev_ioctl RCV_TIMEOUT: %s\n", strerror(-ret));
            goto failure;
        }
    }

    if (with_timestamp) {
        ret = rt_dev_ioctl(s, RTCAN_RTIOC_TAKE_TIMESTAMP, RTCAN_TAKE_TIMESTAMPS);
        if (ret) {
            fprintf(stderr, "rt_dev_ioctl TAKE_TIMESTAMP: %s\n", strerror(-ret));
            goto failure;
        }
    }

    snprintf(name, sizeof(name), "rtcanrecv-%d", getpid());
    ret = rt_task_shadow(&rt_task_desc, name, 0, 0);
    if (ret) {
        fprintf(stderr, "rt_task_shadow: %s\n", strerror(-ret));
        goto failure;
    }

    rt_task();
    /* never returns */

failure:
    cleanup();
    return -1;
}
Пример #7
0
CANDev::CANDev(const std::string &dev_name, const std::string &name,
               const std::vector<CANDev::FilterElement> &filter_vec)
    : frame_buf(1000),
      buf_size(0),
      dev_name_(dev_name),
      name_(name) {
  struct sockaddr_can addr;
  struct ifreq ifr;

  if ((dev = rt_dev_socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
    std::cout << "ERROR: CANDev::CANDev(" << dev_name_ << ", " << name_
              << "): error in opening socket" << std::endl;
    dev = -1;
    return;
  }

  strcpy(ifr.ifr_name, dev_name.c_str());  // NOLINT
  rt_dev_ioctl(dev, SIOCGIFINDEX, &ifr);

  addr.can_family = AF_CAN;
  addr.can_ifindex = ifr.ifr_ifindex;

  int nfilters = filter_vec.size();
  if (nfilters > 0) {
    struct can_filter *rfilter = new can_filter[nfilters];
    for (int i = 0; i < nfilters; i++) {
      rfilter[i].can_id = filter_vec[i].can_id_;
      rfilter[i].can_mask = filter_vec[i].can_mask_;
    }

    if (rt_dev_setsockopt(dev, SOL_CAN_RAW, CAN_RAW_FILTER, rfilter,
                          sizeof(struct can_filter) * nfilters) < 0) {
      std::cout << "ERROR: CANDev::CANDev(" << dev_name_ << ", " << name_
                << "): filter" << std::endl;
      rt_dev_close(dev);
      delete[] rfilter;
      dev = -1;
      return;
    }

    delete[] rfilter;
  }

// #if !defined(HAVE_RTNET)
  // TODO(my_username): check if it is working in RT
  {
    struct timeval timeout;
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    if (setsockopt(dev, SOL_SOCKET, SO_RCVTIMEO, &timeout,
                   sizeof(struct timeval)) < 0) {
      std::cout << "ERROR: CANDev::CANDev: setsockopt SO_RCVTIMEO" << std::endl;
      rt_dev_close(dev);
      dev = -1;
      return;
    }
    if (setsockopt(dev, SOL_SOCKET, SO_SNDTIMEO, &timeout,
                   sizeof(struct timeval)) < 0) {
      std::cout << "ERROR: CANDev::CANDev: setsockopt SO_SNDTIMEO" << std::endl;
      rt_dev_close(dev);
      dev = -1;
      return;
    }
  }
// #else
//    // one second timeout for receive and send
//    rt_dev_ioctl(dev, RTCAN_RTIOC_RCV_TIMEOUT, 1000000000UL);
//    rt_dev_ioctl(dev, RTCAN_RTIOC_SND_TIMEOUT, 1000000000UL);
// #endif

  if (rt_dev_bind(dev, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
    std::cout << "ERROR: CANDev::CANDev(" << dev_name_ << ", " << name_
              << "): error in socket bind" << std::endl;
    rt_dev_close(dev);
    dev = -1;
  }
}
Пример #8
0
int main(int argc, char *argv[])
{
    int ret;
    unsigned int i;
    struct sockaddr_in local_addr;
    struct in_addr dest_ip;


    while (1) {
        switch (getopt(argc, argv, "d:s:t")) {
            case 'd':
                dest_ip_s = optarg;
                break;

            case 's':
                size = atoi(optarg);
                break;

            case 't':
                start_timer = 1;
                break;

            case -1:
                goto end_of_opt;

            default:
                printf("usage: %s -d <dest_ip> -s <size> -t\n", argv[0]);
                return 0;
        }
    }
 end_of_opt:

    inet_aton(dest_ip_s, &dest_ip);

    if (size > 65505)
        size = 65505;

    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);
    signal(SIGHUP, catch_signal);
    mlockall(MCL_CURRENT|MCL_FUTURE);

    printf("destination ip address %s=%08x\n", dest_ip_s, dest_ip.s_addr);
    printf("size %d\n", size);
    printf("start timer %d\n", start_timer);

    /* fill output buffer with test pattern */
    for (i = 0; i < sizeof(buffer_out); i++)
        buffer_out[i] = i & 0xFF;

    /* create rt-socket */
    sock = rt_dev_socket(AF_INET,SOCK_DGRAM,0);
    if (sock < 0) {
        printf(" rt_dev_socket() = %d!\n", sock);
        return sock;
    }

    /* extend the socket pool */
    ret = rt_dev_ioctl(sock, RTNET_RTIOC_EXTPOOL, &add_rtskbs);
    if (ret != (int)add_rtskbs) {
        printf(" rt_dev_ioctl(RT_IOC_SO_EXTPOOL) = %d\n", ret);
        rt_dev_close(sock);
        return -1;
    }

    /* bind the rt-socket to a port */
    memset(&local_addr, 0, sizeof(struct sockaddr_in));
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(PORT);
    local_addr.sin_addr.s_addr = INADDR_ANY;
    ret = rt_dev_bind(sock, (struct sockaddr *)&local_addr,
                      sizeof(struct sockaddr_in));
    if (ret < 0) {
        printf(" rt_dev_bind() = %d!\n", ret);
        rt_dev_close(sock);
        return ret;
    }

    /* set destination address */
    memset(&dest_addr, 0, sizeof(struct sockaddr_in));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(PORT);
    dest_addr.sin_addr = dest_ip;

    if (start_timer) {
        rt_timer_start(TM_ONESHOT);
    }

    ret = rt_task_create(&rt_recv_task, "Receiver", 0, 10, 0);
    if (ret != 0) {
        printf(" rt_task_create(recv) = %d!\n", ret);
        rt_dev_close(sock);
        return ret;
    }

    ret = rt_task_create(&rt_xmit_task, "Sender", 0, 9, 0);
    if (ret != 0) {
        printf(" rt_task_create(xmit) = %d!\n", ret);
        rt_dev_close(sock);
        rt_task_delete(&rt_recv_task);
        return ret;
    }

    rt_task_start(&rt_recv_task, recv_msg, NULL);
    rt_task_start(&rt_xmit_task, xmit_msg, NULL);

    pause();

    if (start_timer)
        rt_timer_stop();

    /* Important: First close the socket! */
    while (rt_dev_close(sock) == -EAGAIN) {
        printf("frag-ip: Socket busy - waiting...\n");
        sleep(1);
    }

    rt_task_delete(&rt_xmit_task);
    rt_task_delete(&rt_recv_task);

    return 0;
}
Пример #9
0
bool GDCNetwork::initialize(char* config_filename)
{
  sockaddr_in temp_addr;

  int temp_values[4];
  int ret;

  for(int i=1; i<=MAX_DOFS; i++)
  {
    ret = read_config_int_array(config_filename, gdc_joint_names_[i], 4, temp_values);

    if(ret && temp_values[2])//check if the joint is in the config file and is active
    {
      printf("Activating Joint %s\n", gdc_joint_names_[i]);

      //we create a map between gdc states and dofs
      GDCState temp_gdcstate;
      temp_gdcstate.dof_number_ = temp_values[3];
      temp_gdcstate.card_number_ = temp_values[1];
      temp_gdcstate.joint_name_ = std::string(gdc_joint_names_[i]);
      gdc_card_states_.push_back(temp_gdcstate);

      activeDOF_[i] = true;

      //create the addressing structure
      memset(&temp_addr, 0, sizeof(temp_addr));
      temp_addr.sin_family = AF_INET;
      temp_addr.sin_addr.s_addr = generateIPAddress(GDCNetworks_[temp_values[0]], temp_values[1]);
      temp_addr.sin_port = htons(GDC_SENDING_PORT);
      remote_ip_address_.push_back(temp_addr);

      //create the receiving socket
      printf("creating socket for port %d\n",i);
      int temp_sock = rt_dev_socket(AF_INET, SOCK_DGRAM, 0);

      if(temp_sock < 0)
      {
        printf("cannot create listener sock, port %d error: %d, %s", i, errno, strerror(errno));
        return false;
      }
      //make the socket non blocking
      int64_t tout = -1;
      if(rt_dev_ioctl(temp_sock, RTNET_RTIOC_TIMEOUT, &tout) < 0)
      {
        printf("cannot make socket non-blocking, port %d error: %d, %s", i, errno, strerror(errno));
        return false;
      }
      memset(&temp_addr, 0, sizeof(temp_addr));
      temp_addr.sin_family = AF_INET;
      temp_addr.sin_addr.s_addr = generateIPAddress(GDCNetworks_[temp_values[0]], BASE_HOST_ADDRESS);
      temp_addr.sin_port = htons(REMOTE_PORT_BASE + temp_values[1]);
      printf("binding\n");

      if(rt_dev_bind(temp_sock, (struct sockaddr *)&temp_addr, sizeof(temp_addr)) < 0)
      {
        printf("cannot bind listener socket, port %d error: %d, %s", i, errno, strerror(errno));
      }

      receiving_sockets_.push_back(temp_sock);
    }
    else
      activeDOF_[i] = false;
  }

  printf("dealing with foot sensors\n.");
  for(int i=0; i<MAX_FOOT; i++)
  {
    ret = read_config_int_array(config_filename, gdc_foot_names_[i], 3, temp_values);
    if(ret && temp_values[2])//check if the foot is in the config file and is active
    {
      //create a state
      FootSensorState temp_footstate;
      temp_footstate.foot_number_ = i;
      temp_footstate.card_number_ = temp_values[1];
      temp_footstate.foot_name_ = std::string(gdc_foot_names_[i]);
      foot_sensor_states_.push_back(temp_footstate);

      active_foot_sensor_[i] = true;

      //create the addressing structure
      memset(&temp_addr, 0, sizeof(temp_addr));
      temp_addr.sin_family = AF_INET;
      temp_addr.sin_addr.s_addr = generateIPAddress(GDCNetworks_[temp_values[0]], temp_values[1]);
      temp_addr.sin_port = htons(GDC_SENDING_PORT);
      remote_ip_address_foot_sensor_.push_back(temp_addr);

      //create the receiving socket
      printf("creating socket for port %d\n",i);
      int temp_sock = rt_dev_socket(AF_INET, SOCK_DGRAM, 0);

      if(temp_sock < 0)
      {
        printf("cannot create listener sock, port %d error: %d, %s", i, errno, strerror(errno));
        return false;
      }
      //make the socket non blocking
      int64_t tout = -1;
      if(rt_dev_ioctl(temp_sock, RTNET_RTIOC_TIMEOUT, &tout) < 0)
      {
        printf("cannot make socket non-blocking, port %d error: %d, %s", i, errno, strerror(errno));
        return false;
      }
      memset(&temp_addr, 0, sizeof(temp_addr));
      temp_addr.sin_family = AF_INET;
      temp_addr.sin_addr.s_addr = generateIPAddress(GDCNetworks_[temp_values[0]], BASE_HOST_ADDRESS);
      temp_addr.sin_port = htons(REMOTE_PORT_BASE + temp_values[1]);
      printf("binding\n");

      if(rt_dev_bind(temp_sock, (struct sockaddr *)&temp_addr, sizeof(temp_addr)) < 0)
      {
        printf("cannot bind listener socket, port %d error: %d, %s", i, errno, strerror(errno));
      }

      receiving_sockets_foot_sensor_.push_back(temp_sock);
    }
  }




  //create the multicast address
  memset(&multi_cast_ip_address_, 0, sizeof(temp_addr));
  multi_cast_ip_address_.sin_family = AF_INET;
  inet_aton(NETWORK_MULTICAST_ADDRESS, &multi_cast_ip_address_.sin_addr);
  multi_cast_ip_address_.sin_port = htons(GDC_SENDING_PORT);


  //now we create a socket to send messages
  printf("creating sending socket\n");

  sender_socket_ = rt_dev_socket(AF_INET, SOCK_DGRAM, 0);

  if(sender_socket_ < 0)
  {
    printf("cannot create sender_socket, error: %d\n", sender_socket_);
    return false;
  }
  memset(&temp_addr, 0, sizeof(temp_addr));
  temp_addr.sin_family = AF_INET;
  temp_addr.sin_addr.s_addr = generateIPAddress(NETWORK_ADDRESS_1, BASE_HOST_ADDRESS);
  temp_addr.sin_port = htons(GDC_SENDING_PORT);
  printf("binding socket\n");

  if(rt_dev_bind(sender_socket_, (struct sockaddr *)&temp_addr, sizeof(temp_addr)) < 0)
  {
    printf("cannot bind sender_socket, error: %d, %s\n", errno, strerror(errno));
    return false;
  }

  //init the logging stuff
  num_of_received_messages_.resize(receiving_sockets_.size());
  num_of_received_foot_messages_.resize(receiving_sockets_foot_sensor_.size());

  return true;
}
Пример #10
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;
}
Пример #11
0
static void sync_task_func(void *arg)
{
    int             ret;
    rtdm_lockctx_t  lock_ctx;
    nanosecs_abs_t  timestamp;
    nanosecs_abs_t  timestamp_master;
    rtser_event_t   ser_rx_event;

    can_frame_t can_frame = {
        .can_id = clock_sync_can_id,
        .can_dlc = sizeof(timestamp),
    };
    struct iovec iov = {
        .iov_base = &can_frame,
        .iov_len = sizeof(can_frame_t),
    };
    struct msghdr msg = {
        .msg_name = NULL,
        .msg_namelen = 0,
        .msg_iov = &iov,
        .msg_iovlen = 1,
        .msg_control = NULL,
        .msg_controllen = 0,
    };

    if (clock_sync_mode == SYNC_CAN_SLAVE) {
        msg.msg_control = &timestamp;
        msg.msg_controllen = sizeof(timestamp);
    }

    while (1) {
        switch (clock_sync_mode) {
            case SYNC_SER_MASTER:
                timestamp = cpu_to_be64(rtdm_clock_read());

                ret = sync_dev_ctx->ops->write_rt(sync_dev_ctx, NULL,
                    &timestamp, sizeof(timestamp));
                if (ret != sizeof(timestamp)) {
                    tims_error("[CLOCK SYNC]: can't write serial time stamp, "
                               "code = %d\n", ret);
                    goto exit_task;
                }

                rtdm_task_wait_period();
                break;

            case SYNC_SER_SLAVE:
                ret = sync_dev_ctx->ops->ioctl_rt(sync_dev_ctx, NULL,
                    RTSER_RTIOC_WAIT_EVENT, &ser_rx_event);
                if (ret < 0) {
                    tims_error("[CLOCK SYNC]: can't read serial time stamp, "
                               "code = %d\n", ret);
                    goto exit_task;
                }

                ret = sync_dev_ctx->ops->read_rt(sync_dev_ctx, NULL,
                    &timestamp_master, sizeof(timestamp_master));
                if (ret != sizeof(timestamp_master)) {
                    tims_error("[CLOCK SYNC]: can't read serial time stamp, "
                               "code = %d\n", ret);
                    goto exit_task;
                }

                timestamp_master = be64_to_cpu(timestamp_master);

                rtdm_lock_get_irqsave(&sync_lock, lock_ctx);
                clock_offset =
                    timestamp_master - ser_rx_event.rxpend_timestamp;
                rtdm_lock_put_irqrestore(&sync_lock, lock_ctx);
                break;

            case SYNC_CAN_MASTER:
                // workaround for kernel working on user data
                iov.iov_len = sizeof(can_frame_t);
                iov.iov_base = &can_frame;
                // workaround end
                *(nanosecs_abs_t *)can_frame.data =
                    cpu_to_be64(rtdm_clock_read());

                ret = sync_dev_ctx->ops->sendmsg_rt(sync_dev_ctx, NULL,
                                                    &msg, 0);
                if (ret < 0) {
                    tims_error("[CLOCK SYNC]: can't send CAN time stamp, "
                               "code = %d\n", ret);
                    goto exit_task;
                }

                rtdm_task_wait_period();
                break;

            case SYNC_CAN_SLAVE:
                // workaround for kernel working on user data
                iov.iov_len = sizeof(can_frame_t);
                iov.iov_base = &can_frame;
                // workaround end

                ret = sync_dev_ctx->ops->recvmsg_rt(sync_dev_ctx, NULL,
                                                    &msg, 0);
                if (ret < 0) {
                    tims_error("[CLOCK SYNC]: can't receive CAN time stamp, "
                               "code = %d\n", ret);
                    return;
                }

                timestamp_master =
                    be64_to_cpu(*(nanosecs_abs_t *)can_frame.data);

                rtdm_lock_get_irqsave(&sync_lock, lock_ctx);
                clock_offset = timestamp_master - timestamp;
                rtdm_lock_put_irqrestore(&sync_lock, lock_ctx);
                break;
        }
    }

 exit_task:
    rtdm_context_unlock(sync_dev_ctx);
}


static __initdata char *mode_str[] = {
    "Local Clock", "RTnet", "CAN Master", "CAN Slave",
    "Serial Master", "Serial Slave"
};

static __initdata struct rtser_config sync_serial_config = {
    .config_mask        = RTSER_SET_BAUD | RTSER_SET_FIFO_DEPTH |
                          RTSER_SET_TIMESTAMP_HISTORY | RTSER_SET_EVENT_MASK,
    .baud_rate          = 115200,
    .fifo_depth         = RTSER_FIFO_DEPTH_8,
    .timestamp_history  = RTSER_RX_TIMESTAMP_HISTORY,
    .event_mask         = RTSER_EVENT_RXPEND,
};

int __init tims_clock_init(void)
{
    struct can_filter   filter;
    int                 nr_filters = 1;
    struct ifreq        can_ifr;
    struct sockaddr_can can_addr;
    int                 ret;

    if (clock_sync_mode < SYNC_NONE || clock_sync_mode > SYNC_SER_SLAVE) {
        tims_error("invalid clock_sync_mode %d", clock_sync_mode);
        return -EINVAL;
    }

    printk("TIMS: clock sync mode is %s\n", mode_str[clock_sync_mode]);
    printk("TIMS: clock sync dev is %s\n", clock_sync_dev);

    rtdm_lock_init(&sync_lock);

    switch(clock_sync_mode) {
        case SYNC_NONE:
            return 0;

        case SYNC_RTNET:
            sync_dev_fd = rt_dev_open(clock_sync_dev, O_RDONLY);
            if (sync_dev_fd < 0)
                goto sync_dev_error;
            set_bit(TIMS_INIT_BIT_SYNC_DEV, &init_flags);
            break;

        case SYNC_CAN_MASTER:
        case SYNC_CAN_SLAVE:
            sync_dev_fd = rt_dev_socket(PF_CAN, SOCK_RAW, 0);
            if (sync_dev_fd < 0) {
                tims_error("[CLOCK SYNC]: error opening CAN socket: %d\n",
                           sync_dev_fd);
                return sync_dev_fd;
            }
            set_bit(TIMS_INIT_BIT_SYNC_DEV, &init_flags);

            strcpy(can_ifr.ifr_name, clock_sync_dev);
            ret = rt_dev_ioctl(sync_dev_fd, SIOCGIFINDEX, &can_ifr);
            if (ret) {
                tims_info("[CLOCK SYNC]: error resolving CAN interface: %d\n",
                          ret);
                return ret;
            }

            if (clock_sync_mode == SYNC_CAN_MASTER)
                nr_filters = 0;
            else {
                filter.can_id   = clock_sync_can_id;
                filter.can_mask = 0xFFFFFFFF;
            }

            ret = rt_dev_setsockopt(sync_dev_fd, SOL_CAN_RAW, CAN_RAW_FILTER,
                                    &filter, nr_filters*sizeof(can_filter_t));
            if (ret < 0)
                goto config_error;

            /* Bind socket to default CAN ID */
            can_addr.can_family  = AF_CAN;
            can_addr.can_ifindex = can_ifr.ifr_ifindex;

            ret = rt_dev_bind(sync_dev_fd, (struct sockaddr *)&can_addr,
                              sizeof(can_addr));
            if (ret < 0)
                goto config_error;

            /* Enable timestamps for incoming packets */
            ret = rt_dev_ioctl(sync_dev_fd, RTCAN_RTIOC_TAKE_TIMESTAMP,
                               RTCAN_TAKE_TIMESTAMPS);
            if (ret < 0)
                goto config_error;

            /* Calculate transmission delay */
            ret = rt_dev_ioctl(sync_dev_fd, SIOCGCANBAUDRATE, &can_ifr);
            if (ret < 0)
                goto config_error;

            /* (47+64 bit) * 1.000.000.000 (ns/sec) / baudrate (bit/s) */
            sync_delay = 1000 * (111000000 / can_ifr.ifr_ifru.ifru_ivalue);
            break;

        case SYNC_SER_MASTER:
        case SYNC_SER_SLAVE:
            sync_dev_fd = rt_dev_open(clock_sync_dev, O_RDWR);
            if (sync_dev_fd < 0)
                goto sync_dev_error;
            set_bit(TIMS_INIT_BIT_SYNC_DEV, &init_flags);

            ret = rt_dev_ioctl(sync_dev_fd, RTSER_RTIOC_SET_CONFIG,
                               &sync_serial_config);
            if (ret < 0)
                goto config_error;

            /* (80 bit) * 1.000.000.000 (ns/sec) / baudrate (bit/s) */
            sync_delay = 1000 * (80000000 / sync_serial_config.baud_rate);
            break;
    }

    sync_dev_ctx = rtdm_context_get(sync_dev_fd);

    if (clock_sync_mode != SYNC_RTNET) {
        ret = rtdm_task_init(&sync_task, "TIMSClockSync", sync_task_func,
                             NULL, CLOCK_SYNC_PRIORITY, CLOCK_SYNC_PERIOD);
        if (ret < 0)
            return ret;
        set_bit(TIMS_INIT_BIT_SYNC_TASK, &init_flags);
    }

    return 0;

 sync_dev_error:
    tims_error("[CLOCK SYNC]: cannot open %s\n", clock_sync_dev);
    return sync_dev_fd;

 config_error:
    tims_info("[CLOCK SYNC]: error configuring sync device: %d\n", ret);
    return ret;
}


void tims_clock_cleanup(void)
{
    if (test_and_clear_bit(TIMS_INIT_BIT_SYNC_DEV, &init_flags))
        rt_dev_close(sync_dev_fd);

    if (test_and_clear_bit(TIMS_INIT_BIT_SYNC_TASK, &init_flags))
        rtdm_task_join_nrt(&sync_task, 100);
}
Пример #12
0
int init_module(void)
{
    int ret;
    unsigned int i;
    struct sockaddr_in local_addr;
    unsigned long dest_ip = rt_inet_aton(dest_ip_s);

    if (size > 65505)
        size = 65505;

    printk("destination ip address %s=%08x\n", dest_ip_s,
           (unsigned int)dest_ip);
    printk("size %d\n", size);
#ifdef CONFIG_RTOS_STARTSTOP_TIMER
    printk("start timer %d\n", start_timer);
#endif

    /* fill output buffer with test pattern */
    for (i = 0; i < sizeof(buffer_out); i++)
        buffer_out[i] = i & 0xFF;

    /* create rt-socket */
    sock = rt_dev_socket(AF_INET,SOCK_DGRAM,0);
    if (sock < 0) {
        printk(" rt_dev_socket() = %d!\n", sock);
        return sock;
    }

    /* extend the socket pool */
    ret = rt_dev_ioctl(sock, RTNET_RTIOC_EXTPOOL, &add_rtskbs);
    if (ret != (int)add_rtskbs) {
        printk(" rt_dev_ioctl(RT_IOC_SO_EXTPOOL) = %d\n", ret);
        rt_dev_close(sock);
        return -1;
    }

    /* bind the rt-socket to a port */
    memset(&local_addr, 0, sizeof(struct sockaddr_in));
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(PORT);
    local_addr.sin_addr.s_addr = INADDR_ANY;
    ret = rt_dev_bind(sock, (struct sockaddr *)&local_addr,
                      sizeof(struct sockaddr_in));
    if (ret < 0) {
        printk(" rt_dev_bind() = %d!\n", ret);
        rt_dev_close(sock);
        return ret;
    }

    /* set destination address */
    memset(&dest_addr, 0, sizeof(struct sockaddr_in));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(PORT);
    dest_addr.sin_addr.s_addr = dest_ip;

#ifdef CONFIG_RTOS_STARTSTOP_TIMER
    if (start_timer) {
        rtos_timer_start_oneshot();
    }
#endif

    ret = rtos_task_init(&rt_recv_task, recv_msg, 0, 9);
    if (ret != 0)
    {
        printk(" rtos_task_init(recv) = %d!\n", ret);
        rt_dev_close(sock);
        return ret;
    }

    ret = rtos_task_init_periodic(&rt_xmit_task, send_msg, 0, 10, CYCLE);
    if (ret != 0) {
        printk(" rtos_task_init_periodic(xmit) = %d!\n", ret);
        rt_dev_close(sock);
        rtos_task_delete(&rt_recv_task);
        return ret;
    }

    return 0;
}
Пример #13
0
int init_module(void)
{
    int ret;
    struct sockaddr_ll local_addr;


    /* set destination address */
    memset(&dest_addr, 0, sizeof(struct sockaddr_ll));
    dest_addr.sll_family   = AF_PACKET;
    dest_addr.sll_protocol = htons(PROTOCOL);
    dest_addr.sll_ifindex  = local_if;
    dest_addr.sll_halen    = 6;

    rt_eth_aton(dest_addr.sll_addr, dest_mac_s);

    printk("destination mac address: %02X:%02X:%02X:%02X:%02X:%02X\n",
           dest_addr.sll_addr[0], dest_addr.sll_addr[1],
           dest_addr.sll_addr[2], dest_addr.sll_addr[3],
           dest_addr.sll_addr[4], dest_addr.sll_addr[5]);
    printk("local interface: %d\n", local_if);

    /* create rt-socket */
    sock = rt_dev_socket(AF_PACKET, SOCK_DGRAM, htons(PROTOCOL));
    if (sock < 0) {
        printk(" rt_dev_socket() = %d!\n", sock);
        return sock;
    }

    /* bind the rt-socket to a port */
    memset(&local_addr, 0, sizeof(struct sockaddr_ll));
    local_addr.sll_family   = AF_PACKET;
    local_addr.sll_protocol = htons(PROTOCOL);
    local_addr.sll_ifindex  = local_if;
    ret = rt_dev_bind(sock, (struct sockaddr *)&local_addr,
                      sizeof(struct sockaddr_ll));
    if (ret < 0) {
        printk(" rt_dev_bind() = %d!\n", ret);
        goto cleanup_sock;
    }

    /* You may have to start the system timer manually
     * on older Xenomai versions (2.0.x):
     * rt_timer_start(TM_ONESHOT); */

    ret = rt_task_create(&rt_recv_task, "recv_task", 0, 9, 0);
    if (ret != 0) {
        printk(" rt_task_create(rt_recv_task) = %d!\n", ret);
        goto cleanup_sock;
    }

    ret = rt_task_start(&rt_recv_task, recv_msg, NULL);
    if (ret != 0) {
        printk(" rt_task_start(rt_recv_task) = %d!\n", ret);
        goto cleanup_recv_task;
    }

    ret = rt_task_create(&rt_xmit_task, "xmit_task", 0, 10, 0);
    if (ret != 0) {
        printk(" rt_task_create(rt_xmit_task) = %d!\n", ret);
        goto cleanup_recv_task;
    }

    ret = rt_task_set_periodic(&rt_xmit_task, TM_INFINITE, CYCLE);
    if (ret != 0) {
        printk(" rt_task_set_periodic(rt_xmit_task) = %d!\n", ret);
        goto cleanup_xmit_task;
    }

    ret = rt_task_start(&rt_xmit_task, send_msg, NULL);
    if (ret != 0) {
        printk(" rt_task_start(rt_xmit_task) = %d!\n", ret);
        goto cleanup_xmit_task;
    }

    return 0;


 cleanup_xmit_task:
    rt_task_delete(&rt_xmit_task);

 cleanup_recv_task:
    rt_task_delete(&rt_recv_task);

 cleanup_sock:
    rt_dev_close(sock);

    return ret;
}
Пример #14
0
static int _init(void)
{
	int broadcast = 1;
	int64_t timeout = -1;

	rt_printk("RtnetTest: Module initialisation started\n");

	memset(buffer_in, 0, sizeof(buffer_in));
	memset(&loc_addr, 0, sizeof (struct sockaddr_in));

	memset(buffer_out, 0, sizeof(buffer_out));
	memset(&tx_addr, 0, sizeof (struct sockaddr_in));

	loc_addr.sin_family      = AF_INET;
	loc_addr.sin_port        = htons(UDPPORT);
	loc_addr.sin_addr.s_addr = INADDR_ANY;

	tx_addr.sin_family       = AF_INET;
	tx_addr.sin_port         = htons(UDPPORT);
	tx_addr.sin_addr.s_addr  = rt_inet_aton("127.0.0.1");

	if (((mbx = rt_typed_named_mbx_init("MYMBX", 2000*sizeof(struct sample), FIFO_Q))) == NULL) {
		rt_printk("RtnetTest: Cannot create the mailbox\n");
		return -1;
	}

	if (((sock = rt_dev_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))) < 0) {
		rt_printk("RtnetTest: Error opening UDP/IP socket: %d\n", sock);
		return -1;
	}
	if (rt_dev_setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) == -1) {
		rt_printk("RtnetTest: Can't set broadcast options\n");
		goto close_socks;
	}

	rt_dev_ioctl(sock, RTNET_RTIOC_TIMEOUT, &timeout);

	if (rt_dev_bind(sock, (struct sockaddr *) &loc_addr, sizeof(struct sockaddr_in)) < 0) {
		rt_printk("RtnetTest: Can't bind the network socket");
		goto close_socks;
	}

	rt_set_periodic_mode();
	period = start_rt_timer(nano2count(WORKCYCLE));

	if (rt_task_init_cpuid(&rx_task, receiver, 0, STKSIZ, 0, 0, 0, CPU) < 0) {
		rt_printk("RtnetTest: Can't initialise the receiver task");
		goto close_socks;
	}

	if (rt_task_init_cpuid(&tx_task, sender, 0, STKSIZ, 0, 0, 0, CPU) < 0) {
		rt_printk("RtnetTest: Can't initialise the transmitter task");
		goto close_socks;
	}

	if (0 != rt_task_make_periodic(&tx_task, rt_get_time() + 20*period, period)) {
		rt_printk("RtnetTest: Make sender periodic failed\n");
		goto close_socks;
	}

	if (rt_task_resume(&rx_task) < 0) {
		rt_printk("RtnetTest: Can't start the receiver task");
		goto close_socks;
	}

	rt_printk("RtnetTest: Module initialisation completed\n");
	return 0;

close_socks:

	rt_dev_close(sock);
	rt_dev_shutdown(sock, SHUT_RDWR);
	return -1;
}
Пример #15
0
int init_module(void)
{
    int ret;
    unsigned int i;
    struct sockaddr_in local_addr;
    unsigned long dest_ip = rt_inet_aton(dest_ip_s);

    if (size > 65505)
        size = 65505;

    printk("destination ip address %s=%08x\n", dest_ip_s,
           (unsigned int)dest_ip);
    printk("size %d\n", size);

    /* fill output buffer with test pattern */
    for (i = 0; i < sizeof(buffer_out); i++)
        buffer_out[i] = i & 0xFF;

    /* create rt-socket */
    sock = rt_dev_socket(AF_INET,SOCK_DGRAM,0);
    if (sock < 0) {
        printk(" rt_dev_socket() = %d!\n", sock);
        return sock;
    }

    /* extend the socket pool */
    ret = rt_dev_ioctl(sock, RTNET_RTIOC_EXTPOOL, &add_rtskbs);
    if (ret != (int)add_rtskbs) {
        printk(" rt_dev_ioctl(RT_IOC_SO_EXTPOOL) = %d\n", ret);
        goto cleanup_sock;
    }

    /* bind the rt-socket to a port */
    memset(&local_addr, 0, sizeof(struct sockaddr_in));
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(PORT);
    local_addr.sin_addr.s_addr = INADDR_ANY;
    ret = rt_dev_bind(sock, (struct sockaddr *)&local_addr,
                      sizeof(struct sockaddr_in));
    if (ret < 0) {
        printk(" rt_dev_bind() = %d!\n", ret);
        goto cleanup_sock;
    }

    /* set destination address */
    memset(&dest_addr, 0, sizeof(struct sockaddr_in));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(PORT);
    dest_addr.sin_addr.s_addr = dest_ip;

    /* You may have to start the system timer manually
     * on older Xenomai versions (2.0.x):
     * rt_timer_start(TM_ONESHOT); */

    ret = rt_task_create(&rt_recv_task, "recv_task", 0, 9, 0);
    if (ret != 0) {
        printk(" rt_task_create(rt_recv_task) = %d!\n", ret);
        goto cleanup_sock;
    }

    ret = rt_task_start(&rt_recv_task, recv_msg, NULL);
    if (ret != 0) {
        printk(" rt_task_start(rt_recv_task) = %d!\n", ret);
        goto cleanup_recv_task;
    }

    ret = rt_task_create(&rt_xmit_task, "xmit_task", 0, 10, 0);
    if (ret != 0) {
        printk(" rt_task_create(rt_xmit_task) = %d!\n", ret);
        goto cleanup_recv_task;
    }

    ret = rt_task_set_periodic(&rt_xmit_task, TM_INFINITE, CYCLE);
    if (ret != 0) {
        printk(" rt_task_set_periodic(rt_xmit_task) = %d!\n", ret);
        goto cleanup_xmit_task;
    }

    ret = rt_task_start(&rt_xmit_task, send_msg, NULL);
    if (ret != 0) {
        printk(" rt_task_start(rt_xmit_task) = %d!\n", ret);
        goto cleanup_xmit_task;
    }

    return 0;


 cleanup_xmit_task:
    rt_task_delete(&rt_xmit_task);

 cleanup_recv_task:
    rt_dev_close(sock);
    rt_task_delete(&rt_recv_task);
    return ret;


 cleanup_sock:
    rt_dev_close(sock);

    return ret;
}
Пример #16
0
void CANSocket::open(int port) throw(std::logic_error, std::runtime_error)
{
	if (isOpen()) {
		(logMessage("CANSocket::%s(): This object is already associated with a CAN port.")
				% __func__).raise<std::logic_error>();
	}

	logMessage("CANSocket::open(%d)") % port;

	int ret;

	ret = rt_dev_socket(PF_CAN, SOCK_RAW, CAN_RAW);
	if (ret < 0) {
		close();
		(logMessage("CANSocket::%s(): Could not open CAN port. rt_dev_socket(): (%d) %s")
				% __func__ % -ret % strerror(-ret)).raise<std::runtime_error>();
	}
	handle = ret;

	struct ifreq ifr;
	char devname[10];
	sprintf(devname, "rtcan%d", port);
	strncpy(ifr.ifr_name, devname, IFNAMSIZ);

	ret = rt_dev_ioctl(handle, SIOCGCANSTATE, &ifr);
	if (ret != 0) {
		close();
		(logMessage("CANSocket::%s(): Could not open CAN port. rt_dev_ioctl(SIOCGCANSTATE): (%d) %s")
				% __func__ % -ret % strerror(-ret)).raise<std::runtime_error>();
	} else {
		// Note: The Xenomai documentation says that "ifr_ifru will be filled
		// with an instance of can_mode_t." This is a documentation bug. In
		// ksrc/drivers/can/rtcan_raw_dev.c ifr_ifru actually gets filled with
		// in instance of can_state_t, which makes a lot more sense.
		can_state_t* state = (can_state_t*) &ifr.ifr_ifru;
		if (*state != CAN_STATE_ACTIVE) {
			const int NUM_STATES = 8;
			const char canStateStrs[NUM_STATES][18] = {
					"active",
					"warning",
					"passive",
					"bus-off",
					"scanning-baudrate",
					"stopped",
					"sleeping",
					"unknown state"
			};

			int index = *state;
			if (index < 0  ||  index >= NUM_STATES) {
				index = NUM_STATES - 1;
			}
			logMessage("  WARNING: CAN_STATE is %s (%d)") % canStateStrs[index] % *state;

			if (*state == CAN_STATE_BUS_OFF) {
				logMessage("  Setting CAN_MODE = CAN_MODE_START");

				can_mode_t* mode = (can_mode_t*) &ifr.ifr_ifru;
				*mode = CAN_MODE_START;
				ret = rt_dev_ioctl(handle, SIOCSCANMODE, &ifr);
				if (ret != 0) {
					close();
					(logMessage("CANSocket::%s(): Could not open CAN port. rt_dev_ioctl(SIOCSCANMODE): (%d) %s")
							% __func__ % -ret % strerror(-ret)).raise<std::runtime_error>();
				}

				// According to Xenomai documentation, the transition from
				// bus-off to active takes at least 128 * 11 * 1e-6 = 0.0014
				// seconds and there's no way to detect when it's done :(
				btsleep(0.1);
			}
		}
	}

	struct can_filter recvFilter[1];
	recvFilter[0].can_id = (Puck::HOST_ID << Puck::NODE_ID_WIDTH) | CAN_INV_FILTER;
	recvFilter[0].can_mask = Puck::FROM_MASK;
	ret = rt_dev_setsockopt(handle, SOL_CAN_RAW, CAN_RAW_FILTER, &recvFilter, sizeof(recvFilter));
	if (ret != 0) {
		close();
		(logMessage("CANSocket::%s(): Could not open CAN port. rt_dev_setsockopt(CAN_RAW_FILTER): (%d) %s")
				% __func__ % -ret % strerror(-ret)).raise<std::runtime_error>();
	}

	// Note: This must be done after the rt_dev_ioctl(SIOCGCANSTATE) call above,
	// otherwise rt_dev_send() will fail with ret = -6 (No such device or
	// address). The ifr.ifr_index gets overwritten because it is actually a
	// member of the ifr.ifr_ifru union.
	ret = rt_dev_ioctl(handle, SIOCGIFINDEX, &ifr);
	if (ret != 0) {
		close();
		(logMessage("CANSocket::%s(): Could not open CAN port. rt_dev_ioctl(SIOCGIFINDEX): (%d) %s")
				% __func__ % -ret % strerror(-ret)).raise<std::runtime_error>();
	}

	struct sockaddr_can toAddr;
	memset(&toAddr, 0, sizeof(toAddr));
	toAddr.can_ifindex = ifr.ifr_ifindex;
	toAddr.can_family = AF_CAN;
	ret = rt_dev_bind(handle, (struct sockaddr *) &toAddr, sizeof(toAddr));
	if (ret != 0) {
		close();
		(logMessage("CANSocket::%s(): Could not open CAN port. rt_dev_bind(): (%d) %s")
				% __func__ % -ret % strerror(-ret)).raise<std::runtime_error>();
	}

	nanosecs_rel_t timeout = (nanosecs_rel_t) CommunicationsBus::TIMEOUT;
	ret = rt_dev_ioctl(handle, RTCAN_RTIOC_RCV_TIMEOUT, &timeout);
	if (ret != 0) {
		close();
		(logMessage("CANSocket::%s(): Could not open CAN port. rt_dev_ioctl(RCV_TIMEOUT): (%d) %s")
				% __func__ % -ret % strerror(-ret)).raise<std::runtime_error>();
	}
	ret = rt_dev_ioctl(handle, RTCAN_RTIOC_SND_TIMEOUT, &timeout);
	if (ret != 0) {
		close();
		(logMessage("CANSocket::%s(): Could not open CAN port. rt_dev_ioctl(SND_TIMEOUT): (%d) %s")
				% __func__ % -ret % strerror(-ret)).raise<std::runtime_error>();
	}
}
Пример #17
0
int main(int argc, char **argv)
{
    int i, opt, ret;
    struct ifreq ifr;
    char name[32];

    struct option long_options[] = {
	{ "help", no_argument, 0, 'h' },
	{ "identifier", required_argument, 0, 'i'},
	{ "rtr", no_argument, 0, 'r'},
	{ "extended", no_argument, 0, 'e'},
	{ "verbose", no_argument, 0, 'v'},
	{ "count", no_argument, 0, 'c'},
	{ "print", required_argument, 0, 'p'},
	{ "loop", required_argument, 0, 'l'},
	{ "delay", required_argument, 0, 'd'},
	{ "send", no_argument, 0, 's'},
	{ "timeout", required_argument, 0, 't'},
	{ "loopback", required_argument, 0, 'L'},
	{ 0, 0, 0, 0},
    };

    mlockall(MCL_CURRENT | MCL_FUTURE);

    signal(SIGTERM, cleanup_and_exit);
    signal(SIGINT, cleanup_and_exit);

    frame.can_id = 1;

    while ((opt = getopt_long(argc, argv, "hvi:l:red:t:cp:sL:",
			      long_options, NULL)) != -1) {
	switch (opt) {
	case 'h':
	    print_usage(argv[0]);
	    exit(0);

	case 'p':
	    print = strtoul(optarg, NULL, 0);

	case 'v':
	    verbose = 1;
	    break;

	case 'c':
	    count = 1;
	    break;

	case 'l':
	    loops = strtoul(optarg, NULL, 0);
	    break;

	case 'i':
	    frame.can_id = strtoul(optarg, NULL, 0);
	    break;

	case 'r':
	    rtr = 1;
	    break;

	case 'e':
	    extended = 1;
	    break;

	case 'd':
	    delay = strtoul(optarg, NULL, 0) * 1000000LL;
	    break;

	case 's':
	    use_send = 1;
	    break;

	case 't':
	    timeout = strtoul(optarg, NULL, 0) * 1000000LL;
	    break;

	case 'L':
	    loopback = strtoul(optarg, NULL, 0);
	    break;

	default:
	    fprintf(stderr, "Unknown option %c\n", opt);
	    break;
	}
    }

    if (optind == argc) {
	print_usage(argv[0]);
	exit(0);
    }

    if (argv[optind] == NULL) {
	fprintf(stderr, "No Interface supplied\n");
	exit(-1);
    }

    if (verbose)
	printf("interface %s\n", argv[optind]);

    ret = rt_dev_socket(PF_CAN, SOCK_RAW, CAN_RAW);
    if (ret < 0) {
	fprintf(stderr, "rt_dev_socket: %s\n", strerror(-ret));
	return -1;
    }
    s = ret;

    if (loopback >= 0) {
	ret = rt_dev_setsockopt(s, SOL_CAN_RAW, CAN_RAW_LOOPBACK,
				&loopback, sizeof(loopback));
	if (ret < 0) {
	    fprintf(stderr, "rt_dev_setsockopt: %s\n", strerror(-ret));
	    goto failure;
	}
	if (verbose)
	    printf("Using loopback=%d\n", loopback);
    }

    strncpy(ifr.ifr_name, argv[optind], IFNAMSIZ);
    if (verbose)
	printf("s=%d, ifr_name=%s\n", s, ifr.ifr_name);

    ret = rt_dev_ioctl(s, SIOCGIFINDEX, &ifr);
    if (ret < 0) {
	fprintf(stderr, "rt_dev_ioctl: %s\n", strerror(-ret));
	goto failure;
    }

    memset(&to_addr, 0, sizeof(to_addr));
    to_addr.can_ifindex = ifr.ifr_ifindex;
    to_addr.can_family = AF_CAN;
    if (use_send) {
	/* Suppress definiton of a default receive filter list */
	ret = rt_dev_setsockopt(s, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0);
	if (ret < 0) {
	    fprintf(stderr, "rt_dev_setsockopt: %s\n", strerror(-ret));
	    goto failure;
	}

	ret = rt_dev_bind(s, (struct sockaddr *)&to_addr, sizeof(to_addr));
	if (ret < 0) {
	    fprintf(stderr, "rt_dev_bind: %s\n", strerror(-ret));
	    goto failure;
	}
    }

    if (count)
	frame.can_dlc = sizeof(int);
    else {
	for (i = optind + 1; i < argc; i++) {
	    frame.data[dlc] = strtoul(argv[i], NULL, 0);
	    dlc++;
	    if( dlc == 8 )
		break;
	}
	frame.can_dlc = dlc;
    }

    if (rtr)
	frame.can_id |= CAN_RTR_FLAG;

    if (extended)
	frame.can_id |= CAN_EFF_FLAG;

    if (timeout) {
	if (verbose)
	    printf("Timeout: %lld ns\n", (long long)timeout);
	ret = rt_dev_ioctl(s, RTCAN_RTIOC_SND_TIMEOUT, &timeout);
	if (ret) {
	    fprintf(stderr, "rt_dev_ioctl SND_TIMEOUT: %s\n", strerror(-ret));
	    goto failure;
	}
    }

    snprintf(name, sizeof(name), "rtcansend-%d", getpid());
    ret = rt_task_shadow(&rt_task_desc, name, 1, 0);
    if (ret) {
	fprintf(stderr, "rt_task_shadow: %s\n", strerror(-ret));
	goto failure;
    }

    rt_task();

    cleanup();
    return 0;

 failure:
    cleanup();
    return -1;
}