Sondeo UART frente a interrupción

Tengo dos UARTpuertos en un MSP430que necesitan transmitir datos entre un controlador de host (Freescale IMX6) y dispositivos potenciales que se pueden conectar en el otro lado. El controlador de host comunica (lectura/escritura) datos con MSP430(incluidos los datos en serie de los dispositivos) a través de un bus I2C.

IMX6 --writes I2C--> MSP430 --writes `UART`0--> Device 0
IMX6 <---reads I2C-- MSP430 <---reads `UART`0-- Device 0

IMX6 --writes I2C--> MSP430 --writes `UART`1--> Device 1
IMX6 <---reads I2C-- MSP430 <---reads `UART`1-- Device 1

Actualmente, UARTlas recepciones se basan en interrupciones en el MSP430. Cuando entra un byte, interrumpe el MSP y arroja el byte a un búfer de anillo.

UARTlas escrituras, por otro lado, se basan en sondeos. En mi ciclo principal, tengo un UART_proceso que se ejecuta. En ese proceso, verifico si el UART TXbúfer de un solo byte del hardware está listo para un byte. Si es así, escribo un nuevo byte, establezco la transferencia y salgo de la función. Con esta funcionalidad, podría pasar (por ejemplo) 1 milisegundo antes de que envíe otro byte al UARTdispositivo, aunque los MSP UARThayan estado listos para transmitir otro byte mucho antes.

Mi preocupación es que si tengo que administrar 2 UARTpuertos MSP430que se ejecutan en 115200baudios, ¿será suficiente escribir un byte cada uno 1ms(potencialmente un poco más o menos) para el dispositivo? La transmisión de velocidad en baudios seguirá siendo 115,200obviamente, pero los bytes se transmitirán lentamente. Algunos cálculos rápidos y aproximados:

  • 1 bit a 115 200 tarda unos 8 µs.
  • 1 byte a 115 200 tardará aproximadamente (8 µs * 8 bits) = 64 µs.

Entonces, como puede ver, se puede transmitir un nuevo byte desde el UARTcontrolador, digamos cada 100 µs. Si estoy enviando un byte cada 1 ms, no estoy transmitiendo al dispositivo muy rápido (alrededor de 1/10) en comparación con la velocidad máxima potencial.

No quiero transmitir a UARTtravés de interrupciones, porque temo que 2 UARTS con ambos RXy TXestar basado en interrupciones puedan apoderarse de mi CPU. Tengo otras cosas importantes que estoy haciendo también en el MSP430. Como aceptar constantemente mensajes I2C a través de interrupciones y manejar un proceso IR basado en interrupciones de temporizador.

He considerado agregar un programador de tareas simple. Pero eso no haría mucho para acelerar las cosas porque probablemente ejecutaría el programador de tareas a intervalos de 1 ms. Esto solo garantizaría un UARTbyte de escritura cada 1 ms (que era lo que estaba proponiendo arriba de todos modos). La otra opción es considerar el uso de DMA con la UARTtransmisión. Pero solo quiero explorar estas opciones si es necesario.

Según su experiencia, ¿la mayoría de los UARTdispositivos/implementaciones estarán bien con la recepción de bytes a una velocidad lenta en comparación con la velocidad en baudios? ¿Alguna sugerencia general? Avísame si no estoy claro en algún punto. ¡Gracias!

Un byte tomará 10 bits con bit de inicio y parada.
¿Puede ejecutar la interrupción Tx con una prioridad más baja (no sé MSP430)? ¿Por qué ejecuta el Tx en el ciclo principal solo cada milisegundo?
Las prioridades de interrupción no se pueden modificar en el chip que estoy usando (MSP430FR5739). Las prioridades se basan en la dirección del vector. Cuanto menor sea la dirección, mayor será la prioridad. Tengo el Tx en el bucle principal donde se procesa dos veces por ciclo de bucle principal. Es probable que reciba servicio aproximadamente cada 300 us la mayor parte del tiempo. Pero ha habido ocasiones en las que se ha tardado más (cuando tengo una gran carga de interrupciones de I2C y un temporizador de emisor de infrarrojos). El 1ms era algo arbitrario. Sin embargo, creo que pasaré a tx'ing basado en interrupciones (alentado por Gustavo).
Por cierto, buen punto sobre los 10 bits por byte. ¡Nunca me molesté en buscar el recuento de bits exacto para las transferencias de bytes UART!
Tal vez su MSP430 esté al límite y necesite algo mejor.

Respuestas (3)

Sí, la mayoría del software que recibe datos a través de un canal asíncrono es independiente de la rapidez con la que llegan los datos (hasta el punto en que entran en juego los tiempos de espera). Para el receptor, su situación es comparable a una tasa de baudios que permite 1 char/ms.

Esto responde más directamente a mi pregunta principal. Los otros comentarios también han sido muy informativos.

Las rutinas basadas en interrupciones no se harán cargo de la CPU a menos que usted las permita.

He escrito muchos controladores uart MSP430 y la forma de abordar TX es hacer que el ISR envíe los bytes. Active el indicador de interrupción y luego deje que el ISR maneje el envío de bytes desde un búfer. Necesita un par de variables en la memoria para administrar esto, pero funciona muy bien.

Recuerda que eres tú quien activa el ISR para enviar los datos. Ya sabes cuántos bytes enviar. El ISR es bastante rápido, por lo que no hay toma de control.

Está utilizando el sondeo que, de hecho, está consumiendo su tiempo de CPU. No hay razón para esto. Las interrupciones no deben temerse, deben dominarse.

No mencionó qué MSP430 está usando, pero he estado ejecutando muchos diseños basados ​​​​en MSP430 con múltiples interfaces y nunca tuve un problema con las interrupciones al cargar la CPU. De hecho, los clientes han estado emocionados porque los problemas que tenían antes debido a las encuestas y otras cosas desaparecieron cuando los rediseñé.

Mencionaste RTOS. Dependiendo del MSP430, esto puede no ser práctico y no lo necesita. Un RTOS no resolverá este tipo de problemas.

A menudo uso sondeos para la transmisión e interrupciones para la recepción; si ese enfoque es adecuado dependerá del tipo de almacenamiento en búfer que tenga el UART y de cómo se compare su tasa de sondeo con la tasa a la que realmente necesita enviar datos.

Algunos chips tienen un UART que requiere que un byte se transmita por completo antes de que el código pueda cargar el siguiente byte. La mayoría de los chips permiten que el procesador cargue al menos un byte además del que actualmente se está agotando. Algunos pueden permitir que el procesador precargue 16 bytes o incluso más.

Si su puerto está configurado para 115,200 baudios, su UART puede almacenar en búfer un carácter más el que se está transmitiendo, y su intervalo de sondeo es de 100 us, entonces probablemente podrá transmitir casi pero no de manera continua, ya que en algunas ocasiones sondeará cuando el UART casi ha terminado de transmitir un byte, cargará un byte y ese byte terminará siendo enviado por completo antes de su próxima operación de sondeo. Si su intervalo de sondeo es mucho más largo que 100 us y el chip es como se describe, probablemente podrá enviar dos caracteres por intervalo de sondeo; si eso es adecuado dependerá de su aplicación.