Example #1
0
void taskh_func(long tid)
{
	RTIME time;
	unsigned int msg = 0, wait;
	rt_send(&taskm, msg);
	rt_send(&taskl, msg);
	while (1) {
		rt_receive(&taskm, &msg);
		time = rt_get_time_ns();
		if (MUTEX_LOCK(&mutex) <= 1) {
			if ((wait = (int)(rt_get_time_ns() - time)) > 250000) {
				rt_printk("PRIORITY INVERSION, WAITED FOR %d us\n", wait/1000);
			} else {
				rt_printk("NO PRIORITY INVERSION, WAITED FOR %d us\n", wait/1000);
			}
			if (SemType) {
				MUTEX_LOCK(&mutex);
				MUTEX_LOCK(&mutex);
				rt_busy_sleep(100000);
				MUTEX_LOCK(&mutex);
			}
			rt_busy_sleep(100000);
			if (SemType) {
				rt_sem_signal(&mutex);
				rt_busy_sleep(100000);
				rt_sem_signal(&mutex);
				rt_sem_signal(&mutex);
			}
			rt_sem_signal(&mutex);
		} else {
			rt_task_suspend(0);
		}
	}
}
int signal_func(void *param)
{
    RT_TASK *rt_signal;
    //TODO: RTIME sampling;
    int value = 0;
    int rval = 0;
    char name[8];
    t_info *t = param;

    snprintf(name, 8, "S_%c", t->id);
    printf("%s\n", name);
    rt_signal = rt_thread_init(nam2num(name), 0, 0, SCHED_FIFO, CPUMAP);
    if (!rt_signal) {
        printf("Could not init real time signal %c\n", t->id);
        rval = -ENODEV;
        goto exit;
    }

    rt_task_make_periodic(rt_signal, rt_get_time() + t->period +
                          t->delay, t->period);
    while (!finish) {
        value = !value;
        printf("[%Ld] signal %c now in %s.\n",
               rt_get_time_ns(),
               t->id,
               value ? "up" : "down");
        rt_task_wait_period();
    }
    rt_task_delete(rt_signal);

exit:
    pthread_exit(NULL);
    return rval;
}
void process(void* arg)
{
    while(1) {
        rt_sem_wait(&tx_sem);

        tx_time = rt_get_time_ns();

        /* send the time   */
        if (sendto_rt(sock, &tx_time, sizeof(RTIME), 0,
                      (struct sockaddr *) &server_addr,
                      sizeof(struct sockaddr_in)) < 0)
            break;
    }
}
void *process(void * arg)
{
	int ret = 0;

	while(1) {
		rt_sem_wait(&tx_sem);

                /* get time        */
                tx_time = rt_get_time_ns();

                /* send the time   */    
		ret=rt_socket_sendto(sock, &tx_time, sizeof(RTIME), 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
	}
}
Example #5
0
void *process(void * arg)
{
	int ret = 0;

	while(1) {
                /* get time        */
                tx_time = rt_get_time_ns();

                /* send the time   */    
		ret=rt_socket_sendto(sock, &tx_time, sizeof(RTIME), 0, (struct sockaddr *) &broadcast_addr, sizeof(struct sockaddr_in));

	        /* wait one period */ 
	        rt_task_wait_period();
	}
}
int echo_rcv(int s,void *arg)
{
	int			ret=0;
	struct msghdr		msg;
	struct iovec		iov;
	struct sockaddr_in	addr;
	

	memset(&msg,0,sizeof(msg));
	iov.iov_base=&buffer;
	iov.iov_len=BUFSIZE;

	msg.msg_name=&addr;
	msg.msg_namelen=sizeof(addr);
	msg.msg_iov=&iov;
	msg.msg_iovlen=1;
	msg.msg_control=NULL;
	msg.msg_controllen=0;

	ret=rt_socket_recvmsg(sock, &msg, 0);

	if ( (ret>0) && (msg.msg_namelen==sizeof(struct sockaddr_in)) ) {
		
		union { unsigned long l; unsigned char c[4]; } rcv;
		struct sockaddr_in *sin = msg.msg_name;

                outb(0x08, PAR_DATA);
                outb(0x18, PAR_DATA);
		
		/* get the time    */
		rx_time = rt_get_time_ns();
		memcpy (&tx_time, buffer, sizeof(RTIME));

		rtf_put(PRINT, &rx_time, sizeof(RTIME));
		rtf_put(PRINT, &tx_time, sizeof(RTIME));

		/* copy the address */
		rcv.l = sin->sin_addr.s_addr;
		
		//rt_sem_signal(&tx_sem);
	}

	return 0;
}
Example #7
0
int echo_rcv(int s,void *arg)
{
	int			ret=0;
	struct msghdr		msg;
	struct iovec		iov;
	struct sockaddr_in	addr;
	struct mrtt_rx_packet	rx_packet;

	if (closing)
		rt_printk("In echo_rcv\n");
	memset(&msg, 0, sizeof(msg));
	iov.iov_base = &buffer;
	iov.iov_len = BUFSIZE;

	msg.msg_name = &addr;
	msg.msg_namelen = sizeof(addr);
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = NULL;
	msg.msg_controllen = 0;

	ret = rt_socket_recvmsg(sock, &msg, 0);

	if ( (ret>0) && (msg.msg_namelen==sizeof(struct sockaddr_in)) ) {
		struct sockaddr_in *sin = msg.msg_name;
		
		/* get the time    */
		rx_time = rt_get_time_ns();
		memcpy(&tx_time, buffer, sizeof(RTIME));

		rx_packet.rx = rx_time;
		rx_packet.tx = tx_time;
		rx_packet.ip_addr = sin->sin_addr.s_addr;

		rtf_put(PRINT, &rx_packet, sizeof(struct mrtt_rx_packet));
	}

	if (closing)
		rt_printk("Exit echo_rcv\n");
	return 0;
}
Example #8
0
void
init_uniform (void)
{
#ifdef USER_MODE
  struct timeval  tv;
  struct timezone tz;

  gettimeofday (&tv, &tz);
  seed = (int) tv.tv_usec;
#ifdef NODE_MT
#warning TO DO seed = mobileId
  //seed += mobileId;
#endif
#ifdef NODE_RG
#warning TO DO seed = rgId
  //seed += rgId;
#endif
#else
  seed = rt_get_time_ns();
#endif
}
void echo_rcv(void *arg)
{
    int                 ret;
    struct msghdr       msg;
    struct iovec        iov;
    struct sockaddr_in  addr;


    while (1) {
        iov.iov_base=&buffer;
        iov.iov_len=BUFSIZE;

        msg.msg_name=&addr;
        msg.msg_namelen=sizeof(addr);
        msg.msg_iov=&iov;
        msg.msg_iovlen=1;
        msg.msg_control=NULL;
        msg.msg_controllen=0;

        ret = recvmsg_rt(sock, &msg, 0);

        if ((ret > 0) && (msg.msg_namelen == sizeof(struct sockaddr_in))) {
            union { unsigned long l; unsigned char c[4]; } rcv;
            struct sockaddr_in *sin = msg.msg_name;

            outb(0xEF, PAR_DATA);
            outb(0xFF, PAR_DATA);

            /* get the time    */
            rx_time = rt_get_time_ns();
            memcpy (&tx_time, buffer, sizeof(RTIME));

            rtf_put(PRINT_FIFO, &rx_time, sizeof(RTIME));
            rtf_put(PRINT_FIFO, &tx_time, sizeof(RTIME));

            /* copy the address */
            rcv.l = sin->sin_addr.s_addr;
        }
    }
}
/* Write an individual PDU (PCAP packet header + mac-context + mac-pdu) */
static int MAC_LTE_PCAP_WritePDU(MAC_Context_Info_t *context,
                                 const uint8_t *PDU, unsigned int length)
{
  pcaprec_hdr_t packet_header;
  uint8_t context_header[256];
  int offset = 0;
  unsigned short tmp16;

  /*****************************************************************/
  /* Context information (same as written by UDP heuristic clients */
  context_header[offset++] = context->radioType;
  context_header[offset++] = context->direction;
  context_header[offset++] = context->rntiType;

  /* RNTI */
  context_header[offset++] = MAC_LTE_RNTI_TAG;
  tmp16 = htons(context->rnti);
  memcpy(context_header+offset, &tmp16, 2);
  offset += 2;

  /* UEId */
  context_header[offset++] = MAC_LTE_UEID_TAG;
  tmp16 = htons(context->ueid);
  memcpy(context_header+offset, &tmp16, 2);
  offset += 2;

  /* Subframe number */
  context_header[offset++] = MAC_LTE_SUBFRAME_TAG;
  tmp16 = htons(context->subFrameNumber);
  memcpy(context_header+offset, &tmp16, 2);
  offset += 2;

  /* CRC Status */
  context_header[offset++] = MAC_LTE_CRC_STATUS_TAG;
  context_header[offset++] = context->crcStatusOK;

  /* Data tag immediately preceding PDU */
  context_header[offset++] = MAC_LTE_PAYLOAD_TAG;

  /****************************************************************/
  /* PCAP Header                                                  */
  /* TODO: Timestamp might want to be relative to a more sensible
     base time... */
#if defined(RTAI)
  {
    unsigned long long int current_ns;

    current_ns = rt_get_time_ns();
    packet_header.ts_sec  = current_ns / 1000000000UL;
    packet_header.ts_usec = current_ns % 1000;
  }
#else
  packet_header.ts_sec = context->subframesSinceCaptureStart / 1000;
  packet_header.ts_usec = (context->subframesSinceCaptureStart % 1000) * 1000;
#endif
  packet_header.incl_len = offset + length;
  packet_header.orig_len = offset + length;

  /***************************************************************/
  /* Now write everything to the file                            */
  fwrite(&packet_header, sizeof(pcaprec_hdr_t), 1, file_fd);
  fwrite(context_header, 1, offset, file_fd);
  fwrite(PDU, 1, length, file_fd);

  return 1;
}
Example #11
0
int PLLReferenceGeneration()
 {
    //Initial test function to try out Real time stuff.
    int m, i=0, err, n;
    lsampl_t data_to_card;
    static comedi_t * dev;
    static int OutputFIFOBufferSize;
    static int PLLGenerationBufferSize;
	unsigned int maxdata;
	unsigned int chanlist[16];
	int ret;
    static lsampl_t data[PLLGenerationBufferNPoints]; //this is the buffer used to send data points out
    comedi_cmd cmd;

    dev = comedi_open(device_names[PLLReferenceGenerationChannel.board_number]);

    //Check the size of the output buffer
    OutputFIFOBufferSize = comedi_get_buffer_size(dev, PLLReferenceGenerationChannel.subdevice);
    rt_printk("OutputFIFO Buffer size is %i\n", OutputFIFOBufferSize);

    //Set the actual buffer size that we will be using to half this and the number of data points to one fourth
    //Now configure the output channel using a Comedi instruction
    //BufferSize is initially set to be double the number of PLLGenerationBufferNPoints
    PLLGenerationBufferSize = 2*PLLGenerationBufferNPoints;


	maxdata = comedi_get_maxdata(dev, PLLReferenceGenerationChannel.subdevice, PLLReferenceGenerationChannel.channel);
	rt_printk("PLL Reference channel max data is %i\n", maxdata);

	offset = maxdata / 2;
	amplitude = maxdata - offset;

	memset(&cmd,0,sizeof(cmd));
	cmd.subdev = PLLReferenceGenerationChannel.subdevice;
	cmd.flags = CMDF_WRITE;
	cmd.start_src = TRIG_INT;
	cmd.start_arg = 0;
	cmd.scan_begin_src = TRIG_TIMER;
	cmd.scan_begin_arg = PLLGenMinPulseTime;  //minimum update time for the
	cmd.convert_src = TRIG_NOW;
	cmd.convert_arg = 0;
	cmd.scan_end_src = TRIG_COUNT;
	cmd.scan_end_arg = NCHAN; //only one channel
	cmd.stop_src = TRIG_NONE;
	cmd.stop_arg = 0;

	cmd.chanlist = chanlist;
	cmd.chanlist_len = NCHAN;

	chanlist[0] = CR_PACK(PLLReferenceGenerationChannel.channel, AO_RANGE, AREF_GROUND);

	dds_init(PLLWaveformFrequency, PLLUpdateFrequency);

	err = comedi_command_test(dev, &cmd);
	if (err < 0) {
		comedi_perror("comedi_command_test");
		exit(1);
	}

	err = comedi_command_test(dev, &cmd);
	if (err < 0) {
		comedi_perror("comedi_command_test");
		exit(1);
	}

	if ((err = comedi_command(dev, &cmd)) < 0) {
		comedi_perror("comedi_command");
		exit(1);
	}

	dds_output(data,PLLGenerationBufferNPoints);
	n = PLLGenerationBufferNPoints * sizeof(sampl_t);
	m = write(comedi_fileno(dev), (void *)data, n);
	if(m < 0){
		perror("write");
		exit(1);
	}else if(m < n)
	{
		fprintf(stderr, "failed to preload output buffer with %i bytes, is it too small?\n"
			"See the --write-buffer option of comedi_config\n", n);
		exit(1);
	}

    if(!(PLLRefGen_Task = rt_task_init_schmod(nam2num( "PLLReferenceGeneration" ), // Name
                                        2, // Priority
                                        0, // Stack Size
                                        0, //, // max_msg_size
                                        SCHED_FIFO, // Policy
                                        CPUMAP ))) // cpus_allowed
        {
            printf("ERROR: Cannot initialize pll reference generation task\n");
            exit(1);
        }

    //specify that this is to run on one CPU
    rt_set_runnable_on_cpuid(PLLRefGen_Task, 1);
    //Convert samp_time, which is in nanoseconds, to tick time
    //sampling_interval = nano2count(SAMP_TIME);  //Converts a value from
                                                //nanoseconds to internal count units.
    mlockall(MCL_CURRENT|MCL_FUTURE);
    rt_make_hard_real_time();
    PLLUpdateTime = nano2count(PLLGenerationLoopTime);
    rt_printk("PLL generation update time is %f12 \n",count2nano((float) PLLUpdateTime));
    // Let's make this task periodic..
    expected = rt_get_time() + 100*PLLUpdateTime;



    rt_task_make_periodic(PLLRefGen_Task, expected, PLLUpdateTime); //period in counts
    //rt_task_resume(Sinewaveloop_Task);
    PLLGenerationOn = TRUE;



    // Concurrent function Loop


     //rt_printk("SineWaveAmplitude is is %f \n",SineWaveAmplitude);
     //rt_printk("SineWaveFrequency is %f \n",SineWaveFrequency);
     //rt_printk("sine_loop_running is %d \n",sine_loop_running);
     //rt_printk("SAMP_TIME is %d \n",SAMP_TIME);
     start_time = (float)rt_get_time_ns()/1E9; //in seconds
     old_time = start_time;
     rt_printk("PLLReferenceGenerationChannel board_it is %p \n",PLLReferenceGenerationChannel.board_id);
     rt_printk("PLLReferenceGenerationChannel devicename is %p \n",*(PLLReferenceGenerationChannel.devicename));
     rt_printk("PLLReferenceGenerationChannel boardname is %p \n",*(PLLReferenceGenerationChannel.boardname));
     rt_printk("PLLReferenceGenerationChannel subdevice is %d \n",PLLReferenceGenerationChannel.subdevice);
     rt_printk("PLLReferenceGenerationChannel channel is %d \n",PLLReferenceGenerationChannel.channel);
     OutputValue = 1;
     PLLGenerationBufferSize = comedi_get_buffer_size(dev, PLLReferenceGenerationChannel.subdevice);
     //sine_loop_running = 0;  //set this to 0 for testing
     while(PLLGenerationOn)
     {
        i++; // Count Loops.
        current_time = (float)rt_get_time_ns()/1E9;
        //rt_printk("LOOP %d,-- Period time: %f12 %f12\n",i, current_time - old_time,count2nano((float)sampling_interval)/1E9);
        OutputValue = SineWaveAmplitude*sin(2*PI*SineWaveFrequency*(current_time-start_time));
        //OutputValue = -1*OutputValue;
        //rt_printk("OutputValue is %f12 \n",OutputValue);
        data_to_card = (lsampl_t) nearbyint(((OutputValue - MinOutputVoltage)/OutputRange)*MaxOutputBits);
        //m=rt_comedi_command_data_write(AnalogOutputChannel.board_id, AnalogOutputChannel.subdevice, NCHAN, data_to_card);
        comedi_lock(dev, AnalogOutputChannel.subdevice);
        m=comedi_data_write(dev, AnalogOutputChannel.subdevice, AnalogOutputChannel.channel, AO_RANGE, AREF_DIFF, data_to_card);
        comedi_unlock(dev, AnalogOutputChannel.subdevice);
//        m=comedi_data_write(AnalogOutputChannel.board_id, AnalogOutputChannel.subdevice,
//               AnalogOutputChannel.channel, AO_RANGE, AREF_GROUND, data_to_card);
        //rt_printk("Data_to_card is %d; result from rt_comedi_command_data_write is %d \n",data_to_card, m);
        //rt_printk("LOOP %d,-- AO Out time: %f12 \n",i, (float)rt_get_time_ns()/1E9 - current_time);
        //rt_printk("Data_to_card is %d \n",data_to_card);
        //old_time = current_time;
/*        if (i== 100000)
        {
            sine_loop_running = 0;
            //printf("LOOP -- run: %d %d\n ",keep_on_running,&keep_on_running);
            //printf("RTAI LOOP -- run: %d \n ",i);
            break;
        }
*/
        rt_task_wait_period(); // And waits until the end of the period.

    }
    rt_make_soft_real_time();
    comedi_close(dev);
    rt_task_delete(Sinewaveloop_Task); //Self termination at end.

    pthread_exit(NULL);
    return 0;
 }
Example #12
0
NANO_TIME rtos_get_time_ns(void) { return rt_get_time_ns(); }
Example #13
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;
}
/** RX_PDSCH Decoding Thread */
static void * rx_pdsch_thread(void *param) {

  //unsigned long cpuid;
  uint8_t rx_pdsch_thread_index = 0;
  uint8_t dlsch_thread_index = 0;
  uint8_t pilot1,pilot2,pilot3,harq_pid,subframe;
  //  uint8_t last_slot;

  uint8_t dual_stream_UE = 0;
  uint8_t i_mod = 0;

  RTIME time_in,time_out;
#ifdef RTAI
  RT_TASK *task;
#endif

  int m,eNB_id = 0;
  int eNB_id_i = 1;
  PHY_VARS_UE *UE = PHY_vars_UE_g[0];

#ifdef RTAI
  task = rt_task_init_schmod(nam2num("RX_PDSCH_THREAD"), 0, 0, 0, SCHED_FIFO, 0xF);

  if (task==NULL) {
    LOG_E(PHY,"[SCHED][RX_PDSCH] Problem starting rx_pdsch thread!!!!\n");
    return 0;
  }
  else {
    LOG_I(PHY,"[SCHED][RX_PDSCH] rx_pdsch_thread started for with id %p\n",task);
  }
#endif

  mlockall(MCL_CURRENT | MCL_FUTURE);

  //rt_set_runnable_on_cpuid(task,1);
  //cpuid = rtai_cpuid();

#ifdef HARD_RT
  rt_make_hard_real_time();
#endif

  if (UE->lte_frame_parms.Ncp == 0) {  // normal prefix
    pilot1 = 4;
    pilot2 = 7;
    pilot3 = 11;
  }
  else {  // extended prefix
    pilot1 = 3;
    pilot2 = 6;
    pilot3 = 9;
  }


  while (!oai_exit){
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_THREAD, 0);
    if (pthread_mutex_lock(&rx_pdsch_mutex) != 0) {
      LOG_E(PHY,"[SCHED][RX_PDSCH] error locking mutex.\n");
    }
    else {
      while (rx_pdsch_instance_cnt < 0) {
	pthread_cond_wait(&rx_pdsch_cond,&rx_pdsch_mutex);
      }
      
      if (pthread_mutex_unlock(&rx_pdsch_mutex) != 0) {	
	LOG_E(PHY,"[SCHED][RX_PDSCH] error unlocking mutex.\n");
      }
    }
    
    vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_THREAD, 1);
 
    //      last_slot = rx_pdsch_slot;
      subframe = UE->slot_rx>>1;
      // Important! assumption that PDCCH procedure of next SF is not called yet
      harq_pid = UE->dlsch_ue[eNB_id][0]->current_harq_pid;
      UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->G = get_G(&UE->lte_frame_parms,
                                                                            UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->nb_rb,
                                                                            UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->rb_alloc,
                                                                            get_Qm(UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs),  
									    UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->Nl,
									    UE->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols,
                                                                            UE->frame_rx,subframe);

      if ((UE->transmission_mode[eNB_id] == 5) && 
          (UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->dl_power_off==0) &&
          (openair_daq_vars.use_ia_receiver > 0)) {
	dual_stream_UE = 1;
	eNB_id_i = UE->n_connected_eNB;
	if (openair_daq_vars.use_ia_receiver == 2) {
	  i_mod =  get_Qm(((UE->frame_rx%1024)/3)%28);
	} else {
	  i_mod =  get_Qm(UE->dlsch_ue[eNB_id][0]->harq_processes[harq_pid]->mcs);
	}
      }
      else {
          dual_stream_UE = 0;
          eNB_id_i = eNB_id+1;
          i_mod = 0;
      }

    if (oai_exit) break;

    LOG_D(PHY,"[SCHED][RX_PDSCH] Frame %d, slot %d: Calling rx_pdsch_decoding with harq_pid %d\n",UE->frame_rx,UE->slot_rx,harq_pid);

    time_in = rt_get_time_ns();

    // Check if we are in even or odd slot
    if (UE->slot_rx%2) { // odd slots

        // measure time
        //time0 = rt_get_time_ns();
        //        rt_printk("[SCHED][RX_PDSCH][before rx_pdsch] Frame %d, slot %d, time %llu\n",UE->frame,last_slot,rt_get_time_ns());
        for (m=pilot2;m<UE->lte_frame_parms.symbols_per_tti;m++) {

            rx_pdsch(UE,
                     PDSCH,
                     eNB_id,
                     eNB_id_i,
                     subframe,
                     m,
                     0,
                     dual_stream_UE,
                     i_mod,
                     harq_pid);
            
        }
        //        time1 = rt_get_time_ns();
        //        rt_printk("[SCHED][RX_PDSCH] Frame %d, slot %d, start %llu, end %llu, proc time: %llu ns\n",UE->frame_rx,last_slot,time0,time1,(time1-time0));

        dlsch_thread_index = harq_pid;
	
        if (pthread_mutex_lock (&dlsch_mutex[dlsch_thread_index]) != 0) {               // Signal MAC_PHY Scheduler
            LOG_E(PHY,"[UE  %d] ERROR pthread_mutex_lock\n",UE->Mod_id);     // lock before accessing shared resource
            //	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
            //return(-1);
        }
        dlsch_instance_cnt[dlsch_thread_index]++;
        dlsch_subframe[dlsch_thread_index] = subframe;
        pthread_mutex_unlock (&dlsch_mutex[dlsch_thread_index]);
        
        if (dlsch_instance_cnt[dlsch_thread_index] == 0) {
            if (pthread_cond_signal(&dlsch_cond[dlsch_thread_index]) != 0) {
                LOG_E(PHY,"[UE  %d] ERROR pthread_cond_signal for dlsch_cond[%d]\n",UE->Mod_id,dlsch_thread_index);
                //	  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
                //return(-1);
            }
        }
        else {
            LOG_W(PHY,"[UE  %d] DLSCH thread for dlsch_thread_index %d busy!!!\n",UE->Mod_id,dlsch_thread_index);
            //	vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT);
            //return(-1);
        }
        
    } else { // even slots

        for (m=UE->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols;m<pilot2;m++) { 

            rx_pdsch(UE,
                     PDSCH,
                     eNB_id,
                     eNB_id_i,
                     subframe,
                     m,
                     (m==UE->lte_ue_pdcch_vars[eNB_id]->num_pdcch_symbols)?1:0,   // first_symbol_flag
                     dual_stream_UE,
                     i_mod,
                     harq_pid);
        }
    }    
    
    time_out = rt_get_time_ns();
    
    if (pthread_mutex_lock(&rx_pdsch_mutex) != 0) {
        msg("[openair][SCHED][RX_PDSCH] error locking mutex.\n");
    }
    else {
        rx_pdsch_instance_cnt--;
        
        if (pthread_mutex_unlock(&rx_pdsch_mutex) != 0) {	
            msg("[openair][SCHED][RX_PDSCH] error unlocking mutex.\n");
        }
    }
    
  }

#ifdef HARD_RT
  rt_make_soft_real_time();
#endif

  LOG_D(PHY,"[openair][SCHED][RX_PDSCH] RX_PDSCH thread exiting\n");  

  return 0;
}
Example #15
0
void* TrackerSim::_thread(void *arg)
{
	RT_TASK *rt_task;
	RTIME interval = nano2count(_read_interval_ms * 1E6);
	MBX *mbx_tracker;
	int val;

	rt_allow_nonroot_hrt();
	mlockall(MCL_CURRENT | MCL_FUTURE);

	// create task
	rt_task = rt_task_init_schmod(nam2num("TSKTRA"), 2, 0, 0, SCHED_FIFO, rttools::cpu_id(0));

	if (!rt_task)
	{
		ERROR("Cannot init TRACKER task");
		pthread_exit(NULL);
	}

	mbx_tracker = rttools::get_mbx(MBX_TRACKER_NAME, MBX_TRACKER_BLOCK * sizeof(trackerdata_t));

	if (!mbx_tracker)
	{
		ERROR("Cannot init TRACKER mailbox");
		rt_task_delete(rt_task);
		pthread_exit(NULL);
	}

	while (_running)
	{
		// simulate the current position
		switch (_sim_type)
		{
		case constant:
			sim_constant();
			break;

		case calculated:
			sim_calculated_az();
			//sim_calculated_el();
			break;

		case from_file:
			sim_from_file();
			break;

		case cipic_angles:
			sim_cipic_angles();
			break;
		}

		_data.timestamp = (unsigned long) rt_get_time_ns();

		// send message (non-blocking)
		val = rt_mbx_send_if(mbx_tracker, &_data, sizeof(trackerdata_t));

		if (-EINVAL == val)
		{
			ERROR("Mailbox is invalid");
			break;
		}

		rt_sleep(interval);
	}

	rt_task_delete(rt_task);
	rttools::del_mbx(MBX_TRACKER_NAME);

	return arg;
}
Example #16
0
/* This is the main eNB thread. It gets woken up by the kernel driver using the RTAI message mechanism (rt_send and rt_receive). */
static void *eNB_thread(void *arg)
{
#ifdef RTAI
  RT_TASK *task;
  RTIME now;
#endif
  unsigned char slot=0,last_slot, next_slot;
  int hw_slot,frame=0;
  unsigned int msg1;
  unsigned int aa,slot_offset, slot_offset_F;
  int diff;
  int delay_cnt;
  RTIME time_in, time_diff;
  int mbox_target=0,mbox_current=0;
  int i,ret;
  int tx_offset;
  int bytes;

#ifdef RTAI
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
  LOG_D(HW,"Started eNB thread (id %p)\n",task);
#ifndef TIMER_ONESHOT_MODE
  now = rt_get_time();
  ret = rt_task_make_periodic(task, now, nano2count(500000LL));
  if (ret!=0)
    LOG_E(HW,"Problem with periodic timer\n");
#endif
#endif

#ifdef HARD_RT
  rt_make_hard_real_time();
#endif

  mlockall(MCL_CURRENT | MCL_FUTURE);

  timing_info.time_min = 100000000ULL;
  timing_info.time_max = 0;
  timing_info.time_avg = 0;
  timing_info.n_samples = 0;

  while (!oai_exit)
    {
      hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
      //LOG_D(HW,"eNB frame %d, time %llu: slot %d, hw_slot %d (mbox %d)\n",frame,rt_get_time_ns(),slot,hw_slot,((unsigned int *)DAQ_MBOX)[0]);
      //this is the mbox counter where we should be 
      //mbox_target = ((((slot+1)%20)*15+1)>>1)%150;
      mbox_target = mbox_bounds[slot];
      //this is the mbox counter where we are
      mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0];
      //this is the time we need to sleep in order to synchronize with the hw (in multiples of DAQ_PERIOD)
      if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
          diff = 150-mbox_current+mbox_target;
      else if ((mbox_current<15) && (mbox_target>=135))
          diff = -150+mbox_target-mbox_current;
      else
          diff = mbox_target - mbox_current;

      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_ENB, slot);
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_ENB, frame);
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX, *((volatile unsigned int *) openair0_exmimo_pci[card].rxcnt_ptr[0]));
      vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLES_DIFF, diff);
      
      time_in = rt_get_time_ns();
      //LOG_D(HW,"eNB Frame %d delaycnt %d : hw_slot %d (%d), slot %d, (slot+1)*15=%d, diff %d, time %llu\n",frame,delay_cnt,hw_slot,((unsigned int *)DAQ_MBOX)[0],slot,(((slot+1)*15)>>1),diff,time_in);
      //LOG_D(HW,"eNB Frame %d, time %llu: sleeping for %llu (slot %d, hw_slot %d, diff %d, mbox %d, delay_cnt %d)\n", frame, time_in, diff*DAQ_PERIOD,slot,hw_slot,diff,((volatile unsigned int *)DAQ_MBOX)[0],delay_cnt);
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,1);
#ifdef TIMER_ONESHOT_MODE
      //ret = rt_sleep_ns(DAQ_PERIOD * (slot%4==0?6:8));
      ret = rt_sleep_ns(500000);
      if (ret)
	LOG_D(HW,"eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame, time_in);
#else
      rt_task_wait_period();
#endif
      vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP,0);
 
      //hw_slot = (((((volatile unsigned int *)DAQ_MBOX)[0]+1)%150)<<1)/15;
      //LOG_D(HW,"eNB Frame %d : hw_slot %d, time %llu\n",frame,hw_slot,rt_get_time_ns());
 
      mbox_current = ((volatile unsigned int *)DAQ_MBOX)[0];
      if ((mbox_current>=135) && (mbox_target<15)) //handle the frame wrap-arround
	diff = 150-mbox_current+mbox_target;
      else if ((mbox_current<15) && (mbox_target>=135))
	diff = -150+mbox_target-mbox_current;
      else
	diff = mbox_target - mbox_current;
      

      last_slot = (slot)%LTE_SLOTS_PER_FRAME;
      if (last_slot <0)
        last_slot+=20;
      next_slot = (slot+3)%LTE_SLOTS_PER_FRAME;
      
      slot++;
      if (slot==20) {
        slot=0;
        frame++;
      }

      if (frame==1000)
	oai_exit=1;

#if defined(ENABLE_ITTI)
      itti_update_lte_time(frame, slot);
#endif
    }

  LOG_D(HW,"eNB_thread: finished, ran %d times.\n",frame);

#ifdef HARD_RT
  rt_make_soft_real_time();
#endif

  // clean task
#ifdef RTAI
  rt_task_delete(task);
#endif
  LOG_D(HW,"Task deleted. returning\n");
  return 0;
}
static void* rt_system_thread(void * arg)
{
	struct timeval tv;	
	int64_t ts1, ts2;
	SEM * shm_sem;
	SEM * sync_sem;
	RT_TASK *task;
	
	M3EcSystemShm * sys = (M3EcSystemShm *)arg;
	printf("Starting real-time thread\n",0);
	RTIME t_last;
	int cntr=0;
	task = rt_task_init_schmod(nam2num("M3SYSP"), 0, 0, 0, SCHED_FIFO, 0xF);
	rt_allow_nonroot_hrt();
	if (task==NULL)
	{
		printf("Failed to create RT-TASK M3SYSP\n",0);
		return 0;
	}
	shm_sem=(SEM*)rt_get_adr(nam2num(SEMNAM_M3LSHM));
	if (!shm_sem)
	{
		printf("Unable to find the SEMNAM_M3LSHM semaphore.\n",0);
		rt_task_delete(task);
		return 0;
	}
	//else
	//	printf("Allocated shm_sem semaphore  %08x \n",shm_sem);
	
	sync_sem=(SEM*)rt_get_adr(nam2num(SEMNAM_M3SYNC));
	if (!sync_sem)
	{
		printf("Unable to find the SEMNAM_M3SYNC semaphore.\n",0);
		rt_task_delete(task);
		rt_sem_delete(shm_sem);
		return 0;
	}
	//else
	//	printf("Allocated sync_sem semaphore  %08x \n",sync_sem);
	
	RTIME tick_period = nano2count(RT_TIMER_TICKS_NS); 
	RTIME now = rt_get_time();
	rt_task_make_periodic(task, now + tick_period, tick_period); 
	mlockall(MCL_CURRENT | MCL_FUTURE);
	rt_make_hard_real_time();
	t_last=now;
	sys_thread_active=1;
	uint64_t tl;
	while(!sys_thread_end)
	{
		rt_sem_wait(sync_sem);
		rt_sem_wait(shm_sem);
		if (cntr%200==0)
		{
			now=rt_get_time_ns();
			float dt = (now-t_last)/1000000.0;
			count2timeval(nano2count(rt_get_real_time_ns()), &tv);
			printf("\n\nM3 Cycle: %d: 200 cycles in %4.3f ms. EC cycles: %d\n", cntr,dt, sys->counter);
			printf("DT: timestamp_dt (uS) : %lld\n",(sys->timestamp_ns-tl)/1000);
			t_last=now;
			SysEcShmPrettyPrint(sys);
		}
		tl=sys->timestamp_ns;
		cntr++;
		rt_sem_signal(shm_sem);
		rt_task_wait_period();
	}	
	printf("Exiting RealTime Thread...\n",0);
	rt_make_soft_real_time();
	rt_task_delete(task);
	sys_thread_active=0;
	return 0;
}
/** ULSCH Decoding Thread */
static void * ulsch_thread(void *param)
{

  //unsigned long cpuid;
  unsigned int ulsch_thread_index = (unsigned int)param;

  RTIME time_in,time_out;
#ifdef RTAI
  RT_TASK *task;
  char ulsch_thread_name[64];
#endif

  int eNB_id = 0, UE_id = 0;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[eNB_id];

  if ((ulsch_thread_index <0) || (ulsch_thread_index>NUMBER_OF_UE_MAX)) {
    LOG_E(PHY,"[SCHED][ULSCH] Illegal ulsch_thread_index %d!!!!\n",ulsch_thread_index);
    return 0;
  }

#ifdef RTAI
  sprintf(ulsch_thread_name,"ULSCH_THREAD%d",ulsch_thread_index);

  LOG_I(PHY,"[SCHED][ULSCH] starting ulsch_thread %s for process %d\n",
        ulsch_thread_name,
        ulsch_thread_index);

  task = rt_task_init_schmod(nam2num(ulsch_thread_name), 0, 0, 0, SCHED_FIFO, 0xF);

  if (task==NULL) {
    LOG_E(PHY,"[SCHED][ULSCH] Problem starting ulsch_thread_index %d!!!!\n",ulsch_thread_index);
    return 0;
  } else {
    LOG_I(PHY,"[SCHED][ULSCH] ulsch_thread for process %d started with id %p\n",
          ulsch_thread_index,
          task);
  }

#endif

  mlockall(MCL_CURRENT | MCL_FUTURE);

  //rt_set_runnable_on_cpuid(task,1);
  //cpuid = rtai_cpuid();

#ifdef HARD_RT
  rt_make_hard_real_time();
#endif

  //ulsch_cpuid[ulsch_thread_index] = cpuid;

  while (!oai_exit) {

    if (pthread_mutex_lock(&ulsch_mutex[ulsch_thread_index]) != 0) {
      LOG_E(PHY,"[SCHED][ULSCH] error locking mutex.\n");
    } else {

      while (ulsch_instance_cnt[ulsch_thread_index] < 0) {
        pthread_cond_wait(&ulsch_cond[ulsch_thread_index],&ulsch_mutex[ulsch_thread_index]);
      }

      if (pthread_mutex_unlock(&ulsch_mutex[ulsch_thread_index]) != 0) {
        LOG_E(PHY,"[SCHED][ULSCH] error unlocking mutex.\n");
      }
    }

    if (oai_exit) break;

    LOG_D(PHY,"[SCHED][ULSCH] Frame %d: Calling ulsch_decoding with ulsch_thread_index = %d\n",phy_vars_eNB->proc[0].frame_tx,ulsch_thread_index);

    time_in = rt_get_time_ns();

    ulsch_decoding_procedures(ulsch_subframe[ulsch_thread_index]<<1,ulsch_thread_index,phy_vars_eNB,0);

    time_out = rt_get_time_ns();

    if (pthread_mutex_lock(&ulsch_mutex[ulsch_thread_index]) != 0) {
      msg("[openair][SCHED][ULSCH] error locking mutex.\n");
    } else {
      ulsch_instance_cnt[ulsch_thread_index]--;

      if (pthread_mutex_unlock(&ulsch_mutex[ulsch_thread_index]) != 0) {
        msg("[openair][SCHED][ULSCH] error unlocking mutex.\n");
      }
    }
  }

#ifdef HARD_RT
  rt_make_soft_real_time();
#endif

  msg("[openair][SCHED][ULSCH] ULSCH thread %d exiting\n",ulsch_thread_index);

  return 0;
}