sleeptest.c 7.07 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

Florian Kaltenberger's avatar
Florian Kaltenberger committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
/*! \file lte-softmodem.c
* \brief main program to control HW and scheduling
* \author R. Knopp, F. Kaltenberger
* \date 2012
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr
* \note
* \warning
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sched.h>
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
#include <pthread.h>

#include "rt_wrapper.h"

#define TIMER_ONESHOT_MODE
#define FRAME_PERIOD 10000000ULL
#define DAQ_PERIOD 500000ULL
#define LTE_SLOTS_PER_FRAME  20

#ifdef RTAI
static SEM *mutex;
//static CND *cond;

static long int thread0;
static long int thread1;
//static long int sync_thread;
#else
#define OPENAIR_THREAD_STACK_SIZE    8192
#define OPENAIR_THREAD_PRIORITY        255
pthread_t thread0;
//pthread_t thread1;
pthread_attr_t attr_dlsch_threads;
struct sched_param sched_param_dlsch;
#endif

int oai_exit = 0;

struct timing_info_t {
  //unsigned int frame, hw_slot, last_slot, next_slot;
  RTIME time_min, time_max, time_avg, time_last, time_now;
  //unsigned int mbox0, mbox1, mbox2, mbox_target;
  unsigned int n_samples;
} timing_info;

void signal_handler(int sig)
{
  void *array[10];
  size_t size;

  if (sig==SIGSEGV) {
    // get void*'s for all entries on the stack
    size = backtrace(array, 10);
87

Florian Kaltenberger's avatar
Florian Kaltenberger committed
88 89 90 91
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
92
  } else {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
    oai_exit=1;
  }
}

void exit_fun(const char* s)
{
  void *array[10];
  size_t size;

  printf("Exiting: %s\n",s);

  oai_exit=1;
  //rt_sleep_ns(FRAME_PERIOD);

  //exit (-1);
}

int frame=0,slot=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 last_slot, next_slot;
  RTIME time_in, time_diff;
  int ret;

#ifdef RTAI
  task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF);
  printf("Started eNB thread (id %p)\n",task);
#ifndef TIMER_ONESHOT_MODE
  now = rt_get_time();
  ret = rt_task_make_periodic(task, now, nano2count(DAQ_PERIOD));
129

Florian Kaltenberger's avatar
Florian Kaltenberger committed
130 131
  if (ret!=0)
    printf("Problem with periodic timer\n");
132

Florian Kaltenberger's avatar
Florian Kaltenberger committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146
#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;

147 148
  while (!oai_exit) {
    time_in = rt_get_time_ns();
Florian Kaltenberger's avatar
Florian Kaltenberger committed
149
#ifdef TIMER_ONESHOT_MODE
150 151 152 153 154
    ret = rt_sleep_ns(DAQ_PERIOD);

    if (ret)
      printf("eNB Frame %d, time %llu: rt_sleep_ns returned %d\n",frame,time_in,ret);

Florian Kaltenberger's avatar
Florian Kaltenberger committed
155
#else
156
    rt_task_wait_period();
Florian Kaltenberger's avatar
Florian Kaltenberger committed
157
#endif
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
    time_diff = rt_get_time_ns() - time_in;

    if (time_diff > timing_info.time_max)
      timing_info.time_max = time_diff;

    if (time_diff < timing_info.time_min)
      timing_info.time_min = time_diff;

    timing_info.time_avg = (timing_info.time_avg*timing_info.n_samples + time_diff)/(timing_info.n_samples+1);
    timing_info.n_samples++;

    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++;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
181
    }
182
  }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198

  printf("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
  printf("Task deleted. returning\n");
  return 0;
}


199 200
int main(int argc, char **argv)
{
Florian Kaltenberger's avatar
Florian Kaltenberger committed
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

#ifdef RTAI
  RT_TASK *task;
  RTIME period;
#else
  int error_code;
#endif
  int i,j,aa;
  void *status;

  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);

#ifndef RTAI
  check_clock();
#endif

  mlockall(MCL_CURRENT | MCL_FUTURE);

#ifdef RTAI
  // make main thread LXRT soft realtime
  task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF);

  // start realtime timer and scheduler
#ifdef TIMER_ONESHOT_MODE
  rt_set_oneshot_mode();
  start_rt_timer(0);
  printf("started RTAI timer in oneshot mode\n");
#else
  rt_set_periodic_mode();
  period = start_rt_timer(nano2count(500000));
  printf("started RTAI timer with period %llu ns\n",count2nano(period));
#endif

  printf("Init mutex\n");
  //mutex = rt_get_adr(nam2num("MUTEX"));
  mutex = rt_sem_init(nam2num("MUTEX"), 1);
239 240 241 242 243

  if (mutex==0) {
    printf("Error init mutex\n");
    exit(-1);
  } else
Florian Kaltenberger's avatar
Florian Kaltenberger committed
244
    printf("mutex=%p\n",mutex);
245

Florian Kaltenberger's avatar
Florian Kaltenberger committed
246 247 248 249 250 251 252 253 254 255 256 257 258 259
#endif

  rt_sleep_ns(10*FRAME_PERIOD);

#ifndef RTAI
  pthread_attr_init (&attr_dlsch_threads);
  pthread_attr_setstacksize(&attr_dlsch_threads,OPENAIR_THREAD_STACK_SIZE);
  //attr_dlsch_threads.priority = 1;
  sched_param_dlsch.sched_priority = sched_get_priority_max(SCHED_FIFO); //OPENAIR_THREAD_PRIORITY;
  pthread_attr_setschedparam  (&attr_dlsch_threads, &sched_param_dlsch);
  pthread_attr_setschedpolicy (&attr_dlsch_threads, SCHED_FIFO);
#endif

#ifdef RTAI
260
  thread0 = rt_thread_create(eNB_thread, NULL, 100000000);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
261
#else
262 263 264 265 266 267 268 269 270
  error_code = pthread_create(&thread0, &attr_dlsch_threads, eNB_thread, NULL);

  if (error_code!= 0) {
    printf("[lte-softmodem.c] Could not allocate eNB_thread, error %d\n",error_code);
    return(error_code);
  } else {
    printf("[lte-softmodem.c] Allocate eNB_thread successful\n");
  }

Florian Kaltenberger's avatar
Florian Kaltenberger committed
271
#endif
272 273
  printf("eNB threads created\n");

Florian Kaltenberger's avatar
Florian Kaltenberger committed
274 275 276 277


  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
278

Florian Kaltenberger's avatar
Florian Kaltenberger committed
279 280 281
  //getchar();
  while (oai_exit==0) {

282 283 284
    printf("eNB Frame %d, hw_slot %d (time %llu): period %llu, sleep time (avg/min/max/samples) %llu / %llu / %llu / %d, ratio %f\n",frame,slot,rt_get_time_ns(),DAQ_PERIOD,timing_info.time_avg,
           timing_info.time_min,timing_info.time_max,timing_info.n_samples,(double)timing_info.time_avg/DAQ_PERIOD);

Florian Kaltenberger's avatar
Florian Kaltenberger committed
285 286 287 288 289 290

    rt_sleep_ns(100*FRAME_PERIOD);
  }

  // stop threads
#ifdef RTAI
291
  rt_thread_join(thread0);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
292
#else
293
  pthread_join(thread0,&status);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
294 295 296 297 298 299 300 301 302
#endif

#ifdef RTAI
  stop_rt_timer();
#endif

  return 0;
}