¿Por qué el código SendChar de UART es diferente entre IRQ y Polling?

0

Ahora estoy tratando de analizar el código UART de Cortex-m3 del STM32F103 en IRQ y modo de sondeo.

Respuesta: Encontré 2 tipos de código de ejemplo, como el siguiente. Esto es IRQ.

/*------------------------------------------------------------------------------
  SenChar
  transmit a character
 *------------------------------------------------------------------------------*/
int SendChar (int c) {
  struct buf_st *p = &tbuf;

                                                  // If the buffer is full, return an error value
  if (SIO_TBUFLEN >= TBUF_SIZE)
    return (-1);

  p->buf [p->in & (TBUF_SIZE - 1)] = c;           // Add data to the transmit buffer.
  p->in++;

  if (tx_restart) {                               // If transmit interrupt is disabled, enable it
    tx_restart = 0;
    USART1->CR1 |= USART_FLAG_TXE;                // enable TX interrupt
  }

  return (0);
}

Este es un método de sondeo.

/*----------------------------------------------------------------------------
  SendChar
  Write character to Serial Port.
 *----------------------------------------------------------------------------*/
int SendChar (int ch)  {

  while (!(USART1->SR & USART_FLAG_TXE));
  USART1->DR = (ch & 0x1FF);

  return (ch);
}

Pero no puedo entender por qué tienen un código de diferencia?

    
pregunta ele_911

1 respuesta

1

Respuesta estúpida: porque uno usa IRQ y el otro sondeo ... ¿Realmente no puedes esperar que dos métodos diferentes tengan el mismo código?

Para el método IRQ, falta la mitad de la implementación, ya que falta el controlador de interrupciones, que en realidad está colocando los bytes del búfer de envío en el registro de datos de la UART.

Y esa es la principal diferencia. El método de interrupción tiene un búfer de envío, por lo que puede rellenar bytes en el búfer y el método volverá aunque los bytes no se hayan enviado. Esto permite que su controlador realice un trabajo mientras la interrupción manejará el envío de los bytes fuera del búfer.

Por otro lado, el método de sondeo envía el byte directamente. Espera hasta que finalice una transferencia en curso del UART y luego envía el siguiente byte.

En ese caso, el método se bloqueará hasta que una transferencia eventualmente en curso finalice y envíe el byte de distancia.

Si solo envías un solo byte, el método de interrupción es una exageración, porque el uso de un búfer para un solo byte es solo un desperdicio si puedes ponerlo directamente en el UART.

Pero piense en el contexto en que se usa típicamente una función de este tipo:

SendString(char* string)
{
    int i=0;
    while (string[i] != 0)
    {
        if (string[i] == SendChar(string[i]))
        {
            i++;
        }
    }
}

Ahora, en el caso del método de interrupción, el SendString tendrá la posibilidad de rellenar toda la cadena en el búfer de envío (si es lo suficientemente grande), regresando muy rápidamente y su programa puede avanzar en el cálculo de cosas o lo que sea .

El método de sondeo tomaría el tiempo necesario para que la UART transfiera los bytes (menos uno porque no espera el último, para ser exactos). Dependiendo de la velocidad de UART, eso podría ser unos milisegundos costosos.

    
respondido por el Arsenal

Lea otras preguntas en las etiquetas