2011-04-13 13 views
7

He estado experimentando con GNU Radio y encontré el programa tunnel.py. Este programa le permite canalizar el tráfico IP a través de un enlace de radio inalámbrico utilizando dispositivos Linux TUN/TAP. En su mayor parte funciona, sin embargo, una parte del código me confunde.¿Tengo un problema de subprocesamiento aquí?

Hay una clase que implementa una 'capa MAC básica'. Esta clase tiene una función de devolución de llamada que escribe un nuevo paquete en el dispositivo TUN. Esta función (phy_rx_callback) se llama desde una secuencia separada.

La función main_loop tiene un sentido de operador antes de transmitir un paquete nuevo. Lo que no entiendo es por qué está detectando un canal de recepción antes de transmitir en un canal de transmisión separado que no se superpone.

Ambos canales, RX y TX, son frecuencias separadas, y nuestro hardware permite la comunicación full-duplex.

SO, mi pregunta es con la ejecución de main_loop, ¿cuáles son las implicaciones de otro subproceso llamando asincrónicamente a la función phy_rx_callback? El problema es que estoy tratando de entender el propósito del lazo de detección del portador, encontré que al comentar ese código se reduce severamente el rendimiento. No tiene sentido para mí que usted monitoree un canal de recepción antes de usar un canal de transmisión, esencialmente convirtiéndolo en semidúplex. Entonces no veo el propósito de usar dos frecuencias, una para transmitir y otra para recibir. Empecé a preguntarme si había un extraño problema de enhebrado aquí.

Se crea inicialmente una sola instancia de la clase cs_mac. Un 'puntero' a la función rx_callback se pasa unos pocos niveles a la clase de subprocesos que realmente lo llama. Aquí está la clase cs_mac:

class cs_mac(object): 
    def __init__(self, tun_fd, verbose=False): 
     self.tun_fd = tun_fd  # file descriptor for TUN/TAP interface 
     self.verbose = verbose 
     self.tb = None    # top block (access to PHY) 

    def set_top_block(self, tb): 
     self.tb = tb 

    def phy_rx_callback(self, ok, payload): 
     if self.verbose: 
      print "Rx: ok = %r len(payload) = %4d" % (ok, len(payload)) 
     if ok: 
      os.write(self.tun_fd, payload) 

    def main_loop(self): 
     min_delay = 0.001    # seconds 
     while 1: 
      payload = os.read(self.tun_fd, 10*1024) 
      if not payload: 
       self.tb.send_pkt(eof=True) 
       break 
      if self.verbose: 
       print "Tx: len(payload) = %4d" % (len(payload),) 
      delay = min_delay 
      while self.tb.carrier_sensed(): 
       sys.stderr.write('B') 
       time.sleep(delay) 
       if delay < 0.050: 
        delay = delay * 2  # exponential back-off 
      self.tb.send_pkt(payload) 

Ok, así que usar ctypes.CDLL('libc.so.6').syscall(186)), que llama gettid descubrí que el hilo llamando a la función rx_callback tiene el mismo PID, sino un TID diferente.

La pregunta es, ¿cuáles son las implicaciones de tener una llamada de subproceso independiente una función de un objeto en el hilo principal (mientras que el hilo está en constante bucle)?

+0

No puedo decir que sé mucho de GNU Radio, pero aquí están mis 2 centavos. No debería tener problemas para colocar TX y RX en hilos separados, siempre y cuando utilicen recursos separados en el lado de la Radio GNU, tanto en el software como en el hardware. Usted dice que usan canales separados, por lo que parece que pueden estar separados. Por otro lado, están usando la misma antena, ¿así que puedes transmitir y recibir al mismo tiempo? – ktdrv

Respuesta

0

La función main_loop tiene un sentido de operador antes de transmitir un paquete nuevo. Lo que no entiendo es por qué está detectando un canal de recepción antes de transmitir en un canal de transmisión separado que no se superpone.

El CSMA/CA está diseñado para ser utilizado con sistemas half-duplex, donde todos los nodos usan la misma frecuencia para TX y RX. Así que tienes razón, no tiene sentido detectar el canal RX si estás transmitiendo en uno diferente.

carrier_sensed() se invoca en el archivo receive_path.py por lo que debe ejecutarse en el subproceso RX. En mi código, comente las líneas sys.stderr.write ('B') y time.sleep (delay) y esto no parece afectar el rendimiento. Puede ser diferente en mi caso ya que uso una placa secundaria XCVR que es semidúplex.

Cuestiones relacionadas