Sleep on Arm Cortex

4

Estoy intentando poner en reposo un procesador m4 de cortezax (m3 con extensiones dsp) por poco menos de un segundo. Quiero poder decirle que se duerma, luego un segundo más tarde, o cuando se presiona un botón, retome justo donde lo dejé. He buscado en el manual de referencia y los modos VLPS o LLS parecen ajustarse a mis necesidades. Idealmente, me gustaría una función de retardo glorificado, para que se duerma por un segundo. No sé cómo comenzar a ingresar a ese modo o cómo programar el NVIC. Estoy usando C en metal desnudo.

Cualquier ayuda sería muy apreciada.

Aquí está el código:

#include "IntervalTimer.h"

//The following is where the SLEEPDEEP flag is at
#define SCR         (*((volatile unsigned long *) 0xE000ED10))

volatile uint32_t timerCounter0;
boolean printNow = false;

void timerCallback0() {
  timerCounter0++;
  printNow = true;
}

void setup() {
  SCR = SCR | 0x04;    //Set SLEEPDEEP
  Serial.begin(true);
  IntervalTimer timer0;
  timer0.begin(timerCallback0, 1000000);
}

void loop() {
  if (printNow) {
    Serial.println(timerCounter0);
    printNow = false;
    asm("wfi\n");
  }
}
    
pregunta robostork

3 respuestas

1

Estás contando muchos períodos de un temporizador bastante corto, cada vencimiento de los cuales requiere que te despiertes. Para obtener el máximo ahorro de energía, debe colocar la sincronización completamente en hardware, de modo que solo genere una interrupción al final del período deseado, o al menos con bastante poca frecuencia. Probablemente debería considerar el uso de un valor mayor en el registro del temporizador y, posiblemente, el uso de un divisor prescalar. (Incluso si se está despertando solo unas cuantas veces por segundo y, por lo tanto, no gasta mucha energía, le resultará difícil medir el consumo de energía a menos que use un alcance para medir a través de una resistencia en serie)

Sin embargo, incluso entonces es probable que aún se esté ejecutando un reloj PLL rápido, que consume mucha energía. Por lo tanto, para un mayor ahorro de energía, querrá cambiar a una fuente de reloj de baja potencia, como un reloj de respaldo de rango de KHz interno o externo, o al menos desactivar el PLL y posiblemente activar cualquier divisor de preescala de reloj de todo el sistema.

Y también es probable que tenga muchas partes del chip encendidas y sincronizadas que no son necesarias en el modo de suspensión; es probable que desee apagar y anular todo, excepto el GPIO, el controlador de interrupciones, el módulo de contador y la RAM.

Además, debe auditar el diseño de su circuito para cualquier caso en el que esté transmitiendo una señal contra una resistencia pullup o desplegable, o incluso deje que una entrada digital flote cerca de una transición lógica.

Lograr que un sistema descienda a los modos de espera de microamperios puede ser un proyecto involucrado, ya que elimina una lixiviación eléctrica tras otra. También tenga cuidado con las conexiones de depurador, serie, USB, etc., no solo como posibles cargas, sino también como posibles fuentes de energía ocultas para que el sistema obtenga energía mientras pasa por alto lo que esté midiendo (sí, puede obtener energía de los pines de datos).

    
respondido por el Chris Stratton
3

No estoy seguro de qué MCU está utilizando exactamente, así que revisé el STM32F4 manual de referencia , con el que estoy más familiarizado. Dado que los modos de suspensión son implementados por el núcleo ARM, debe ser similar a cualquier otra MCU Cortex M4. La Sección 5.3.3 trata sobre el ingreso / salida del modo de suspensión (verificándolo para más detalles).

Para entrar en modo de suspensión:

  

El modo de suspensión se ingresa mediante la ejecución de las instrucciones WFI (Wait For Interrupt) o WFE (Wait for Event).

Según el valor de algunos registros, el modo de suspensión se ingresa inmediatamente o solo después de salir del ISR de prioridad más baja.

Para salir después de 1 segundo, deberá configurar un temporizador que activará un ISR después de 1 segundo. (Ya que esto depende de la implementación de MCU, omitiré los detalles para el STM32F4). Si se ingresó el modo de suspensión con WFI, esta interrupción (así como cualquier otra interrupción) activará la MCU. Si necesita un control más detallado sobre qué debe hacer que se despierte la MCU, debe dormir con WFE y configurar el evento de activación (sección 10.2.3 del manual).

    
respondido por el abey
0

No estoy seguro de si esto es lo que buscabas, pero voy a intentarlo de todos modos.

Al usar C, debería poder hacer que el procesador no haga nada (es decir, dormir) usando la función sleep() de <time.h> .

Actualización:

#include <time.h>

 int main() {
     int sleepms;
     sleep(sleepms); //Sleep for "sleepms" milliseconds
 }
    
respondido por el haneefmubarak

Lea otras preguntas en las etiquetas