Manera correcta de esperar N ciclos en ARM Cortex-M4

Después de habilitar un reloj para un puerto determinado, debe esperar 4 ciclos para que el reloj termine de inicializarse. ¿Cómo se pueden esperar N ciclos de la manera adecuada?

En mi código usé esto:

__asm("nop");
__asm("nop");
__asm("nop");
__asm("nop");

Después de lo cual, uKeil IDE parece dejar de quejarse.

Alternativamente, espera un ciclo en el registro de estado del reloj. En caso de que la inicialización tarde más de lo esperado (falla de pll o encendido en caída de tensión/arranque de cristal)
Los NOP son una mala idea. "NOP no hace nada. NOP no es necesariamente un NOP que requiere mucho tiempo. El procesador puede eliminarlo de la canalización antes de que llegue a la etapa de ejecución. Use NOP para rellenar, por ejemplo, para colocar la siguiente instrucción en un límite de 64 bits". que se cita de infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/…
estos mcus se basan en canalizaciones y no son deterministas, por lo que, a diferencia de los viejos tiempos, no puede simplemente insertar instrucciones y asumir que toman una cierta cantidad de tiempo. puede ajustar algún código en una situación determinada, seguro, pero tiene que ajustarlo, no puede simplemente contar las instrucciones. La forma correcta de consumir una cantidad específica de tiempo es usar un temporizador (y luego está la latencia no determinista y el código del controlador que lo acompaña, pero es más predecible y confiable que las instrucciones de conteo manual).
si solo quiere matar el tiempo de una manera simple y que el compilador no se interponga en su camino, voltatile funciona, prefiero una función ficticia, en algún asm coloque la instrucción bx lr. luego haz un ciclo for(i=0;i<100;i++) dummy(i); y el compilador no puede optimizar ese bucle.

Respuestas (1)

Este es un método de aquí :

 volatile unsigned long delay;

 SYSCTL_RCGC2_R |= 0x00000010;   // 1) activate clock for Port E
 delay = SYSCTL_RCGC2_R;         //    allow time for clock to stabilize

También puede configurarnos los relojes e ir a hacer otra cosa durante algunos ciclos (inicializar algunas cosas), pero eso es un error potencial en el futuro.


Editar: la línea ficticia se compila en:

  400286:   681b        ldr r3, [r3, #0]
  400288:   9301        str r3, [sp, #4]

En la corteza M4

ldr es 2 ciclos

str es de 2 ciclos

Consulte aquí los recuentos de ciclos de M4.

La palabra clave volatile evita que las instrucciones ldr y str se combinen, según tengo entendido.

Veo lo que hiciste alli.
He visto esto antes, pero es muy vago para mí. ¿Cómo sé si una tarea ficticia tomará al menos 4 ciclos?
@Daveel; Creo que "barreras de memoria" y "volátiles" te darán la respuesta.