⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 antenna.c

📁 This a framework to test new ideas in transmission technology. Actual development is a LDPC-coder in
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************             antenna.c  -  The antenna-implementation                            -------------------    begin                :  2002    authors              :  Linus Gasser    emails               :  linus.gasser@epfl.ch ***************************************************************************//***************************************************************************                                 Changes                                 ------- date - name - description 02-10-01 - ineiti - create 02-12-11 - ineiti - Changed from a DMA-packed thing to a most general                     antenna. 03/08/18 - ineiti - changed dispatch-thread to FIFO-scheduling with                     priority 1 04/01/07 - ineiti - fixed race-condition while initialising the dispatcher                     and starting it. 04/03/29 - ineiti - deleted thread_join on exiting the dispatcher, because                     this doesn't seem to be possible 04/06/01 - ineiti - only one thread that works on all channels. This                     fixes problems with multi-threading and assures		     a more neat handling of MIMO situations  **************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//** * This is an interface to different channel-implementations. */#define DBG_LVL 0#define EXPORT_SYMTAB#include "system.h"#include "debugging.h"#include "memory.h"#include "antenna.h"#include "sdb.h"typedef struct {  pthread_t thread;  void *stack;  pthread_cond_t cond;  pthread_mutex_t mutex;  int slot_len;  int state;  int offset;  int ch_id[MAX_ANTENNAS];  swr_sdb_id notify_sdb[MAX_ANTENNAS];}dispatch_t;#define STATE_EXIT 0#define STATE_STOPPED 1#define STATE_RUNNING 2// The dispatcher threaddispatch_t disp_thread;// The array of the antenna-parametersswr_ant_param_t params[ MAX_ANTENNAS ];// How many antennas are initialised alreadyint initialised_antennas;/** * @short The dispatcher thread */void *ant_dispatch( void* arg ) {  dispatch_t *this = &disp_thread;  int nbr_ant, wait, blocks, slots;  swr_ant_notify_t *notify;  swr_usr_msg_t *msg;  struct sched_param p;  // Make this a FIFO-realtime thread.  p.sched_priority = 1;  pthread_setschedparam (pthread_self(), SCHED_FIFO, &p);  // Initialising  PR_DBG( 2, "Dispatcher started, initialising\n" );  wait = blocks = this->offset = slots = 0;  // The main loop, once for each slot  do {    // Do the transmission, whatever it is, and wait for the next slot    if ( wait > 0 ) {      PR_DBG( 4, "Dispatcher is going to sleep for %i us\n",	      wait );      usleep( wait );    } else {      PR_DBG( 4, "Not waiting\n" );    }    if ( this->state == STATE_STOPPED ) {      // Go to sleep      PR_DBG( 4, "Dispatcher is waiting for further instructions\n" );      pthread_mutex_lock( &this->mutex );      pthread_cond_signal( &this->cond );      pthread_cond_wait( &this->cond, &this->mutex );      pthread_mutex_unlock( &this->mutex );      PR_DBG( 4, "Dispatcher is going to do %i\n", this->state );    }    // Perhaps we have to quit    if ( this->state == STATE_EXIT ) {      PR_DBG( 4, "Going to exit\n" );      break;    }    // Notify all queues    for ( nbr_ant=0; nbr_ant<initialised_antennas; nbr_ant++ ){      swr_sdb_id notify_sdb = this->notify_sdb[nbr_ant];       if ( notify_sdb >= 0 ) {	PR_DBG( 4, "Notifying queue %i\n", nbr_ant );	msg = swr_malloc( sizeof( swr_usr_msg_t ) );	strcpy( msg->id, "ANT" );	notify = swr_malloc( sizeof( swr_ant_notify_t ) );	notify->blocks = blocks + this->offset;	notify->slots = slots;	notify->slot_begin = ( notify->blocks % params[ nbr_ant ].frame_blocks ) *	  DAQ_DMA_BLOCK_SIZE_BYTES;	msg->data = notify;	PR_DBG( 4, "Sending to id %i: slot %i, blocks %i, offset %i\n",		notify_sdb, slots, blocks, this->offset );	swr_sdb_send_msg( this->notify_sdb[nbr_ant], SUBS_MSG_USER, msg, -1 );	PR_DBG( 4, "Sent message to %i\n", notify_sdb );      }    }    // The time up to the next slot    blocks += this->slot_len;    slots++;    // Get the time in us to wait for the next slot to pass    PR_DBG( 4, "How long do we have to wait?\n" );    wait = swr_ant_ch_io( blocks + this->offset );    PR_DBG( 4, "Finished while-loop and will wait for %i\n", wait );  } while ( this->state != STATE_EXIT );  PR_DBG( 3, "Byebye from the dispatcher\n" );  return NULL;}// The space we allocate for each thread#define THREAD_STACK_SIZE 16384/** * Initialises an antenna */int swr_ant_init( swr_sdb_id notify_sdb ) {  pthread_attr_t attr;  int id, ch;  if ( ( id = swr_ant_ch_init( params + initialised_antennas ) ) < 0 ) {    PR_DBG( 0, "Failed to initialise an antenna\n" );    return -1;  }  ch = initialised_antennas++;  disp_thread.ch_id[ch] = id;  disp_thread.notify_sdb[ch] = notify_sdb;  if ( !ch ){    // We have to initialise the thread    if ( disp_thread.state != STATE_EXIT ) {      PR_DBG( 0, "Dispatcher %i already exists\n", initialised_antennas );      initialised_antennas--;      return -1;    }    #ifndef REDHAT_TLS    // Initialisation of the dispatcher-thread, needs it's own    // stack.    disp_thread.stack = swr_malloc( THREAD_STACK_SIZE );    if ( !disp_thread.stack )      goto start_dma_err_stack;#endif        pthread_attr_init( &attr );#ifndef REDHAT_TLS    pthread_attr_setstackaddr( &attr, disp_thread.stack );    pthread_attr_setstacksize( &attr, THREAD_STACK_SIZE );#endif        pthread_attr_setfp_np( &attr, 1 );    disp_thread.state = STATE_STOPPED;    disp_thread.offset = 0;    pthread_cond_init( &disp_thread.cond, NULL );    pthread_mutex_init( &disp_thread.mutex, NULL );        pthread_mutex_lock( &disp_thread.mutex );#ifndef REDHAT_TLS    if ( pthread_create( &disp_thread.thread, &attr, ant_dispatch, 			 NULL ) < 0 )#else    if ( pthread_create( &disp_thread.thread, NULL, ant_dispatch, 			 NULL ) < 0 )#endif	      goto start_dma_err_pthread;        pthread_attr_destroy( &attr );        // Wait for the thread to sleep with cond_wait    pthread_cond_wait( &disp_thread.cond, &disp_thread.mutex );    pthread_mutex_unlock( &disp_thread.mutex );  }  return id;   start_dma_err_pthread:  PR_DBG( 0, "Couldn't start ch_dispatch\n" );  pthread_attr_destroy( &attr );#ifndef REDHAT_TLS  swr_free( disp_thread.stack ); start_dma_err_stack:#endif    swr_ant_ch_free( ch );  PR_DBG( 0, "Error\n" );  return -1;}/** * @short Deletes an antenna */int swr_ant_free( int nbr_ant ) {//  swr_ant_stop();  if ( nbr_ant >= MAX_ANTENNAS ) {    PR_DBG( 0, "Asked for antenna %i, but only %i are available\n",            nbr_ant, MAX_ANTENNAS );    return -1;  }  if ( disp_thread.state == STATE_EXIT ) {    PR_DBG( 0, "Can't stop dispatcher: not initialised\n" );    return -1;  }  if ( !--initialised_antennas ){    // It's the last antenna, exit the dispatcher    PR_DBG( 2, "Exit dispatcher\n" );    // First we have to stop the thread    pthread_mutex_lock( &disp_thread.mutex );    disp_thread.state = STATE_EXIT;    pthread_cond_signal( &disp_thread.cond );    pthread_mutex_unlock( &disp_thread.mutex );    PR_DBG( 2, "Dispatcher stopped\n" );    // Then wait for it to finish    pthread_cancel( disp_thread.thread );    //  pthread_join( disp_thread.thread, NULL );    PR_DBG( 2, "Thread cancelled (but not joined)\n" );    // And stop the channel    swr_ant_ch_free( nbr_ant );    PR_DBG( 1, "Stopped Channel\n" );    // Free the mutex and conditional    pthread_mutex_destroy( &disp_thread.mutex );    pthread_cond_destroy( &disp_thread.cond );#ifndef REDHAT_TLS    // Then do some cleaning-up    swr_free( disp_thread.stack );#endif  } else {    PR_DBG( 1, "Cleaned up one antenna\n" );  }  return 0;}/** * @short Starts the antenna */int swr_ant_start( int blocks_per_frame ) {  int nbr_ant;  swr_ant_param_t *ant;  PR_DBG( 1, "Starting antennas\n" );  // Put the dispatcher in running state

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -