cómo mantenerse mutuamente exclusivo entre la interrupción y la tarea en ucos-III

3

Estoy ejecutando ucos-III en un tablero que tiene stm32 cpu y un sensor de giroscopio. ahora hago una interrupción en respuesta a la recepción de datos desde el giroscopio, y luego guardo los datos en un búfer. en el otro lado, comienzo una tarea con OSTaskCreate () que se utiliza para leer datos del búfer y analizarlos / analizarlos para calcular el grado. ahora quiero saber cómo mantener el funcionamiento exclusivo mutuo entre la función de interrupción y la función de tarea cuando se visita el búfer compartido. Antes de eso, he intentado usar habilitar / deshabilitar la interrupción con la macro ENTER_CRITICAL_SECTION. pero alguien me dijo que esa no es exactamente la mejor manera de hacerlo, porque cuando lo desactivas, también cierras la puerta para que os responda a otra fuente de interrupción. Entonces, ¿puedes decirme cuál es la mejor manera de hacer eso? ¿Hay algún otro marco de comunicación más adecuado para esta situación?

    
pregunta DarkHorse

1 respuesta

2

Si está utilizando STM32, probablemente tenga la posibilidad de enmascarar interrupciones específicas. Si está seguro de que solo la tarea y la interrupción del giro son los dos "hilos" que acceden a esta memoria compartida, podría enmascarar el giro del ISR. De esta manera, todas las demás interrupciones aún se podrían permitir, pero el acceso a la memoria compartida sigue siendo "atómico".

No sé qué MCU / CPU específica está ejecutando, pero el registro para enmascarar bits en Cortex-M3 / 4 se llama:

$$ EXTI- > IMR $$

EDITAR:

El doc indica en la página 69:

"Si se puede acceder a una sección crítica mediante una Rutina de servicio de interrupción (ISR) y una tarea, es necesario deshabilitar las interrupciones para proteger la región crítica".

Este suele ser el caso, a menos que pueda garantizar de otro modo que el ISR que tiene acceso a los datos compartidos no se active.

Cuando usas uC / OS-III OS_CRITICAL_ENTER () y OS_CRITICAL_EXIT () I asumo ellos llaman a la interrupción global deshabilitar / habilitar, pero como mencioné anteriormente, puedes enmascarar y deshabilitar las interrupciones que tengan acceso a estos datos compartidos antes de acceder a estos datos, luego habilítelos nuevamente cuando termine de acceder a los datos compartidos.

También hay otras formas de hacerlo. Si tiene un búfer de anillo y quizás algunas variables de índice, puede usar OS_CRITICAL_ENTER () justo antes de leer las variables de índice (que son memoria compartida) en una variable local y OS_CRITICAL_EXIT () después. No es necesario copiar el búfer de anillo, ya que no accederá a la misma dirección de memoria al mismo tiempo, suponiendo que los datos de escritura ISR y los datos de lectura del código de la aplicación. Copiar a las variables locales solo tomará algunos ciclos, por lo que las posibilidades de interrupciones son muy bajas durante este tiempo. También creo que la mayoría de las MCU / CPU ARM guardan una interrupción de cada tipo (el bit de indicador de interrupción específico) y cuando llamas a OS_CRITICAL_EXIT () se servirán. Si sucede que dos de las mismas interrupciones se activaron durante la copia de la variable local, una se perderá, pero esto es muy desagradable.

    
respondido por el iQt

Lea otras preguntas en las etiquetas