Programación de tareas del sistema integrado para la adquisición de datos en una red CAN

Estoy luchando con el concepto de cómo programar mis tareas.

Mi configuración: STM32F103 conectado a CAN. Tomando medidas con un módulo Lidar V3 de comunicaciones a través de I2C, luego distribuyendo esa medida en el CAN

La interrupción 1 es una interrupción del temporizador de 1 ms para iniciar el envío de mensajes en CAN

la interrupción 2 está activa al recibir el mensaje CAN

También tengo que sondear un registro a través de I2C en la unidad LIDAR para asegurarme de que la medición haya finalizado antes de poder usar I2C para leer el registro de distancia, fragmento de código que se muestra a continuación

        status = CheckLidarStatus();

        while ((status & LIDAR_BUSY) == LIDAR_BUSY)
        {
            status = CheckLidarStatus();
        }

Lo que creo que es el flujo correcto que debe tomar mi programa se muestra a continuación:

flujo de

Mis principales preocupaciones son:

  1. ¿El flujo parece una forma lógica de abordar esto?

  2. Si doy prioridad a la interrupción del temporizador (en lugar de RX int) para la transmisión CAN, ¿afectará esto negativamente a la red CAN, es decir, no tratará los mensajes CAN recibidos con la suficiente rapidez?

  3. Si cualquiera de las interrupciones está activa durante las comunicaciones I2C, ¿provocará que las comunicaciones I2C se "caigan"?

  4. ¿Es aceptable sentarse en un ciclo while esperando que el estado de Checklidar regrese como no ocupado, o hay una mejor manera de hacerlo?

¿Qué velocidad de bus CAN? El intervalo de 1 ms es muy rápido para el bus CAN.
@Jeroen3 Tasa de baudios de 500k, según mis cálculos, hay 250us por mensaje de cuadro de formato EXT que da una sobrecarga de 750us. ¿Cuál sería una tasa de actualización más típica para la transmisión CAN?
Un intervalo de 100 ms se considera rápido. Los principales estándares (p. ej., j1939) a menudo especifican que los mensajes no deben repetirse en 100 ms. Así que sí, 10 ms tal vez. Pero 1 ms, definitivamente no en una red donde no controlas todos los nodos.
@ Jeroen3 está bien, genial, ¡gracias por avisarnos!
@Jeroen3 10ms es bastante estándar. 100 ms es basura, no puede usar esos largos retrasos en un bus CAN de control de máquina. Si J1939 especificó intervalos de 100 ms, entonces J1939 no debe usarse en vehículos. Pero como lo es, no creo que los intervalos de 100 ms puedan ser obligatorios.
@Lundin Es una referencia, J1939 no está muy estrictamente definido. Puedes hacer redes más pequeñas. Depende del integrador de sistemas después de todo.

Respuestas (2)

  1. Sí, me parece lógico. Aunque, ¿cuál es la cantidad máxima de tiempo que el periférico lidar podría estar ocupado? Si eso es más de 1 milisegundo, podría perder una oportunidad de transmisión. Tal vez el caso ocupado debería simplemente omitir la lectura de datos en lugar de volver a sondear el estado.

  2. Sí, el controlador de interrupciones de menor prioridad se mantendrá desactivado mientras se ejecuta el controlador de interrupciones de mayor prioridad. Si el controlador de interrupción del temporizador de mayor prioridad se ejecuta más de lo que tarda el periférico CAN en recibir suficientes mensajes para desbordarse, perdería mensajes. Es por eso que es una buena regla general mantener breves los controladores de interrupciones. Y si todo lo que hace la interrupción del temporizador es establecer una bandera, entonces dudo que vaya a tener un problema.

    Otra forma de considerar esto es cuál es la penalización cuando cualquiera de los controladores de interrupción es retrasado por el otro. Cuando la interrupción de CAN se retrasa por la interrupción del temporizador, agregaría un retraso a la respuesta de CAN o, en el peor de los casos, soltaría un mensaje. Cuando la interrupción del temporizador se retrasa por la interrupción CAN, entonces agregaría fluctuación a la interrupción del temporizador. En el peor de los casos, se caería un milisegundo, pero la interrupción de CAN tendría que ejecutarse durante más de un milisegundo para que eso suceda. Entonces, ¿qué es menos deseable para su aplicación, un poco de retraso o un poco de nerviosismo?

  3. Es dudoso que cualquiera de las interrupciones rompa las comunicaciones I2C. Probablemente esté utilizando un periférico de controlador I2C que transmite/recibe bits en su mayoría independientemente de la CPU. El controlador I2C continuará registrando bits de entrada y salida según sea necesario sin el efecto de las interrupciones. (Si estuviera golpeando cada bit, habría un mayor impacto porque los relojes individuales podrían estirarse por una interrupción no relacionada. Pero incluso eso no es necesariamente un problema debido a la naturaleza síncrona de I2C. El dispositivo esclavo no debería ' No importa si los pulsos del reloj I2C se estiran).

  4. Puede ser aceptable sondear el estado LIDAR. Si no tiene nada más que hacer para la CPU, ¿cuál es el daño? Pero si el periférico lidar tiene una interrupción de "datos listos" de algún tipo, entonces podría habilitar esa interrupción y esperar la interrupción en lugar de sondear el estado.

1. Lo intentaré, omitiendo el registro de distancia de lectura en lugar de sondear el estado. En realidad, no menciona lo que sucedería si se aplicara un comando de lectura mientras su estado está ocupado, imagino que me daría el valor de registro pero no se actualizaría hasta que finalice la medición.
2. ¡Esto es realmente útil, gracias! 3. sí, es un periférico, no es el estiramiento lo que me preocupaba, sino que la brecha entre un punto de parada y un punto de inicio era demasiado grande, lo que me preocupaba. por ejemplo, para leer, envío la dirección de lo que quiero leer, luego detengo I2C. Luego comencé I2C nuevamente con la dirección del dispositivo en modo de lectura para recibir los datos almacenados en el registro. la brecha entre el inicio y la parada era mi preocupación, ya que la hoja de datos no alude a la rapidez con que se debe hacer esto
4. El lidar no es capaz de generar una interrupción ya que está conectado a través de I2C, y no genera automáticamente comunicaciones I2C para indicar que la medición ha finalizado. Sin embargo, como mencioné en mi primer comentario, me dio la idea de que puedo omitir la verificación del estado por completo y aceptar que puedo leer el registro de distancia con más frecuencia de lo que realmente se actualiza. Sin embargo, la hoja de datos para el lidar es breve y no indica las repercusiones de leer registros que no sean el estado mientras está ocupado realizando una medición. ¡Creo que debería estar bien!
¡Gracias por la respuesta muy útil y mejoró mi comprensión en general! Creo que me has dado lo suficiente para completar esto ahora.

Es la naturaleza de CAN que cuando intenta enviar un mensaje, puede experimentar colisiones con mensajes de mayor prioridad que necesita recibir y procesar.

Su propuesta muestra ISR extremadamente simples que simplemente establecen indicadores, y todo el trabajo real se realiza en un solo subproceso de fondo (no ISR).

No estoy familiarizado con los detalles del controlador CAN del STM32 y específicamente qué tan autónomo podría ser, pero su propuesta parece inadecuada con respecto a este problema.

Es lo suficientemente autónomo como para que solo tenga que marcar un buzón de correo listo para transmitir.
Gracias por su respuesta, solo los mensajes destinados a este nodo requerirían algún procesamiento por parte del procesador, lo que requeriría tomar los datos contenidos y aplicarlos al lidar a través de i2c (la configuración cambia en el módulo). ¿Me recomendaría poner este comando I2C en el ISR?
¡No, definitivamente no! El ISR de recepción de CAN debe tomar las medidas necesarias para que la interfaz CAN esté lista para recibir el siguiente mensaje, pero cualquier otro trabajo, como la comunicación con el LIDAR, debe posponerse a un subproceso en segundo plano.
ah, está bien, ahora veo lo que quieres decir, disculpas. Mi RX INT se activa solo al recibir un mensaje para este nodo. Para que el receptor esté listo para recibir mensajes aplicables nuevamente, tengo que liberar el FIFO, lo que significa configurar un poco, pero esto solo se puede hacer después de leer los datos. ¡Lo cual, como sugieres, lo dejaré en el hilo de fondo! Muchas gracias
De alguna manera, no me estoy aclarando. Si necesita leer datos del FIFO del controlador CAN para que esté listo para recibir el siguiente mensaje, definitivamente debe hacerlo en el ISR, colocar los datos en un búfer de memoria adecuado y luego establecer una bandera o lo que sea para el hilo de fondo Sin embargo, transmitir esos datos a través de la interfaz I2C lleva tiempo, lo que NO debe hacerse en el ISR. En cambio, el subproceso de fondo debe leer los datos del búfer de memoria y transmitirlos al LIDAR al ritmo que sea necesario.
Si fuera a hacer un proyecto como este, tendría un "hilo" dedicado solo a administrar la interfaz I2C al LIDAR. Verificaría si hay mensajes provenientes del bus CAN y los enviaría al LIDAR; de lo contrario, haría el sondeo de los datos de distancia. Esto facilita la gestión de la disputa entre los dos usos de la interfaz I2C.
Creo que es más probable que sea mi falta de comprensión con respecto a CAN y la programación que su claridad. Sin embargo, su último punto es claro y muy útil (+1)